mirror of
https://github.com/bitwarden/browser
synced 2026-01-05 01:53:55 +00:00
WebAuthn (#163)
This commit is contained in:
@@ -66,8 +66,8 @@ import { UpdateProfileRequest } from '../models/request/updateProfileRequest';
|
||||
import { UpdateTwoFactorAuthenticatorRequest } from '../models/request/updateTwoFactorAuthenticatorRequest';
|
||||
import { UpdateTwoFactorDuoRequest } from '../models/request/updateTwoFactorDuoRequest';
|
||||
import { UpdateTwoFactorEmailRequest } from '../models/request/updateTwoFactorEmailRequest';
|
||||
import { UpdateTwoFactorU2fDeleteRequest } from '../models/request/updateTwoFactorU2fDeleteRequest';
|
||||
import { UpdateTwoFactorU2fRequest } from '../models/request/updateTwoFactorU2fRequest';
|
||||
import { UpdateTwoFactorWebAuthnDeleteRequest } from '../models/request/updateTwoFactorWebAuthnDeleteRequest';
|
||||
import { UpdateTwoFactorWebAuthnRequest } from '../models/request/updateTwoFactorWebAuthnRequest';
|
||||
import { UpdateTwoFactorYubioOtpRequest } from '../models/request/updateTwoFactorYubioOtpRequest';
|
||||
import { VerifyBankRequest } from '../models/request/verifyBankRequest';
|
||||
import { VerifyDeleteRecoverRequest } from '../models/request/verifyDeleteRecoverRequest';
|
||||
@@ -123,10 +123,8 @@ import { TwoFactorDuoResponse } from '../models/response/twoFactorDuoResponse';
|
||||
import { TwoFactorEmailResponse } from '../models/response/twoFactorEmailResponse';
|
||||
import { TwoFactorProviderResponse } from '../models/response/twoFactorProviderResponse';
|
||||
import { TwoFactorRecoverResponse } from '../models/response/twoFactorRescoverResponse';
|
||||
import {
|
||||
ChallengeResponse,
|
||||
TwoFactorU2fResponse,
|
||||
} from '../models/response/twoFactorU2fResponse';
|
||||
import { TwoFactorWebAuthnResponse } from '../models/response/twoFactorWebAuthnResponse';
|
||||
import { ChallengeResponse } from '../models/response/twoFactorWebAuthnResponse';
|
||||
import { TwoFactorYubiKeyResponse } from '../models/response/twoFactorYubiKeyResponse';
|
||||
import { UserKeyResponse } from '../models/response/userKeyResponse';
|
||||
|
||||
@@ -849,13 +847,13 @@ export class ApiService implements ApiServiceAbstraction {
|
||||
return new TwoFactorYubiKeyResponse(r);
|
||||
}
|
||||
|
||||
async getTwoFactorU2f(request: PasswordVerificationRequest): Promise<TwoFactorU2fResponse> {
|
||||
const r = await this.send('POST', '/two-factor/get-u2f', request, true, true);
|
||||
return new TwoFactorU2fResponse(r);
|
||||
async getTwoFactorWebAuthn(request: PasswordVerificationRequest): Promise<TwoFactorWebAuthnResponse> {
|
||||
const r = await this.send('POST', '/two-factor/get-webauthn', request, true, true);
|
||||
return new TwoFactorWebAuthnResponse(r);
|
||||
}
|
||||
|
||||
async getTwoFactorU2fChallenge(request: PasswordVerificationRequest): Promise<ChallengeResponse> {
|
||||
const r = await this.send('POST', '/two-factor/get-u2f-challenge', request, true, true);
|
||||
async getTwoFactorWebAuthnChallenge(request: PasswordVerificationRequest): Promise<ChallengeResponse> {
|
||||
const r = await this.send('POST', '/two-factor/get-webauthn-challenge', request, true, true);
|
||||
return new ChallengeResponse(r);
|
||||
}
|
||||
|
||||
@@ -891,14 +889,28 @@ export class ApiService implements ApiServiceAbstraction {
|
||||
return new TwoFactorYubiKeyResponse(r);
|
||||
}
|
||||
|
||||
async putTwoFactorU2f(request: UpdateTwoFactorU2fRequest): Promise<TwoFactorU2fResponse> {
|
||||
const r = await this.send('PUT', '/two-factor/u2f', request, true, true);
|
||||
return new TwoFactorU2fResponse(r);
|
||||
async putTwoFactorWebAuthn(request: UpdateTwoFactorWebAuthnRequest): Promise<TwoFactorWebAuthnResponse> {
|
||||
const response = request.deviceResponse.response as AuthenticatorAttestationResponse;
|
||||
const data: any = Object.assign({}, request);
|
||||
|
||||
data.deviceResponse = {
|
||||
id: request.deviceResponse.id,
|
||||
rawId: btoa(request.deviceResponse.id),
|
||||
type: request.deviceResponse.type,
|
||||
extensions: request.deviceResponse.getClientExtensionResults(),
|
||||
response: {
|
||||
AttestationObject: Utils.fromBufferToB64(response.attestationObject),
|
||||
clientDataJson: Utils.fromBufferToB64(response.clientDataJSON),
|
||||
},
|
||||
};
|
||||
|
||||
const r = await this.send('PUT', '/two-factor/webauthn', data, true, true);
|
||||
return new TwoFactorWebAuthnResponse(r);
|
||||
}
|
||||
|
||||
async deleteTwoFactorU2f(request: UpdateTwoFactorU2fDeleteRequest): Promise<TwoFactorU2fResponse> {
|
||||
const r = await this.send('DELETE', '/two-factor/u2f', request, true, true);
|
||||
return new TwoFactorU2fResponse(r);
|
||||
async deleteTwoFactorWebAuthn(request: UpdateTwoFactorWebAuthnDeleteRequest): Promise<TwoFactorWebAuthnResponse> {
|
||||
const r = await this.send('DELETE', '/two-factor/webauthn', request, true, true);
|
||||
return new TwoFactorWebAuthnResponse(r);
|
||||
}
|
||||
|
||||
async putTwoFactorDisable(request: TwoFactorProviderRequest): Promise<TwoFactorProviderResponse> {
|
||||
|
||||
@@ -57,14 +57,6 @@ export const TwoFactorProviders = {
|
||||
sort: 4,
|
||||
premium: false,
|
||||
},
|
||||
[TwoFactorProviderType.U2f]: {
|
||||
type: TwoFactorProviderType.U2f,
|
||||
name: null as string,
|
||||
description: null as string,
|
||||
priority: 4,
|
||||
sort: 5,
|
||||
premium: true,
|
||||
},
|
||||
[TwoFactorProviderType.Email]: {
|
||||
type: TwoFactorProviderType.Email,
|
||||
name: null as string,
|
||||
@@ -73,6 +65,14 @@ export const TwoFactorProviders = {
|
||||
sort: 6,
|
||||
premium: false,
|
||||
},
|
||||
[TwoFactorProviderType.WebAuthn]: {
|
||||
type: TwoFactorProviderType.WebAuthn,
|
||||
name: null as string,
|
||||
description: null as string,
|
||||
priority: 4,
|
||||
sort: 5,
|
||||
premium: true,
|
||||
},
|
||||
};
|
||||
|
||||
export class AuthService implements AuthServiceAbstraction {
|
||||
@@ -111,8 +111,8 @@ export class AuthService implements AuthServiceAbstraction {
|
||||
TwoFactorProviders[TwoFactorProviderType.OrganizationDuo].description =
|
||||
this.i18nService.t('duoOrganizationDesc');
|
||||
|
||||
TwoFactorProviders[TwoFactorProviderType.U2f].name = this.i18nService.t('u2fTitle');
|
||||
TwoFactorProviders[TwoFactorProviderType.U2f].description = this.i18nService.t('u2fDesc');
|
||||
TwoFactorProviders[TwoFactorProviderType.WebAuthn].name = this.i18nService.t('webAuthnTitle');
|
||||
TwoFactorProviders[TwoFactorProviderType.WebAuthn].description = this.i18nService.t('webAuthnDesc');
|
||||
|
||||
TwoFactorProviders[TwoFactorProviderType.Yubikey].name = this.i18nService.t('yubiKeyTitle');
|
||||
TwoFactorProviders[TwoFactorProviderType.Yubikey].description = this.i18nService.t('yubiKeyDesc');
|
||||
@@ -196,8 +196,8 @@ export class AuthService implements AuthServiceAbstraction {
|
||||
providers.push(TwoFactorProviders[TwoFactorProviderType.Duo]);
|
||||
}
|
||||
|
||||
if (this.twoFactorProvidersData.has(TwoFactorProviderType.U2f) && this.platformUtilsService.supportsU2f(win)) {
|
||||
providers.push(TwoFactorProviders[TwoFactorProviderType.U2f]);
|
||||
if (this.twoFactorProvidersData.has(TwoFactorProviderType.WebAuthn) && this.platformUtilsService.supportsWebAuthn(win)) {
|
||||
providers.push(TwoFactorProviders[TwoFactorProviderType.WebAuthn]);
|
||||
}
|
||||
|
||||
if (this.twoFactorProvidersData.has(TwoFactorProviderType.Email)) {
|
||||
@@ -207,7 +207,7 @@ export class AuthService implements AuthServiceAbstraction {
|
||||
return providers;
|
||||
}
|
||||
|
||||
getDefaultTwoFactorProvider(u2fSupported: boolean): TwoFactorProviderType {
|
||||
getDefaultTwoFactorProvider(webAuthnSupported: boolean): TwoFactorProviderType {
|
||||
if (this.twoFactorProvidersData == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -222,7 +222,7 @@ export class AuthService implements AuthServiceAbstraction {
|
||||
this.twoFactorProvidersData.forEach((value, type) => {
|
||||
const provider = (TwoFactorProviders as any)[type];
|
||||
if (provider != null && provider.priority > providerPriority) {
|
||||
if (type === TwoFactorProviderType.U2f && !u2fSupported) {
|
||||
if (type === TwoFactorProviderType.WebAuthn && !webAuthnSupported) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user