Skip to content

Commit

Permalink
Merge pull request #4933 from BitGo/WP-2592-authenticateWithPasskey
Browse files Browse the repository at this point in the history
feat(sdk-api): authenticate with passkey params
  • Loading branch information
pranavjain97 committed Sep 27, 2024
2 parents ac08e70 + 77d569a commit 9fa8553
Showing 1 changed file with 63 additions and 0 deletions.
63 changes: 63 additions & 0 deletions modules/sdk-api/src/bitgoAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,32 @@ export class BitGoAPI implements BitGoBase {
return authParams;
}

/**
* Validate the passkey response is in the expected format
* Should be as is returned from navigator.credentials.get()
*/
validatePasskeyResponse(passkeyResponse: string): void {
const parsedPasskeyResponse = JSON.parse(passkeyResponse);
if (!parsedPasskeyResponse && !parsedPasskeyResponse.response) {
throw new Error('unexpected webauthnResponse');
}
if (!_.isString(parsedPasskeyResponse.id)) {
throw new Error('id is missing');
}
if (!_.isString(parsedPasskeyResponse.response.authenticatorData)) {
throw new Error('authenticatorData is missing');
}
if (!_.isString(parsedPasskeyResponse.response.clientDataJSON)) {
throw new Error('clientDataJSON is missing');
}
if (!_.isString(parsedPasskeyResponse.response.signature)) {
throw new Error('signature is missing');
}
if (!_.isString(parsedPasskeyResponse.response.userHandle)) {
throw new Error('userHandle is missing');
}
}

/**
* Synchronous method for activating an access token.
*/
Expand Down Expand Up @@ -915,6 +941,43 @@ export class BitGoAPI implements BitGoBase {
}
}

/**
* Login to the bitgo platform with passkey.
*/
async authenticateWithPasskey(passkey: string): Promise<LoginResponse | any> {
try {
if (this._token) {
return new Error('already logged in');
}

const authUrl = this.microservicesUrl('/api/auth/v1/session');
const request = this.post(authUrl);

this.validatePasskeyResponse(passkey);
const userId = JSON.parse(passkey).response.userHandle;

const response: superagent.Response = await request.send({
passkey: passkey,
userId: userId,
});
// 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 {
throw new Error('failed to create access token');
}

return handleResponseResult<LoginResponse>()(response);
} catch (e) {
handleResponseError(e);
}
}

/**
*
* @param responseBody Response body object
Expand Down

0 comments on commit 9fa8553

Please sign in to comment.