UNPKG

@yubion-dev-team/yubion-fido2-server-sdk-client-js

Version:

This project is a client-side SDK to support WebAuthn API calls for YubiOn FIDO2 Server Service.

158 lines 6.25 kB
/** * Converts a JSON-friendly `PublicKeyCredentialCreationOptions` object into the * format expected by the `navigator.credentials.create()` method by decoding * Base64URL strings into `ArrayBuffer`s. * @param creationOptionsJson The JSON-friendly creation options. * @returns The binary-compatible creation options. */ export function convertCreationOptionsToBinary(creationOptionsJson) { if (PublicKeyCredential.parseCreationOptionsFromJSON) { return PublicKeyCredential.parseCreationOptionsFromJSON(creationOptionsJson); } return { challenge: base64UrlDecode(creationOptionsJson.challenge), pubKeyCredParams: creationOptionsJson.pubKeyCredParams, rp: { id: creationOptionsJson.rp.id, name: creationOptionsJson.rp.name, }, user: { id: base64UrlDecode(creationOptionsJson.user.id), name: creationOptionsJson.user.name, displayName: creationOptionsJson.user.displayName, }, attestation: creationOptionsJson.attestation, authenticatorSelection: creationOptionsJson.authenticatorSelection, excludeCredentials: creationOptionsJson.excludeCredentials?.map((x) => ({ id: base64UrlDecode(x.id), type: x.type, transports: x.transports, })), extensions: creationOptionsJson.extensions, timeout: creationOptionsJson.timeout, }; } /** * Converts a `PublicKeyCredential` object returned by the WebAuthn API into a * JSON-serializable object by recursively encoding all `ArrayBuffer` and `TypedArray` * instances into Base64URL strings. * @param pubKeyCred The `PublicKeyCredential` object. * @returns A JSON-serializable representation of the credential. */ export function convertPublicKeyCredentialToJsonable(pubKeyCred) { if (pubKeyCred instanceof PublicKeyCredential && pubKeyCred.toJSON) { return pubKeyCred.toJSON(); } return arrayBufToBase64url(pubKeyCred); } /** * Converts a JSON-friendly `PublicKeyCredentialRequestOptions` object into the * format expected by the `navigator.credentials.get()` method by decoding * Base64URL strings into `ArrayBuffer`s. * @param requestOptionsJson The JSON-friendly request options. * @returns The binary-compatible request options. */ export function convertRequestOptionsToBinary(requestOptionsJson) { if (PublicKeyCredential.parseRequestOptionsFromJSON) { return PublicKeyCredential.parseRequestOptionsFromJSON(requestOptionsJson); } return { challenge: base64UrlDecode(requestOptionsJson.challenge), allowCredentials: requestOptionsJson.allowCredentials ? requestOptionsJson.allowCredentials.map((x) => ({ id: base64UrlDecode(x.id), type: x.type, transports: x.transports, })) : undefined, rpId: requestOptionsJson.rpId, timeout: requestOptionsJson.timeout, userVerification: requestOptionsJson.userVerification, extensions: requestOptionsJson.extensions, }; } /** * Recursively finds and converts all ArrayBuffer and Uint8Array instances in an object * to Base64URL-encoded strings. * @param data The object to process. * @returns A new object with binary data encoded. */ const arrayBufToBase64url = function (data) { if (data instanceof Array) { let ary = []; for (let i of data) { ary.push(arrayBufToBase64url(i)); } return ary; } if (data instanceof ArrayBuffer || data instanceof Uint8Array) { return base64UrlEncode(data); } if (data instanceof PublicKeyCredential) { const obj = {}; obj.id = data.id; obj.rawId = base64UrlEncode(data.rawId); obj.type = data.type; obj.response = {}; if (data.response instanceof AuthenticatorAssertionResponse) { obj.response.clientDataJSON = base64UrlEncode(data.response.clientDataJSON); obj.response.authenticatorData = base64UrlEncode(data.response.authenticatorData); obj.response.signature = base64UrlEncode(data.response.signature); if (data.response.userHandle) { obj.response.userHandle = base64UrlEncode(data.response.userHandle); } } else if (data.response instanceof AuthenticatorAttestationResponse) { obj.response.attestationObject = base64UrlEncode(data.response.attestationObject); obj.response.clientDataJSON = base64UrlEncode(data.response.clientDataJSON); } const clientExtensionResults = data.getClientExtensionResults(); if (clientExtensionResults) { obj.clientExtensionResults = arrayBufToBase64url(clientExtensionResults); } if ('authenticatorAttachment' in data && data.authenticatorAttachment) { obj.authenticatorAttachment = data.authenticatorAttachment; } return obj; } if (data instanceof Object) { let obj = {}; for (let key in data) { if (Object.prototype.hasOwnProperty.call(data, key)) { obj[key] = arrayBufToBase64url(data[key]); } } return obj; } return data; }; /** * Decodes a Base64URL-encoded string into an ArrayBuffer. * @param encodedData The Base64URL string. * @returns The decoded ArrayBuffer. */ function base64UrlDecode(encodedData) { const standardBase64 = encodedData.replace(/-/g, '+').replace(/_/g, '/'); const binaryString = atob(standardBase64); const len = binaryString.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { bytes[i] = binaryString.charCodeAt(i); } return bytes.buffer; } /** * Encodes an ArrayBuffer into a Base64URL string. * @param data The ArrayBuffer to encode. * @returns The Base64URL-encoded string. */ function base64UrlEncode(data) { const bytes = new Uint8Array(data); let binary = ''; for (let i = 0; i < bytes.byteLength; i++) { binary += String.fromCharCode(bytes[i]); } return btoa(binary) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=/g, ''); } //# sourceMappingURL=index.js.map