1 import { arrayToBinaryString, encodeBase64 } from '@proton/crypto/lib/utils';
4 PublicKeyCredentialCreationOptionsSerialized,
6 RegisterCredentialsPayload,
9 export * from './interface';
11 const convertCreationToExpectedFormat = (
12 publicKey: PublicKeyCredentialCreationOptionsSerialized
13 ): CredentialCreationOptions => {
14 const { challenge, user, excludeCredentials, ...rest } = publicKey;
19 challenge: new Uint8Array(challenge).buffer,
22 id: new Uint8Array(user.id),
24 excludeCredentials: excludeCredentials?.map((credentials) => ({
26 id: new Uint8Array(credentials.id),
32 export const getCreatePayload = async (
33 registerCredentials: RegisterCredentials
34 ): Promise<RegisterCredentialsPayload> => {
35 const credentialCreationOptions = convertCreationToExpectedFormat(
36 registerCredentials.RegistrationOptions.publicKey
38 const credentials = await navigator.credentials.create(credentialCreationOptions);
39 const publicKeyCredentials = credentials as PublicKeyCredential;
40 if (!credentials || !('rawId' in credentials) || !('attestationObject' in publicKeyCredentials.response)) {
41 throw new Error('No credentials received');
43 const response = publicKeyCredentials.response as AuthenticatorAttestationResponse & {
44 getTransports: () => string[];
47 RegistrationOptions: registerCredentials.RegistrationOptions,
48 ClientData: response.clientDataJSON
49 ? encodeBase64(arrayToBinaryString(new Uint8Array(response.clientDataJSON)))
51 AttestationObject: response.attestationObject
52 ? encodeBase64(arrayToBinaryString(new Uint8Array(response.attestationObject)))
54 Transports: response.getTransports?.() || [],