@simplewebauthn/browser 10.0.0 → 11.0.0-alpha3

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 (110) hide show
  1. package/bundle/index.es5.umd.min.js +2 -0
  2. package/esm/helpers/base64URLStringToBuffer.d.ts +9 -0
  3. package/esm/helpers/base64URLStringToBuffer.d.ts.map +1 -0
  4. package/esm/helpers/base64URLStringToBuffer.js +29 -0
  5. package/esm/helpers/browserSupportsWebAuthn.d.ts +8 -0
  6. package/esm/helpers/browserSupportsWebAuthn.d.ts.map +1 -0
  7. package/esm/helpers/browserSupportsWebAuthn.js +11 -0
  8. package/esm/helpers/browserSupportsWebAuthnAutofill.d.ts +9 -0
  9. package/esm/helpers/browserSupportsWebAuthnAutofill.d.ts.map +1 -0
  10. package/esm/helpers/browserSupportsWebAuthnAutofill.js +26 -0
  11. package/esm/helpers/bufferToBase64URLString.d.ts +8 -0
  12. package/esm/helpers/bufferToBase64URLString.d.ts.map +1 -0
  13. package/esm/helpers/bufferToBase64URLString.js +15 -0
  14. package/esm/helpers/identifyAuthenticationError.d.ts +9 -0
  15. package/esm/helpers/identifyAuthenticationError.d.ts.map +1 -0
  16. package/esm/helpers/identifyAuthenticationError.js +61 -0
  17. package/esm/helpers/identifyRegistrationError.d.ts +9 -0
  18. package/esm/helpers/identifyRegistrationError.d.ts.map +1 -0
  19. package/esm/helpers/identifyRegistrationError.js +126 -0
  20. package/esm/helpers/isValidDomain.d.ts +10 -0
  21. package/esm/helpers/isValidDomain.d.ts.map +1 -0
  22. package/esm/helpers/isValidDomain.js +14 -0
  23. package/esm/helpers/platformAuthenticatorIsAvailable.d.ts +8 -0
  24. package/esm/helpers/platformAuthenticatorIsAvailable.d.ts.map +1 -0
  25. package/esm/helpers/platformAuthenticatorIsAvailable.js +13 -0
  26. package/{dist/types → esm}/helpers/toAuthenticatorAttachment.d.ts +4 -0
  27. package/esm/helpers/toAuthenticatorAttachment.d.ts.map +1 -0
  28. package/esm/helpers/toAuthenticatorAttachment.js +13 -0
  29. package/esm/helpers/toPublicKeyCredentialDescriptor.d.ts +3 -0
  30. package/esm/helpers/toPublicKeyCredentialDescriptor.d.ts.map +1 -0
  31. package/esm/helpers/toPublicKeyCredentialDescriptor.js +14 -0
  32. package/esm/helpers/webAuthnAbortService.d.ts +14 -0
  33. package/esm/helpers/webAuthnAbortService.d.ts.map +1 -0
  34. package/esm/helpers/webAuthnAbortService.js +45 -0
  35. package/{dist/types → esm}/helpers/webAuthnError.d.ts +19 -1
  36. package/esm/helpers/webAuthnError.d.ts.map +1 -0
  37. package/esm/helpers/webAuthnError.js +31 -0
  38. package/esm/index.d.ts +16 -0
  39. package/esm/index.d.ts.map +1 -0
  40. package/{dist/types/index.d.ts → esm/index.js} +13 -10
  41. package/esm/methods/startAuthentication.d.ts +15 -0
  42. package/esm/methods/startAuthentication.d.ts.map +1 -0
  43. package/esm/methods/startAuthentication.js +89 -0
  44. package/esm/methods/startRegistration.d.ts +13 -0
  45. package/esm/methods/startRegistration.d.ts.map +1 -0
  46. package/esm/methods/startRegistration.js +115 -0
  47. package/esm/package.json +3 -0
  48. package/package.json +24 -29
  49. package/script/helpers/base64URLStringToBuffer.d.ts +9 -0
  50. package/script/helpers/base64URLStringToBuffer.d.ts.map +1 -0
  51. package/script/helpers/base64URLStringToBuffer.js +32 -0
  52. package/script/helpers/browserSupportsWebAuthn.d.ts +8 -0
  53. package/script/helpers/browserSupportsWebAuthn.d.ts.map +1 -0
  54. package/script/helpers/browserSupportsWebAuthn.js +15 -0
  55. package/script/helpers/browserSupportsWebAuthnAutofill.d.ts +9 -0
  56. package/script/helpers/browserSupportsWebAuthnAutofill.d.ts.map +1 -0
  57. package/script/helpers/browserSupportsWebAuthnAutofill.js +30 -0
  58. package/script/helpers/bufferToBase64URLString.d.ts +8 -0
  59. package/script/helpers/bufferToBase64URLString.d.ts.map +1 -0
  60. package/script/helpers/bufferToBase64URLString.js +18 -0
  61. package/script/helpers/identifyAuthenticationError.d.ts +9 -0
  62. package/script/helpers/identifyAuthenticationError.d.ts.map +1 -0
  63. package/script/helpers/identifyAuthenticationError.js +64 -0
  64. package/script/helpers/identifyRegistrationError.d.ts +9 -0
  65. package/script/helpers/identifyRegistrationError.d.ts.map +1 -0
  66. package/script/helpers/identifyRegistrationError.js +129 -0
  67. package/script/helpers/isValidDomain.d.ts +10 -0
  68. package/script/helpers/isValidDomain.d.ts.map +1 -0
  69. package/script/helpers/isValidDomain.js +17 -0
  70. package/script/helpers/platformAuthenticatorIsAvailable.d.ts +8 -0
  71. package/script/helpers/platformAuthenticatorIsAvailable.d.ts.map +1 -0
  72. package/script/helpers/platformAuthenticatorIsAvailable.js +16 -0
  73. package/script/helpers/toAuthenticatorAttachment.d.ts +6 -0
  74. package/script/helpers/toAuthenticatorAttachment.d.ts.map +1 -0
  75. package/script/helpers/toAuthenticatorAttachment.js +16 -0
  76. package/script/helpers/toPublicKeyCredentialDescriptor.d.ts +3 -0
  77. package/script/helpers/toPublicKeyCredentialDescriptor.d.ts.map +1 -0
  78. package/script/helpers/toPublicKeyCredentialDescriptor.js +17 -0
  79. package/script/helpers/webAuthnAbortService.d.ts +14 -0
  80. package/script/helpers/webAuthnAbortService.d.ts.map +1 -0
  81. package/script/helpers/webAuthnAbortService.js +48 -0
  82. package/script/helpers/webAuthnError.d.ts +28 -0
  83. package/script/helpers/webAuthnError.d.ts.map +1 -0
  84. package/script/helpers/webAuthnError.js +35 -0
  85. package/script/index.d.ts +16 -0
  86. package/script/index.d.ts.map +1 -0
  87. package/script/index.js +25 -0
  88. package/script/methods/startAuthentication.d.ts +15 -0
  89. package/script/methods/startAuthentication.d.ts.map +1 -0
  90. package/script/methods/startAuthentication.js +92 -0
  91. package/script/methods/startRegistration.d.ts +13 -0
  92. package/script/methods/startRegistration.d.ts.map +1 -0
  93. package/script/methods/startRegistration.js +118 -0
  94. package/script/package.json +3 -0
  95. package/dist/bundle/index.es5.umd.min.js +0 -2
  96. package/dist/bundle/index.js +0 -384
  97. package/dist/bundle/index.umd.min.js +0 -2
  98. package/dist/types/helpers/base64URLStringToBuffer.d.ts +0 -1
  99. package/dist/types/helpers/browserSupportsWebAuthn.d.ts +0 -1
  100. package/dist/types/helpers/browserSupportsWebAuthnAutofill.d.ts +0 -1
  101. package/dist/types/helpers/bufferToBase64URLString.d.ts +0 -1
  102. package/dist/types/helpers/identifyAuthenticationError.d.ts +0 -5
  103. package/dist/types/helpers/identifyRegistrationError.d.ts +0 -5
  104. package/dist/types/helpers/isValidDomain.d.ts +0 -1
  105. package/dist/types/helpers/platformAuthenticatorIsAvailable.d.ts +0 -1
  106. package/dist/types/helpers/toPublicKeyCredentialDescriptor.d.ts +0 -2
  107. package/dist/types/helpers/webAuthnAbortService.d.ts +0 -7
  108. package/dist/types/methods/startAuthentication.d.ts +0 -2
  109. package/dist/types/methods/startRegistration.d.ts +0 -2
  110. package/jest-environment.js +0 -29
