@simplewebauthn/browser 11.0.0 → 13.0.0-alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +33 -23
  2. package/dist/bundle/index.es5.umd.min.js +2 -2
  3. package/dist/bundle/index.umd.min.js +2 -2
  4. package/esm/helpers/base64URLStringToBuffer.d.ts +9 -0
  5. package/esm/helpers/base64URLStringToBuffer.d.ts.map +1 -0
  6. package/esm/helpers/base64URLStringToBuffer.js +29 -0
  7. package/esm/helpers/browserSupportsWebAuthn.d.ts +12 -0
  8. package/esm/helpers/browserSupportsWebAuthn.d.ts.map +1 -0
  9. package/esm/helpers/browserSupportsWebAuthn.js +14 -0
  10. package/esm/helpers/browserSupportsWebAuthnAutofill.d.ts +9 -0
  11. package/esm/helpers/browserSupportsWebAuthnAutofill.d.ts.map +1 -0
  12. package/esm/helpers/browserSupportsWebAuthnAutofill.js +26 -0
  13. package/esm/helpers/bufferToBase64URLString.d.ts +8 -0
  14. package/esm/helpers/bufferToBase64URLString.d.ts.map +1 -0
  15. package/esm/helpers/bufferToBase64URLString.js +15 -0
  16. package/esm/helpers/identifyAuthenticationError.d.ts +9 -0
  17. package/esm/helpers/identifyAuthenticationError.d.ts.map +1 -0
  18. package/esm/helpers/identifyAuthenticationError.js +61 -0
  19. package/esm/helpers/identifyRegistrationError.d.ts +9 -0
  20. package/esm/helpers/identifyRegistrationError.d.ts.map +1 -0
  21. package/esm/helpers/identifyRegistrationError.js +126 -0
  22. package/esm/helpers/isValidDomain.d.ts +10 -0
  23. package/esm/helpers/isValidDomain.d.ts.map +1 -0
  24. package/esm/helpers/isValidDomain.js +14 -0
  25. package/esm/helpers/platformAuthenticatorIsAvailable.d.ts +8 -0
  26. package/esm/helpers/platformAuthenticatorIsAvailable.d.ts.map +1 -0
  27. package/esm/helpers/platformAuthenticatorIsAvailable.js +13 -0
  28. package/esm/helpers/toAuthenticatorAttachment.d.ts +6 -0
  29. package/esm/helpers/toAuthenticatorAttachment.d.ts.map +1 -0
  30. package/esm/helpers/toAuthenticatorAttachment.js +13 -0
  31. package/esm/helpers/toPublicKeyCredentialDescriptor.d.ts +3 -0
  32. package/esm/helpers/toPublicKeyCredentialDescriptor.d.ts.map +1 -0
  33. package/esm/helpers/toPublicKeyCredentialDescriptor.js +14 -0
  34. package/esm/helpers/webAuthnAbortService.d.ts +22 -0
  35. package/esm/helpers/webAuthnAbortService.d.ts.map +1 -0
  36. package/esm/helpers/webAuthnAbortService.js +37 -0
  37. package/{dist/types → esm}/helpers/webAuthnError.d.ts +18 -0
  38. package/esm/helpers/webAuthnError.d.ts.map +1 -0
  39. package/esm/helpers/webAuthnError.js +31 -0
  40. package/esm/index.d.ts +11 -0
  41. package/esm/index.d.ts.map +1 -0
  42. package/esm/index.js +10 -0
  43. package/esm/methods/startAuthentication.d.ts +15 -0
  44. package/esm/methods/startAuthentication.d.ts.map +1 -0
  45. package/esm/methods/startAuthentication.js +89 -0
  46. package/esm/methods/startRegistration.d.ts +13 -0
  47. package/esm/methods/startRegistration.d.ts.map +1 -0
  48. package/esm/methods/startRegistration.js +115 -0
  49. package/esm/package.json +3 -0
  50. package/esm/types/dom.d.ts +329 -0
  51. package/esm/types/dom.d.ts.map +1 -0
  52. package/esm/types/dom.js +1 -0
  53. package/esm/types/index.d.ts +205 -0
  54. package/esm/types/index.d.ts.map +1 -0
  55. package/esm/types/index.js +1 -0
  56. package/package.json +25 -31
  57. package/script/helpers/base64URLStringToBuffer.d.ts +9 -0
  58. package/script/helpers/base64URLStringToBuffer.d.ts.map +1 -0
  59. package/script/helpers/base64URLStringToBuffer.js +32 -0
  60. package/script/helpers/browserSupportsWebAuthn.d.ts +12 -0
  61. package/script/helpers/browserSupportsWebAuthn.d.ts.map +1 -0
  62. package/script/helpers/browserSupportsWebAuthn.js +18 -0
  63. package/script/helpers/browserSupportsWebAuthnAutofill.d.ts +9 -0
  64. package/script/helpers/browserSupportsWebAuthnAutofill.d.ts.map +1 -0
  65. package/script/helpers/browserSupportsWebAuthnAutofill.js +30 -0
  66. package/script/helpers/bufferToBase64URLString.d.ts +8 -0
  67. package/script/helpers/bufferToBase64URLString.d.ts.map +1 -0
  68. package/script/helpers/bufferToBase64URLString.js +18 -0
  69. package/script/helpers/identifyAuthenticationError.d.ts +9 -0
  70. package/script/helpers/identifyAuthenticationError.d.ts.map +1 -0
  71. package/script/helpers/identifyAuthenticationError.js +64 -0
  72. package/script/helpers/identifyRegistrationError.d.ts +9 -0
  73. package/script/helpers/identifyRegistrationError.d.ts.map +1 -0
  74. package/script/helpers/identifyRegistrationError.js +129 -0
  75. package/script/helpers/isValidDomain.d.ts +10 -0
  76. package/script/helpers/isValidDomain.d.ts.map +1 -0
  77. package/script/helpers/isValidDomain.js +17 -0
  78. package/script/helpers/platformAuthenticatorIsAvailable.d.ts +8 -0
  79. package/script/helpers/platformAuthenticatorIsAvailable.d.ts.map +1 -0
  80. package/script/helpers/platformAuthenticatorIsAvailable.js +16 -0
  81. package/script/helpers/toAuthenticatorAttachment.d.ts +6 -0
  82. package/script/helpers/toAuthenticatorAttachment.d.ts.map +1 -0
  83. package/script/helpers/toAuthenticatorAttachment.js +16 -0
  84. package/script/helpers/toPublicKeyCredentialDescriptor.d.ts +3 -0
  85. package/script/helpers/toPublicKeyCredentialDescriptor.d.ts.map +1 -0
  86. package/script/helpers/toPublicKeyCredentialDescriptor.js +17 -0
  87. package/script/helpers/webAuthnAbortService.d.ts +22 -0
  88. package/script/helpers/webAuthnAbortService.d.ts.map +1 -0
  89. package/script/helpers/webAuthnAbortService.js +40 -0
  90. package/script/helpers/webAuthnError.d.ts +28 -0
  91. package/script/helpers/webAuthnError.d.ts.map +1 -0
  92. package/script/helpers/webAuthnError.js +35 -0
  93. package/script/index.d.ts +11 -0
  94. package/script/index.d.ts.map +1 -0
  95. package/script/index.js +26 -0
  96. package/script/methods/startAuthentication.d.ts +15 -0
  97. package/script/methods/startAuthentication.d.ts.map +1 -0
  98. package/script/methods/startAuthentication.js +92 -0
  99. package/script/methods/startRegistration.d.ts +13 -0
  100. package/script/methods/startRegistration.d.ts.map +1 -0
  101. package/script/methods/startRegistration.js +118 -0
  102. package/script/package.json +3 -0
  103. package/script/types/dom.d.ts +329 -0
  104. package/script/types/dom.d.ts.map +1 -0
  105. package/script/types/dom.js +2 -0
  106. package/script/types/index.d.ts +205 -0
  107. package/script/types/index.d.ts.map +1 -0
  108. package/script/types/index.js +2 -0
  109. package/dist/bundle/index.js +0 -398
  110. package/dist/types/helpers/base64URLStringToBuffer.d.ts +0 -1
  111. package/dist/types/helpers/browserSupportsWebAuthn.d.ts +0 -1
  112. package/dist/types/helpers/browserSupportsWebAuthnAutofill.d.ts +0 -1
  113. package/dist/types/helpers/bufferToBase64URLString.d.ts +0 -1
  114. package/dist/types/helpers/identifyAuthenticationError.d.ts +0 -5
  115. package/dist/types/helpers/identifyRegistrationError.d.ts +0 -5
  116. package/dist/types/helpers/isValidDomain.d.ts +0 -1
  117. package/dist/types/helpers/platformAuthenticatorIsAvailable.d.ts +0 -1
  118. package/dist/types/helpers/toAuthenticatorAttachment.d.ts +0 -2
  119. package/dist/types/helpers/toPublicKeyCredentialDescriptor.d.ts +0 -2
  120. package/dist/types/helpers/webAuthnAbortService.d.ts +0 -7
  121. package/dist/types/index.d.ts +0 -11
  122. package/dist/types/methods/startAuthentication.d.ts +0 -7
  123. package/dist/types/methods/startRegistration.d.ts +0 -6
  124. package/jest-environment.js +0 -29
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.base64URLStringToBuffer = base64URLStringToBuffer;
4
+ /**
5
+ * Convert from a Base64URL-encoded string to an Array Buffer. Best used when converting a
6
+ * credential ID from a JSON string to an ArrayBuffer, like in allowCredentials or
7
+ * excludeCredentials
8
+ *
9
+ * Helper method to compliment `bufferToBase64URLString`
10
+ */
11
+ function base64URLStringToBuffer(base64URLString) {
12
+ // Convert from Base64URL to Base64
13
+ const base64 = base64URLString.replace(/-/g, '+').replace(/_/g, '/');
14
+ /**
15
+ * Pad with '=' until it's a multiple of four
16
+ * (4 - (85 % 4 = 1) = 3) % 4 = 3 padding
17
+ * (4 - (86 % 4 = 2) = 2) % 4 = 2 padding
18
+ * (4 - (87 % 4 = 3) = 1) % 4 = 1 padding
19
+ * (4 - (88 % 4 = 0) = 4) % 4 = 0 padding
20
+ */
21
+ const padLength = (4 - (base64.length % 4)) % 4;
22
+ const padded = base64.padEnd(base64.length + padLength, '=');
23
+ // Convert to a binary string
24
+ const binary = atob(padded);
25
+ // Convert binary string to buffer
26
+ const buffer = new ArrayBuffer(binary.length);
27
+ const bytes = new Uint8Array(buffer);
28
+ for (let i = 0; i < binary.length; i++) {
29
+ bytes[i] = binary.charCodeAt(i);
30
+ }
31
+ return buffer;
32
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Determine if the browser is capable of Webauthn
3
+ */
4
+ export declare function browserSupportsWebAuthn(): boolean;
5
+ /**
6
+ * Make it possible to stub the return value during testing
7
+ * @ignore Don't include this in docs output
8
+ */
9
+ export declare const _browserSupportsWebAuthnInternals: {
10
+ stubThis: (value: boolean) => boolean;
11
+ };
12
+ //# sourceMappingURL=browserSupportsWebAuthn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browserSupportsWebAuthn.d.ts","sourceRoot":"","sources":["../../src/helpers/browserSupportsWebAuthn.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAKjD;AAED;;;GAGG;AACH,eAAO,MAAM,iCAAiC;sBAC1B,OAAO;CAC1B,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._browserSupportsWebAuthnInternals = void 0;
4
+ exports.browserSupportsWebAuthn = browserSupportsWebAuthn;
5
+ /**
6
+ * Determine if the browser is capable of Webauthn
7
+ */
8
+ function browserSupportsWebAuthn() {
9
+ return exports._browserSupportsWebAuthnInternals.stubThis(globalThis?.PublicKeyCredential !== undefined &&
10
+ typeof globalThis.PublicKeyCredential === 'function');
11
+ }
12
+ /**
13
+ * Make it possible to stub the return value during testing
14
+ * @ignore Don't include this in docs output
15
+ */
16
+ exports._browserSupportsWebAuthnInternals = {
17
+ stubThis: (value) => value,
18
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Determine if the browser supports conditional UI, so that WebAuthn credentials can
3
+ * be shown to the user in the browser's typical password autofill popup.
4
+ */
5
+ export declare function browserSupportsWebAuthnAutofill(): Promise<boolean>;
6
+ export declare const _browserSupportsWebAuthnAutofillInternals: {
7
+ stubThis: (value: Promise<boolean>) => Promise<boolean>;
8
+ };
9
+ //# sourceMappingURL=browserSupportsWebAuthnAutofill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browserSupportsWebAuthnAutofill.d.ts","sourceRoot":"","sources":["../../src/helpers/browserSupportsWebAuthnAutofill.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,+BAA+B,IAAI,OAAO,CAAC,OAAO,CAAC,CAyBlE;AAGD,eAAO,MAAM,yCAAyC;sBAClC,OAAO,CAAC,OAAO,CAAC;CACnC,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._browserSupportsWebAuthnAutofillInternals = void 0;
4
+ exports.browserSupportsWebAuthnAutofill = browserSupportsWebAuthnAutofill;
5
+ const browserSupportsWebAuthn_js_1 = require("./browserSupportsWebAuthn.js");
6
+ /**
7
+ * Determine if the browser supports conditional UI, so that WebAuthn credentials can
8
+ * be shown to the user in the browser's typical password autofill popup.
9
+ */
10
+ function browserSupportsWebAuthnAutofill() {
11
+ if (!(0, browserSupportsWebAuthn_js_1.browserSupportsWebAuthn)()) {
12
+ return exports._browserSupportsWebAuthnAutofillInternals.stubThis(new Promise((resolve) => resolve(false)));
13
+ }
14
+ /**
15
+ * I don't like the `as unknown` here but there's a `declare var PublicKeyCredential` in
16
+ * TS' DOM lib that's making it difficult for me to just go `as PublicKeyCredentialFuture` as I
17
+ * want. I think I'm fine with this for now since it's _supposed_ to be temporary, until TS types
18
+ * have a chance to catch up.
19
+ */
20
+ const globalPublicKeyCredential = globalThis
21
+ .PublicKeyCredential;
22
+ if (globalPublicKeyCredential?.isConditionalMediationAvailable === undefined) {
23
+ return exports._browserSupportsWebAuthnAutofillInternals.stubThis(new Promise((resolve) => resolve(false)));
24
+ }
25
+ return exports._browserSupportsWebAuthnAutofillInternals.stubThis(globalPublicKeyCredential.isConditionalMediationAvailable());
26
+ }
27
+ // Make it possible to stub the return value during testing
28
+ exports._browserSupportsWebAuthnAutofillInternals = {
29
+ stubThis: (value) => value,
30
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Convert the given array buffer into a Base64URL-encoded string. Ideal for converting various
3
+ * credential response ArrayBuffers to string for sending back to the server as JSON.
4
+ *
5
+ * Helper method to compliment `base64URLStringToBuffer`
6
+ */
7
+ export declare function bufferToBase64URLString(buffer: ArrayBuffer): string;
8
+ //# sourceMappingURL=bufferToBase64URLString.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bufferToBase64URLString.d.ts","sourceRoot":"","sources":["../../src/helpers/bufferToBase64URLString.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAWnE"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bufferToBase64URLString = bufferToBase64URLString;
4
+ /**
5
+ * Convert the given array buffer into a Base64URL-encoded string. Ideal for converting various
6
+ * credential response ArrayBuffers to string for sending back to the server as JSON.
7
+ *
8
+ * Helper method to compliment `base64URLStringToBuffer`
9
+ */
10
+ function bufferToBase64URLString(buffer) {
11
+ const bytes = new Uint8Array(buffer);
12
+ let str = '';
13
+ for (const charCode of bytes) {
14
+ str += String.fromCharCode(charCode);
15
+ }
16
+ const base64String = btoa(str);
17
+ return base64String.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
18
+ }
@@ -0,0 +1,9 @@
1
+ import { WebAuthnError } from './webAuthnError.js';
2
+ /**
3
+ * Attempt to intuit _why_ an error was raised after calling `navigator.credentials.get()`
4
+ */
5
+ export declare function identifyAuthenticationError({ error, options, }: {
6
+ error: Error;
7
+ options: CredentialRequestOptions;
8
+ }): WebAuthnError | Error;
9
+ //# sourceMappingURL=identifyAuthenticationError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identifyAuthenticationError.d.ts","sourceRoot":"","sources":["../../src/helpers/identifyAuthenticationError.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,EAC1C,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,wBAAwB,CAAC;CACnC,GAAG,aAAa,GAAG,KAAK,CAuDxB"}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.identifyAuthenticationError = identifyAuthenticationError;
4
+ const isValidDomain_js_1 = require("./isValidDomain.js");
5
+ const webAuthnError_js_1 = require("./webAuthnError.js");
6
+ /**
7
+ * Attempt to intuit _why_ an error was raised after calling `navigator.credentials.get()`
8
+ */
9
+ function identifyAuthenticationError({ error, options, }) {
10
+ const { publicKey } = options;
11
+ if (!publicKey) {
12
+ throw Error('options was missing required publicKey property');
13
+ }
14
+ if (error.name === 'AbortError') {
15
+ if (options.signal instanceof AbortSignal) {
16
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 16)
17
+ return new webAuthnError_js_1.WebAuthnError({
18
+ message: 'Authentication ceremony was sent an abort signal',
19
+ code: 'ERROR_CEREMONY_ABORTED',
20
+ cause: error,
21
+ });
22
+ }
23
+ }
24
+ else if (error.name === 'NotAllowedError') {
25
+ /**
26
+ * Pass the error directly through. Platforms are overloading this error beyond what the spec
27
+ * defines and we don't want to overwrite potentially useful error messages.
28
+ */
29
+ return new webAuthnError_js_1.WebAuthnError({
30
+ message: error.message,
31
+ code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY',
32
+ cause: error,
33
+ });
34
+ }
35
+ else if (error.name === 'SecurityError') {
36
+ const effectiveDomain = globalThis.location.hostname;
37
+ if (!(0, isValidDomain_js_1.isValidDomain)(effectiveDomain)) {
38
+ // https://www.w3.org/TR/webauthn-2/#sctn-discover-from-external-source (Step 5)
39
+ return new webAuthnError_js_1.WebAuthnError({
40
+ message: `${globalThis.location.hostname} is an invalid domain`,
41
+ code: 'ERROR_INVALID_DOMAIN',
42
+ cause: error,
43
+ });
44
+ }
45
+ else if (publicKey.rpId !== effectiveDomain) {
46
+ // https://www.w3.org/TR/webauthn-2/#sctn-discover-from-external-source (Step 6)
47
+ return new webAuthnError_js_1.WebAuthnError({
48
+ message: `The RP ID "${publicKey.rpId}" is invalid for this domain`,
49
+ code: 'ERROR_INVALID_RP_ID',
50
+ cause: error,
51
+ });
52
+ }
53
+ }
54
+ else if (error.name === 'UnknownError') {
55
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-get-assertion (Step 1)
56
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-get-assertion (Step 12)
57
+ return new webAuthnError_js_1.WebAuthnError({
58
+ message: 'The authenticator was unable to process the specified options, or could not create a new assertion signature',
59
+ code: 'ERROR_AUTHENTICATOR_GENERAL_ERROR',
60
+ cause: error,
61
+ });
62
+ }
63
+ return error;
64
+ }
@@ -0,0 +1,9 @@
1
+ import { WebAuthnError } from './webAuthnError.js';
2
+ /**
3
+ * Attempt to intuit _why_ an error was raised after calling `navigator.credentials.create()`
4
+ */
5
+ export declare function identifyRegistrationError({ error, options, }: {
6
+ error: Error;
7
+ options: CredentialCreationOptions;
8
+ }): WebAuthnError | Error;
9
+ //# sourceMappingURL=identifyRegistrationError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identifyRegistrationError.d.ts","sourceRoot":"","sources":["../../src/helpers/identifyRegistrationError.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,yBAAyB,CAAC;CACpC,GAAG,aAAa,GAAG,KAAK,CA4HxB"}
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.identifyRegistrationError = identifyRegistrationError;
4
+ const isValidDomain_js_1 = require("./isValidDomain.js");
5
+ const webAuthnError_js_1 = require("./webAuthnError.js");
6
+ /**
7
+ * Attempt to intuit _why_ an error was raised after calling `navigator.credentials.create()`
8
+ */
9
+ function identifyRegistrationError({ error, options, }) {
10
+ const { publicKey } = options;
11
+ if (!publicKey) {
12
+ throw Error('options was missing required publicKey property');
13
+ }
14
+ if (error.name === 'AbortError') {
15
+ if (options.signal instanceof AbortSignal) {
16
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 16)
17
+ return new webAuthnError_js_1.WebAuthnError({
18
+ message: 'Registration ceremony was sent an abort signal',
19
+ code: 'ERROR_CEREMONY_ABORTED',
20
+ cause: error,
21
+ });
22
+ }
23
+ }
24
+ else if (error.name === 'ConstraintError') {
25
+ if (publicKey.authenticatorSelection?.requireResidentKey === true) {
26
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 4)
27
+ return new webAuthnError_js_1.WebAuthnError({
28
+ message: 'Discoverable credentials were required but no available authenticator supported it',
29
+ code: 'ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT',
30
+ cause: error,
31
+ });
32
+ }
33
+ else if (
34
+ // @ts-ignore: `mediation` doesn't yet exist on CredentialCreationOptions but it's possible as of Sept 2024
35
+ options.mediation === 'conditional' &&
36
+ publicKey.authenticatorSelection?.userVerification === 'required') {
37
+ // https://w3c.github.io/webauthn/#sctn-createCredential (Step 22.4)
38
+ return new webAuthnError_js_1.WebAuthnError({
39
+ message: 'User verification was required during automatic registration but it could not be performed',
40
+ code: 'ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE',
41
+ cause: error,
42
+ });
43
+ }
44
+ else if (publicKey.authenticatorSelection?.userVerification === 'required') {
45
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 5)
46
+ return new webAuthnError_js_1.WebAuthnError({
47
+ message: 'User verification was required but no available authenticator supported it',
48
+ code: 'ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT',
49
+ cause: error,
50
+ });
51
+ }
52
+ }
53
+ else if (error.name === 'InvalidStateError') {
54
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 20)
55
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 3)
56
+ return new webAuthnError_js_1.WebAuthnError({
57
+ message: 'The authenticator was previously registered',
58
+ code: 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED',
59
+ cause: error,
60
+ });
61
+ }
62
+ else if (error.name === 'NotAllowedError') {
63
+ /**
64
+ * Pass the error directly through. Platforms are overloading this error beyond what the spec
65
+ * defines and we don't want to overwrite potentially useful error messages.
66
+ */
67
+ return new webAuthnError_js_1.WebAuthnError({
68
+ message: error.message,
69
+ code: 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY',
70
+ cause: error,
71
+ });
72
+ }
73
+ else if (error.name === 'NotSupportedError') {
74
+ const validPubKeyCredParams = publicKey.pubKeyCredParams.filter((param) => param.type === 'public-key');
75
+ if (validPubKeyCredParams.length === 0) {
76
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 10)
77
+ return new webAuthnError_js_1.WebAuthnError({
78
+ message: 'No entry in pubKeyCredParams was of type "public-key"',
79
+ code: 'ERROR_MALFORMED_PUBKEYCREDPARAMS',
80
+ cause: error,
81
+ });
82
+ }
83
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 2)
84
+ return new webAuthnError_js_1.WebAuthnError({
85
+ message: 'No available authenticator supported any of the specified pubKeyCredParams algorithms',
86
+ code: 'ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG',
87
+ cause: error,
88
+ });
89
+ }
90
+ else if (error.name === 'SecurityError') {
91
+ const effectiveDomain = globalThis.location.hostname;
92
+ if (!(0, isValidDomain_js_1.isValidDomain)(effectiveDomain)) {
93
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 7)
94
+ return new webAuthnError_js_1.WebAuthnError({
95
+ message: `${globalThis.location.hostname} is an invalid domain`,
96
+ code: 'ERROR_INVALID_DOMAIN',
97
+ cause: error,
98
+ });
99
+ }
100
+ else if (publicKey.rp.id !== effectiveDomain) {
101
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 8)
102
+ return new webAuthnError_js_1.WebAuthnError({
103
+ message: `The RP ID "${publicKey.rp.id}" is invalid for this domain`,
104
+ code: 'ERROR_INVALID_RP_ID',
105
+ cause: error,
106
+ });
107
+ }
108
+ }
109
+ else if (error.name === 'TypeError') {
110
+ if (publicKey.user.id.byteLength < 1 || publicKey.user.id.byteLength > 64) {
111
+ // https://www.w3.org/TR/webauthn-2/#sctn-createCredential (Step 5)
112
+ return new webAuthnError_js_1.WebAuthnError({
113
+ message: 'User ID was not between 1 and 64 characters',
114
+ code: 'ERROR_INVALID_USER_ID_LENGTH',
115
+ cause: error,
116
+ });
117
+ }
118
+ }
119
+ else if (error.name === 'UnknownError') {
120
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 1)
121
+ // https://www.w3.org/TR/webauthn-2/#sctn-op-make-cred (Step 8)
122
+ return new webAuthnError_js_1.WebAuthnError({
123
+ message: 'The authenticator was unable to process the specified options, or could not create a new credential',
124
+ code: 'ERROR_AUTHENTICATOR_GENERAL_ERROR',
125
+ cause: error,
126
+ });
127
+ }
128
+ return error;
129
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * A simple test to determine if a hostname is a properly-formatted domain name
3
+ *
4
+ * A "valid domain" is defined here: https://url.spec.whatwg.org/#valid-domain
5
+ *
6
+ * Regex sourced from here:
7
+ * https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch08s15.html
8
+ */
9
+ export declare function isValidDomain(hostname: string): boolean;
10
+ //# sourceMappingURL=isValidDomain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isValidDomain.d.ts","sourceRoot":"","sources":["../../src/helpers/isValidDomain.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAMvD"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidDomain = isValidDomain;
4
+ /**
5
+ * A simple test to determine if a hostname is a properly-formatted domain name
6
+ *
7
+ * A "valid domain" is defined here: https://url.spec.whatwg.org/#valid-domain
8
+ *
9
+ * Regex sourced from here:
10
+ * https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch08s15.html
11
+ */
12
+ function isValidDomain(hostname) {
13
+ return (
14
+ // Consider localhost valid as well since it's okay wrt Secure Contexts
15
+ hostname === 'localhost' ||
16
+ /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(hostname));
17
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Determine whether the browser can communicate with a built-in authenticator, like
3
+ * Touch ID, Android fingerprint scanner, or Windows Hello.
4
+ *
5
+ * This method will _not_ be able to tell you the name of the platform authenticator.
6
+ */
7
+ export declare function platformAuthenticatorIsAvailable(): Promise<boolean>;
8
+ //# sourceMappingURL=platformAuthenticatorIsAvailable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platformAuthenticatorIsAvailable.d.ts","sourceRoot":"","sources":["../../src/helpers/platformAuthenticatorIsAvailable.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,gCAAgC,IAAI,OAAO,CAAC,OAAO,CAAC,CAMnE"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.platformAuthenticatorIsAvailable = platformAuthenticatorIsAvailable;
4
+ const browserSupportsWebAuthn_js_1 = require("./browserSupportsWebAuthn.js");
5
+ /**
6
+ * Determine whether the browser can communicate with a built-in authenticator, like
7
+ * Touch ID, Android fingerprint scanner, or Windows Hello.
8
+ *
9
+ * This method will _not_ be able to tell you the name of the platform authenticator.
10
+ */
11
+ function platformAuthenticatorIsAvailable() {
12
+ if (!(0, browserSupportsWebAuthn_js_1.browserSupportsWebAuthn)()) {
13
+ return new Promise((resolve) => resolve(false));
14
+ }
15
+ return PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();
16
+ }
@@ -0,0 +1,6 @@
1
+ import type { AuthenticatorAttachment } from '../types/index.js';
2
+ /**
3
+ * If possible coerce a `string` value into a known `AuthenticatorAttachment`
4
+ */
5
+ export declare function toAuthenticatorAttachment(attachment: string | null): AuthenticatorAttachment | undefined;
6
+ //# sourceMappingURL=toAuthenticatorAttachment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toAuthenticatorAttachment.d.ts","sourceRoot":"","sources":["../../src/helpers/toAuthenticatorAttachment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAIjE;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,uBAAuB,GAAG,SAAS,CAUrC"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toAuthenticatorAttachment = toAuthenticatorAttachment;
4
+ const attachments = ['cross-platform', 'platform'];
5
+ /**
6
+ * If possible coerce a `string` value into a known `AuthenticatorAttachment`
7
+ */
8
+ function toAuthenticatorAttachment(attachment) {
9
+ if (!attachment) {
10
+ return;
11
+ }
12
+ if (attachments.indexOf(attachment) < 0) {
13
+ return;
14
+ }
15
+ return attachment;
16
+ }
@@ -0,0 +1,3 @@
1
+ import type { PublicKeyCredentialDescriptor, PublicKeyCredentialDescriptorJSON } from '../types/index.js';
2
+ export declare function toPublicKeyCredentialDescriptor(descriptor: PublicKeyCredentialDescriptorJSON): PublicKeyCredentialDescriptor;
3
+ //# sourceMappingURL=toPublicKeyCredentialDescriptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toPublicKeyCredentialDescriptor.d.ts","sourceRoot":"","sources":["../../src/helpers/toPublicKeyCredentialDescriptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,6BAA6B,EAC7B,iCAAiC,EAClC,MAAM,mBAAmB,CAAC;AAG3B,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,iCAAiC,GAC5C,6BAA6B,CAa/B"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toPublicKeyCredentialDescriptor = toPublicKeyCredentialDescriptor;
4
+ const base64URLStringToBuffer_js_1 = require("./base64URLStringToBuffer.js");
5
+ function toPublicKeyCredentialDescriptor(descriptor) {
6
+ const { id } = descriptor;
7
+ return {
8
+ ...descriptor,
9
+ id: (0, base64URLStringToBuffer_js_1.base64URLStringToBuffer)(id),
10
+ /**
11
+ * `descriptor.transports` is an array of our `AuthenticatorTransportFuture` that includes newer
12
+ * transports that TypeScript's DOM lib is ignorant of. Convince TS that our list of transports
13
+ * are fine to pass to WebAuthn since browsers will recognize the new value.
14
+ */
15
+ transports: descriptor.transports,
16
+ };
17
+ }
@@ -0,0 +1,22 @@
1
+ interface WebAuthnAbortService {
2
+ /**
3
+ * Prepare an abort signal that will help support multiple auth attempts without needing to
4
+ * reload the page. This is automatically called whenever `startRegistration()` and
5
+ * `startAuthentication()` are called.
6
+ */
7
+ createNewAbortSignal(): AbortSignal;
8
+ /**
9
+ * Manually cancel any active WebAuthn registration or authentication attempt.
10
+ */
11
+ cancelCeremony(): void;
12
+ }
13
+ /**
14
+ * A service singleton to help ensure that only a single WebAuthn ceremony is active at a time.
15
+ *
16
+ * Users of **@simplewebauthn/browser** shouldn't typically need to use this, but it can help e.g.
17
+ * developers building projects that use client-side routing to better control the behavior of
18
+ * their UX in response to router navigation events.
19
+ */
20
+ export declare const WebAuthnAbortService: WebAuthnAbortService;
21
+ export {};
22
+ //# sourceMappingURL=webAuthnAbortService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webAuthnAbortService.d.ts","sourceRoot":"","sources":["../../src/helpers/webAuthnAbortService.ts"],"names":[],"mappings":"AAAA,UAAU,oBAAoB;IAC5B;;;;OAIG;IACH,oBAAoB,IAAI,WAAW,CAAC;IACpC;;OAEG;IACH,cAAc,IAAI,IAAI,CAAC;CACxB;AAkCD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,oBAAqD,CAAC"}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebAuthnAbortService = void 0;
4
+ class BaseWebAuthnAbortService {
5
+ constructor() {
6
+ Object.defineProperty(this, "controller", {
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true,
10
+ value: void 0
11
+ });
12
+ }
13
+ createNewAbortSignal() {
14
+ // Abort any existing calls to navigator.credentials.create() or navigator.credentials.get()
15
+ if (this.controller) {
16
+ const abortError = new Error('Cancelling existing WebAuthn API call for new one');
17
+ abortError.name = 'AbortError';
18
+ this.controller.abort(abortError);
19
+ }
20
+ const newController = new AbortController();
21
+ this.controller = newController;
22
+ return newController.signal;
23
+ }
24
+ cancelCeremony() {
25
+ if (this.controller) {
26
+ const abortError = new Error('Manually cancelling existing WebAuthn API call');
27
+ abortError.name = 'AbortError';
28
+ this.controller.abort(abortError);
29
+ this.controller = undefined;
30
+ }
31
+ }
32
+ }
33
+ /**
34
+ * A service singleton to help ensure that only a single WebAuthn ceremony is active at a time.
35
+ *
36
+ * Users of **@simplewebauthn/browser** shouldn't typically need to use this, but it can help e.g.
37
+ * developers building projects that use client-side routing to better control the behavior of
38
+ * their UX in response to router navigation events.
39
+ */
40
+ exports.WebAuthnAbortService = new BaseWebAuthnAbortService();
@@ -0,0 +1,28 @@
1
+ /**
2
+ * A custom Error used to return a more nuanced error detailing _why_ one of the eight documented
3
+ * errors in the spec was raised after calling `navigator.credentials.create()` or
4
+ * `navigator.credentials.get()`:
5
+ *
6
+ * - `AbortError`
7
+ * - `ConstraintError`
8
+ * - `InvalidStateError`
9
+ * - `NotAllowedError`
10
+ * - `NotSupportedError`
11
+ * - `SecurityError`
12
+ * - `TypeError`
13
+ * - `UnknownError`
14
+ *
15
+ * Error messages were determined through investigation of the spec to determine under which
16
+ * scenarios a given error would be raised.
17
+ */
18
+ export declare class WebAuthnError extends Error {
19
+ code: WebAuthnErrorCode;
20
+ constructor({ message, code, cause, name, }: {
21
+ message: string;
22
+ code: WebAuthnErrorCode;
23
+ cause: Error;
24
+ name?: string;
25
+ });
26
+ }
27
+ export type WebAuthnErrorCode = 'ERROR_CEREMONY_ABORTED' | 'ERROR_INVALID_DOMAIN' | 'ERROR_INVALID_RP_ID' | 'ERROR_INVALID_USER_ID_LENGTH' | 'ERROR_MALFORMED_PUBKEYCREDPARAMS' | 'ERROR_AUTHENTICATOR_GENERAL_ERROR' | 'ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT' | 'ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT' | 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED' | 'ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG' | 'ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE' | 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY';
28
+ //# sourceMappingURL=webAuthnError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webAuthnError.d.ts","sourceRoot":"","sources":["../../src/helpers/webAuthnError.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACtC,IAAI,EAAE,iBAAiB,CAAC;gBAEZ,EACV,OAAO,EACP,IAAI,EACJ,KAAK,EACL,IAAI,GACL,EAAE;QACD,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,iBAAiB,CAAC;QACxB,KAAK,EAAE,KAAK,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;CAMF;AAED,MAAM,MAAM,iBAAiB,GACzB,wBAAwB,GACxB,sBAAsB,GACtB,qBAAqB,GACrB,8BAA8B,GAC9B,kCAAkC,GAClC,mCAAmC,GACnC,6DAA6D,GAC7D,uDAAuD,GACvD,2CAA2C,GAC3C,uDAAuD,GACvD,+CAA+C,GAC/C,sCAAsC,CAAC"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebAuthnError = void 0;
4
+ /**
5
+ * A custom Error used to return a more nuanced error detailing _why_ one of the eight documented
6
+ * errors in the spec was raised after calling `navigator.credentials.create()` or
7
+ * `navigator.credentials.get()`:
8
+ *
9
+ * - `AbortError`
10
+ * - `ConstraintError`
11
+ * - `InvalidStateError`
12
+ * - `NotAllowedError`
13
+ * - `NotSupportedError`
14
+ * - `SecurityError`
15
+ * - `TypeError`
16
+ * - `UnknownError`
17
+ *
18
+ * Error messages were determined through investigation of the spec to determine under which
19
+ * scenarios a given error would be raised.
20
+ */
21
+ class WebAuthnError extends Error {
22
+ constructor({ message, code, cause, name, }) {
23
+ // @ts-ignore: help Rollup understand that `cause` is okay to set
24
+ super(message, { cause });
25
+ Object.defineProperty(this, "code", {
26
+ enumerable: true,
27
+ configurable: true,
28
+ writable: true,
29
+ value: void 0
30
+ });
31
+ this.name = name ?? cause.name;
32
+ this.code = code;
33
+ }
34
+ }
35
+ exports.WebAuthnError = WebAuthnError;
@@ -0,0 +1,11 @@
1
+ export * from './methods/startRegistration.js';
2
+ export * from './methods/startAuthentication.js';
3
+ export * from './helpers/browserSupportsWebAuthn.js';
4
+ export * from './helpers/platformAuthenticatorIsAvailable.js';
5
+ export * from './helpers/browserSupportsWebAuthnAutofill.js';
6
+ export * from './helpers/base64URLStringToBuffer.js';
7
+ export * from './helpers/bufferToBase64URLString.js';
8
+ export * from './helpers/webAuthnAbortService.js';
9
+ export * from './helpers/webAuthnError.js';
10
+ export * from './types/index.js';
11
+ //# sourceMappingURL=index.d.ts.map