2021-02-24 22:53:57 +00:00
// Copyright (C) 2021 Storj Labs, Inc.
// See LICENSE for copying information.
< template >
2021-08-30 15:15:43 +01:00
< div class = "encrypt-container" >
< EncryptIcon / >
< h1 class = "encrypt-container__title" > Encrypt your data < / h1 >
< p class = "encrypt-container__info" >
The encryption passphrase is used to encrypt and access the data that you upload to Storj DCS . We strongly
encourage you to use a mnemonic phrase , which is automatically generated one on the client - side for you .
< span v-if ="isOnboardingTour" >
Alternatively , you can skip this step and enter a passphrase later into the Uplink CLI during setup .
< / span >
< / p >
< div class = "encrypt-container__header" >
< p class = "encrypt-container__header__rec" > RECOMMENDED < / p >
< div class = "encrypt-container__header__row" >
< p class = "encrypt-container__header__row__gen" : class = "{ active: isGenerate }" @click ="setToGenerate" > Generate Phrase < / p >
< div class = "encrypt-container__header__row__right" >
< p class = "encrypt-container__header__row__right__enter" : class = "{ active: !isGenerate }" @click ="setToEnter" > Enter Your Own Passphrase < / p >
< VInfo
class = "encrypt-container__header__row__right__info-button"
text = "We strongly encourage you to use a mnemonic phrase, which is automatically generated one on the client-side for you. Alternatively, you can enter your own passphrase."
>
< InfoIcon class = "encrypt-container__header__row__right__info-button__image" / >
< / VInfo >
< / div >
2021-02-24 22:53:57 +00:00
< / div >
< / div >
2021-08-30 15:15:43 +01:00
< div v-if ="isGenerate" class="encrypt-container__generate" >
< p class = "encrypt-container__generate__value" > { { passphrase } } < / p >
< VButton
class = "encrypt-container__generate__button"
label = "Copy"
width = "66px"
height = "30px"
is - blue - white = "true"
: on - press = "onCopyClick"
/ >
2021-04-14 16:38:58 +01:00
< / div >
2021-08-30 15:15:43 +01:00
< div v -else class = "encrypt-container__enter" >
< HeaderlessInput
placeholder = "Enter a passphrase here..."
width = "100%"
: error = "enterError"
@ setData = "setPassphrase"
/ >
2021-02-24 22:53:57 +00:00
< / div >
2021-08-30 15:15:43 +01:00
< div class = "encrypt-container__save" >
< h2 class = "encrypt-container__save__title" > Save your encryption passphrase < / h2 >
< p class = "encrypt-container__save__msg" >
Please note that Storj does not know or store your encryption passphrase . If you lose it , you will
not be able to recover your files .
2021-04-14 16:38:58 +01:00
< / p >
2021-08-30 15:15:43 +01:00
< p class = "encrypt-container__save__download" @click ="onDownloadClick" > Download as a text file < / p >
< / div >
< div class = "encrypt-container__buttons" >
< VButton
v - if = "isOnboardingTour"
class = "encrypt-container__buttons__back"
label = "< Back"
height = "64px"
border - radius = "62px"
: on - press = "onBackClick"
is - grey - blue = "true"
: is - disabled = "isLoading"
/ >
< VButton
v - if = "isOnboardingTour"
class = "encrypt-container__buttons__skip"
label = "Skip for now"
height = "64px"
border - radius = "62px"
: on - press = "onSkipClick"
is - grey - blue = "true"
: is - disabled = "isLoading"
/ >
< VButton
label = "Next >"
height = "64px"
border - radius = "62px"
: on - press = "onNextButtonClick"
: is - disabled = "isLoading"
/ >
2021-04-14 16:38:58 +01:00
< / div >
2021-02-24 22:53:57 +00:00
< / div >
< / template >
< script lang = "ts" >
import { Component , Prop , Vue } from 'vue-property-decorator' ;
2021-08-30 15:15:43 +01:00
import * as bip39 from "bip39" ;
2021-02-24 22:53:57 +00:00
2021-08-30 15:15:43 +01:00
import { RouteConfig } from "@/router" ;
import { LocalData , UserIDPassSalt } from "@/utils/localData" ;
import { Download } from "@/utils/download" ;
2021-02-24 22:53:57 +00:00
2021-08-30 15:15:43 +01:00
import VButton from '@/components/common/VButton.vue' ;
import VInfo from "@/components/common/VInfo.vue" ;
import HeaderlessInput from "@/components/common/HeaderlessInput.vue" ;
2021-02-24 22:53:57 +00:00
2021-08-30 15:15:43 +01:00
import EncryptIcon from "@/../static/images/objects/encrypt.svg" ;
import InfoIcon from "@/../static/images/common/greyInfo.svg" ;
2021-04-12 17:58:36 +01:00
2021-08-31 14:49:45 +01:00
// @vue/component
2021-02-24 22:53:57 +00:00
@ Component ( {
components : {
2021-08-30 15:15:43 +01:00
EncryptIcon ,
InfoIcon ,
VInfo ,
2021-02-24 22:53:57 +00:00
VButton ,
2021-08-30 15:15:43 +01:00
HeaderlessInput ,
2021-02-24 22:53:57 +00:00
} ,
} )
export default class GeneratePassphrase extends Vue {
@ Prop ( { default : ( ) => null } )
2021-08-30 15:15:43 +01:00
public readonly onNextClick : ( ) => unknown ;
@ Prop ( { default : ( ) => null } )
public readonly onBackClick : ( ) => unknown ;
@ Prop ( { default : ( ) => null } )
public readonly onSkipClick : ( ) => unknown ;
2021-02-24 22:53:57 +00:00
@ Prop ( { default : ( ) => null } )
public readonly setParentPassphrase : ( passphrase : string ) => void ;
@ Prop ( { default : false } )
public readonly isLoading : boolean ;
2021-04-14 16:38:58 +01:00
2021-08-30 15:15:43 +01:00
public isGenerate = true ;
public enterError = '' ;
2021-08-02 19:17:49 +01:00
public passphrase = '' ;
2021-02-24 22:53:57 +00:00
/ * *
* Lifecycle hook after initial render .
2021-08-30 15:15:43 +01:00
* Chooses correct state and generates mnemonic .
2021-02-24 22:53:57 +00:00
* /
public mounted ( ) : void {
2021-08-30 15:15:43 +01:00
const idPassSalt : UserIDPassSalt | null = LocalData . getUserIDPassSalt ( ) ;
if ( idPassSalt && idPassSalt . userId === this . $store . getters . user . id ) {
this . isGenerate = false ;
return ;
}
2021-02-24 22:53:57 +00:00
this . passphrase = bip39 . generateMnemonic ( ) ;
this . setParentPassphrase ( this . passphrase ) ;
}
2021-08-30 15:15:43 +01:00
/ * *
* Holds on copy button click logic .
* Copies passphrase to clipboard .
* /
public onCopyClick ( ) : void {
this . $copyText ( this . passphrase ) ;
this . $notify . success ( 'Passphrase was copied successfully' ) ;
}
2021-02-24 22:53:57 +00:00
2021-08-30 15:15:43 +01:00
/ * *
* Holds on download button click logic .
* Downloads encryption passphrase as a txt file .
* /
public onDownloadClick ( ) : void {
if ( ! this . passphrase ) {
this . enterError = 'Can\'t be empty!' ;
2021-02-24 22:53:57 +00:00
return ;
}
2021-08-30 15:15:43 +01:00
const fileName = 'StorjEncryptionPassphrase.txt' ;
2021-04-12 17:58:36 +01:00
2021-08-30 15:15:43 +01:00
Download . file ( this . passphrase , fileName ) ;
2021-02-24 22:53:57 +00:00
}
/ * *
2021-08-30 15:15:43 +01:00
* Sets passphrase from child component .
2021-02-24 22:53:57 +00:00
* /
2021-08-30 15:15:43 +01:00
public setPassphrase ( passphrase : string ) : void {
if ( this . enterError ) this . enterError = '' ;
2021-02-24 22:53:57 +00:00
2021-08-30 15:15:43 +01:00
this . passphrase = passphrase ;
2021-02-24 22:53:57 +00:00
this . setParentPassphrase ( this . passphrase ) ;
}
/ * *
2021-08-30 15:15:43 +01:00
* Sets view state to enter passphrase .
2021-02-24 22:53:57 +00:00
* /
2021-08-30 15:15:43 +01:00
public setToEnter ( ) : void {
2021-02-24 22:53:57 +00:00
this . passphrase = '' ;
2021-08-30 15:15:43 +01:00
this . isGenerate = false ;
2021-02-24 22:53:57 +00:00
}
/ * *
2021-08-30 15:15:43 +01:00
* Sets view state to generate passphrase .
2021-02-24 22:53:57 +00:00
* /
2021-08-30 15:15:43 +01:00
public setToGenerate ( ) : void {
if ( this . enterError ) this . enterError = '' ;
this . passphrase = bip39 . generateMnemonic ( ) ;
this . isGenerate = true ;
2021-02-24 22:53:57 +00:00
}
/ * *
2021-08-30 15:15:43 +01:00
* Holds on next button click logic .
2021-02-24 22:53:57 +00:00
* /
2021-08-30 15:15:43 +01:00
public async onNextButtonClick ( ) : Promise < void > {
if ( ! this . passphrase ) {
this . enterError = 'Can\'t be empty!' ;
return ;
}
await this . onNextClick ( ) ;
2021-02-24 22:53:57 +00:00
}
2021-04-14 16:38:58 +01:00
/ * *
2021-08-30 15:15:43 +01:00
* Indicates if current route is onboarding tour .
2021-04-14 16:38:58 +01:00
* /
2021-08-30 15:15:43 +01:00
public get isOnboardingTour ( ) : boolean {
return this . $route . path . includes ( RouteConfig . OnboardingTour . path ) ;
2021-04-14 16:38:58 +01:00
}
2021-02-24 22:53:57 +00:00
}
< / script >
< style scoped lang = "scss" >
2021-08-30 15:15:43 +01:00
. encrypt - container {
2021-02-24 22:53:57 +00:00
font - family : 'font_regular' , sans - serif ;
2021-08-30 15:15:43 +01:00
padding : 60 px ;
max - width : 500 px ;
background : # fcfcfc ;
box - shadow : 0 0 32 px rgba ( 0 , 0 , 0 , 0.04 ) ;
border - radius : 20 px ;
margin : 30 px auto 0 auto ;
2021-02-24 22:53:57 +00:00
& _ _title {
font - family : 'font_bold' , sans - serif ;
2021-08-30 15:15:43 +01:00
font - size : 36 px ;
line - height : 56 px ;
letter - spacing : 1 px ;
color : # 14142 b ;
margin : 35 px 0 10 px 0 ;
2021-02-24 22:53:57 +00:00
}
2021-08-30 15:15:43 +01:00
& _ _info {
font - size : 16 px ;
line - height : 32 px ;
letter - spacing : 0.75 px ;
color : # 1 b2533 ;
margin - bottom : 20 px ;
}
& _ _header {
& _ _rec {
font - size : 12 px ;
line - height : 15 px ;
color : # 1 b2533 ;
opacity : 0.4 ;
margin - bottom : 15 px ;
}
2021-02-24 22:53:57 +00:00
2021-08-30 15:15:43 +01:00
& _ _row {
2021-02-24 22:53:57 +00:00
display : flex ;
align - items : center ;
2021-08-30 15:15:43 +01:00
justify - content : space - between ;
2021-02-24 22:53:57 +00:00
2021-08-30 15:15:43 +01:00
& _ _gen {
2021-02-24 22:53:57 +00:00
font - family : 'font_bold' , sans - serif ;
font - size : 16 px ;
line - height : 19 px ;
2021-08-30 15:15:43 +01:00
color : # a9b5c1 ;
padding - bottom : 10 px ;
border - bottom : 5 px solid # fff ;
cursor : pointer ;
}
& _ _right {
display : flex ;
align - items : flex - start ;
& _ _enter {
font - family : 'font_bold' , sans - serif ;
font - size : 16 px ;
line - height : 19 px ;
color : # a9b5c1 ;
cursor : pointer ;
margin - right : 10 px ;
padding - bottom : 10 px ;
border - bottom : 5 px solid # fff ;
}
& _ _info - button {
& _ _image {
cursor : pointer ;
}
}
2021-02-24 22:53:57 +00:00
}
}
2021-08-30 15:15:43 +01:00
}
2021-02-24 22:53:57 +00:00
2021-08-30 15:15:43 +01:00
& _ _generate {
margin - top : 25 px ;
display : flex ;
align - items : center ;
padding : 25 px ;
background : # eff0f7 ;
border - radius : 10 px ;
& _ _value {
2021-04-14 16:38:58 +01:00
font - size : 16 px ;
2021-08-30 15:15:43 +01:00
line - height : 28 px ;
color : # 384 b65 ;
}
& _ _button {
margin - left : 32 px ;
min - width : 66 px ;
2021-04-14 16:38:58 +01:00
}
}
2021-08-30 15:15:43 +01:00
& _ _enter {
margin - top : 25 px ;
}
& _ _save {
2021-04-14 16:38:58 +01:00
border : 1 px solid # e6e9ef ;
2021-08-30 15:15:43 +01:00
border - radius : 10 px ;
padding : 25 px ;
margin - top : 35 px ;
2021-04-14 16:38:58 +01:00
& _ _title {
font - family : 'font_bold' , sans - serif ;
font - size : 16 px ;
line - height : 19 px ;
color : # 1 b2533 ;
2021-08-30 15:15:43 +01:00
margin - bottom : 10 px ;
2021-04-14 16:38:58 +01:00
}
2021-08-30 15:15:43 +01:00
& _ _msg {
2021-04-14 16:38:58 +01:00
font - size : 14 px ;
2021-08-30 15:15:43 +01:00
line - height : 20 px ;
2021-04-14 16:38:58 +01:00
color : # 1 b2533 ;
2021-08-30 15:15:43 +01:00
margin - bottom : 10 px ;
2021-02-24 22:53:57 +00:00
}
2021-08-30 15:15:43 +01:00
& _ _download {
2021-02-24 22:53:57 +00:00
font - family : 'font_bold' , sans - serif ;
font - size : 16 px ;
2021-08-30 15:15:43 +01:00
line - height : 19 px ;
color : # 0068 dc ;
cursor : pointer ;
2021-02-24 22:53:57 +00:00
}
}
2021-08-30 15:15:43 +01:00
& _ _buttons {
2021-02-24 22:53:57 +00:00
width : 100 % ;
display : flex ;
2021-08-30 15:15:43 +01:00
align - items : center ;
margin - top : 30 px ;
2021-02-24 22:53:57 +00:00
2021-08-30 15:15:43 +01:00
& _ _back ,
& _ _skip {
margin - right : 24 px ;
2021-02-24 22:53:57 +00:00
}
}
}
. active {
2021-08-30 15:15:43 +01:00
color : # 0149 ff ;
border - color : # 0149 ff ;
2021-02-24 22:53:57 +00:00
}
2021-08-30 15:15:43 +01:00
: : v - deep . info _ _box _ _message {
min - width : 440 px ;
2021-02-24 22:53:57 +00:00
2021-08-30 15:15:43 +01:00
& _ _regular - text {
line - height : 32 px ;
2021-02-24 22:53:57 +00:00
}
}
< / style >