From a74a4e2546597a5c1553aa6358d3bca5f9ea658b Mon Sep 17 00:00:00 2001 From: Pranav Jain Date: Fri, 27 Sep 2024 13:44:22 -0400 Subject: [PATCH] chore(sdk-core): use the raw response returned from webauthn Ticket: WP-2592 TICKET: WP-2592 --- modules/sdk-api/src/bitgoAPI.ts | 54 +++++++++++---------------------- modules/sdk-api/src/types.ts | 18 +---------- 2 files changed, 19 insertions(+), 53 deletions(-) diff --git a/modules/sdk-api/src/bitgoAPI.ts b/modules/sdk-api/src/bitgoAPI.ts index 694cb33cbf..2a4473268d 100644 --- a/modules/sdk-api/src/bitgoAPI.ts +++ b/modules/sdk-api/src/bitgoAPI.ts @@ -65,7 +65,6 @@ import { LoginResponse, PingOptions, ProcessedAuthenticationOptions, - ProcessedAuthenticationPasskeyOptions, ReconstitutedSecret, ReconstituteSecretOptions, RegisterPushTokenOptions, @@ -775,48 +774,29 @@ export class BitGoAPI implements BitGoBase { } /** - * Process auth passkey options into an object for bitgo authentication. + * Validate the passkey response is in the expected format + * Should be as is returned from navigator.credentials.get() */ - preprocessAuthenticationPasskeyParams(params: AuthenticateWithPasskeyOptions): ProcessedAuthenticationPasskeyOptions { + validatePasskeyResponse(params: AuthenticateWithPasskeyOptions): void { if (!_.isString(params.username)) { throw new Error('expected string username'); } - - if (!_.isString(params.credId)) { - throw new Error('expected string credId'); + const webauthnResponse = JSON.parse(params.webauthnResponse); + if (!webauthnResponse && !webauthnResponse.response) { + throw new Error('unexpected webauthnResponse'); } - - if (!_.isString(params.authenticatorData)) { - throw new Error('required string authenticatorData'); + if (!_.isString(webauthnResponse.rawId)) { + throw new Error('rawId is missing'); } - - if (!_.isString(params.signature)) { - throw new Error('required string signature'); + if (!_.isString(webauthnResponse.response.authenticatorData)) { + throw new Error('authenticatorData is missing'); } - - if (!_.isString(params.clientDataJSON)) { - throw new Error('required string clientDataJSON'); + if (!_.isString(webauthnResponse.response.clientDataJSON)) { + throw new Error('clientDataJSON is missing'); } - - const processedParams: ProcessedAuthenticationPasskeyOptions = { - username: params.username, - credId: params.credId, - authenticatorData: params.authenticatorData, - signature: params.signature, - clientDataJSON: params.clientDataJSON, - }; - - if (params.extensible) { - this._extensionKey = makeRandomKey(); - processedParams.extensible = true; - processedParams.extensionAddress = getAddressP2PKH(this._extensionKey); - } - - if (params.forReset2FA) { - processedParams.forReset2FA = true; + if (!_.isString(webauthnResponse.response.signature)) { + throw new Error('signature is missing'); } - - return params; } /** @@ -976,15 +956,17 @@ export class BitGoAPI implements BitGoBase { } const authUrl = this.microservicesUrl('/api/auth/v1/session'); - const authParams = this.preprocessAuthenticationPasskeyParams(params); const request = this.post(authUrl); - const response: superagent.Response = await request.send(authParams); + this.validatePasskeyResponse(params); + + const response: superagent.Response = await request.send(params); // extract body and user information const body = response.body; this._user = body.user; // Expecting unencrypted access token in response for now + // TODO (WP-2733): Use GPG encryption to decrypt access token if (body.access_token) { this._token = body.access_token; } else { diff --git a/modules/sdk-api/src/types.ts b/modules/sdk-api/src/types.ts index bc0ac82548..cdc601e6c9 100644 --- a/modules/sdk-api/src/types.ts +++ b/modules/sdk-api/src/types.ts @@ -106,12 +106,7 @@ export interface AuthenticateOptions { export interface AuthenticateWithPasskeyOptions { username: string; - credId: string; - authenticatorData: string; - signature: string; - clientDataJSON: string; - extensible?: boolean; - forReset2FA?: boolean; + webauthnResponse: string; } export interface ProcessedAuthenticationOptions { @@ -126,17 +121,6 @@ export interface ProcessedAuthenticationOptions { forReset2FA?: boolean; } -export interface ProcessedAuthenticationPasskeyOptions { - username: string; - credId: string; - authenticatorData: string; - signature: string; - clientDataJSON: string; - extensible?: boolean; - extensionAddress?: string; - forReset2FA?: boolean; -} - export interface User { username: string; }