@@ -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 { AuthenticatorAttachment } from '@simplewebauthn/types';
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,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAIhE;;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 '@simplewebauthn/types';
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,uBAAuB,CAAC;AAI/B,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,14 @@
1
+ interface WebAuthnAbortService {
2
+ createNewAbortSignal(): AbortSignal;
3
+ cancelCeremony(): void;
4
+ }
5
+ /**
6
+ * A service singleton to help ensure that only a single WebAuthn ceremony is active at a time.
7
+ *
8
+ * Users of **@simplewebauthn/browser** shouldn't typically need to use this, but it can help e.g.
9
+ * developers building projects that use client-side routing to better control the behavior of
10
+ * their UX in response to router navigation events.
11
+ */
12
+ export declare const WebAuthnAbortService: WebAuthnAbortService;
13
+ export {};
14
+ //# 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,oBAAoB,IAAI,WAAW,CAAC;IACpC,cAAc,IAAI,IAAI,CAAC;CACxB;AA0CD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,oBAAqD,CAAC"}
@@ -0,0 +1,48 @@
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
+ /**
14
+ * Prepare an abort signal that will help support multiple auth attempts without needing to
15
+ * reload the page. This is automatically called whenever `startRegistration()` and
16
+ * `startAuthentication()` are called.
17
+ */
18
+ createNewAbortSignal() {
19
+ // Abort any existing calls to navigator.credentials.create() or navigator.credentials.get()
20
+ if (this.controller) {
21
+ const abortError = new Error('Cancelling existing WebAuthn API call for new one');
22
+ abortError.name = 'AbortError';
23
+ this.controller.abort(abortError);
24
+ }
25
+ const newController = new AbortController();
26
+ this.controller = newController;
27
+ return newController.signal;
28
+ }
29
+ /**
30
+ * Manually cancel any active WebAuthn registration or authentication attempt.
31
+ */
32
+ cancelCeremony() {
33
+ if (this.controller) {
34
+ const abortError = new Error('Manually cancelling existing WebAuthn API call');
35
+ abortError.name = 'AbortError';
36
+ this.controller.abort(abortError);
37
+ this.controller = undefined;
38
+ }
39
+ }
40
+ }
41
+ /**
42
+ * A service singleton to help ensure that only a single WebAuthn ceremony is active at a time.
43
+ *
44
+ * Users of **@simplewebauthn/browser** shouldn't typically need to use this, but it can help e.g.
45
+ * developers building projects that use client-side routing to better control the behavior of
46
+ * their UX in response to router navigation events.
47
+ */
48
+ 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,16 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * @module @simplewebauthn/browser
4
+ */
5
+ import { startRegistration } from './methods/startRegistration.js';
6
+ import { startAuthentication } from './methods/startAuthentication.js';
7
+ import { browserSupportsWebAuthn } from './helpers/browserSupportsWebAuthn.js';
8
+ import { platformAuthenticatorIsAvailable } from './helpers/platformAuthenticatorIsAvailable.js';
9
+ import { browserSupportsWebAuthnAutofill } from './helpers/browserSupportsWebAuthnAutofill.js';
10
+ import { base64URLStringToBuffer } from './helpers/base64URLStringToBuffer.js';
11
+ import { bufferToBase64URLString } from './helpers/bufferToBase64URLString.js';
12
+ import { WebAuthnAbortService } from './helpers/webAuthnAbortService.js';
13
+ import { WebAuthnError } from './helpers/webAuthnError.js';
14
+ export { base64URLStringToBuffer, browserSupportsWebAuthn, browserSupportsWebAuthnAutofill, bufferToBase64URLString, platformAuthenticatorIsAvailable, startAuthentication, startRegistration, WebAuthnAbortService, WebAuthnError, };
15
+ export type { WebAuthnErrorCode } from './helpers/webAuthnError.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,gCAAgC,EAAE,MAAM,+CAA+C,CAAC;AACjG,OAAO,EAAE,+BAA+B,EAAE,MAAM,8CAA8C,CAAC;AAC/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,+BAA+B,EAC/B,uBAAuB,EACvB,gCAAgC,EAChC,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,GACd,CAAC;AAEF,YAAY,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebAuthnError = exports.WebAuthnAbortService = exports.startRegistration = exports.startAuthentication = exports.platformAuthenticatorIsAvailable = exports.bufferToBase64URLString = exports.browserSupportsWebAuthnAutofill = exports.browserSupportsWebAuthn = exports.base64URLStringToBuffer = void 0;
4
+ /**
5
+ * @packageDocumentation
6
+ * @module @simplewebauthn/browser
7
+ */
8
+ const startRegistration_js_1 = require("./methods/startRegistration.js");
9
+ Object.defineProperty(exports, "startRegistration", { enumerable: true, get: function () { return startRegistration_js_1.startRegistration; } });
10
+ const startAuthentication_js_1 = require("./methods/startAuthentication.js");
11
+ Object.defineProperty(exports, "startAuthentication", { enumerable: true, get: function () { return startAuthentication_js_1.startAuthentication; } });
12
+ const browserSupportsWebAuthn_js_1 = require("./helpers/browserSupportsWebAuthn.js");
13
+ Object.defineProperty(exports, "browserSupportsWebAuthn", { enumerable: true, get: function () { return browserSupportsWebAuthn_js_1.browserSupportsWebAuthn; } });
14
+ const platformAuthenticatorIsAvailable_js_1 = require("./helpers/platformAuthenticatorIsAvailable.js");
15
+ Object.defineProperty(exports, "platformAuthenticatorIsAvailable", { enumerable: true, get: function () { return platformAuthenticatorIsAvailable_js_1.platformAuthenticatorIsAvailable; } });
16
+ const browserSupportsWebAuthnAutofill_js_1 = require("./helpers/browserSupportsWebAuthnAutofill.js");
17
+ Object.defineProperty(exports, "browserSupportsWebAuthnAutofill", { enumerable: true, get: function () { return browserSupportsWebAuthnAutofill_js_1.browserSupportsWebAuthnAutofill; } });
18
+ const base64URLStringToBuffer_js_1 = require("./helpers/base64URLStringToBuffer.js");
19
+ Object.defineProperty(exports, "base64URLStringToBuffer", { enumerable: true, get: function () { return base64URLStringToBuffer_js_1.base64URLStringToBuffer; } });
20
+ const bufferToBase64URLString_js_1 = require("./helpers/bufferToBase64URLString.js");
21
+ Object.defineProperty(exports, "bufferToBase64URLString", { enumerable: true, get: function () { return bufferToBase64URLString_js_1.bufferToBase64URLString; } });
22
+ const webAuthnAbortService_js_1 = require("./helpers/webAuthnAbortService.js");
23
+ Object.defineProperty(exports, "WebAuthnAbortService", { enumerable: true, get: function () { return webAuthnAbortService_js_1.WebAuthnAbortService; } });
24
+ const webAuthnError_js_1 = require("./helpers/webAuthnError.js");
25
+ Object.defineProperty(exports, "WebAuthnError", { enumerable: true, get: function () { return webAuthnError_js_1.WebAuthnError; } });
@@ -0,0 +1,15 @@
1
+ import { AuthenticationResponseJSON, PublicKeyCredentialRequestOptionsJSON } from '@simplewebauthn/types';
2
+ export type StartAuthenticationOpts = {
3
+ optionsJSON: PublicKeyCredentialRequestOptionsJSON;
4
+ useBrowserAutofill?: boolean;
5
+ verifyBrowserAutofillInput?: boolean;
6
+ };
7
+ /**
8
+ * Begin authenticator "login" via WebAuthn assertion
9
+ *
10
+ * @param optionsJSON Output from **@simplewebauthn/server**'s `generateAuthenticationOptions()`
11
+ * @param useBrowserAutofill (Optional) Initialize conditional UI to enable logging in via browser autofill prompts. Defaults to `false`.
12
+ * @param verifyBrowserAutofillInput (Optional) Ensure a suitable `<input>` element is present when `useBrowserAutofill` is `true`. Defaults to `true`.
13
+ */
14
+ export declare function startAuthentication(options: StartAuthenticationOpts): Promise<AuthenticationResponseJSON>;
15
+ //# sourceMappingURL=startAuthentication.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startAuthentication.d.ts","sourceRoot":"","sources":["../../src/methods/startAuthentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,0BAA0B,EAC1B,qCAAqC,EACtC,MAAM,uBAAuB,CAAC;AAW/B,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,EAAE,qCAAqC,CAAC;IACnD,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACtC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,0BAA0B,CAAC,CAkGrC"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startAuthentication = startAuthentication;
4
+ const bufferToBase64URLString_js_1 = require("../helpers/bufferToBase64URLString.js");
5
+ const base64URLStringToBuffer_js_1 = require("../helpers/base64URLStringToBuffer.js");
6
+ const browserSupportsWebAuthn_js_1 = require("../helpers/browserSupportsWebAuthn.js");
7
+ const browserSupportsWebAuthnAutofill_js_1 = require("../helpers/browserSupportsWebAuthnAutofill.js");
8
+ const toPublicKeyCredentialDescriptor_js_1 = require("../helpers/toPublicKeyCredentialDescriptor.js");
9
+ const identifyAuthenticationError_js_1 = require("../helpers/identifyAuthenticationError.js");
10
+ const webAuthnAbortService_js_1 = require("../helpers/webAuthnAbortService.js");
11
+ const toAuthenticatorAttachment_js_1 = require("../helpers/toAuthenticatorAttachment.js");
12
+ /**
13
+ * Begin authenticator "login" via WebAuthn assertion
14
+ *
15
+ * @param optionsJSON Output from **@simplewebauthn/server**'s `generateAuthenticationOptions()`
16
+ * @param useBrowserAutofill (Optional) Initialize conditional UI to enable logging in via browser autofill prompts. Defaults to `false`.
17
+ * @param verifyBrowserAutofillInput (Optional) Ensure a suitable `<input>` element is present when `useBrowserAutofill` is `true`. Defaults to `true`.
18
+ */
19
+ async function startAuthentication(options) {
20
+ const { optionsJSON, useBrowserAutofill = false, verifyBrowserAutofillInput = true, } = options;
21
+ if (!(0, browserSupportsWebAuthn_js_1.browserSupportsWebAuthn)()) {
22
+ throw new Error('WebAuthn is not supported in this browser');
23
+ }
24
+ // We need to avoid passing empty array to avoid blocking retrieval
25
+ // of public key
26
+ let allowCredentials;
27
+ if (optionsJSON.allowCredentials?.length !== 0) {
28
+ allowCredentials = optionsJSON.allowCredentials?.map(toPublicKeyCredentialDescriptor_js_1.toPublicKeyCredentialDescriptor);
29
+ }
30
+ // We need to convert some values to Uint8Arrays before passing the credentials to the navigator
31
+ const publicKey = {
32
+ ...optionsJSON,
33
+ challenge: (0, base64URLStringToBuffer_js_1.base64URLStringToBuffer)(optionsJSON.challenge),
34
+ allowCredentials,
35
+ };
36
+ // Prepare options for `.get()`
37
+ const getOptions = {};
38
+ /**
39
+ * Set up the page to prompt the user to select a credential for authentication via the browser's
40
+ * input autofill mechanism.
41
+ */
42
+ if (useBrowserAutofill) {
43
+ if (!(await (0, browserSupportsWebAuthnAutofill_js_1.browserSupportsWebAuthnAutofill)())) {
44
+ throw Error('Browser does not support WebAuthn autofill');
45
+ }
46
+ // Check for an <input> with "webauthn" in its `autocomplete` attribute
47
+ const eligibleInputs = document.querySelectorAll("input[autocomplete$='webauthn']");
48
+ // WebAuthn autofill requires at least one valid input
49
+ if (eligibleInputs.length < 1 && verifyBrowserAutofillInput) {
50
+ throw Error('No <input> with "webauthn" as the only or last value in its `autocomplete` attribute was detected');
51
+ }
52
+ // `CredentialMediationRequirement` doesn't know about "conditional" yet as of
53
+ // typescript@4.6.3
54
+ getOptions.mediation = 'conditional';
55
+ // Conditional UI requires an empty allow list
56
+ publicKey.allowCredentials = [];
57
+ }
58
+ // Finalize options
59
+ getOptions.publicKey = publicKey;
60
+ // Set up the ability to cancel this request if the user attempts another
61
+ getOptions.signal = webAuthnAbortService_js_1.WebAuthnAbortService.createNewAbortSignal();
62
+ // Wait for the user to complete assertion
63
+ let credential;
64
+ try {
65
+ credential = (await navigator.credentials.get(getOptions));
66
+ }
67
+ catch (err) {
68
+ throw (0, identifyAuthenticationError_js_1.identifyAuthenticationError)({ error: err, options: getOptions });
69
+ }
70
+ if (!credential) {
71
+ throw new Error('Authentication was not completed');
72
+ }
73
+ const { id, rawId, response, type } = credential;
74
+ let userHandle = undefined;
75
+ if (response.userHandle) {
76
+ userHandle = (0, bufferToBase64URLString_js_1.bufferToBase64URLString)(response.userHandle);
77
+ }
78
+ // Convert values to base64 to make it easier to send back to the server
79
+ return {
80
+ id,
81
+ rawId: (0, bufferToBase64URLString_js_1.bufferToBase64URLString)(rawId),
82
+ response: {
83
+ authenticatorData: (0, bufferToBase64URLString_js_1.bufferToBase64URLString)(response.authenticatorData),
84
+ clientDataJSON: (0, bufferToBase64URLString_js_1.bufferToBase64URLString)(response.clientDataJSON),
85
+ signature: (0, bufferToBase64URLString_js_1.bufferToBase64URLString)(response.signature),
86
+ userHandle,
87
+ },
88
+ type,
89
+ clientExtensionResults: credential.getClientExtensionResults(),
90
+ authenticatorAttachment: (0, toAuthenticatorAttachment_js_1.toAuthenticatorAttachment)(credential.authenticatorAttachment),
91
+ };
92
+ }
@@ -0,0 +1,13 @@
1
+ import { PublicKeyCredentialCreationOptionsJSON, RegistrationResponseJSON } from '@simplewebauthn/types';
2
+ export type StartRegistrationOpts = {
3
+ optionsJSON: PublicKeyCredentialCreationOptionsJSON;
4
+ useAutoRegister?: boolean;
5
+ };
6
+ /**
7
+ * Begin authenticator "registration" via WebAuthn attestation
8
+ *
9
+ * @param optionsJSON Output from **@simplewebauthn/server**'s `generateRegistrationOptions()`
10
+ * @param useAutoRegister (Optional) Try to silently create a passkey with the password manager that the user just signed in with. Defaults to `false`.
11
+ */
12
+ export declare function startRegistration(options: StartRegistrationOpts): Promise<RegistrationResponseJSON>;
13
+ //# sourceMappingURL=startRegistration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startRegistration.d.ts","sourceRoot":"","sources":["../../src/methods/startRegistration.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,sCAAsC,EAEtC,wBAAwB,EACzB,MAAM,uBAAuB,CAAC;AAU/B,MAAM,MAAM,qBAAqB,GAAG;IAClC,WAAW,EAAE,sCAAsC,CAAC;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,wBAAwB,CAAC,CA6GnC"}