1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-06-28 10:55:27 +02:00
bitwarden-browser/src/app/settings/two-factor-setup.component.ts

186 lines
6.8 KiB
TypeScript
Raw Normal View History

2018-06-27 04:51:58 +02:00
import {
Component,
2018-06-27 15:20:09 +02:00
ComponentFactoryResolver,
2018-06-27 04:51:58 +02:00
OnInit,
2018-06-27 15:20:09 +02:00
Type,
ViewChild,
ViewContainerRef,
2018-06-27 04:51:58 +02:00
} from '@angular/core';
import { ApiService } from 'jslib/abstractions/api.service';
2018-07-18 15:21:23 +02:00
import { MessagingService } from 'jslib/abstractions/messaging.service';
import { PolicyService } from 'jslib/abstractions/policy.service';
2018-08-29 05:17:58 +02:00
import { UserService } from 'jslib/abstractions/user.service';
2018-06-27 04:51:58 +02:00
import { TwoFactorProviders } from 'jslib/services/auth.service';
import { PolicyType } from 'jslib/enums/policyType';
2018-06-27 04:51:58 +02:00
import { TwoFactorProviderType } from 'jslib/enums/twoFactorProviderType';
2018-06-27 15:20:09 +02:00
import { ModalComponent } from '../modal.component';
import { TwoFactorAuthenticatorComponent } from './two-factor-authenticator.component';
2018-06-27 21:27:59 +02:00
import { TwoFactorDuoComponent } from './two-factor-duo.component';
2018-06-27 22:56:11 +02:00
import { TwoFactorEmailComponent } from './two-factor-email.component';
2018-06-28 15:40:11 +02:00
import { TwoFactorRecoveryComponent } from './two-factor-recovery.component';
2018-06-27 23:50:31 +02:00
import { TwoFactorU2fComponent } from './two-factor-u2f.component';
2018-06-27 19:45:11 +02:00
import { TwoFactorYubiKeyComponent } from './two-factor-yubikey.component';
2018-06-27 15:20:09 +02:00
2018-06-27 04:51:58 +02:00
@Component({
selector: 'app-two-factor-setup',
templateUrl: 'two-factor-setup.component.html',
})
export class TwoFactorSetupComponent implements OnInit {
2018-06-27 15:20:09 +02:00
@ViewChild('recoveryTemplate', { read: ViewContainerRef }) recoveryModalRef: ViewContainerRef;
@ViewChild('authenticatorTemplate', { read: ViewContainerRef }) authenticatorModalRef: ViewContainerRef;
@ViewChild('yubikeyTemplate', { read: ViewContainerRef }) yubikeyModalRef: ViewContainerRef;
@ViewChild('u2fTemplate', { read: ViewContainerRef }) u2fModalRef: ViewContainerRef;
@ViewChild('duoTemplate', { read: ViewContainerRef }) duoModalRef: ViewContainerRef;
2018-06-27 22:56:11 +02:00
@ViewChild('emailTemplate', { read: ViewContainerRef }) emailModalRef: ViewContainerRef;
2018-06-27 15:20:09 +02:00
2018-07-18 23:20:35 +02:00
organizationId: string;
2018-06-27 04:51:58 +02:00
providers: any[] = [];
2018-08-29 05:17:58 +02:00
canAccessPremium: boolean;
showPolicyWarning = false;
2018-06-27 04:51:58 +02:00
loading = true;
2018-06-27 15:20:09 +02:00
private modal: ModalComponent = null;
2018-08-29 05:17:58 +02:00
constructor(protected apiService: ApiService, protected userService: UserService,
protected componentFactoryResolver: ComponentFactoryResolver, protected messagingService: MessagingService,
protected policyService: PolicyService) { }
2018-06-27 04:51:58 +02:00
async ngOnInit() {
2018-08-29 05:17:58 +02:00
this.canAccessPremium = await this.userService.canAccessPremium();
2018-06-27 04:51:58 +02:00
for (const key in TwoFactorProviders) {
if (!TwoFactorProviders.hasOwnProperty(key)) {
continue;
}
const p = (TwoFactorProviders as any)[key];
2018-07-18 23:10:26 +02:00
if (this.filterProvider(p.type)) {
2018-06-27 04:51:58 +02:00
continue;
}
this.providers.push({
type: p.type,
name: p.name,
description: p.description,
enabled: false,
premium: p.premium,
sort: p.sort,
});
}
this.providers.sort((a: any, b: any) => a.sort - b.sort);
await this.load();
}
async load() {
this.loading = true;
2018-07-18 23:10:26 +02:00
const providerList = await this.getTwoFactorProviders();
2018-06-27 04:51:58 +02:00
providerList.data.forEach((p) => {
this.providers.forEach((p2) => {
if (p.type === p2.type) {
p2.enabled = p.enabled;
}
});
});
this.evaluatePolicies();
2018-06-27 04:51:58 +02:00
this.loading = false;
}
2018-06-27 15:20:09 +02:00
manage(type: TwoFactorProviderType) {
switch (type) {
case TwoFactorProviderType.Authenticator:
2018-06-27 19:45:11 +02:00
const authComp = this.openModal(this.authenticatorModalRef, TwoFactorAuthenticatorComponent);
authComp.onUpdated.subscribe((enabled: boolean) => {
2018-06-27 21:27:59 +02:00
this.updateStatus(enabled, TwoFactorProviderType.Authenticator);
2018-06-27 15:20:09 +02:00
});
break;
2018-06-27 19:45:11 +02:00
case TwoFactorProviderType.Yubikey:
const yubiComp = this.openModal(this.yubikeyModalRef, TwoFactorYubiKeyComponent);
yubiComp.onUpdated.subscribe((enabled: boolean) => {
2018-06-27 21:27:59 +02:00
this.updateStatus(enabled, TwoFactorProviderType.Yubikey);
});
break;
case TwoFactorProviderType.Duo:
const duoComp = this.openModal(this.duoModalRef, TwoFactorDuoComponent);
duoComp.onUpdated.subscribe((enabled: boolean) => {
this.updateStatus(enabled, TwoFactorProviderType.Duo);
2018-06-27 19:45:11 +02:00
});
break;
2018-06-27 22:56:11 +02:00
case TwoFactorProviderType.Email:
const emailComp = this.openModal(this.emailModalRef, TwoFactorEmailComponent);
emailComp.onUpdated.subscribe((enabled: boolean) => {
this.updateStatus(enabled, TwoFactorProviderType.Email);
});
break;
2018-06-27 23:50:31 +02:00
case TwoFactorProviderType.U2f:
const u2fComp = this.openModal(this.u2fModalRef, TwoFactorU2fComponent);
u2fComp.onUpdated.subscribe((enabled: boolean) => {
this.updateStatus(enabled, TwoFactorProviderType.U2f);
});
break;
2018-06-27 15:20:09 +02:00
default:
break;
}
}
2018-06-28 15:40:11 +02:00
recoveryCode() {
this.openModal(this.recoveryModalRef, TwoFactorRecoveryComponent);
}
2018-07-18 15:21:23 +02:00
async premiumRequired() {
2018-08-29 05:17:58 +02:00
if (!this.canAccessPremium) {
2018-07-18 15:21:23 +02:00
this.messagingService.send('premiumRequired');
return;
}
}
2018-07-18 23:10:26 +02:00
protected getTwoFactorProviders() {
return this.apiService.getTwoFactorProviders();
}
protected filterProvider(type: TwoFactorProviderType) {
return type === TwoFactorProviderType.OrganizationDuo;
}
protected openModal<T>(ref: ViewContainerRef, type: Type<T>): T {
2018-06-27 15:20:09 +02:00
if (this.modal != null) {
this.modal.close();
}
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
this.modal = ref.createComponent(factory).instance;
const childComponent = this.modal.show<T>(type, ref);
this.modal.onClosed.subscribe(() => {
this.modal = null;
});
return childComponent;
}
2018-07-18 23:10:26 +02:00
protected updateStatus(enabled: boolean, type: TwoFactorProviderType) {
2018-06-27 15:20:09 +02:00
if (!enabled && this.modal != null) {
this.modal.close();
}
this.providers.forEach((p) => {
if (p.type === type) {
p.enabled = enabled;
}
});
this.evaluatePolicies();
}
private async evaluatePolicies() {
if (this.organizationId == null && this.providers.filter((p) => p.enabled).length === 1) {
const policies = await this.policyService.getAll(PolicyType.TwoFactorAuthentication);
this.showPolicyWarning = policies != null && policies.some((p) => p.enabled);
} else {
this.showPolicyWarning = false;
}
2018-06-27 15:20:09 +02:00
}
2018-06-27 04:51:58 +02:00
}