summaryrefslogtreecommitdiffhomepage
path: root/packages/browser/src/methods/startRegistration.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/browser/src/methods/startRegistration.ts')
-rw-r--r--packages/browser/src/methods/startRegistration.ts65
1 files changed, 65 insertions, 0 deletions
diff --git a/packages/browser/src/methods/startRegistration.ts b/packages/browser/src/methods/startRegistration.ts
new file mode 100644
index 0000000..eec07c5
--- /dev/null
+++ b/packages/browser/src/methods/startRegistration.ts
@@ -0,0 +1,65 @@
+import {
+ PublicKeyCredentialCreationOptionsJSON,
+ RegistrationCredential,
+ RegistrationCredentialJSON,
+} from '@simplewebauthn/typescript-types';
+
+import utf8StringToBuffer from '../helpers/utf8StringToBuffer';
+import bufferToBase64URLString from '../helpers/bufferToBase64URLString';
+import base64URLStringToBuffer from '../helpers/base64URLStringToBuffer';
+import { browserSupportsWebauthn } from '../helpers/browserSupportsWebauthn';
+import toPublicKeyCredentialDescriptor from '../helpers/toPublicKeyCredentialDescriptor';
+
+/**
+ * Begin authenticator "registration" via WebAuthn attestation
+ *
+ * @param creationOptionsJSON Output from @simplewebauthn/server's generateRegistrationOptions(...)
+ */
+export default async function startRegistration(
+ creationOptionsJSON: PublicKeyCredentialCreationOptionsJSON,
+): Promise<RegistrationCredentialJSON> {
+ if (!browserSupportsWebauthn()) {
+ throw new Error('WebAuthn is not supported in this browser');
+ }
+
+ // We need to convert some values to Uint8Arrays before passing the credentials to the navigator
+ const publicKey: PublicKeyCredentialCreationOptions = {
+ ...creationOptionsJSON,
+ challenge: base64URLStringToBuffer(creationOptionsJSON.challenge),
+ user: {
+ ...creationOptionsJSON.user,
+ id: utf8StringToBuffer(creationOptionsJSON.user.id),
+ },
+ excludeCredentials: creationOptionsJSON.excludeCredentials.map(toPublicKeyCredentialDescriptor),
+ };
+
+ // Wait for the user to complete attestation
+ const credential = (await navigator.credentials.create({ publicKey })) as RegistrationCredential;
+
+ if (!credential) {
+ throw new Error('Registration was not completed');
+ }
+
+ const { id, rawId, response, type } = credential;
+
+ // Convert values to base64 to make it easier to send back to the server
+ const credentialJSON: RegistrationCredentialJSON = {
+ id,
+ rawId: bufferToBase64URLString(rawId),
+ response: {
+ attestationObject: bufferToBase64URLString(response.attestationObject),
+ clientDataJSON: bufferToBase64URLString(response.clientDataJSON),
+ },
+ type,
+ clientExtensionResults: credential.getClientExtensionResults(),
+ };
+
+ /**
+ * Include the authenticator's transports if the browser supports querying for them
+ */
+ if (typeof response.getTransports === 'function') {
+ credentialJSON.transports = response.getTransports();
+ }
+
+ return credentialJSON;
+}