mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-23 11:56:00 +01:00
2fa recovery code view
This commit is contained in:
parent
ff65297275
commit
b9895ba79a
@ -45,6 +45,7 @@ import { SettingsComponent } from './settings/settings.component';
|
|||||||
import { TwoFactorAuthenticatorComponent } from './settings/two-factor-authenticator.component';
|
import { TwoFactorAuthenticatorComponent } from './settings/two-factor-authenticator.component';
|
||||||
import { TwoFactorDuoComponent } from './settings/two-factor-duo.component';
|
import { TwoFactorDuoComponent } from './settings/two-factor-duo.component';
|
||||||
import { TwoFactorEmailComponent } from './settings/two-factor-email.component';
|
import { TwoFactorEmailComponent } from './settings/two-factor-email.component';
|
||||||
|
import { TwoFactorRecoveryComponent } from './settings/two-factor-recovery.component';
|
||||||
import { TwoFactorSetupComponent } from './settings/two-factor-setup.component';
|
import { TwoFactorSetupComponent } from './settings/two-factor-setup.component';
|
||||||
import { TwoFactorU2fComponent } from './settings/two-factor-u2f.component';
|
import { TwoFactorU2fComponent } from './settings/two-factor-u2f.component';
|
||||||
import { TwoFactorVerifyComponent } from './settings/two-factor-verify.component';
|
import { TwoFactorVerifyComponent } from './settings/two-factor-verify.component';
|
||||||
@ -154,10 +155,11 @@ import { SearchCiphersPipe } from 'jslib/angular/pipes/search-ciphers.pipe';
|
|||||||
TwoFactorDuoComponent,
|
TwoFactorDuoComponent,
|
||||||
TwoFactorEmailComponent,
|
TwoFactorEmailComponent,
|
||||||
TwoFactorOptionsComponent,
|
TwoFactorOptionsComponent,
|
||||||
|
TwoFactorRecoveryComponent,
|
||||||
|
TwoFactorSetupComponent,
|
||||||
TwoFactorU2fComponent,
|
TwoFactorU2fComponent,
|
||||||
TwoFactorVerifyComponent,
|
TwoFactorVerifyComponent,
|
||||||
TwoFactorYubiKeyComponent,
|
TwoFactorYubiKeyComponent,
|
||||||
TwoFactorSetupComponent,
|
|
||||||
UserLayoutComponent,
|
UserLayoutComponent,
|
||||||
VaultComponent,
|
VaultComponent,
|
||||||
],
|
],
|
||||||
@ -179,6 +181,7 @@ import { SearchCiphersPipe } from 'jslib/angular/pipes/search-ciphers.pipe';
|
|||||||
TwoFactorDuoComponent,
|
TwoFactorDuoComponent,
|
||||||
TwoFactorEmailComponent,
|
TwoFactorEmailComponent,
|
||||||
TwoFactorOptionsComponent,
|
TwoFactorOptionsComponent,
|
||||||
|
TwoFactorRecoveryComponent,
|
||||||
TwoFactorU2fComponent,
|
TwoFactorU2fComponent,
|
||||||
TwoFactorYubiKeyComponent,
|
TwoFactorYubiKeyComponent,
|
||||||
],
|
],
|
||||||
|
27
src/app/settings/two-factor-recovery.component.html
Normal file
27
src/app/settings/two-factor-recovery.component.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<div class="modal fade">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h2 class="modal-title">
|
||||||
|
{{'twoStepLogin' | i18n}}
|
||||||
|
<small>{{'recoveryCodeTitle' | i18n}}</small>
|
||||||
|
</h2>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" attr.aria-label="{{'close' | i18n}}">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<app-two-factor-verify [type]="-1" (onAuthed)="auth($event)" *ngIf="!authed">
|
||||||
|
</app-two-factor-verify>
|
||||||
|
<ng-container *ngIf="authed">
|
||||||
|
<div class="modal-body text-center">
|
||||||
|
<p>{{'twoFactorRecoveryYourCode' | i18n}}:</p>
|
||||||
|
<code>{{code}}</code>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button appBlurClick type="button" class="btn btn-primary" (click)="print()">{{'printCode' | i18n}}</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">{{'close' | i18n}}</button>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
46
src/app/settings/two-factor-recovery.component.ts
Normal file
46
src/app/settings/two-factor-recovery.component.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||||
|
|
||||||
|
import { TwoFactorRecoverResponse } from 'jslib/models/response/twoFactorRescoverResponse';
|
||||||
|
|
||||||
|
import { TwoFactorProviderType } from 'jslib/enums/twoFactorProviderType';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-two-factor-recovery',
|
||||||
|
templateUrl: 'two-factor-recovery.component.html',
|
||||||
|
})
|
||||||
|
export class TwoFactorRecoveryComponent {
|
||||||
|
code: string;
|
||||||
|
authed: boolean;
|
||||||
|
twoFactorProviderType = TwoFactorProviderType;
|
||||||
|
|
||||||
|
constructor(private i18nService: I18nService) { }
|
||||||
|
|
||||||
|
auth(authResponse: any) {
|
||||||
|
this.authed = true;
|
||||||
|
this.processResponse(authResponse.response);
|
||||||
|
}
|
||||||
|
|
||||||
|
print() {
|
||||||
|
const w = window.open();
|
||||||
|
w.document.write('<div style="font-size: 18px; text-align: center;">' +
|
||||||
|
'<p>' + this.i18nService.t('twoFactorRecoveryYourCode') + ':</p>' +
|
||||||
|
'<code style="font-family: Menlo, Monaco, Consolas, \'Courier New\', monospace;">' +
|
||||||
|
this.code + '</code></div>' +
|
||||||
|
'<p style="text-align: center;">' + new Date() + '</p>');
|
||||||
|
w.print();
|
||||||
|
w.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private formatString(s: string) {
|
||||||
|
if (s == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return s.replace(/(.{4})/g, '$1 ').trim().toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
private processResponse(response: TwoFactorRecoverResponse) {
|
||||||
|
this.code = this.formatString(response.code);
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<app-callout type="warning">
|
<app-callout type="warning">
|
||||||
<p>{{'twoStepLoginRecoveryWarning' | i18n}}</p>
|
<p>{{'twoStepLoginRecoveryWarning' | i18n}}</p>
|
||||||
<button type="button" class="btn btn-outline-secondary">{{'viewRecoveryCode' | i18n}}</button>
|
<button type="button" class="btn btn-outline-secondary" (click)="recoveryCode()">{{'viewRecoveryCode' | i18n}}</button>
|
||||||
</app-callout>
|
</app-callout>
|
||||||
<h2 class="mt-5">
|
<h2 class="mt-5">
|
||||||
{{'providers' | i18n}}
|
{{'providers' | i18n}}
|
||||||
|
@ -19,6 +19,7 @@ import { ModalComponent } from '../modal.component';
|
|||||||
import { TwoFactorAuthenticatorComponent } from './two-factor-authenticator.component';
|
import { TwoFactorAuthenticatorComponent } from './two-factor-authenticator.component';
|
||||||
import { TwoFactorDuoComponent } from './two-factor-duo.component';
|
import { TwoFactorDuoComponent } from './two-factor-duo.component';
|
||||||
import { TwoFactorEmailComponent } from './two-factor-email.component';
|
import { TwoFactorEmailComponent } from './two-factor-email.component';
|
||||||
|
import { TwoFactorRecoveryComponent } from './two-factor-recovery.component';
|
||||||
import { TwoFactorU2fComponent } from './two-factor-u2f.component';
|
import { TwoFactorU2fComponent } from './two-factor-u2f.component';
|
||||||
import { TwoFactorYubiKeyComponent } from './two-factor-yubikey.component';
|
import { TwoFactorYubiKeyComponent } from './two-factor-yubikey.component';
|
||||||
|
|
||||||
@ -120,6 +121,10 @@ export class TwoFactorSetupComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recoveryCode() {
|
||||||
|
this.openModal(this.recoveryModalRef, TwoFactorRecoveryComponent);
|
||||||
|
}
|
||||||
|
|
||||||
private openModal<T>(ref: ViewContainerRef, type: Type<T>): T {
|
private openModal<T>(ref: ViewContainerRef, type: Type<T>): T {
|
||||||
if (this.modal != null) {
|
if (this.modal != null) {
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
|
@ -46,6 +46,9 @@ export class TwoFactorVerifyComponent {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
|
case -1:
|
||||||
|
this.formPromise = this.apiService.getTwoFactorRecover(request);
|
||||||
|
break;
|
||||||
case TwoFactorProviderType.Duo:
|
case TwoFactorProviderType.Duo:
|
||||||
this.formPromise = this.apiService.getTwoFactorDuo(request);
|
this.formPromise = this.apiService.getTwoFactorDuo(request);
|
||||||
break;
|
break;
|
||||||
|
@ -1125,5 +1125,12 @@
|
|||||||
},
|
},
|
||||||
"twoFactorU2fProblemReading": {
|
"twoFactorU2fProblemReading": {
|
||||||
"message": "There was a problem reading the security key."
|
"message": "There was a problem reading the security key."
|
||||||
|
},
|
||||||
|
"twoFactorRecoveryYourCode": {
|
||||||
|
"message": "Your Bitwarden two-step login recovery code"
|
||||||
|
},
|
||||||
|
"printCode": {
|
||||||
|
"message": "Print Code",
|
||||||
|
"description": "Print 2FA recovery code"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -378,6 +378,12 @@ app-avatar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app-two-factor-recovery {
|
||||||
|
code {
|
||||||
|
font-size: $font-size-lg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#duo-frame {
|
#duo-frame {
|
||||||
background: url('../images/loading.svg') 0 0 no-repeat;
|
background: url('../images/loading.svg') 0 0 no-repeat;
|
||||||
height: 330px;
|
height: 330px;
|
||||||
|
Loading…
Reference in New Issue
Block a user