storj/web/satellite/src/components/objects/EnterPassphrase.vue
Vitalii Shpital c3ae122aa7 web/satellite: enter passphrase step for objects page
WHAT:
enter passphrase step for users who has already created passphrase

WHY:
to let users proceed to upload step

Change-Id: I084aec5b863981978cf190f99ee95154fbed9aab
2021-03-19 10:59:32 +00:00

262 lines
7.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (C) 2021 Storj Labs, Inc.
// See LICENSE for copying information.
<template>
<div class="enter-pass">
<h1 class="enter-pass__title">Access Data in Browser</h1>
<div class="enter-pass__warning">
<div class="enter-pass__warning__header">
<WarningIcon/>
<p class="enter-pass__warning__header__label">Would you like to access files in your browser?</p>
</div>
<p class="enter-pass__warning__message">
Entering your encryption passphrase here will share encryption data with your browser.
<a
class="enter-pass__warning__message__link"
:href="docsLink"
target="_blank"
rel="noopener norefferer"
>
Learn More
</a>
</p>
</div>
<label class="enter-pass__textarea" for="enter-pass-textarea">
<p class="enter-pass__textarea__label">Encryption Passphrase</p>
<textarea
class="enter-pass__textarea__input"
:class="{ error: isError }"
id="enter-pass-textarea"
placeholder="Enter encryption passphrase here"
rows="2"
v-model="passphrase"
@input="resetErrors"
/>
</label>
<div class="enter-pass__error" v-if="isError">
<h2 class="enter-pass__error__title">Encryption Passphrase Does not Match</h2>
<p class="enter-pass__error__message">
This passphrase hasnt yet been used in the browser. Please ensure this is the encryption passphrase
used in libulink or the Uplink CLI.
</p>
<label class="enter-pass__error__check-area" :class="{ error: isCheckboxError }" for="error-checkbox">
<input
class="enter-pass__error__check-area__checkbox"
id="error-checkbox"
type="checkbox"
v-model="isCheckboxChecked"
@change="isCheckboxError = false"
>
I acknowledge this passphrase has not been used in this browser before.
</label>
</div>
<VButton
class="enter-pass__next-button"
label="Access Data"
width="100%"
height="48px"
:on-press="onAccessDataClick"
:is-disabled="!passphrase"
/>
</div>
</template>
<script lang="ts">
import pbkdf2 from 'pbkdf2';
import { Component, Vue } from 'vue-property-decorator';
import VButton from '@/components/common/VButton.vue';
import WarningIcon from '@/../static/images/common/greyWarning.svg';
import { RouteConfig } from '@/router';
import { LocalData, UserIDPassSalt } from '@/utils/localData';
import { MetaUtils } from '@/utils/meta';
@Component({
components: {
VButton,
WarningIcon,
},
})
export default class EnterPassphrase extends Vue {
public passphrase: string = '';
public isError: boolean = false;
public isCheckboxChecked: boolean = false;
public isCheckboxError: boolean = false;
/**
* Returns docs link from config.
*/
public get docsLink(): string {
return MetaUtils.getMetaContent('documentation-url');
}
/**
* Holds on access data button click logic.
*/
public onAccessDataClick(): void {
if (!this.passphrase) return;
const hashFromStorage: UserIDPassSalt | null = LocalData.getUserIDPassSalt();
if (!hashFromStorage) return;
pbkdf2.pbkdf2(this.passphrase, hashFromStorage.salt, 1, 64, (error, key) => {
if (error) return this.$notify.error(error.message);
const hashFromInput: string = key.toString('hex');
const areHashesEqual = () => {
return hashFromStorage.passwordHash === hashFromInput;
};
switch (true) {
case areHashesEqual() ||
!areHashesEqual() && this.isError && this.isCheckboxChecked:
this.$router.push(RouteConfig.UploadFile.path);
return;
case !areHashesEqual() && this.isError && !this.isCheckboxChecked:
this.isCheckboxError = true;
return;
case !areHashesEqual():
this.isError = true;
return;
default:
}
});
}
/**
* Reset all error states to default.
*/
public resetErrors(): void {
this.isCheckboxError = false;
this.isCheckboxChecked = false;
this.isError = false;
}
}
</script>
<style scoped lang="scss">
.enter-pass {
padding: 45px 50px 60px 50px;
max-width: 515px;
min-width: 515px;
font-family: 'font_regular', sans-serif;
font-style: normal;
display: flex;
flex-direction: column;
align-items: center;
background-color: #fff;
border-radius: 6px;
margin: 100px 0 30px 0;
&__title {
font-family: 'font_bold', sans-serif;
font-weight: bold;
font-size: 22px;
line-height: 27px;
color: #000;
margin: 0 0 30px 0;
}
&__warning {
display: flex;
flex-direction: column;
padding: 20px;
width: calc(100% - 40px);
background: #f5f6fa;
border: 1px solid #a9b5c1;
border-radius: 8px;
&__header {
display: flex;
align-items: center;
&__label {
font-style: normal;
font-family: 'font_bold', sans-serif;
font-size: 16px;
line-height: 19px;
color: #1b2533;
margin: 0 0 0 15px;
}
}
&__message {
font-size: 16px;
line-height: 19px;
color: #1b2533;
margin: 10px 0 0 0;
&__link {
font-family: 'font_medium', sans-serif;
color: #0068dc;
text-decoration: underline;
}
}
}
&__textarea {
width: 100%;
font-size: 16px;
line-height: 21px;
color: #354049;
margin: 26px 0 10px 0;
&__label {
margin: 0 0 8px 0;
}
&__input {
padding: 15px 20px;
resize: none;
width: calc(100% - 42px);
font-size: 14px;
line-height: 25px;
border-radius: 6px;
}
}
&__error {
display: flex;
flex-direction: column;
align-items: flex-start;
color: #ce3030;
&__title {
font-family: 'font_medium', sans-serif;
font-size: 16px;
line-height: 21px;
margin: 0 0 5px 0;
}
&__message {
font-weight: normal;
margin: 0 0 20px 0;
}
&__check-area {
margin-bottom: 32px;
font-size: 14px;
line-height: 19px;
color: #1b2533;
display: flex;
align-items: center;
cursor: pointer;
&__checkbox {
margin: 0 10px 0 0;
}
}
}
}
.error {
border-color: #ce3030;
color: #ce3030;
}
</style>