@ideem/plugins.passkeys-plus
Version:
Extend your ZSM Client SDK with Passkeys Plus functionality, enabling advanced passkey management and integration, with optional, sync-proof device-binding and attestation, invisible second-factor authentication, and user identity verification!
114 lines (95 loc) • 7.82 kB
JavaScript
import eventCoordinator from '@ideem/zsm-client-sdk/EventCoordinator.js';
import RelyingPartyBase from '@ideem/zsm-client-sdk/RelyingPartyBase.js';
import { b64urlToBuf, toObject } from '@ideem/zsm-client-sdk/Utils.js';
eventCoordinator.update('RelyingParty');
//## BEGIN RelyingParty ===================================================================================================================================
class RelyingParty extends RelyingPartyBase {
constructor(host, apiKey, applicationID, appEnvironment, usePasskeys= false) {
super(host, apiKey, applicationID, appEnvironment);
if(usePasskeys != 'undefined' && usePasskeys != undefined && usePasskeys) {
this.addlRelyingPartyBodyProps = {use_origin: "true"};
}
eventCoordinator.update('RelyingParty', 'READY');
}
//! PASSKEYS PLUS RELYING PARTY METHODS=========================================================================================================================
/**
* @name pkpRegistrationStart
* @description Starts the registration process for a passkey using the Relying Party.
* @param {string} userIdentifier The identifier for the user.
* @returns {Promise<Object>} Resolves with the Relying Party Challenge object.
* @throws {Error} If the Relying Party Challenge is not retrieved successfully.
* @throws {Error} If the public key is not found in the Relying Party Challenge.
* @throws {Error} If the user ID is not found in the Relying Party Challenge.
* @extends RelyingPartyBase Adds this function to base class.
* @memberOf RelyingParty, PasskeysPlus
*/
pkpRegistrationStart = async (userIdentifier) => {
const paChallenge = await this.createIdentityThenRegistrationStart(userIdentifier);
if(!paChallenge) throw new Error(`[PK+ RelyingParty] :: pkpRegistrationStart :: Unable to retrieve Platform Authority Challenge from Relying Party Server!`);
if(!paChallenge?.publicKey) throw new Error(`[PK+ RelyingParty] :: pkpRegistrationStart :: Platform Authority Challenge's Public Key was not found!`);
paChallenge.publicKey.challenge = b64urlToBuf(paChallenge.publicKey.challenge);
if(!paChallenge?.publicKey?.user) throw new Error(`[PK+ RelyingParty] :: pkpRegistrationStart :: User for the Platform Authority Challenge Public Key's user node was not found!`);
paChallenge.publicKey.user.id = b64urlToBuf(paChallenge.publicKey.user.id);
return paChallenge;
}
/**
* @name pkpRegistrationFinish
* @description Completes the registration process for a passkey using the Relying Party.
* @param {Object} paCredential The Platform Authenticator Credential object.
* @returns {Promise<Object>} Resolves with the registration result.
* @throws {Error} If the Platform Authenticator Credential is not provided.
* @throws {Error} If the Platform Authenticator response is invalid.
* @extends RelyingPartyBase Adds this function to base class.
* @memberOf RelyingParty, PasskeysPlus
*/
pkpRegistrationFinish = async (paCredential) => {
if (!paCredential) throw new Error('[PK+ RelyingParty] :: pkpRegistrationFinish :: No Platform Authenticator Credential provided!');
const paRegistrationResult = await this.registrationFinish(paCredential);
if (!paRegistrationResult) throw new Error('[PK+ RelyingParty] :: pkpRegistrationFinish :: Platform Authenticator response was invalid!');
this.credentialID = paCredential.id;
return Object.assign(paRegistrationResult, {credentialID: this.credentialID});
}
/**
* @name pkpAuthenticationStart
* @description Starts the authentication process for a passkey using the Relying Party.
* @param {string} credentialID The identifier for the user.
* @returns {Promise<Object>} Resolves with the Relying Party Challenge object.
* @throws {Error} If the Relying Party Challenge is not retrieved successfully.
* @throws {Error} If the public key is not found in the Relying Party Challenge.
* @throws {Error} If the allowCredentials ID is not found in the Relying Party Challenge.
* @extends RelyingPartyBase Adds this function to base class.
* @memberOf RelyingParty, PasskeysPlus
*/
pkpAuthenticationStart = async (credentialID) => {
let paChallenge = await this.authenticationStart(credentialID);
if(!paChallenge) throw new Error('[PK+ RelyingParty] :: pkpAuthenticationStart :: Unable to retrieve Platform Authority Challenge from Relying Party Server!');
paChallenge = toObject(paChallenge);
if(!paChallenge?.rcr ||
!paChallenge?.rcr?.publicKey) throw new Error(`[PK+ RelyingParty] :: pkpAuthenticationStart :: Platform Authority's RCR challenge and/or publicKey was not found!`);
const paRCRPublicKey = paChallenge.rcr.publicKey;
paRCRPublicKey.challenge = b64urlToBuf(paRCRPublicKey.challenge);
const paAllowCredentials = paRCRPublicKey.allowCredentials;
if(!paAllowCredentials ||
!paAllowCredentials[0]?.id) throw new Error(`[PK+ RelyingParty] :: pkpAuthenticationStart :: Platform Authority Challenge's allowCredentials and/or id was not found!`);
paAllowCredentials[0].id = b64urlToBuf(paAllowCredentials[0].id);
return paRCRPublicKey;
}
/**
* @name pkpAuthenticationFinish
* @description Completes the authentication process for a passkey using the Relying Party.
* @param {Object} paCredential The Platform Authenticator Credential object.
* @returns {Promise<Object>} Resolves with the authentication result.
* @throws {Error} If the Platform Authenticator Credential is not provided.
* @throws {Error} If the Platform Authenticator response is invalid.
* @extends RelyingPartyBase Adds this function to base class.
* @memberOf RelyingParty, PasskeysPlus
*/
pkpAuthenticationFinish = async (paCredential) => {
if (!paCredential) throw new Error('[PK+ RelyingParty] :: pkpAuthenticationFinish :: No Platform Authenticator Credential provided!');
const paAuthenticationResult = await this.authenticationFinish(paCredential);
if (!paAuthenticationResult) throw new Error('[PK+ RelyingParty] :: pkpAuthenticationFinish :: Platform Authenticator response was invalid!');
return paAuthenticationResult;
}
}
//## END RelyingParty =====================================================================================================================================
export default RelyingParty;