mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
fix(two-factor) [PM-21204]: Users without premium cannot disable premium 2FA (#17134)
* refactor(two-factor-service) [PM-21204]: Stub API methods in TwoFactorService (domain). * refactor(two-factor-service) [PM-21204]: Build out stubs and add documentation. * refactor(two-factor-service) [PM-21204]: Update TwoFactorApiService call sites to use TwoFactorService. * refactor(two-fatcor) [PM-21204]: Remove deprecated and unused formPromise methods. * refactor(two-factor) [PM-21204]: Move 2FA-supporting services into common/auth/two-factor feature namespace. * refactor(two-factor) [PM-21204]: Update imports for service/init containers. * feat(two-factor) [PM-21204]: Add a disabling flow for Premium 2FA when enabled on a non-Premium account. * fix(two-factor-service) [PM-21204]: Fix type-safety of module constants. * fix(multiple) [PM-21204]: Prettier. * fix(user-verification-dialog) [PM-21204]: Remove bodyText configuration for this use. * fix(user-verification-dialog) [PM-21204]: Improve the error message displayed to the user.
This commit is contained in:
@@ -2,7 +2,7 @@ import { DOCUMENT } from "@angular/common";
|
|||||||
import { inject, Inject, Injectable } from "@angular/core";
|
import { inject, Inject, Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { AbstractThemingService } from "@bitwarden/angular/platform/services/theming/theming.service.abstraction";
|
import { AbstractThemingService } from "@bitwarden/angular/platform/services/theming/theming.service.abstraction";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli
|
|||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||||
import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction";
|
import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
@@ -28,7 +27,7 @@ import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/ide
|
|||||||
import { PasswordRequest } from "@bitwarden/common/auth/models/request/password.request";
|
import { PasswordRequest } from "@bitwarden/common/auth/models/request/password.request";
|
||||||
import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two-factor-email.request";
|
import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two-factor-email.request";
|
||||||
import { UpdateTempPasswordRequest } from "@bitwarden/common/auth/models/request/update-temp-password.request";
|
import { UpdateTempPasswordRequest } from "@bitwarden/common/auth/models/request/update-temp-password.request";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import { TwoFactorService, TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { ClientType } from "@bitwarden/common/enums";
|
import { ClientType } from "@bitwarden/common/enums";
|
||||||
import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service";
|
import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service";
|
||||||
import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string";
|
import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string";
|
||||||
|
|||||||
@@ -49,10 +49,14 @@ import { DefaultActiveUserAccessor } from "@bitwarden/common/auth/services/defau
|
|||||||
import { DevicesApiServiceImplementation } from "@bitwarden/common/auth/services/devices-api.service.implementation";
|
import { DevicesApiServiceImplementation } from "@bitwarden/common/auth/services/devices-api.service.implementation";
|
||||||
import { MasterPasswordApiService } from "@bitwarden/common/auth/services/master-password/master-password-api.service.implementation";
|
import { MasterPasswordApiService } from "@bitwarden/common/auth/services/master-password/master-password-api.service.implementation";
|
||||||
import { TokenService } from "@bitwarden/common/auth/services/token.service";
|
import { TokenService } from "@bitwarden/common/auth/services/token.service";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/services/two-factor.service";
|
|
||||||
import { UserVerificationApiService } from "@bitwarden/common/auth/services/user-verification/user-verification-api.service";
|
import { UserVerificationApiService } from "@bitwarden/common/auth/services/user-verification/user-verification-api.service";
|
||||||
import { UserVerificationService } from "@bitwarden/common/auth/services/user-verification/user-verification.service";
|
import { UserVerificationService } from "@bitwarden/common/auth/services/user-verification/user-verification.service";
|
||||||
import { TwoFactorApiService, DefaultTwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import {
|
||||||
|
DefaultTwoFactorService,
|
||||||
|
TwoFactorService,
|
||||||
|
TwoFactorApiService,
|
||||||
|
DefaultTwoFactorApiService,
|
||||||
|
} from "@bitwarden/common/auth/two-factor";
|
||||||
import {
|
import {
|
||||||
AutofillSettingsService,
|
AutofillSettingsService,
|
||||||
AutofillSettingsServiceAbstraction,
|
AutofillSettingsServiceAbstraction,
|
||||||
@@ -627,10 +631,11 @@ export class ServiceContainer {
|
|||||||
this.stateProvider,
|
this.stateProvider,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.twoFactorService = new TwoFactorService(
|
this.twoFactorService = new DefaultTwoFactorService(
|
||||||
this.i18nService,
|
this.i18nService,
|
||||||
this.platformUtilsService,
|
this.platformUtilsService,
|
||||||
this.globalStateProvider,
|
this.globalStateProvider,
|
||||||
|
this.twoFactorApiService,
|
||||||
);
|
);
|
||||||
|
|
||||||
const sdkClientFactory = flagEnabled("sdk")
|
const sdkClientFactory = flagEnabled("sdk")
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { AbstractThemingService } from "@bitwarden/angular/platform/services/the
|
|||||||
import { WINDOW } from "@bitwarden/angular/services/injection-tokens";
|
import { WINDOW } from "@bitwarden/angular/services/injection-tokens";
|
||||||
import { EventUploadService as EventUploadServiceAbstraction } from "@bitwarden/common/abstractions/event/event-upload.service";
|
import { EventUploadService as EventUploadServiceAbstraction } from "@bitwarden/common/abstractions/event/event-upload.service";
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||||
import { DefaultVaultTimeoutService } from "@bitwarden/common/key-management/vault-timeout";
|
import { DefaultVaultTimeoutService } from "@bitwarden/common/key-management/vault-timeout";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
@@ -39,7 +39,7 @@ export class InitService {
|
|||||||
private vaultTimeoutService: DefaultVaultTimeoutService,
|
private vaultTimeoutService: DefaultVaultTimeoutService,
|
||||||
private i18nService: I18nServiceAbstraction,
|
private i18nService: I18nServiceAbstraction,
|
||||||
private eventUploadService: EventUploadServiceAbstraction,
|
private eventUploadService: EventUploadServiceAbstraction,
|
||||||
private twoFactorService: TwoFactorServiceAbstraction,
|
private twoFactorService: TwoFactorService,
|
||||||
private notificationsService: ServerNotificationsService,
|
private notificationsService: ServerNotificationsService,
|
||||||
private platformUtilsService: PlatformUtilsServiceAbstraction,
|
private platformUtilsService: PlatformUtilsServiceAbstraction,
|
||||||
private stateService: StateServiceAbstraction,
|
private stateService: StateServiceAbstraction,
|
||||||
|
|||||||
@@ -11,16 +11,17 @@ import {
|
|||||||
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { TwoFactorDuoResponse } from "@bitwarden/common/auth/models/response/two-factor-duo.response";
|
import { TwoFactorDuoResponse } from "@bitwarden/common/auth/models/response/two-factor-duo.response";
|
||||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
import { DialogRef, DialogService } from "@bitwarden/components";
|
import { DialogRef, DialogService, ToastService } from "@bitwarden/components";
|
||||||
|
|
||||||
import { TwoFactorSetupDuoComponent } from "../../../auth/settings/two-factor/two-factor-setup-duo.component";
|
import { TwoFactorSetupDuoComponent } from "../../../auth/settings/two-factor/two-factor-setup-duo.component";
|
||||||
import { TwoFactorSetupComponent as BaseTwoFactorSetupComponent } from "../../../auth/settings/two-factor/two-factor-setup.component";
|
import { TwoFactorSetupComponent as BaseTwoFactorSetupComponent } from "../../../auth/settings/two-factor/two-factor-setup.component";
|
||||||
@@ -37,7 +38,7 @@ export class TwoFactorSetupComponent extends BaseTwoFactorSetupComponent impleme
|
|||||||
tabbedHeader = false;
|
tabbedHeader = false;
|
||||||
constructor(
|
constructor(
|
||||||
dialogService: DialogService,
|
dialogService: DialogService,
|
||||||
twoFactorApiService: TwoFactorApiService,
|
twoFactorService: TwoFactorService,
|
||||||
messagingService: MessagingService,
|
messagingService: MessagingService,
|
||||||
policyService: PolicyService,
|
policyService: PolicyService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
@@ -46,16 +47,20 @@ export class TwoFactorSetupComponent extends BaseTwoFactorSetupComponent impleme
|
|||||||
protected accountService: AccountService,
|
protected accountService: AccountService,
|
||||||
configService: ConfigService,
|
configService: ConfigService,
|
||||||
i18nService: I18nService,
|
i18nService: I18nService,
|
||||||
|
protected userVerificationService: UserVerificationService,
|
||||||
|
protected toastService: ToastService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
dialogService,
|
dialogService,
|
||||||
twoFactorApiService,
|
twoFactorService,
|
||||||
messagingService,
|
messagingService,
|
||||||
policyService,
|
policyService,
|
||||||
billingAccountProfileStateService,
|
billingAccountProfileStateService,
|
||||||
accountService,
|
accountService,
|
||||||
configService,
|
configService,
|
||||||
i18nService,
|
i18nService,
|
||||||
|
userVerificationService,
|
||||||
|
toastService,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +123,7 @@ export class TwoFactorSetupComponent extends BaseTwoFactorSetupComponent impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected getTwoFactorProviders() {
|
protected getTwoFactorProviders() {
|
||||||
return this.twoFactorApiService.getTwoFactorOrganizationProviders(this.organizationId);
|
return this.twoFactorService.getTwoFactorOrganizationProviders(this.organizationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected filterProvider(type: TwoFactorProviderType): boolean {
|
protected filterProvider(type: TwoFactorProviderType): boolean {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
|||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { TwoFactorProviderResponse } from "@bitwarden/common/auth/models/response/two-factor-provider.response";
|
import { TwoFactorProviderResponse } from "@bitwarden/common/auth/models/response/two-factor-provider.response";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
@@ -23,14 +23,14 @@ describe("ChangeEmailComponent", () => {
|
|||||||
let fixture: ComponentFixture<ChangeEmailComponent>;
|
let fixture: ComponentFixture<ChangeEmailComponent>;
|
||||||
|
|
||||||
let apiService: MockProxy<ApiService>;
|
let apiService: MockProxy<ApiService>;
|
||||||
let twoFactorApiService: MockProxy<TwoFactorApiService>;
|
let twoFactorService: MockProxy<TwoFactorService>;
|
||||||
let accountService: FakeAccountService;
|
let accountService: FakeAccountService;
|
||||||
let keyService: MockProxy<KeyService>;
|
let keyService: MockProxy<KeyService>;
|
||||||
let kdfConfigService: MockProxy<KdfConfigService>;
|
let kdfConfigService: MockProxy<KdfConfigService>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
apiService = mock<ApiService>();
|
apiService = mock<ApiService>();
|
||||||
twoFactorApiService = mock<TwoFactorApiService>();
|
twoFactorService = mock<TwoFactorService>();
|
||||||
keyService = mock<KeyService>();
|
keyService = mock<KeyService>();
|
||||||
kdfConfigService = mock<KdfConfigService>();
|
kdfConfigService = mock<KdfConfigService>();
|
||||||
accountService = mockAccountServiceWith("UserId" as UserId);
|
accountService = mockAccountServiceWith("UserId" as UserId);
|
||||||
@@ -40,7 +40,7 @@ describe("ChangeEmailComponent", () => {
|
|||||||
providers: [
|
providers: [
|
||||||
{ provide: AccountService, useValue: accountService },
|
{ provide: AccountService, useValue: accountService },
|
||||||
{ provide: ApiService, useValue: apiService },
|
{ provide: ApiService, useValue: apiService },
|
||||||
{ provide: TwoFactorApiService, useValue: twoFactorApiService },
|
{ provide: TwoFactorService, useValue: twoFactorService },
|
||||||
{ provide: I18nService, useValue: { t: (key: string) => key } },
|
{ provide: I18nService, useValue: { t: (key: string) => key } },
|
||||||
{ provide: KeyService, useValue: keyService },
|
{ provide: KeyService, useValue: keyService },
|
||||||
{ provide: MessagingService, useValue: mock<MessagingService>() },
|
{ provide: MessagingService, useValue: mock<MessagingService>() },
|
||||||
@@ -61,7 +61,7 @@ describe("ChangeEmailComponent", () => {
|
|||||||
|
|
||||||
describe("ngOnInit", () => {
|
describe("ngOnInit", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
twoFactorApiService.getTwoFactorProviders.mockResolvedValue({
|
twoFactorService.getEnabledTwoFactorProviders.mockResolvedValue({
|
||||||
data: [{ type: TwoFactorProviderType.Email, enabled: true } as TwoFactorProviderResponse],
|
data: [{ type: TwoFactorProviderType.Email, enabled: true } as TwoFactorProviderResponse],
|
||||||
} as ListResponse<TwoFactorProviderResponse>);
|
} as ListResponse<TwoFactorProviderResponse>);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-p
|
|||||||
import { EmailTokenRequest } from "@bitwarden/common/auth/models/request/email-token.request";
|
import { EmailTokenRequest } from "@bitwarden/common/auth/models/request/email-token.request";
|
||||||
import { EmailRequest } from "@bitwarden/common/auth/models/request/email.request";
|
import { EmailRequest } from "@bitwarden/common/auth/models/request/email.request";
|
||||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
import { UserId } from "@bitwarden/common/types/guid";
|
import { UserId } from "@bitwarden/common/types/guid";
|
||||||
@@ -40,7 +40,7 @@ export class ChangeEmailComponent implements OnInit {
|
|||||||
constructor(
|
constructor(
|
||||||
private accountService: AccountService,
|
private accountService: AccountService,
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
private twoFactorApiService: TwoFactorApiService,
|
private twoFactorService: TwoFactorService,
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private keyService: KeyService,
|
private keyService: KeyService,
|
||||||
private messagingService: MessagingService,
|
private messagingService: MessagingService,
|
||||||
@@ -52,7 +52,7 @@ export class ChangeEmailComponent implements OnInit {
|
|||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
|
this.userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
|
||||||
|
|
||||||
const twoFactorProviders = await this.twoFactorApiService.getTwoFactorProviders();
|
const twoFactorProviders = await this.twoFactorService.getEnabledTwoFactorProviders();
|
||||||
this.showTwoFactorEmailWarning = twoFactorProviders.data.some(
|
this.showTwoFactorEmailWarning = twoFactorProviders.data.some(
|
||||||
(p) => p.type === TwoFactorProviderType.Email && p.enabled,
|
(p) => p.type === TwoFactorProviderType.Email && p.enabled,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-a
|
|||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||||
import { SetVerifyDevicesRequest } from "@bitwarden/common/auth/models/request/set-verify-devices.request";
|
import { SetVerifyDevicesRequest } from "@bitwarden/common/auth/models/request/set-verify-devices.request";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { Verification } from "@bitwarden/common/auth/types/verification";
|
import { Verification } from "@bitwarden/common/auth/types/verification";
|
||||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
@@ -66,7 +66,7 @@ export class SetAccountVerifyDevicesDialogComponent implements OnInit, OnDestroy
|
|||||||
private userVerificationService: UserVerificationService,
|
private userVerificationService: UserVerificationService,
|
||||||
private dialogRef: DialogRef,
|
private dialogRef: DialogRef,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
private twoFactorApiService: TwoFactorApiService,
|
private twoFactorService: TwoFactorService,
|
||||||
) {
|
) {
|
||||||
this.accountService.accountVerifyNewDeviceLogin$
|
this.accountService.accountVerifyNewDeviceLogin$
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
@@ -76,7 +76,7 @@ export class SetAccountVerifyDevicesDialogComponent implements OnInit, OnDestroy
|
|||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
const twoFactorProviders = await this.twoFactorApiService.getTwoFactorProviders();
|
const twoFactorProviders = await this.twoFactorService.getEnabledTwoFactorProviders();
|
||||||
this.has2faConfigured = twoFactorProviders.data.length > 0;
|
this.has2faConfigured = twoFactorProviders.data.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-p
|
|||||||
import { DisableTwoFactorAuthenticatorRequest } from "@bitwarden/common/auth/models/request/disable-two-factor-authenticator.request";
|
import { DisableTwoFactorAuthenticatorRequest } from "@bitwarden/common/auth/models/request/disable-two-factor-authenticator.request";
|
||||||
import { UpdateTwoFactorAuthenticatorRequest } from "@bitwarden/common/auth/models/request/update-two-factor-authenticator.request";
|
import { UpdateTwoFactorAuthenticatorRequest } from "@bitwarden/common/auth/models/request/update-two-factor-authenticator.request";
|
||||||
import { TwoFactorAuthenticatorResponse } from "@bitwarden/common/auth/models/response/two-factor-authenticator.response";
|
import { TwoFactorAuthenticatorResponse } from "@bitwarden/common/auth/models/response/two-factor-authenticator.response";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
@@ -96,7 +96,7 @@ export class TwoFactorSetupAuthenticatorComponent
|
|||||||
constructor(
|
constructor(
|
||||||
@Inject(DIALOG_DATA) protected data: AuthResponse<TwoFactorAuthenticatorResponse>,
|
@Inject(DIALOG_DATA) protected data: AuthResponse<TwoFactorAuthenticatorResponse>,
|
||||||
private dialogRef: DialogRef,
|
private dialogRef: DialogRef,
|
||||||
twoFactorApiService: TwoFactorApiService,
|
twoFactorService: TwoFactorService,
|
||||||
i18nService: I18nService,
|
i18nService: I18nService,
|
||||||
userVerificationService: UserVerificationService,
|
userVerificationService: UserVerificationService,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
@@ -108,7 +108,7 @@ export class TwoFactorSetupAuthenticatorComponent
|
|||||||
protected toastService: ToastService,
|
protected toastService: ToastService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
twoFactorApiService,
|
twoFactorService,
|
||||||
i18nService,
|
i18nService,
|
||||||
platformUtilsService,
|
platformUtilsService,
|
||||||
logService,
|
logService,
|
||||||
@@ -158,7 +158,7 @@ export class TwoFactorSetupAuthenticatorComponent
|
|||||||
request.key = this.key;
|
request.key = this.key;
|
||||||
request.userVerificationToken = this.userVerificationToken;
|
request.userVerificationToken = this.userVerificationToken;
|
||||||
|
|
||||||
const response = await this.twoFactorApiService.putTwoFactorAuthenticator(request);
|
const response = await this.twoFactorService.putTwoFactorAuthenticator(request);
|
||||||
await this.processResponse(response);
|
await this.processResponse(response);
|
||||||
this.onUpdated.emit(true);
|
this.onUpdated.emit(true);
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ export class TwoFactorSetupAuthenticatorComponent
|
|||||||
request.type = this.type;
|
request.type = this.type;
|
||||||
request.key = this.key;
|
request.key = this.key;
|
||||||
request.userVerificationToken = this.userVerificationToken;
|
request.userVerificationToken = this.userVerificationToken;
|
||||||
await this.twoFactorApiService.deleteTwoFactorAuthenticator(request);
|
await this.twoFactorService.deleteTwoFactorAuthenticator(request);
|
||||||
this.enabled = false;
|
this.enabled = false;
|
||||||
this.toastService.showToast({
|
this.toastService.showToast({
|
||||||
variant: "success",
|
variant: "success",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { UserVerificationService } from "@bitwarden/common/auth/abstractions/use
|
|||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { UpdateTwoFactorDuoRequest } from "@bitwarden/common/auth/models/request/update-two-factor-duo.request";
|
import { UpdateTwoFactorDuoRequest } from "@bitwarden/common/auth/models/request/update-two-factor-duo.request";
|
||||||
import { TwoFactorDuoResponse } from "@bitwarden/common/auth/models/response/two-factor-duo.response";
|
import { TwoFactorDuoResponse } from "@bitwarden/common/auth/models/response/two-factor-duo.response";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
@@ -67,7 +67,7 @@ export class TwoFactorSetupDuoComponent
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DIALOG_DATA) protected data: TwoFactorDuoComponentConfig,
|
@Inject(DIALOG_DATA) protected data: TwoFactorDuoComponentConfig,
|
||||||
twoFactorApiService: TwoFactorApiService,
|
twoFactorService: TwoFactorService,
|
||||||
i18nService: I18nService,
|
i18nService: I18nService,
|
||||||
platformUtilsService: PlatformUtilsService,
|
platformUtilsService: PlatformUtilsService,
|
||||||
logService: LogService,
|
logService: LogService,
|
||||||
@@ -78,7 +78,7 @@ export class TwoFactorSetupDuoComponent
|
|||||||
protected toastService: ToastService,
|
protected toastService: ToastService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
twoFactorApiService,
|
twoFactorService,
|
||||||
i18nService,
|
i18nService,
|
||||||
platformUtilsService,
|
platformUtilsService,
|
||||||
logService,
|
logService,
|
||||||
@@ -143,12 +143,12 @@ export class TwoFactorSetupDuoComponent
|
|||||||
let response: TwoFactorDuoResponse;
|
let response: TwoFactorDuoResponse;
|
||||||
|
|
||||||
if (this.organizationId != null) {
|
if (this.organizationId != null) {
|
||||||
response = await this.twoFactorApiService.putTwoFactorOrganizationDuo(
|
response = await this.twoFactorService.putTwoFactorOrganizationDuo(
|
||||||
this.organizationId,
|
this.organizationId,
|
||||||
request,
|
request,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
response = await this.twoFactorApiService.putTwoFactorDuo(request);
|
response = await this.twoFactorService.putTwoFactorDuo(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.processResponse(response);
|
this.processResponse(response);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-p
|
|||||||
import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two-factor-email.request";
|
import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two-factor-email.request";
|
||||||
import { UpdateTwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/update-two-factor-email.request";
|
import { UpdateTwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/update-two-factor-email.request";
|
||||||
import { TwoFactorEmailResponse } from "@bitwarden/common/auth/models/response/two-factor-email.response";
|
import { TwoFactorEmailResponse } from "@bitwarden/common/auth/models/response/two-factor-email.response";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
@@ -70,7 +70,7 @@ export class TwoFactorSetupEmailComponent
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DIALOG_DATA) protected data: AuthResponse<TwoFactorEmailResponse>,
|
@Inject(DIALOG_DATA) protected data: AuthResponse<TwoFactorEmailResponse>,
|
||||||
twoFactorApiService: TwoFactorApiService,
|
twoFactorService: TwoFactorService,
|
||||||
i18nService: I18nService,
|
i18nService: I18nService,
|
||||||
platformUtilsService: PlatformUtilsService,
|
platformUtilsService: PlatformUtilsService,
|
||||||
logService: LogService,
|
logService: LogService,
|
||||||
@@ -82,7 +82,7 @@ export class TwoFactorSetupEmailComponent
|
|||||||
protected toastService: ToastService,
|
protected toastService: ToastService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
twoFactorApiService,
|
twoFactorService,
|
||||||
i18nService,
|
i18nService,
|
||||||
platformUtilsService,
|
platformUtilsService,
|
||||||
logService,
|
logService,
|
||||||
@@ -135,7 +135,7 @@ export class TwoFactorSetupEmailComponent
|
|||||||
sendEmail = async () => {
|
sendEmail = async () => {
|
||||||
const request = await this.buildRequestModel(TwoFactorEmailRequest);
|
const request = await this.buildRequestModel(TwoFactorEmailRequest);
|
||||||
request.email = this.email;
|
request.email = this.email;
|
||||||
this.emailPromise = this.twoFactorApiService.postTwoFactorEmailSetup(request);
|
this.emailPromise = this.twoFactorService.postTwoFactorEmailSetup(request);
|
||||||
await this.emailPromise;
|
await this.emailPromise;
|
||||||
this.sentEmail = this.email;
|
this.sentEmail = this.email;
|
||||||
};
|
};
|
||||||
@@ -145,7 +145,7 @@ export class TwoFactorSetupEmailComponent
|
|||||||
request.email = this.email;
|
request.email = this.email;
|
||||||
request.token = this.token;
|
request.token = this.token;
|
||||||
|
|
||||||
const response = await this.twoFactorApiService.putTwoFactorEmail(request);
|
const response = await this.twoFactorService.putTwoFactorEmail(request);
|
||||||
await this.processResponse(response);
|
await this.processResponse(response);
|
||||||
this.onUpdated.emit(true);
|
this.onUpdated.emit(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-p
|
|||||||
import { VerificationType } from "@bitwarden/common/auth/enums/verification-type";
|
import { VerificationType } from "@bitwarden/common/auth/enums/verification-type";
|
||||||
import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request";
|
import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request";
|
||||||
import { TwoFactorProviderRequest } from "@bitwarden/common/auth/models/request/two-factor-provider.request";
|
import { TwoFactorProviderRequest } from "@bitwarden/common/auth/models/request/two-factor-provider.request";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { AuthResponseBase } from "@bitwarden/common/auth/types/auth-response";
|
import { AuthResponseBase } from "@bitwarden/common/auth/types/auth-response";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
@@ -32,7 +32,7 @@ export abstract class TwoFactorSetupMethodBaseComponent {
|
|||||||
protected componentName = "";
|
protected componentName = "";
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected twoFactorApiService: TwoFactorApiService,
|
protected twoFactorService: TwoFactorService,
|
||||||
protected i18nService: I18nService,
|
protected i18nService: I18nService,
|
||||||
protected platformUtilsService: PlatformUtilsService,
|
protected platformUtilsService: PlatformUtilsService,
|
||||||
protected logService: LogService,
|
protected logService: LogService,
|
||||||
@@ -47,58 +47,6 @@ export abstract class TwoFactorSetupMethodBaseComponent {
|
|||||||
this.authed = true;
|
this.authed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @deprecated used for formPromise flows.*/
|
|
||||||
protected async enable(enableFunction: () => Promise<void>) {
|
|
||||||
try {
|
|
||||||
await enableFunction();
|
|
||||||
this.onUpdated.emit(true);
|
|
||||||
} catch (e) {
|
|
||||||
this.logService.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated used for formPromise flows.
|
|
||||||
* TODO: Remove this method when formPromises are removed from all flows.
|
|
||||||
* */
|
|
||||||
protected async disable(promise: Promise<unknown>) {
|
|
||||||
const confirmed = await this.dialogService.openSimpleDialog({
|
|
||||||
title: { key: "disable" },
|
|
||||||
content: { key: "twoStepDisableDesc" },
|
|
||||||
type: "warning",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!confirmed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const request = await this.buildRequestModel(TwoFactorProviderRequest);
|
|
||||||
if (this.type === undefined) {
|
|
||||||
throw new Error("Two-factor provider type is required");
|
|
||||||
}
|
|
||||||
request.type = this.type;
|
|
||||||
if (this.organizationId != null) {
|
|
||||||
promise = this.twoFactorApiService.putTwoFactorOrganizationDisable(
|
|
||||||
this.organizationId,
|
|
||||||
request,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
promise = this.twoFactorApiService.putTwoFactorDisable(request);
|
|
||||||
}
|
|
||||||
await promise;
|
|
||||||
this.enabled = false;
|
|
||||||
this.toastService.showToast({
|
|
||||||
variant: "success",
|
|
||||||
title: "",
|
|
||||||
message: this.i18nService.t("twoStepDisabled"),
|
|
||||||
});
|
|
||||||
this.onUpdated.emit(false);
|
|
||||||
} catch (e) {
|
|
||||||
this.logService.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async disableMethod() {
|
protected async disableMethod() {
|
||||||
const confirmed = await this.dialogService.openSimpleDialog({
|
const confirmed = await this.dialogService.openSimpleDialog({
|
||||||
title: { key: "disable" },
|
title: { key: "disable" },
|
||||||
@@ -116,9 +64,9 @@ export abstract class TwoFactorSetupMethodBaseComponent {
|
|||||||
}
|
}
|
||||||
request.type = this.type;
|
request.type = this.type;
|
||||||
if (this.organizationId != null) {
|
if (this.organizationId != null) {
|
||||||
await this.twoFactorApiService.putTwoFactorOrganizationDisable(this.organizationId, request);
|
await this.twoFactorService.putTwoFactorOrganizationDisable(this.organizationId, request);
|
||||||
} else {
|
} else {
|
||||||
await this.twoFactorApiService.putTwoFactorDisable(request);
|
await this.twoFactorService.putTwoFactorDisable(request);
|
||||||
}
|
}
|
||||||
this.enabled = false;
|
this.enabled = false;
|
||||||
this.toastService.showToast({
|
this.toastService.showToast({
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
ChallengeResponse,
|
ChallengeResponse,
|
||||||
TwoFactorWebAuthnResponse,
|
TwoFactorWebAuthnResponse,
|
||||||
} from "@bitwarden/common/auth/models/response/two-factor-web-authn.response";
|
} from "@bitwarden/common/auth/models/response/two-factor-web-authn.response";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
@@ -72,7 +72,6 @@ export class TwoFactorSetupWebAuthnComponent extends TwoFactorSetupMethodBaseCom
|
|||||||
webAuthnListening: boolean = false;
|
webAuthnListening: boolean = false;
|
||||||
webAuthnResponse: PublicKeyCredential | null = null;
|
webAuthnResponse: PublicKeyCredential | null = null;
|
||||||
challengePromise: Promise<ChallengeResponse> | undefined;
|
challengePromise: Promise<ChallengeResponse> | undefined;
|
||||||
formPromise: Promise<TwoFactorWebAuthnResponse> | undefined;
|
|
||||||
|
|
||||||
override componentName = "app-two-factor-webauthn";
|
override componentName = "app-two-factor-webauthn";
|
||||||
|
|
||||||
@@ -81,7 +80,7 @@ export class TwoFactorSetupWebAuthnComponent extends TwoFactorSetupMethodBaseCom
|
|||||||
constructor(
|
constructor(
|
||||||
@Inject(DIALOG_DATA) protected data: AuthResponse<TwoFactorWebAuthnResponse>,
|
@Inject(DIALOG_DATA) protected data: AuthResponse<TwoFactorWebAuthnResponse>,
|
||||||
private dialogRef: DialogRef,
|
private dialogRef: DialogRef,
|
||||||
twoFactorApiService: TwoFactorApiService,
|
twoFactorService: TwoFactorService,
|
||||||
i18nService: I18nService,
|
i18nService: I18nService,
|
||||||
platformUtilsService: PlatformUtilsService,
|
platformUtilsService: PlatformUtilsService,
|
||||||
private ngZone: NgZone,
|
private ngZone: NgZone,
|
||||||
@@ -91,7 +90,7 @@ export class TwoFactorSetupWebAuthnComponent extends TwoFactorSetupMethodBaseCom
|
|||||||
toastService: ToastService,
|
toastService: ToastService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
twoFactorApiService,
|
twoFactorService,
|
||||||
i18nService,
|
i18nService,
|
||||||
platformUtilsService,
|
platformUtilsService,
|
||||||
logService,
|
logService,
|
||||||
@@ -129,7 +128,7 @@ export class TwoFactorSetupWebAuthnComponent extends TwoFactorSetupMethodBaseCom
|
|||||||
request.id = this.keyIdAvailable;
|
request.id = this.keyIdAvailable;
|
||||||
request.name = this.formGroup.value.name || "";
|
request.name = this.formGroup.value.name || "";
|
||||||
|
|
||||||
const response = await this.twoFactorApiService.putTwoFactorWebAuthn(request);
|
const response = await this.twoFactorService.putTwoFactorWebAuthn(request);
|
||||||
this.processResponse(response);
|
this.processResponse(response);
|
||||||
this.toastService.showToast({
|
this.toastService.showToast({
|
||||||
title: this.i18nService.t("success"),
|
title: this.i18nService.t("success"),
|
||||||
@@ -165,7 +164,7 @@ export class TwoFactorSetupWebAuthnComponent extends TwoFactorSetupMethodBaseCom
|
|||||||
const request = await this.buildRequestModel(UpdateTwoFactorWebAuthnDeleteRequest);
|
const request = await this.buildRequestModel(UpdateTwoFactorWebAuthnDeleteRequest);
|
||||||
request.id = key.id;
|
request.id = key.id;
|
||||||
try {
|
try {
|
||||||
key.removePromise = this.twoFactorApiService.deleteTwoFactorWebAuthn(request);
|
key.removePromise = this.twoFactorService.deleteTwoFactorWebAuthn(request);
|
||||||
const response = await key.removePromise;
|
const response = await key.removePromise;
|
||||||
key.removePromise = null;
|
key.removePromise = null;
|
||||||
await this.processResponse(response);
|
await this.processResponse(response);
|
||||||
@@ -179,7 +178,7 @@ export class TwoFactorSetupWebAuthnComponent extends TwoFactorSetupMethodBaseCom
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const request = await this.buildRequestModel(SecretVerificationRequest);
|
const request = await this.buildRequestModel(SecretVerificationRequest);
|
||||||
this.challengePromise = this.twoFactorApiService.getTwoFactorWebAuthnChallenge(request);
|
this.challengePromise = this.twoFactorService.getTwoFactorWebAuthnChallenge(request);
|
||||||
const challenge = await this.challengePromise;
|
const challenge = await this.challengePromise;
|
||||||
this.readDevice(challenge);
|
this.readDevice(challenge);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { UserVerificationService } from "@bitwarden/common/auth/abstractions/use
|
|||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { UpdateTwoFactorYubikeyOtpRequest } from "@bitwarden/common/auth/models/request/update-two-factor-yubikey-otp.request";
|
import { UpdateTwoFactorYubikeyOtpRequest } from "@bitwarden/common/auth/models/request/update-two-factor-yubikey-otp.request";
|
||||||
import { TwoFactorYubiKeyResponse } from "@bitwarden/common/auth/models/response/two-factor-yubi-key.response";
|
import { TwoFactorYubiKeyResponse } from "@bitwarden/common/auth/models/response/two-factor-yubi-key.response";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
@@ -74,9 +74,6 @@ export class TwoFactorSetupYubiKeyComponent
|
|||||||
keys: Key[] = [];
|
keys: Key[] = [];
|
||||||
anyKeyHasNfc = false;
|
anyKeyHasNfc = false;
|
||||||
|
|
||||||
formPromise: Promise<TwoFactorYubiKeyResponse> | undefined;
|
|
||||||
disablePromise: Promise<unknown> | undefined;
|
|
||||||
|
|
||||||
override componentName = "app-two-factor-yubikey";
|
override componentName = "app-two-factor-yubikey";
|
||||||
formGroup:
|
formGroup:
|
||||||
| FormGroup<{
|
| FormGroup<{
|
||||||
@@ -95,7 +92,7 @@ export class TwoFactorSetupYubiKeyComponent
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DIALOG_DATA) protected data: AuthResponse<TwoFactorYubiKeyResponse>,
|
@Inject(DIALOG_DATA) protected data: AuthResponse<TwoFactorYubiKeyResponse>,
|
||||||
twoFactorApiService: TwoFactorApiService,
|
twoFactorService: TwoFactorService,
|
||||||
i18nService: I18nService,
|
i18nService: I18nService,
|
||||||
platformUtilsService: PlatformUtilsService,
|
platformUtilsService: PlatformUtilsService,
|
||||||
logService: LogService,
|
logService: LogService,
|
||||||
@@ -105,7 +102,7 @@ export class TwoFactorSetupYubiKeyComponent
|
|||||||
protected toastService: ToastService,
|
protected toastService: ToastService,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
twoFactorApiService,
|
twoFactorService,
|
||||||
i18nService,
|
i18nService,
|
||||||
platformUtilsService,
|
platformUtilsService,
|
||||||
logService,
|
logService,
|
||||||
@@ -178,7 +175,7 @@ export class TwoFactorSetupYubiKeyComponent
|
|||||||
request.key5 = keys != null && keys.length > 4 ? (keys[4]?.key ?? "") : "";
|
request.key5 = keys != null && keys.length > 4 ? (keys[4]?.key ?? "") : "";
|
||||||
request.nfc = this.formGroup.value.anyKeyHasNfc ?? false;
|
request.nfc = this.formGroup.value.anyKeyHasNfc ?? false;
|
||||||
|
|
||||||
this.processResponse(await this.twoFactorApiService.putTwoFactorYubiKey(request));
|
this.processResponse(await this.twoFactorService.putTwoFactorYubiKey(request));
|
||||||
this.refreshFormArrayData();
|
this.refreshFormArrayData();
|
||||||
this.toastService.showToast({
|
this.toastService.showToast({
|
||||||
title: this.i18nService.t("success"),
|
title: this.i18nService.t("success"),
|
||||||
|
|||||||
@@ -71,15 +71,26 @@
|
|||||||
<div class="tw-mt-2 tw-text-wrap">{{ p.description }}</div>
|
<div class="tw-mt-2 tw-text-wrap">{{ p.description }}</div>
|
||||||
</div>
|
</div>
|
||||||
<bit-item-action slot="end">
|
<bit-item-action slot="end">
|
||||||
<button
|
@if (p.premium && p.enabled && !(canAccessPremium$ | async)) {
|
||||||
type="button"
|
<button
|
||||||
bitButton
|
type="button"
|
||||||
buttonType="secondary"
|
bitButton
|
||||||
[disabled]="!(canAccessPremium$ | async) && p.premium"
|
buttonType="danger"
|
||||||
(click)="manage(p.type)"
|
(click)="disablePremium2faTypeForNonPremiumUser(p.type)"
|
||||||
>
|
>
|
||||||
{{ "manage" | i18n }}
|
{{ "disable" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
|
} @else {
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
bitButton
|
||||||
|
buttonType="secondary"
|
||||||
|
[disabled]="!(canAccessPremium$ | async) && p.premium"
|
||||||
|
(click)="manage(p.type)"
|
||||||
|
>
|
||||||
|
{{ "manage" | i18n }}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
</bit-item-action>
|
</bit-item-action>
|
||||||
</bit-item>
|
</bit-item>
|
||||||
</bit-item-group>
|
</bit-item-group>
|
||||||
|
|||||||
@@ -12,26 +12,28 @@ import {
|
|||||||
} from "rxjs";
|
} from "rxjs";
|
||||||
|
|
||||||
import { PremiumBadgeComponent } from "@bitwarden/angular/billing/components/premium-badge";
|
import { PremiumBadgeComponent } from "@bitwarden/angular/billing/components/premium-badge";
|
||||||
|
import { UserVerificationDialogComponent } from "@bitwarden/auth/angular";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
|
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
|
import { TwoFactorProviderRequest } from "@bitwarden/common/auth/models/request/two-factor-provider.request";
|
||||||
import { TwoFactorAuthenticatorResponse } from "@bitwarden/common/auth/models/response/two-factor-authenticator.response";
|
import { TwoFactorAuthenticatorResponse } from "@bitwarden/common/auth/models/response/two-factor-authenticator.response";
|
||||||
import { TwoFactorDuoResponse } from "@bitwarden/common/auth/models/response/two-factor-duo.response";
|
import { TwoFactorDuoResponse } from "@bitwarden/common/auth/models/response/two-factor-duo.response";
|
||||||
import { TwoFactorEmailResponse } from "@bitwarden/common/auth/models/response/two-factor-email.response";
|
import { TwoFactorEmailResponse } from "@bitwarden/common/auth/models/response/two-factor-email.response";
|
||||||
import { TwoFactorWebAuthnResponse } from "@bitwarden/common/auth/models/response/two-factor-web-authn.response";
|
import { TwoFactorWebAuthnResponse } from "@bitwarden/common/auth/models/response/two-factor-web-authn.response";
|
||||||
import { TwoFactorYubiKeyResponse } from "@bitwarden/common/auth/models/response/two-factor-yubi-key.response";
|
import { TwoFactorYubiKeyResponse } from "@bitwarden/common/auth/models/response/two-factor-yubi-key.response";
|
||||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||||
import { TwoFactorProviders } from "@bitwarden/common/auth/services/two-factor.service";
|
import { TwoFactorService, TwoFactorProviders } from "@bitwarden/common/auth/two-factor";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
|
||||||
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { ProductTierType } from "@bitwarden/common/billing/enums";
|
import { ProductTierType } from "@bitwarden/common/billing/enums";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
import { DialogRef, DialogService, ItemModule } from "@bitwarden/components";
|
import { DialogRef, DialogService, ItemModule, ToastService } from "@bitwarden/components";
|
||||||
|
|
||||||
import { HeaderModule } from "../../../layouts/header/header.module";
|
import { HeaderModule } from "../../../layouts/header/header.module";
|
||||||
import { SharedModule } from "../../../shared/shared.module";
|
import { SharedModule } from "../../../shared/shared.module";
|
||||||
@@ -59,7 +61,6 @@ export class TwoFactorSetupComponent implements OnInit, OnDestroy {
|
|||||||
recoveryCodeWarningMessage: string;
|
recoveryCodeWarningMessage: string;
|
||||||
showPolicyWarning = false;
|
showPolicyWarning = false;
|
||||||
loading = true;
|
loading = true;
|
||||||
formPromise: Promise<any>;
|
|
||||||
|
|
||||||
tabbedHeader = true;
|
tabbedHeader = true;
|
||||||
|
|
||||||
@@ -69,13 +70,15 @@ export class TwoFactorSetupComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected dialogService: DialogService,
|
protected dialogService: DialogService,
|
||||||
protected twoFactorApiService: TwoFactorApiService,
|
protected twoFactorService: TwoFactorService,
|
||||||
protected messagingService: MessagingService,
|
protected messagingService: MessagingService,
|
||||||
protected policyService: PolicyService,
|
protected policyService: PolicyService,
|
||||||
billingAccountProfileStateService: BillingAccountProfileStateService,
|
billingAccountProfileStateService: BillingAccountProfileStateService,
|
||||||
protected accountService: AccountService,
|
protected accountService: AccountService,
|
||||||
protected configService: ConfigService,
|
protected configService: ConfigService,
|
||||||
protected i18nService: I18nService,
|
protected i18nService: I18nService,
|
||||||
|
protected userVerificationService: UserVerificationService,
|
||||||
|
protected toastService: ToastService,
|
||||||
) {
|
) {
|
||||||
this.canAccessPremium$ = this.accountService.activeAccount$.pipe(
|
this.canAccessPremium$ = this.accountService.activeAccount$.pipe(
|
||||||
switchMap((account) =>
|
switchMap((account) =>
|
||||||
@@ -150,6 +153,50 @@ export class TwoFactorSetupComponent implements OnInit, OnDestroy {
|
|||||||
return await lastValueFrom(twoFactorVerifyDialogRef.closed);
|
return await lastValueFrom(twoFactorVerifyDialogRef.closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For users who enabled a premium-only 2fa provider,
|
||||||
|
* they should still be allowed to disable that provider
|
||||||
|
* (without otherwise modifying) if they no longer have
|
||||||
|
* premium access [PM-21204]
|
||||||
|
* @param type the 2FA Provider Type
|
||||||
|
*/
|
||||||
|
async disablePremium2faTypeForNonPremiumUser(type: TwoFactorProviderType) {
|
||||||
|
// Use UserVerificationDialogComponent instead of TwoFactorVerifyComponent
|
||||||
|
// because the latter makes GET API calls that require premium for YubiKey/Duo.
|
||||||
|
// The disable endpoint only requires user verification, not provider configuration.
|
||||||
|
const result = await UserVerificationDialogComponent.open(this.dialogService, {
|
||||||
|
title: "twoStepLogin",
|
||||||
|
verificationType: {
|
||||||
|
type: "custom",
|
||||||
|
verificationFn: async (secret) => {
|
||||||
|
const request = await this.userVerificationService.buildRequest<TwoFactorProviderRequest>(
|
||||||
|
secret,
|
||||||
|
TwoFactorProviderRequest,
|
||||||
|
);
|
||||||
|
request.type = type;
|
||||||
|
|
||||||
|
await this.twoFactorService.putTwoFactorDisable(request);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.userAction === "cancel") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result.verificationSuccess) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toastService.showToast({
|
||||||
|
variant: "success",
|
||||||
|
title: "",
|
||||||
|
message: this.i18nService.t("twoStepDisabled"),
|
||||||
|
});
|
||||||
|
this.updateStatus(false, type);
|
||||||
|
}
|
||||||
|
|
||||||
async manage(type: TwoFactorProviderType) {
|
async manage(type: TwoFactorProviderType) {
|
||||||
// clear any existing subscriptions before creating a new one
|
// clear any existing subscriptions before creating a new one
|
||||||
this.twoFactorSetupSubscription?.unsubscribe();
|
this.twoFactorSetupSubscription?.unsubscribe();
|
||||||
@@ -264,7 +311,7 @@ export class TwoFactorSetupComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected getTwoFactorProviders() {
|
protected getTwoFactorProviders() {
|
||||||
return this.twoFactorApiService.getTwoFactorProviders();
|
return this.twoFactorService.getEnabledTwoFactorProviders();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected filterProvider(type: TwoFactorProviderType): boolean {
|
protected filterProvider(type: TwoFactorProviderType): boolean {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { UserVerificationFormInputComponent } from "@bitwarden/auth/angular";
|
|||||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request";
|
import { SecretVerificationRequest } from "@bitwarden/common/auth/models/request/secret-verification.request";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
||||||
import { TwoFactorResponse } from "@bitwarden/common/auth/types/two-factor-response";
|
import { TwoFactorResponse } from "@bitwarden/common/auth/types/two-factor-response";
|
||||||
import { VerificationWithSecret } from "@bitwarden/common/auth/types/verification";
|
import { VerificationWithSecret } from "@bitwarden/common/auth/types/verification";
|
||||||
@@ -54,7 +54,7 @@ export class TwoFactorVerifyComponent {
|
|||||||
constructor(
|
constructor(
|
||||||
@Inject(DIALOG_DATA) protected data: TwoFactorVerifyDialogData,
|
@Inject(DIALOG_DATA) protected data: TwoFactorVerifyDialogData,
|
||||||
private dialogRef: DialogRef,
|
private dialogRef: DialogRef,
|
||||||
private twoFactorApiService: TwoFactorApiService,
|
private twoFactorService: TwoFactorService,
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private userVerificationService: UserVerificationService,
|
private userVerificationService: UserVerificationService,
|
||||||
) {
|
) {
|
||||||
@@ -110,22 +110,22 @@ export class TwoFactorVerifyComponent {
|
|||||||
private apiCall(request: SecretVerificationRequest): Promise<TwoFactorResponse> {
|
private apiCall(request: SecretVerificationRequest): Promise<TwoFactorResponse> {
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
case -1 as TwoFactorProviderType:
|
case -1 as TwoFactorProviderType:
|
||||||
return this.twoFactorApiService.getTwoFactorRecover(request);
|
return this.twoFactorService.getTwoFactorRecover(request);
|
||||||
case TwoFactorProviderType.Duo:
|
case TwoFactorProviderType.Duo:
|
||||||
case TwoFactorProviderType.OrganizationDuo:
|
case TwoFactorProviderType.OrganizationDuo:
|
||||||
if (this.organizationId != null) {
|
if (this.organizationId != null) {
|
||||||
return this.twoFactorApiService.getTwoFactorOrganizationDuo(this.organizationId, request);
|
return this.twoFactorService.getTwoFactorOrganizationDuo(this.organizationId, request);
|
||||||
} else {
|
} else {
|
||||||
return this.twoFactorApiService.getTwoFactorDuo(request);
|
return this.twoFactorService.getTwoFactorDuo(request);
|
||||||
}
|
}
|
||||||
case TwoFactorProviderType.Email:
|
case TwoFactorProviderType.Email:
|
||||||
return this.twoFactorApiService.getTwoFactorEmail(request);
|
return this.twoFactorService.getTwoFactorEmail(request);
|
||||||
case TwoFactorProviderType.WebAuthn:
|
case TwoFactorProviderType.WebAuthn:
|
||||||
return this.twoFactorApiService.getTwoFactorWebAuthn(request);
|
return this.twoFactorService.getTwoFactorWebAuthn(request);
|
||||||
case TwoFactorProviderType.Authenticator:
|
case TwoFactorProviderType.Authenticator:
|
||||||
return this.twoFactorApiService.getTwoFactorAuthenticator(request);
|
return this.twoFactorService.getTwoFactorAuthenticator(request);
|
||||||
case TwoFactorProviderType.Yubikey:
|
case TwoFactorProviderType.Yubikey:
|
||||||
return this.twoFactorApiService.getTwoFactorYubiKey(request);
|
return this.twoFactorService.getTwoFactorYubiKey(request);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown two-factor type: ${this.type}`);
|
throw new Error(`Unknown two-factor type: ${this.type}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { AbstractThemingService } from "@bitwarden/angular/platform/services/the
|
|||||||
import { WINDOW } from "@bitwarden/angular/services/injection-tokens";
|
import { WINDOW } from "@bitwarden/angular/services/injection-tokens";
|
||||||
import { EventUploadService as EventUploadServiceAbstraction } from "@bitwarden/common/abstractions/event/event-upload.service";
|
import { EventUploadService as EventUploadServiceAbstraction } from "@bitwarden/common/abstractions/event/event-upload.service";
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||||
import { DefaultVaultTimeoutService } from "@bitwarden/common/key-management/vault-timeout";
|
import { DefaultVaultTimeoutService } from "@bitwarden/common/key-management/vault-timeout";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
@@ -31,7 +31,7 @@ export class InitService {
|
|||||||
private vaultTimeoutService: DefaultVaultTimeoutService,
|
private vaultTimeoutService: DefaultVaultTimeoutService,
|
||||||
private i18nService: I18nServiceAbstraction,
|
private i18nService: I18nServiceAbstraction,
|
||||||
private eventUploadService: EventUploadServiceAbstraction,
|
private eventUploadService: EventUploadServiceAbstraction,
|
||||||
private twoFactorService: TwoFactorServiceAbstraction,
|
private twoFactorService: TwoFactorService,
|
||||||
private keyService: KeyServiceAbstraction,
|
private keyService: KeyServiceAbstraction,
|
||||||
private themingService: AbstractThemingService,
|
private themingService: AbstractThemingService,
|
||||||
private encryptService: EncryptService,
|
private encryptService: EncryptService,
|
||||||
|
|||||||
@@ -12178,5 +12178,8 @@
|
|||||||
},
|
},
|
||||||
"confirmNoSelectedCriticalApplicationsDesc": {
|
"confirmNoSelectedCriticalApplicationsDesc": {
|
||||||
"message": "Are you sure you want to continue?"
|
"message": "Are you sure you want to continue?"
|
||||||
|
},
|
||||||
|
"userVerificationFailed": {
|
||||||
|
"message": "User verification failed."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ import { MasterPasswordApiService as MasterPasswordApiServiceAbstraction } from
|
|||||||
import { PasswordResetEnrollmentServiceAbstraction } from "@bitwarden/common/auth/abstractions/password-reset-enrollment.service.abstraction";
|
import { PasswordResetEnrollmentServiceAbstraction } from "@bitwarden/common/auth/abstractions/password-reset-enrollment.service.abstraction";
|
||||||
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification-api.service.abstraction";
|
import { UserVerificationApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification-api.service.abstraction";
|
||||||
import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
import { UserVerificationService as UserVerificationServiceAbstraction } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||||
import { WebAuthnLoginApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login-api.service.abstraction";
|
import { WebAuthnLoginApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login-api.service.abstraction";
|
||||||
@@ -125,13 +124,17 @@ import { OrganizationInviteService } from "@bitwarden/common/auth/services/organ
|
|||||||
import { PasswordResetEnrollmentServiceImplementation } from "@bitwarden/common/auth/services/password-reset-enrollment.service.implementation";
|
import { PasswordResetEnrollmentServiceImplementation } from "@bitwarden/common/auth/services/password-reset-enrollment.service.implementation";
|
||||||
import { SsoLoginService } from "@bitwarden/common/auth/services/sso-login.service";
|
import { SsoLoginService } from "@bitwarden/common/auth/services/sso-login.service";
|
||||||
import { TokenService } from "@bitwarden/common/auth/services/token.service";
|
import { TokenService } from "@bitwarden/common/auth/services/token.service";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/services/two-factor.service";
|
|
||||||
import { UserVerificationApiService } from "@bitwarden/common/auth/services/user-verification/user-verification-api.service";
|
import { UserVerificationApiService } from "@bitwarden/common/auth/services/user-verification/user-verification-api.service";
|
||||||
import { UserVerificationService } from "@bitwarden/common/auth/services/user-verification/user-verification.service";
|
import { UserVerificationService } from "@bitwarden/common/auth/services/user-verification/user-verification.service";
|
||||||
import { WebAuthnLoginApiService } from "@bitwarden/common/auth/services/webauthn-login/webauthn-login-api.service";
|
import { WebAuthnLoginApiService } from "@bitwarden/common/auth/services/webauthn-login/webauthn-login-api.service";
|
||||||
import { WebAuthnLoginPrfKeyService } from "@bitwarden/common/auth/services/webauthn-login/webauthn-login-prf-key.service";
|
import { WebAuthnLoginPrfKeyService } from "@bitwarden/common/auth/services/webauthn-login/webauthn-login-prf-key.service";
|
||||||
import { WebAuthnLoginService } from "@bitwarden/common/auth/services/webauthn-login/webauthn-login.service";
|
import { WebAuthnLoginService } from "@bitwarden/common/auth/services/webauthn-login/webauthn-login.service";
|
||||||
import { TwoFactorApiService, DefaultTwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import {
|
||||||
|
TwoFactorApiService,
|
||||||
|
DefaultTwoFactorApiService,
|
||||||
|
TwoFactorService,
|
||||||
|
DefaultTwoFactorService,
|
||||||
|
} from "@bitwarden/common/auth/two-factor";
|
||||||
import {
|
import {
|
||||||
AutofillSettingsService,
|
AutofillSettingsService,
|
||||||
AutofillSettingsServiceAbstraction,
|
AutofillSettingsServiceAbstraction,
|
||||||
@@ -527,7 +530,7 @@ const safeProviders: SafeProvider[] = [
|
|||||||
KeyConnectorServiceAbstraction,
|
KeyConnectorServiceAbstraction,
|
||||||
EnvironmentService,
|
EnvironmentService,
|
||||||
StateServiceAbstraction,
|
StateServiceAbstraction,
|
||||||
TwoFactorServiceAbstraction,
|
TwoFactorService,
|
||||||
I18nServiceAbstraction,
|
I18nServiceAbstraction,
|
||||||
EncryptService,
|
EncryptService,
|
||||||
PasswordStrengthServiceAbstraction,
|
PasswordStrengthServiceAbstraction,
|
||||||
@@ -1165,9 +1168,14 @@ const safeProviders: SafeProvider[] = [
|
|||||||
deps: [StateProvider],
|
deps: [StateProvider],
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: TwoFactorServiceAbstraction,
|
provide: TwoFactorService,
|
||||||
useClass: TwoFactorService,
|
useClass: DefaultTwoFactorService,
|
||||||
deps: [I18nServiceAbstraction, PlatformUtilsServiceAbstraction, GlobalStateProvider],
|
deps: [
|
||||||
|
I18nServiceAbstraction,
|
||||||
|
PlatformUtilsServiceAbstraction,
|
||||||
|
GlobalStateProvider,
|
||||||
|
TwoFactorApiService,
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: FormValidationErrorsServiceAbstraction,
|
provide: FormValidationErrorsServiceAbstraction,
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import { ReactiveFormsModule, FormsModule, FormControl } from "@angular/forms";
|
|||||||
|
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two-factor-email.request";
|
import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two-factor-email.request";
|
||||||
import { TwoFactorApiService } from "@bitwarden/common/auth/two-factor";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
@@ -68,7 +67,6 @@ export class TwoFactorAuthEmailComponent implements OnInit {
|
|||||||
protected loginStrategyService: LoginStrategyServiceAbstraction,
|
protected loginStrategyService: LoginStrategyServiceAbstraction,
|
||||||
protected platformUtilsService: PlatformUtilsService,
|
protected platformUtilsService: PlatformUtilsService,
|
||||||
protected logService: LogService,
|
protected logService: LogService,
|
||||||
protected twoFactorApiService: TwoFactorApiService,
|
|
||||||
protected appIdService: AppIdService,
|
protected appIdService: AppIdService,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
private cacheService: TwoFactorAuthEmailComponentCacheService,
|
private cacheService: TwoFactorAuthEmailComponentCacheService,
|
||||||
@@ -137,7 +135,7 @@ export class TwoFactorAuthEmailComponent implements OnInit {
|
|||||||
request.deviceIdentifier = await this.appIdService.getAppId();
|
request.deviceIdentifier = await this.appIdService.getAppId();
|
||||||
request.authRequestAccessCode = (await this.loginStrategyService.getAccessCode()) ?? "";
|
request.authRequestAccessCode = (await this.loginStrategyService.getAccessCode()) ?? "";
|
||||||
request.authRequestId = (await this.loginStrategyService.getAuthRequestId()) ?? "";
|
request.authRequestId = (await this.loginStrategyService.getAuthRequestId()) ?? "";
|
||||||
this.emailPromise = this.twoFactorApiService.postTwoFactorEmail(request);
|
this.emailPromise = this.twoFactorService.postTwoFactorEmail(request);
|
||||||
await this.emailPromise;
|
await this.emailPromise;
|
||||||
|
|
||||||
this.emailSent = true;
|
this.emailSent = true;
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import { firstValueFrom } from "rxjs";
|
|||||||
|
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { WINDOW } from "@bitwarden/angular/services/injection-tokens";
|
import { WINDOW } from "@bitwarden/angular/services/injection-tokens";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { WebAuthnIFrame } from "@bitwarden/common/auth/webauthn-iframe";
|
import { WebAuthnIFrame } from "@bitwarden/common/auth/webauthn-iframe";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
|||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||||
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||||
import { AuthenticationType } from "@bitwarden/common/auth/enums/authentication-type";
|
import { AuthenticationType } from "@bitwarden/common/auth/enums/authentication-type";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request";
|
import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request";
|
||||||
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service";
|
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service";
|
||||||
import {
|
import {
|
||||||
InternalMasterPasswordServiceAbstraction,
|
InternalMasterPasswordServiceAbstraction,
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ import {
|
|||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||||
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request";
|
import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request";
|
||||||
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service";
|
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service";
|
||||||
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
|
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
|
||||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import { provideRouter, Router } from "@angular/router";
|
|||||||
import { mock, MockProxy } from "jest-mock-extended";
|
import { mock, MockProxy } from "jest-mock-extended";
|
||||||
import { BehaviorSubject } from "rxjs";
|
import { BehaviorSubject } from "rxjs";
|
||||||
|
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { AuthenticationType } from "@bitwarden/common/auth/enums/authentication-type";
|
import { AuthenticationType } from "@bitwarden/common/auth/enums/authentication-type";
|
||||||
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
|
|
||||||
import { LoginStrategyServiceAbstraction } from "../../common";
|
import { LoginStrategyServiceAbstraction } from "../../common";
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
} from "@angular/router";
|
} from "@angular/router";
|
||||||
import { firstValueFrom } from "rxjs";
|
import { firstValueFrom } from "rxjs";
|
||||||
|
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
|
|
||||||
import { LoginStrategyServiceAbstraction } from "../../common";
|
import { LoginStrategyServiceAbstraction } from "../../common";
|
||||||
|
|
||||||
|
|||||||
@@ -9,11 +9,8 @@ import {
|
|||||||
TwoFactorAuthWebAuthnIcon,
|
TwoFactorAuthWebAuthnIcon,
|
||||||
TwoFactorAuthYubicoIcon,
|
TwoFactorAuthYubicoIcon,
|
||||||
} from "@bitwarden/assets/svg";
|
} from "@bitwarden/assets/svg";
|
||||||
import {
|
|
||||||
TwoFactorProviderDetails,
|
|
||||||
TwoFactorService,
|
|
||||||
} from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
|
import { TwoFactorProviderDetails, TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
|
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
|
||||||
// eslint-disable-next-line no-restricted-imports
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -277,13 +277,13 @@ export class UserVerificationDialogComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch {
|
||||||
// Catch handles OTP and MP verification scenarios as those throw errors on verification failure instead of returning false like PIN and biometrics.
|
// Catch handles OTP and MP verification scenarios as those throw errors on verification failure instead of returning false like PIN and biometrics.
|
||||||
this.invalidSecret = true;
|
this.invalidSecret = true;
|
||||||
this.toastService.showToast({
|
this.toastService.showToast({
|
||||||
variant: "error",
|
variant: "error",
|
||||||
title: this.i18nService.t("error"),
|
title: this.i18nService.t("error"),
|
||||||
message: e.message,
|
message: this.i18nService.t("userVerificationFailed"),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import { BehaviorSubject } from "rxjs";
|
|||||||
|
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
||||||
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||||
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction";
|
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction";
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
|||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
@@ -16,6 +15,7 @@ import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/id
|
|||||||
import { IdentityTwoFactorResponse } from "@bitwarden/common/auth/models/response/identity-two-factor.response";
|
import { IdentityTwoFactorResponse } from "@bitwarden/common/auth/models/response/identity-two-factor.response";
|
||||||
import { MasterPasswordPolicyResponse } from "@bitwarden/common/auth/models/response/master-password-policy.response";
|
import { MasterPasswordPolicyResponse } from "@bitwarden/common/auth/models/response/master-password-policy.response";
|
||||||
import { IUserDecryptionOptionsServerResponse } from "@bitwarden/common/auth/models/response/user-decryption-options/user-decryption-options.response";
|
import { IUserDecryptionOptionsServerResponse } from "@bitwarden/common/auth/models/response/user-decryption-options/user-decryption-options.response";
|
||||||
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||||
import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string";
|
import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string";
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { BehaviorSubject, filter, firstValueFrom, timeout, Observable } from "rx
|
|||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
@@ -16,6 +15,7 @@ import { WebAuthnLoginTokenRequest } from "@bitwarden/common/auth/models/request
|
|||||||
import { IdentityDeviceVerificationResponse } from "@bitwarden/common/auth/models/response/identity-device-verification.response";
|
import { IdentityDeviceVerificationResponse } from "@bitwarden/common/auth/models/response/identity-device-verification.response";
|
||||||
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
||||||
import { IdentityTwoFactorResponse } from "@bitwarden/common/auth/models/response/identity-two-factor.response";
|
import { IdentityTwoFactorResponse } from "@bitwarden/common/auth/models/response/identity-two-factor.response";
|
||||||
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||||
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
|
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
|||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
|
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
|
||||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
||||||
import { IdentityTwoFactorResponse } from "@bitwarden/common/auth/models/response/identity-two-factor.response";
|
import { IdentityTwoFactorResponse } from "@bitwarden/common/auth/models/response/identity-two-factor.response";
|
||||||
import { MasterPasswordPolicyResponse } from "@bitwarden/common/auth/models/response/master-password-policy.response";
|
import { MasterPasswordPolicyResponse } from "@bitwarden/common/auth/models/response/master-password-policy.response";
|
||||||
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||||
import { FakeMasterPasswordService } from "@bitwarden/common/key-management/master-password/services/fake-master-password.service";
|
import { FakeMasterPasswordService } from "@bitwarden/common/key-management/master-password/services/fake-master-password.service";
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import { BehaviorSubject, of } from "rxjs";
|
|||||||
|
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { AdminAuthRequestStorable } from "@bitwarden/common/auth/models/domain/admin-auth-req-storable";
|
import { AdminAuthRequestStorable } from "@bitwarden/common/auth/models/domain/admin-auth-req-storable";
|
||||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||||
import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response";
|
import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response";
|
||||||
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
||||||
import { IUserDecryptionOptionsServerResponse } from "@bitwarden/common/auth/models/response/user-decryption-options/user-decryption-options.response";
|
import { IUserDecryptionOptionsServerResponse } from "@bitwarden/common/auth/models/response/user-decryption-options/user-decryption-options.response";
|
||||||
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||||
import { EncryptedString } from "@bitwarden/common/key-management/crypto/models/enc-string";
|
import { EncryptedString } from "@bitwarden/common/key-management/crypto/models/enc-string";
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { BehaviorSubject } from "rxjs";
|
|||||||
|
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||||
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service";
|
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service";
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import { BehaviorSubject } from "rxjs";
|
|||||||
|
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
||||||
import { IUserDecryptionOptionsServerResponse } from "@bitwarden/common/auth/models/response/user-decryption-options/user-decryption-options.response";
|
import { IUserDecryptionOptionsServerResponse } from "@bitwarden/common/auth/models/response/user-decryption-options/user-decryption-options.response";
|
||||||
import { WebAuthnLoginAssertionResponseRequest } from "@bitwarden/common/auth/services/webauthn-login/request/webauthn-login-assertion-response.request";
|
import { WebAuthnLoginAssertionResponseRequest } from "@bitwarden/common/auth/services/webauthn-login/request/webauthn-login-assertion-response.request";
|
||||||
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||||
import { FakeMasterPasswordService } from "@bitwarden/common/key-management/master-password/services/fake-master-password.service";
|
import { FakeMasterPasswordService } from "@bitwarden/common/key-management/master-password/services/fake-master-password.service";
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import { BehaviorSubject } from "rxjs";
|
|||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request";
|
import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request";
|
||||||
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response";
|
||||||
import { IdentityTwoFactorResponse } from "@bitwarden/common/auth/models/response/identity-two-factor.response";
|
import { IdentityTwoFactorResponse } from "@bitwarden/common/auth/models/response/identity-two-factor.response";
|
||||||
import { PreloginResponse } from "@bitwarden/common/auth/models/response/prelogin.response";
|
import { PreloginResponse } from "@bitwarden/common/auth/models/response/prelogin.response";
|
||||||
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||||
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction";
|
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction";
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
|||||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
|
||||||
import { AuthenticationType } from "@bitwarden/common/auth/enums/authentication-type";
|
import { AuthenticationType } from "@bitwarden/common/auth/enums/authentication-type";
|
||||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||||
import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request";
|
import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request";
|
||||||
|
import { TwoFactorService } from "@bitwarden/common/auth/two-factor";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
import { TwoFactorProviderType } from "../enums/two-factor-provider-type";
|
|
||||||
import { IdentityTwoFactorResponse } from "../models/response/identity-two-factor.response";
|
|
||||||
|
|
||||||
export interface TwoFactorProviderDetails {
|
|
||||||
type: TwoFactorProviderType;
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
priority: number;
|
|
||||||
sort: number;
|
|
||||||
premium: boolean;
|
|
||||||
}
|
|
||||||
export abstract class TwoFactorService {
|
|
||||||
/**
|
|
||||||
* Initializes the client-side's TwoFactorProviders const with translations.
|
|
||||||
*/
|
|
||||||
abstract init(): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a list of two-factor providers from state that are supported on the current client.
|
|
||||||
* E.g., WebAuthn and Duo are not available on all clients.
|
|
||||||
* @returns A list of supported two-factor providers or an empty list if none are stored in state.
|
|
||||||
*/
|
|
||||||
abstract getSupportedProviders(win: Window): Promise<TwoFactorProviderDetails[]>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the previously selected two-factor provider or the default two factor provider based on priority.
|
|
||||||
* @param webAuthnSupported - Whether or not WebAuthn is supported by the client. Prevents WebAuthn from being the default provider if false.
|
|
||||||
*/
|
|
||||||
abstract getDefaultProvider(webAuthnSupported: boolean): Promise<TwoFactorProviderType>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the selected two-factor provider in state.
|
|
||||||
* @param type - The type of two-factor provider to set as the selected provider.
|
|
||||||
*/
|
|
||||||
abstract setSelectedProvider(type: TwoFactorProviderType): Promise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the selected two-factor provider from state.
|
|
||||||
*/
|
|
||||||
abstract clearSelectedProvider(): Promise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the list of available two-factor providers in state.
|
|
||||||
* @param response - the response from Identity for when 2FA is required. Includes the list of available 2FA providers.
|
|
||||||
*/
|
|
||||||
abstract setProviders(response: IdentityTwoFactorResponse): Promise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the list of available two-factor providers from state.
|
|
||||||
*/
|
|
||||||
abstract clearProviders(): Promise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the list of two-factor providers from state.
|
|
||||||
* Note: no filtering is done here, so this will return all providers, including potentially
|
|
||||||
* unsupported ones for the current client.
|
|
||||||
* @returns A list of two-factor providers or null if none are stored in state.
|
|
||||||
*/
|
|
||||||
abstract getProviders(): Promise<Map<TwoFactorProviderType, { [key: string]: string }> | null>;
|
|
||||||
}
|
|
||||||
@@ -1,212 +0,0 @@
|
|||||||
// FIXME: Update this file to be type safe and remove this and next line
|
|
||||||
// @ts-strict-ignore
|
|
||||||
import { firstValueFrom, map } from "rxjs";
|
|
||||||
|
|
||||||
import { I18nService } from "../../platform/abstractions/i18n.service";
|
|
||||||
import { PlatformUtilsService } from "../../platform/abstractions/platform-utils.service";
|
|
||||||
import { Utils } from "../../platform/misc/utils";
|
|
||||||
import { GlobalStateProvider, KeyDefinition, TWO_FACTOR_MEMORY } from "../../platform/state";
|
|
||||||
import {
|
|
||||||
TwoFactorProviderDetails,
|
|
||||||
TwoFactorService as TwoFactorServiceAbstraction,
|
|
||||||
} from "../abstractions/two-factor.service";
|
|
||||||
import { TwoFactorProviderType } from "../enums/two-factor-provider-type";
|
|
||||||
import { IdentityTwoFactorResponse } from "../models/response/identity-two-factor.response";
|
|
||||||
|
|
||||||
export const TwoFactorProviders: Partial<Record<TwoFactorProviderType, TwoFactorProviderDetails>> =
|
|
||||||
{
|
|
||||||
[TwoFactorProviderType.Authenticator]: {
|
|
||||||
type: TwoFactorProviderType.Authenticator,
|
|
||||||
name: null as string,
|
|
||||||
description: null as string,
|
|
||||||
priority: 1,
|
|
||||||
sort: 2,
|
|
||||||
premium: false,
|
|
||||||
},
|
|
||||||
[TwoFactorProviderType.Yubikey]: {
|
|
||||||
type: TwoFactorProviderType.Yubikey,
|
|
||||||
name: null as string,
|
|
||||||
description: null as string,
|
|
||||||
priority: 3,
|
|
||||||
sort: 4,
|
|
||||||
premium: true,
|
|
||||||
},
|
|
||||||
[TwoFactorProviderType.Duo]: {
|
|
||||||
type: TwoFactorProviderType.Duo,
|
|
||||||
name: "Duo",
|
|
||||||
description: null as string,
|
|
||||||
priority: 2,
|
|
||||||
sort: 5,
|
|
||||||
premium: true,
|
|
||||||
},
|
|
||||||
[TwoFactorProviderType.OrganizationDuo]: {
|
|
||||||
type: TwoFactorProviderType.OrganizationDuo,
|
|
||||||
name: "Duo (Organization)",
|
|
||||||
description: null as string,
|
|
||||||
priority: 10,
|
|
||||||
sort: 6,
|
|
||||||
premium: false,
|
|
||||||
},
|
|
||||||
[TwoFactorProviderType.Email]: {
|
|
||||||
type: TwoFactorProviderType.Email,
|
|
||||||
name: null as string,
|
|
||||||
description: null as string,
|
|
||||||
priority: 0,
|
|
||||||
sort: 1,
|
|
||||||
premium: false,
|
|
||||||
},
|
|
||||||
[TwoFactorProviderType.WebAuthn]: {
|
|
||||||
type: TwoFactorProviderType.WebAuthn,
|
|
||||||
name: null as string,
|
|
||||||
description: null as string,
|
|
||||||
priority: 4,
|
|
||||||
sort: 3,
|
|
||||||
premium: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Memory storage as only required during authentication process
|
|
||||||
export const PROVIDERS = KeyDefinition.record<Record<string, string>, TwoFactorProviderType>(
|
|
||||||
TWO_FACTOR_MEMORY,
|
|
||||||
"providers",
|
|
||||||
{
|
|
||||||
deserializer: (obj) => obj,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Memory storage as only required during authentication process
|
|
||||||
export const SELECTED_PROVIDER = new KeyDefinition<TwoFactorProviderType>(
|
|
||||||
TWO_FACTOR_MEMORY,
|
|
||||||
"selected",
|
|
||||||
{
|
|
||||||
deserializer: (obj) => obj,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
export class TwoFactorService implements TwoFactorServiceAbstraction {
|
|
||||||
private providersState = this.globalStateProvider.get(PROVIDERS);
|
|
||||||
private selectedState = this.globalStateProvider.get(SELECTED_PROVIDER);
|
|
||||||
readonly providers$ = this.providersState.state$.pipe(
|
|
||||||
map((providers) => Utils.recordToMap(providers)),
|
|
||||||
);
|
|
||||||
readonly selected$ = this.selectedState.state$;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private i18nService: I18nService,
|
|
||||||
private platformUtilsService: PlatformUtilsService,
|
|
||||||
private globalStateProvider: GlobalStateProvider,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
TwoFactorProviders[TwoFactorProviderType.Email].name = this.i18nService.t("emailTitle");
|
|
||||||
TwoFactorProviders[TwoFactorProviderType.Email].description = this.i18nService.t("emailDescV2");
|
|
||||||
|
|
||||||
TwoFactorProviders[TwoFactorProviderType.Authenticator].name =
|
|
||||||
this.i18nService.t("authenticatorAppTitle");
|
|
||||||
TwoFactorProviders[TwoFactorProviderType.Authenticator].description =
|
|
||||||
this.i18nService.t("authenticatorAppDescV2");
|
|
||||||
|
|
||||||
TwoFactorProviders[TwoFactorProviderType.Duo].description = this.i18nService.t("duoDescV2");
|
|
||||||
|
|
||||||
TwoFactorProviders[TwoFactorProviderType.OrganizationDuo].name =
|
|
||||||
"Duo (" + this.i18nService.t("organization") + ")";
|
|
||||||
TwoFactorProviders[TwoFactorProviderType.OrganizationDuo].description =
|
|
||||||
this.i18nService.t("duoOrganizationDesc");
|
|
||||||
|
|
||||||
TwoFactorProviders[TwoFactorProviderType.WebAuthn].name = this.i18nService.t("webAuthnTitle");
|
|
||||||
TwoFactorProviders[TwoFactorProviderType.WebAuthn].description =
|
|
||||||
this.i18nService.t("webAuthnDesc");
|
|
||||||
|
|
||||||
TwoFactorProviders[TwoFactorProviderType.Yubikey].name = this.i18nService.t("yubiKeyTitleV2");
|
|
||||||
TwoFactorProviders[TwoFactorProviderType.Yubikey].description =
|
|
||||||
this.i18nService.t("yubiKeyDesc");
|
|
||||||
}
|
|
||||||
|
|
||||||
async getSupportedProviders(win: Window): Promise<TwoFactorProviderDetails[]> {
|
|
||||||
const data = await firstValueFrom(this.providers$);
|
|
||||||
const providers: any[] = [];
|
|
||||||
if (data == null) {
|
|
||||||
return providers;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
data.has(TwoFactorProviderType.OrganizationDuo) &&
|
|
||||||
this.platformUtilsService.supportsDuo()
|
|
||||||
) {
|
|
||||||
providers.push(TwoFactorProviders[TwoFactorProviderType.OrganizationDuo]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.has(TwoFactorProviderType.Authenticator)) {
|
|
||||||
providers.push(TwoFactorProviders[TwoFactorProviderType.Authenticator]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.has(TwoFactorProviderType.Yubikey)) {
|
|
||||||
providers.push(TwoFactorProviders[TwoFactorProviderType.Yubikey]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.has(TwoFactorProviderType.Duo) && this.platformUtilsService.supportsDuo()) {
|
|
||||||
providers.push(TwoFactorProviders[TwoFactorProviderType.Duo]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
data.has(TwoFactorProviderType.WebAuthn) &&
|
|
||||||
this.platformUtilsService.supportsWebAuthn(win)
|
|
||||||
) {
|
|
||||||
providers.push(TwoFactorProviders[TwoFactorProviderType.WebAuthn]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.has(TwoFactorProviderType.Email)) {
|
|
||||||
providers.push(TwoFactorProviders[TwoFactorProviderType.Email]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return providers;
|
|
||||||
}
|
|
||||||
|
|
||||||
async getDefaultProvider(webAuthnSupported: boolean): Promise<TwoFactorProviderType> {
|
|
||||||
const data = await firstValueFrom(this.providers$);
|
|
||||||
const selected = await firstValueFrom(this.selected$);
|
|
||||||
if (data == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selected != null && data.has(selected)) {
|
|
||||||
return selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
let providerType: TwoFactorProviderType = null;
|
|
||||||
let providerPriority = -1;
|
|
||||||
data.forEach((_value, type) => {
|
|
||||||
const provider = (TwoFactorProviders as any)[type];
|
|
||||||
if (provider != null && provider.priority > providerPriority) {
|
|
||||||
if (type === TwoFactorProviderType.WebAuthn && !webAuthnSupported) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
providerType = type;
|
|
||||||
providerPriority = provider.priority;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return providerType;
|
|
||||||
}
|
|
||||||
|
|
||||||
async setSelectedProvider(type: TwoFactorProviderType): Promise<void> {
|
|
||||||
await this.selectedState.update(() => type);
|
|
||||||
}
|
|
||||||
|
|
||||||
async clearSelectedProvider(): Promise<void> {
|
|
||||||
await this.selectedState.update(() => null);
|
|
||||||
}
|
|
||||||
|
|
||||||
async setProviders(response: IdentityTwoFactorResponse): Promise<void> {
|
|
||||||
await this.providersState.update(() => response.twoFactorProviders2);
|
|
||||||
}
|
|
||||||
|
|
||||||
async clearProviders(): Promise<void> {
|
|
||||||
await this.providersState.update(() => null);
|
|
||||||
}
|
|
||||||
|
|
||||||
getProviders(): Promise<Map<TwoFactorProviderType, { [key: string]: string }> | null> {
|
|
||||||
return firstValueFrom(this.providers$);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2
libs/common/src/auth/two-factor/abstractions/index.ts
Normal file
2
libs/common/src/auth/two-factor/abstractions/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./two-factor-api.service";
|
||||||
|
export * from "./two-factor.service";
|
||||||
@@ -0,0 +1,497 @@
|
|||||||
|
import { ListResponse } from "../../../models/response/list.response";
|
||||||
|
import { KeyDefinition, TWO_FACTOR_MEMORY } from "../../../platform/state";
|
||||||
|
import { TwoFactorProviderType } from "../../enums/two-factor-provider-type";
|
||||||
|
import { DisableTwoFactorAuthenticatorRequest } from "../../models/request/disable-two-factor-authenticator.request";
|
||||||
|
import { SecretVerificationRequest } from "../../models/request/secret-verification.request";
|
||||||
|
import { TwoFactorEmailRequest } from "../../models/request/two-factor-email.request";
|
||||||
|
import { TwoFactorProviderRequest } from "../../models/request/two-factor-provider.request";
|
||||||
|
import { UpdateTwoFactorAuthenticatorRequest } from "../../models/request/update-two-factor-authenticator.request";
|
||||||
|
import { UpdateTwoFactorDuoRequest } from "../../models/request/update-two-factor-duo.request";
|
||||||
|
import { UpdateTwoFactorEmailRequest } from "../../models/request/update-two-factor-email.request";
|
||||||
|
import { UpdateTwoFactorWebAuthnDeleteRequest } from "../../models/request/update-two-factor-web-authn-delete.request";
|
||||||
|
import { UpdateTwoFactorWebAuthnRequest } from "../../models/request/update-two-factor-web-authn.request";
|
||||||
|
import { UpdateTwoFactorYubikeyOtpRequest } from "../../models/request/update-two-factor-yubikey-otp.request";
|
||||||
|
import { IdentityTwoFactorResponse } from "../../models/response/identity-two-factor.response";
|
||||||
|
import { TwoFactorAuthenticatorResponse } from "../../models/response/two-factor-authenticator.response";
|
||||||
|
import { TwoFactorDuoResponse } from "../../models/response/two-factor-duo.response";
|
||||||
|
import { TwoFactorEmailResponse } from "../../models/response/two-factor-email.response";
|
||||||
|
import { TwoFactorProviderResponse } from "../../models/response/two-factor-provider.response";
|
||||||
|
import { TwoFactorRecoverResponse } from "../../models/response/two-factor-recover.response";
|
||||||
|
import {
|
||||||
|
ChallengeResponse,
|
||||||
|
TwoFactorWebAuthnResponse,
|
||||||
|
} from "../../models/response/two-factor-web-authn.response";
|
||||||
|
import { TwoFactorYubiKeyResponse } from "../../models/response/two-factor-yubi-key.response";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metadata and display information for a two-factor authentication provider.
|
||||||
|
* Used by UI components to render provider selection and configuration screens.
|
||||||
|
*/
|
||||||
|
export interface TwoFactorProviderDetails {
|
||||||
|
/** The unique identifier for this provider type. */
|
||||||
|
type: TwoFactorProviderType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display name for the provider, localized via {@link TwoFactorService.init}.
|
||||||
|
* Examples: "Authenticator App", "Email", "YubiKey".
|
||||||
|
*/
|
||||||
|
name: string | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User-facing description explaining what this provider is and how it works.
|
||||||
|
* Localized via {@link TwoFactorService.init}.
|
||||||
|
*/
|
||||||
|
description: string | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selection priority during login when multiple providers are available.
|
||||||
|
* Higher values are preferred. Used to determine the default provider.
|
||||||
|
* Range: 0 (lowest) to 10 (highest).
|
||||||
|
*/
|
||||||
|
priority: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display order in provider lists within settings UI.
|
||||||
|
* Lower values appear first (1 = first position).
|
||||||
|
*/
|
||||||
|
sort: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this provider requires an active premium subscription.
|
||||||
|
* Premium providers: Duo (personal), YubiKey.
|
||||||
|
* Organization providers (e.g., OrganizationDuo) do not require personal premium.
|
||||||
|
*/
|
||||||
|
premium: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registry of all supported two-factor authentication providers with their metadata.
|
||||||
|
* Strings (name, description) are initialized as null and populated with localized
|
||||||
|
* translations when {@link TwoFactorService.init} is called during application startup.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* This constant is mutated during initialization. Components should not access it before
|
||||||
|
* the service's init() method has been called.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* // During app init
|
||||||
|
* twoFactorService.init();
|
||||||
|
*
|
||||||
|
* // In components
|
||||||
|
* const authenticator = TwoFactorProviders[TwoFactorProviderType.Authenticator];
|
||||||
|
* console.log(authenticator.name); // "Authenticator App" (localized)
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export const TwoFactorProviders: Partial<Record<TwoFactorProviderType, TwoFactorProviderDetails>> =
|
||||||
|
{
|
||||||
|
[TwoFactorProviderType.Authenticator]: {
|
||||||
|
type: TwoFactorProviderType.Authenticator,
|
||||||
|
name: null,
|
||||||
|
description: null,
|
||||||
|
priority: 1,
|
||||||
|
sort: 2,
|
||||||
|
premium: false,
|
||||||
|
},
|
||||||
|
[TwoFactorProviderType.Yubikey]: {
|
||||||
|
type: TwoFactorProviderType.Yubikey,
|
||||||
|
name: null,
|
||||||
|
description: null,
|
||||||
|
priority: 3,
|
||||||
|
sort: 4,
|
||||||
|
premium: true,
|
||||||
|
},
|
||||||
|
[TwoFactorProviderType.Duo]: {
|
||||||
|
type: TwoFactorProviderType.Duo,
|
||||||
|
name: "Duo",
|
||||||
|
description: null,
|
||||||
|
priority: 2,
|
||||||
|
sort: 5,
|
||||||
|
premium: true,
|
||||||
|
},
|
||||||
|
[TwoFactorProviderType.OrganizationDuo]: {
|
||||||
|
type: TwoFactorProviderType.OrganizationDuo,
|
||||||
|
name: "Duo (Organization)",
|
||||||
|
description: null,
|
||||||
|
priority: 10,
|
||||||
|
sort: 6,
|
||||||
|
premium: false,
|
||||||
|
},
|
||||||
|
[TwoFactorProviderType.Email]: {
|
||||||
|
type: TwoFactorProviderType.Email,
|
||||||
|
name: null,
|
||||||
|
description: null,
|
||||||
|
priority: 0,
|
||||||
|
sort: 1,
|
||||||
|
premium: false,
|
||||||
|
},
|
||||||
|
[TwoFactorProviderType.WebAuthn]: {
|
||||||
|
type: TwoFactorProviderType.WebAuthn,
|
||||||
|
name: null,
|
||||||
|
description: null,
|
||||||
|
priority: 4,
|
||||||
|
sort: 3,
|
||||||
|
premium: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Memory storage as only required during authentication process
|
||||||
|
export const PROVIDERS = KeyDefinition.record<Record<string, string>, TwoFactorProviderType>(
|
||||||
|
TWO_FACTOR_MEMORY,
|
||||||
|
"providers",
|
||||||
|
{
|
||||||
|
deserializer: (obj) => obj,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Memory storage as only required during authentication process
|
||||||
|
export const SELECTED_PROVIDER = new KeyDefinition<TwoFactorProviderType>(
|
||||||
|
TWO_FACTOR_MEMORY,
|
||||||
|
"selected",
|
||||||
|
{
|
||||||
|
deserializer: (obj) => obj,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export abstract class TwoFactorService {
|
||||||
|
/**
|
||||||
|
* Initializes the client-side's TwoFactorProviders const with translations.
|
||||||
|
*/
|
||||||
|
abstract init(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of two-factor providers from state that are supported on the current client.
|
||||||
|
* E.g., WebAuthn and Duo are not available on all clients.
|
||||||
|
* @returns A list of supported two-factor providers or an empty list if none are stored in state.
|
||||||
|
*/
|
||||||
|
abstract getSupportedProviders(win: Window): Promise<TwoFactorProviderDetails[]>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the previously selected two-factor provider or the default two factor provider based on priority.
|
||||||
|
* @param webAuthnSupported - Whether or not WebAuthn is supported by the client. Prevents WebAuthn from being the default provider if false.
|
||||||
|
*/
|
||||||
|
abstract getDefaultProvider(webAuthnSupported: boolean): Promise<TwoFactorProviderType>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the selected two-factor provider in state.
|
||||||
|
* @param type - The type of two-factor provider to set as the selected provider.
|
||||||
|
*/
|
||||||
|
abstract setSelectedProvider(type: TwoFactorProviderType): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the selected two-factor provider from state.
|
||||||
|
*/
|
||||||
|
abstract clearSelectedProvider(): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the list of available two-factor providers in state.
|
||||||
|
* @param response - the response from Identity for when 2FA is required. Includes the list of available 2FA providers.
|
||||||
|
*/
|
||||||
|
abstract setProviders(response: IdentityTwoFactorResponse): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the list of available two-factor providers from state.
|
||||||
|
*/
|
||||||
|
abstract clearProviders(): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of two-factor providers from state.
|
||||||
|
* Note: no filtering is done here, so this will return all providers, including potentially
|
||||||
|
* unsupported ones for the current client.
|
||||||
|
* @returns A list of two-factor providers or null if none are stored in state.
|
||||||
|
*/
|
||||||
|
abstract getProviders(): Promise<Map<TwoFactorProviderType, { [key: string]: string }> | null>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the enabled two-factor providers for the current user from the API.
|
||||||
|
* Used for settings management.
|
||||||
|
* @returns A promise that resolves to a list response containing enabled two-factor provider configurations.
|
||||||
|
*/
|
||||||
|
abstract getEnabledTwoFactorProviders(): Promise<ListResponse<TwoFactorProviderResponse>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the enabled two-factor providers for an organization from the API.
|
||||||
|
* Requires organization administrator permissions.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param organizationId The ID of the organization.
|
||||||
|
* @returns A promise that resolves to a list response containing enabled two-factor provider configurations.
|
||||||
|
*/
|
||||||
|
abstract getTwoFactorOrganizationProviders(
|
||||||
|
organizationId: string,
|
||||||
|
): Promise<ListResponse<TwoFactorProviderResponse>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the authenticator (TOTP) two-factor configuration for the current user from the API.
|
||||||
|
* Requires user verification via master password or OTP.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link SecretVerificationRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the authenticator configuration including the secret key.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract getTwoFactorAuthenticator(
|
||||||
|
request: SecretVerificationRequest,
|
||||||
|
): Promise<TwoFactorAuthenticatorResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the email two-factor configuration for the current user from the API.
|
||||||
|
* Requires user verification via master password or OTP.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link SecretVerificationRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the email two-factor configuration.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract getTwoFactorEmail(request: SecretVerificationRequest): Promise<TwoFactorEmailResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Duo two-factor configuration for the current user from the API.
|
||||||
|
* Requires user verification and an active premium subscription.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link SecretVerificationRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the Duo configuration.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract getTwoFactorDuo(request: SecretVerificationRequest): Promise<TwoFactorDuoResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Duo two-factor configuration for an organization from the API.
|
||||||
|
* Requires user verification and organization policy management permissions.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param organizationId The ID of the organization.
|
||||||
|
* @param request The {@link SecretVerificationRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the organization Duo configuration.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract getTwoFactorOrganizationDuo(
|
||||||
|
organizationId: string,
|
||||||
|
request: SecretVerificationRequest,
|
||||||
|
): Promise<TwoFactorDuoResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the YubiKey OTP two-factor configuration for the current user from the API.
|
||||||
|
* Requires user verification and an active premium subscription.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link SecretVerificationRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the YubiKey configuration.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract getTwoFactorYubiKey(
|
||||||
|
request: SecretVerificationRequest,
|
||||||
|
): Promise<TwoFactorYubiKeyResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the WebAuthn (FIDO2) two-factor configuration for the current user from the API.
|
||||||
|
* Requires user verification via master password or OTP.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link SecretVerificationRequest} to authentication.
|
||||||
|
* @returns A promise that resolves to the WebAuthn configuration including registered credentials.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract getTwoFactorWebAuthn(
|
||||||
|
request: SecretVerificationRequest,
|
||||||
|
): Promise<TwoFactorWebAuthnResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a WebAuthn challenge for registering a new WebAuthn credential from the API.
|
||||||
|
* This must be called before putTwoFactorWebAuthn to obtain the cryptographic challenge
|
||||||
|
* required for credential creation. The challenge is used by the browser's WebAuthn API.
|
||||||
|
* Requires user verification via master password or OTP.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link SecretVerificationRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the credential creation options containing the challenge.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract getTwoFactorWebAuthnChallenge(
|
||||||
|
request: SecretVerificationRequest,
|
||||||
|
): Promise<ChallengeResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the recovery code configuration for the current user from the API.
|
||||||
|
* The recovery code should be stored securely by the user.
|
||||||
|
* Requires user verification via master password or OTP.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param verification The verification information to prove authentication.
|
||||||
|
* @returns A promise that resolves to the recovery code configuration.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract getTwoFactorRecover(
|
||||||
|
request: SecretVerificationRequest,
|
||||||
|
): Promise<TwoFactorRecoverResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables or updates the authenticator (TOTP) two-factor provider.
|
||||||
|
* Validates the provided token against the shared secret before enabling.
|
||||||
|
* The token must be generated by an authenticator app using the secret key.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link UpdateTwoFactorAuthenticatorRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the updated authenticator configuration.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract putTwoFactorAuthenticator(
|
||||||
|
request: UpdateTwoFactorAuthenticatorRequest,
|
||||||
|
): Promise<TwoFactorAuthenticatorResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables the authenticator (TOTP) two-factor provider for the current user.
|
||||||
|
* Requires user verification token to confirm the operation.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link DisableTwoFactorAuthenticatorRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the updated provider status.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract deleteTwoFactorAuthenticator(
|
||||||
|
request: DisableTwoFactorAuthenticatorRequest,
|
||||||
|
): Promise<TwoFactorProviderResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables or updates the email two-factor provider for the current user.
|
||||||
|
* Validates the email verification token sent via postTwoFactorEmailSetup before enabling.
|
||||||
|
* The token must match the code sent to the specified email address.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link UpdateTwoFactorEmailRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the updated email two-factor configuration.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract putTwoFactorEmail(request: UpdateTwoFactorEmailRequest): Promise<TwoFactorEmailResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables or updates the Duo two-factor provider for the current user.
|
||||||
|
* Validates the Duo configuration (client ID, client secret, and host) before enabling.
|
||||||
|
* Requires user verification and an active premium subscription.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link UpdateTwoFactorDuoRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the updated Duo configuration.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract putTwoFactorDuo(request: UpdateTwoFactorDuoRequest): Promise<TwoFactorDuoResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables or updates the Duo two-factor provider for an organization.
|
||||||
|
* Validates the Duo configuration (client ID, client secret, and host) before enabling.
|
||||||
|
* Requires user verification and organization policy management permissions.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param organizationId The ID of the organization.
|
||||||
|
* @param request The {@link UpdateTwoFactorDuoRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the updated organization Duo configuration.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract putTwoFactorOrganizationDuo(
|
||||||
|
organizationId: string,
|
||||||
|
request: UpdateTwoFactorDuoRequest,
|
||||||
|
): Promise<TwoFactorDuoResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables or updates the YubiKey OTP two-factor provider for the current user.
|
||||||
|
* Validates each provided YubiKey by testing an OTP from the device.
|
||||||
|
* Supports up to 5 YubiKey devices. Empty key slots are allowed.
|
||||||
|
* Requires user verification and an active premium subscription.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link UpdateTwoFactorYubikeyOtpRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the updated YubiKey configuration.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract putTwoFactorYubiKey(
|
||||||
|
request: UpdateTwoFactorYubikeyOtpRequest,
|
||||||
|
): Promise<TwoFactorYubiKeyResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a new WebAuthn (FIDO2) credential for two-factor authentication for the current user.
|
||||||
|
* Must be called after getTwoFactorWebAuthnChallenge to complete the registration flow.
|
||||||
|
* The device response contains the signed challenge from the authenticator device.
|
||||||
|
* Requires user verification via master password or OTP.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link UpdateTwoFactorWebAuthnRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the updated WebAuthn configuration with the new credential.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract putTwoFactorWebAuthn(
|
||||||
|
request: UpdateTwoFactorWebAuthnRequest,
|
||||||
|
): Promise<TwoFactorWebAuthnResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a specific WebAuthn (FIDO2) credential from the user's account.
|
||||||
|
* The credential will no longer be usable for two-factor authentication.
|
||||||
|
* Other registered WebAuthn credentials remain active.
|
||||||
|
* Requires user verification via master password or OTP.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link UpdateTwoFactorWebAuthnDeleteRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the updated WebAuthn configuration.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract deleteTwoFactorWebAuthn(
|
||||||
|
request: UpdateTwoFactorWebAuthnDeleteRequest,
|
||||||
|
): Promise<TwoFactorWebAuthnResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables a specific two-factor provider for the current user.
|
||||||
|
* The provider will no longer be required or usable for authentication.
|
||||||
|
* Requires user verification via master password or OTP.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link TwoFactorProviderRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the updated provider status.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract putTwoFactorDisable(
|
||||||
|
request: TwoFactorProviderRequest,
|
||||||
|
): Promise<TwoFactorProviderResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables a specific two-factor provider for an organization.
|
||||||
|
* The provider will no longer be available for organization members.
|
||||||
|
* Requires user verification and organization policy management permissions.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param organizationId The ID of the organization.
|
||||||
|
* @param request The {@link TwoFactorProviderRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves to the updated provider status.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract putTwoFactorOrganizationDisable(
|
||||||
|
organizationId: string,
|
||||||
|
request: TwoFactorProviderRequest,
|
||||||
|
): Promise<TwoFactorProviderResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiates email two-factor setup by sending a verification code to the specified email address.
|
||||||
|
* This is the first step in enabling email two-factor authentication.
|
||||||
|
* The verification code must be provided to putTwoFactorEmail to complete setup.
|
||||||
|
* Only used during initial configuration, not during login flows.
|
||||||
|
* Requires user verification via master password or OTP.
|
||||||
|
* Used for settings management.
|
||||||
|
*
|
||||||
|
* @param request The {@link TwoFactorEmailRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves when the verification email has been sent.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract postTwoFactorEmailSetup(request: TwoFactorEmailRequest): Promise<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a two-factor authentication code via email during the login flow.
|
||||||
|
* Supports multiple authentication contexts including standard login, SSO, and passwordless flows.
|
||||||
|
* This is used to deliver codes during authentication, not during initial setup.
|
||||||
|
* May be called without authentication for login scenarios.
|
||||||
|
* Used during authentication flows.
|
||||||
|
*
|
||||||
|
* @param request The {@link TwoFactorEmailRequest} to prove authentication.
|
||||||
|
* @returns A promise that resolves when the authentication email has been sent.
|
||||||
|
* @remarks Use {@link UserVerificationService.buildRequest} to create the request object.
|
||||||
|
*/
|
||||||
|
abstract postTwoFactorEmail(request: TwoFactorEmailRequest): Promise<any>;
|
||||||
|
}
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
export { TwoFactorApiService } from "./two-factor-api.service";
|
export * from "./abstractions";
|
||||||
export { DefaultTwoFactorApiService } from "./default-two-factor-api.service";
|
export * from "./services";
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import { TwoFactorYubiKeyResponse } from "@bitwarden/common/auth/models/response
|
|||||||
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
||||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||||
|
|
||||||
import { TwoFactorApiService } from "./two-factor-api.service";
|
import { TwoFactorApiService } from "../abstractions/two-factor-api.service";
|
||||||
|
|
||||||
export class DefaultTwoFactorApiService implements TwoFactorApiService {
|
export class DefaultTwoFactorApiService implements TwoFactorApiService {
|
||||||
constructor(private apiService: ApiService) {}
|
constructor(private apiService: ApiService) {}
|
||||||
@@ -0,0 +1,279 @@
|
|||||||
|
// FIXME: Update this file to be type safe and remove this and next line
|
||||||
|
// @ts-strict-ignore
|
||||||
|
import { firstValueFrom, map } from "rxjs";
|
||||||
|
|
||||||
|
import { TwoFactorApiService } from "..";
|
||||||
|
import { ListResponse } from "../../../models/response/list.response";
|
||||||
|
import { I18nService } from "../../../platform/abstractions/i18n.service";
|
||||||
|
import { PlatformUtilsService } from "../../../platform/abstractions/platform-utils.service";
|
||||||
|
import { Utils } from "../../../platform/misc/utils";
|
||||||
|
import { GlobalStateProvider } from "../../../platform/state";
|
||||||
|
import { TwoFactorProviderType } from "../../enums/two-factor-provider-type";
|
||||||
|
import { DisableTwoFactorAuthenticatorRequest } from "../../models/request/disable-two-factor-authenticator.request";
|
||||||
|
import { SecretVerificationRequest } from "../../models/request/secret-verification.request";
|
||||||
|
import { TwoFactorEmailRequest } from "../../models/request/two-factor-email.request";
|
||||||
|
import { TwoFactorProviderRequest } from "../../models/request/two-factor-provider.request";
|
||||||
|
import { UpdateTwoFactorAuthenticatorRequest } from "../../models/request/update-two-factor-authenticator.request";
|
||||||
|
import { UpdateTwoFactorDuoRequest } from "../../models/request/update-two-factor-duo.request";
|
||||||
|
import { UpdateTwoFactorEmailRequest } from "../../models/request/update-two-factor-email.request";
|
||||||
|
import { UpdateTwoFactorWebAuthnDeleteRequest } from "../../models/request/update-two-factor-web-authn-delete.request";
|
||||||
|
import { UpdateTwoFactorWebAuthnRequest } from "../../models/request/update-two-factor-web-authn.request";
|
||||||
|
import { UpdateTwoFactorYubikeyOtpRequest } from "../../models/request/update-two-factor-yubikey-otp.request";
|
||||||
|
import { IdentityTwoFactorResponse } from "../../models/response/identity-two-factor.response";
|
||||||
|
import { TwoFactorAuthenticatorResponse } from "../../models/response/two-factor-authenticator.response";
|
||||||
|
import { TwoFactorDuoResponse } from "../../models/response/two-factor-duo.response";
|
||||||
|
import { TwoFactorEmailResponse } from "../../models/response/two-factor-email.response";
|
||||||
|
import { TwoFactorProviderResponse } from "../../models/response/two-factor-provider.response";
|
||||||
|
import { TwoFactorRecoverResponse } from "../../models/response/two-factor-recover.response";
|
||||||
|
import {
|
||||||
|
TwoFactorWebAuthnResponse,
|
||||||
|
ChallengeResponse,
|
||||||
|
} from "../../models/response/two-factor-web-authn.response";
|
||||||
|
import { TwoFactorYubiKeyResponse } from "../../models/response/two-factor-yubi-key.response";
|
||||||
|
import {
|
||||||
|
PROVIDERS,
|
||||||
|
SELECTED_PROVIDER,
|
||||||
|
TwoFactorProviderDetails,
|
||||||
|
TwoFactorProviders,
|
||||||
|
TwoFactorService as TwoFactorServiceAbstraction,
|
||||||
|
} from "../abstractions/two-factor.service";
|
||||||
|
|
||||||
|
export class DefaultTwoFactorService implements TwoFactorServiceAbstraction {
|
||||||
|
private providersState = this.globalStateProvider.get(PROVIDERS);
|
||||||
|
private selectedState = this.globalStateProvider.get(SELECTED_PROVIDER);
|
||||||
|
readonly providers$ = this.providersState.state$.pipe(
|
||||||
|
map((providers) => Utils.recordToMap(providers)),
|
||||||
|
);
|
||||||
|
readonly selected$ = this.selectedState.state$;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private i18nService: I18nService,
|
||||||
|
private platformUtilsService: PlatformUtilsService,
|
||||||
|
private globalStateProvider: GlobalStateProvider,
|
||||||
|
private twoFactorApiService: TwoFactorApiService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
TwoFactorProviders[TwoFactorProviderType.Email].name = this.i18nService.t("emailTitle");
|
||||||
|
TwoFactorProviders[TwoFactorProviderType.Email].description = this.i18nService.t("emailDescV2");
|
||||||
|
|
||||||
|
TwoFactorProviders[TwoFactorProviderType.Authenticator].name =
|
||||||
|
this.i18nService.t("authenticatorAppTitle");
|
||||||
|
TwoFactorProviders[TwoFactorProviderType.Authenticator].description =
|
||||||
|
this.i18nService.t("authenticatorAppDescV2");
|
||||||
|
|
||||||
|
TwoFactorProviders[TwoFactorProviderType.Duo].description = this.i18nService.t("duoDescV2");
|
||||||
|
|
||||||
|
TwoFactorProviders[TwoFactorProviderType.OrganizationDuo].name =
|
||||||
|
"Duo (" + this.i18nService.t("organization") + ")";
|
||||||
|
TwoFactorProviders[TwoFactorProviderType.OrganizationDuo].description =
|
||||||
|
this.i18nService.t("duoOrganizationDesc");
|
||||||
|
|
||||||
|
TwoFactorProviders[TwoFactorProviderType.WebAuthn].name = this.i18nService.t("webAuthnTitle");
|
||||||
|
TwoFactorProviders[TwoFactorProviderType.WebAuthn].description =
|
||||||
|
this.i18nService.t("webAuthnDesc");
|
||||||
|
|
||||||
|
TwoFactorProviders[TwoFactorProviderType.Yubikey].name = this.i18nService.t("yubiKeyTitleV2");
|
||||||
|
TwoFactorProviders[TwoFactorProviderType.Yubikey].description =
|
||||||
|
this.i18nService.t("yubiKeyDesc");
|
||||||
|
}
|
||||||
|
|
||||||
|
async getSupportedProviders(win: Window): Promise<TwoFactorProviderDetails[]> {
|
||||||
|
const data = await firstValueFrom(this.providers$);
|
||||||
|
const providers: any[] = [];
|
||||||
|
if (data == null) {
|
||||||
|
return providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
data.has(TwoFactorProviderType.OrganizationDuo) &&
|
||||||
|
this.platformUtilsService.supportsDuo()
|
||||||
|
) {
|
||||||
|
providers.push(TwoFactorProviders[TwoFactorProviderType.OrganizationDuo]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.has(TwoFactorProviderType.Authenticator)) {
|
||||||
|
providers.push(TwoFactorProviders[TwoFactorProviderType.Authenticator]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.has(TwoFactorProviderType.Yubikey)) {
|
||||||
|
providers.push(TwoFactorProviders[TwoFactorProviderType.Yubikey]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.has(TwoFactorProviderType.Duo) && this.platformUtilsService.supportsDuo()) {
|
||||||
|
providers.push(TwoFactorProviders[TwoFactorProviderType.Duo]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
data.has(TwoFactorProviderType.WebAuthn) &&
|
||||||
|
this.platformUtilsService.supportsWebAuthn(win)
|
||||||
|
) {
|
||||||
|
providers.push(TwoFactorProviders[TwoFactorProviderType.WebAuthn]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.has(TwoFactorProviderType.Email)) {
|
||||||
|
providers.push(TwoFactorProviders[TwoFactorProviderType.Email]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDefaultProvider(webAuthnSupported: boolean): Promise<TwoFactorProviderType> {
|
||||||
|
const data = await firstValueFrom(this.providers$);
|
||||||
|
const selected = await firstValueFrom(this.selected$);
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selected != null && data.has(selected)) {
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
let providerType: TwoFactorProviderType = null;
|
||||||
|
let providerPriority = -1;
|
||||||
|
data.forEach((_value, type) => {
|
||||||
|
const provider = (TwoFactorProviders as any)[type];
|
||||||
|
if (provider != null && provider.priority > providerPriority) {
|
||||||
|
if (type === TwoFactorProviderType.WebAuthn && !webAuthnSupported) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
providerType = type;
|
||||||
|
providerPriority = provider.priority;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return providerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
async setSelectedProvider(type: TwoFactorProviderType): Promise<void> {
|
||||||
|
await this.selectedState.update(() => type);
|
||||||
|
}
|
||||||
|
|
||||||
|
async clearSelectedProvider(): Promise<void> {
|
||||||
|
await this.selectedState.update(() => null);
|
||||||
|
}
|
||||||
|
|
||||||
|
async setProviders(response: IdentityTwoFactorResponse): Promise<void> {
|
||||||
|
await this.providersState.update(() => response.twoFactorProviders2);
|
||||||
|
}
|
||||||
|
|
||||||
|
async clearProviders(): Promise<void> {
|
||||||
|
await this.providersState.update(() => null);
|
||||||
|
}
|
||||||
|
|
||||||
|
getProviders(): Promise<Map<TwoFactorProviderType, { [key: string]: string }> | null> {
|
||||||
|
return firstValueFrom(this.providers$);
|
||||||
|
}
|
||||||
|
|
||||||
|
getEnabledTwoFactorProviders(): Promise<ListResponse<TwoFactorProviderResponse>> {
|
||||||
|
return this.twoFactorApiService.getTwoFactorProviders();
|
||||||
|
}
|
||||||
|
|
||||||
|
getTwoFactorOrganizationProviders(
|
||||||
|
organizationId: string,
|
||||||
|
): Promise<ListResponse<TwoFactorProviderResponse>> {
|
||||||
|
return this.twoFactorApiService.getTwoFactorOrganizationProviders(organizationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTwoFactorAuthenticator(
|
||||||
|
request: SecretVerificationRequest,
|
||||||
|
): Promise<TwoFactorAuthenticatorResponse> {
|
||||||
|
return this.twoFactorApiService.getTwoFactorAuthenticator(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTwoFactorEmail(request: SecretVerificationRequest): Promise<TwoFactorEmailResponse> {
|
||||||
|
return this.twoFactorApiService.getTwoFactorEmail(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTwoFactorDuo(request: SecretVerificationRequest): Promise<TwoFactorDuoResponse> {
|
||||||
|
return this.twoFactorApiService.getTwoFactorDuo(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTwoFactorOrganizationDuo(
|
||||||
|
organizationId: string,
|
||||||
|
request: SecretVerificationRequest,
|
||||||
|
): Promise<TwoFactorDuoResponse> {
|
||||||
|
return this.twoFactorApiService.getTwoFactorOrganizationDuo(organizationId, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTwoFactorYubiKey(request: SecretVerificationRequest): Promise<TwoFactorYubiKeyResponse> {
|
||||||
|
return this.twoFactorApiService.getTwoFactorYubiKey(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTwoFactorWebAuthn(request: SecretVerificationRequest): Promise<TwoFactorWebAuthnResponse> {
|
||||||
|
return this.twoFactorApiService.getTwoFactorWebAuthn(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTwoFactorWebAuthnChallenge(request: SecretVerificationRequest): Promise<ChallengeResponse> {
|
||||||
|
return this.twoFactorApiService.getTwoFactorWebAuthnChallenge(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTwoFactorRecover(request: SecretVerificationRequest): Promise<TwoFactorRecoverResponse> {
|
||||||
|
return this.twoFactorApiService.getTwoFactorRecover(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
putTwoFactorAuthenticator(
|
||||||
|
request: UpdateTwoFactorAuthenticatorRequest,
|
||||||
|
): Promise<TwoFactorAuthenticatorResponse> {
|
||||||
|
return this.twoFactorApiService.putTwoFactorAuthenticator(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteTwoFactorAuthenticator(
|
||||||
|
request: DisableTwoFactorAuthenticatorRequest,
|
||||||
|
): Promise<TwoFactorProviderResponse> {
|
||||||
|
return this.twoFactorApiService.deleteTwoFactorAuthenticator(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
putTwoFactorEmail(request: UpdateTwoFactorEmailRequest): Promise<TwoFactorEmailResponse> {
|
||||||
|
return this.twoFactorApiService.putTwoFactorEmail(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
putTwoFactorDuo(request: UpdateTwoFactorDuoRequest): Promise<TwoFactorDuoResponse> {
|
||||||
|
return this.twoFactorApiService.putTwoFactorDuo(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
putTwoFactorOrganizationDuo(
|
||||||
|
organizationId: string,
|
||||||
|
request: UpdateTwoFactorDuoRequest,
|
||||||
|
): Promise<TwoFactorDuoResponse> {
|
||||||
|
return this.twoFactorApiService.putTwoFactorOrganizationDuo(organizationId, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
putTwoFactorYubiKey(
|
||||||
|
request: UpdateTwoFactorYubikeyOtpRequest,
|
||||||
|
): Promise<TwoFactorYubiKeyResponse> {
|
||||||
|
return this.twoFactorApiService.putTwoFactorYubiKey(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
putTwoFactorWebAuthn(
|
||||||
|
request: UpdateTwoFactorWebAuthnRequest,
|
||||||
|
): Promise<TwoFactorWebAuthnResponse> {
|
||||||
|
return this.twoFactorApiService.putTwoFactorWebAuthn(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteTwoFactorWebAuthn(
|
||||||
|
request: UpdateTwoFactorWebAuthnDeleteRequest,
|
||||||
|
): Promise<TwoFactorWebAuthnResponse> {
|
||||||
|
return this.twoFactorApiService.deleteTwoFactorWebAuthn(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
putTwoFactorDisable(request: TwoFactorProviderRequest): Promise<TwoFactorProviderResponse> {
|
||||||
|
return this.twoFactorApiService.putTwoFactorDisable(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
putTwoFactorOrganizationDisable(
|
||||||
|
organizationId: string,
|
||||||
|
request: TwoFactorProviderRequest,
|
||||||
|
): Promise<TwoFactorProviderResponse> {
|
||||||
|
return this.twoFactorApiService.putTwoFactorOrganizationDisable(organizationId, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
postTwoFactorEmailSetup(request: TwoFactorEmailRequest): Promise<any> {
|
||||||
|
return this.twoFactorApiService.postTwoFactorEmailSetup(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
postTwoFactorEmail(request: TwoFactorEmailRequest): Promise<any> {
|
||||||
|
return this.twoFactorApiService.postTwoFactorEmail(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
2
libs/common/src/auth/two-factor/services/index.ts
Normal file
2
libs/common/src/auth/two-factor/services/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./default-two-factor-api.service";
|
||||||
|
export * from "./default-two-factor.service";
|
||||||
Reference in New Issue
Block a user