@simplewebauthn/server 9.0.3 → 10.0.1

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 (52) hide show
  1. package/README.md +2 -2
  2. package/esm/authentication/generateAuthenticationOptions.d.ts +16 -14
  3. package/esm/authentication/generateAuthenticationOptions.js +21 -16
  4. package/esm/authentication/verifyAuthenticationResponse.d.ts +13 -18
  5. package/esm/authentication/verifyAuthenticationResponse.js +12 -17
  6. package/esm/deps.d.ts +1 -1
  7. package/esm/helpers/convertCertBufferToPEM.js +1 -1
  8. package/esm/helpers/decodeClientDataJSON.d.ts +2 -1
  9. package/esm/helpers/decodeClientDataJSON.js +1 -1
  10. package/esm/helpers/generateUserID.d.ts +7 -0
  11. package/esm/helpers/generateUserID.js +17 -0
  12. package/esm/helpers/index.d.ts +2 -1
  13. package/esm/helpers/index.js +2 -1
  14. package/esm/helpers/iso/isoBase64URL.d.ts +10 -5
  15. package/esm/helpers/iso/isoBase64URL.js +13 -7
  16. package/esm/helpers/iso/isoCrypto/getWebCrypto.d.ts +0 -289
  17. package/esm/helpers/iso/isoCrypto/getWebCrypto.js +26 -41
  18. package/esm/helpers/iso/isoCrypto/unwrapEC2Signature.d.ts +2 -1
  19. package/esm/helpers/iso/isoCrypto/unwrapEC2Signature.js +58 -16
  20. package/esm/helpers/iso/isoCrypto/verify.js +6 -2
  21. package/esm/metadata/parseJWT.js +2 -2
  22. package/esm/registration/generateRegistrationOptions.d.ts +19 -19
  23. package/esm/registration/generateRegistrationOptions.js +40 -22
  24. package/esm/registration/verifications/verifyAttestationAndroidSafetyNet.js +2 -2
  25. package/esm/registration/verifyRegistrationResponse.d.ts +9 -12
  26. package/esm/registration/verifyRegistrationResponse.js +8 -11
  27. package/package.json +3 -3
  28. package/script/authentication/generateAuthenticationOptions.d.ts +16 -14
  29. package/script/authentication/generateAuthenticationOptions.js +21 -16
  30. package/script/authentication/verifyAuthenticationResponse.d.ts +13 -18
  31. package/script/authentication/verifyAuthenticationResponse.js +12 -17
  32. package/script/deps.d.ts +1 -1
  33. package/script/helpers/convertCertBufferToPEM.js +1 -1
  34. package/script/helpers/decodeClientDataJSON.d.ts +2 -1
  35. package/script/helpers/decodeClientDataJSON.js +1 -1
  36. package/script/helpers/generateUserID.d.ts +7 -0
  37. package/script/helpers/generateUserID.js +21 -0
  38. package/script/helpers/index.d.ts +2 -1
  39. package/script/helpers/index.js +3 -1
  40. package/script/helpers/iso/isoBase64URL.d.ts +10 -5
  41. package/script/helpers/iso/isoBase64URL.js +18 -11
  42. package/script/helpers/iso/isoCrypto/getWebCrypto.d.ts +0 -288
  43. package/script/helpers/iso/isoCrypto/getWebCrypto.js +26 -64
  44. package/script/helpers/iso/isoCrypto/unwrapEC2Signature.d.ts +2 -1
  45. package/script/helpers/iso/isoCrypto/unwrapEC2Signature.js +58 -16
  46. package/script/helpers/iso/isoCrypto/verify.js +5 -1
  47. package/script/metadata/parseJWT.js +2 -2
  48. package/script/registration/generateRegistrationOptions.d.ts +19 -19
  49. package/script/registration/generateRegistrationOptions.js +40 -22
  50. package/script/registration/verifications/verifyAttestationAndroidSafetyNet.js +2 -2
  51. package/script/registration/verifyRegistrationResponse.d.ts +9 -12
  52. package/script/registration/verifyRegistrationResponse.js +8 -11
@@ -1,14 +1,17 @@
1
- import type { AttestationConveyancePreference, AuthenticationExtensionsClientInputs, AuthenticatorSelectionCriteria, COSEAlgorithmIdentifier, PublicKeyCredentialCreationOptionsJSON, PublicKeyCredentialDescriptorFuture } from '../deps.js';
1
+ import type { AttestationConveyancePreference, AuthenticationExtensionsClientInputs, AuthenticatorSelectionCriteria, AuthenticatorTransportFuture, Base64URLString, COSEAlgorithmIdentifier, PublicKeyCredentialCreationOptionsJSON } from '../deps.js';
2
2
  export type GenerateRegistrationOptionsOpts = {
3
3
  rpName: string;
4
4
  rpID: string;
5
- userID: string;
6
5
  userName: string;
6
+ userID?: Uint8Array;
7
7
  challenge?: string | Uint8Array;
8
8
  userDisplayName?: string;
9
9
  timeout?: number;
10
10
  attestationType?: AttestationConveyancePreference;
11
- excludeCredentials?: PublicKeyCredentialDescriptorFuture[];
11
+ excludeCredentials?: {
12
+ id: Base64URLString;
13
+ transports?: AuthenticatorTransportFuture[];
14
+ }[];
12
15
  authenticatorSelection?: AuthenticatorSelectionCriteria;
13
16
  extensions?: AuthenticationExtensionsClientInputs;
14
17
  supportedAlgorithmIDs?: COSEAlgorithmIdentifier[];
@@ -20,24 +23,21 @@ export type GenerateRegistrationOptionsOpts = {
20
23
  */
21
24
  export declare const supportedCOSEAlgorithmIdentifiers: COSEAlgorithmIdentifier[];
22
25
  /**
23
- * Prepare a value to pass into navigator.credentials.create(...) for authenticator "registration"
26
+ * Prepare a value to pass into navigator.credentials.create(...) for authenticator registration
24
27
  *
25
28
  * **Options:**
26
29
  *
27
- * @param rpName User-visible, "friendly" website/service name
28
- * @param rpID Valid domain name (after `https://`)
29
- * @param userID User's website-specific unique ID
30
- * @param userName User's website-specific username (email, etc...)
31
- * @param challenge Random value the authenticator needs to sign and pass back
32
- * @param userDisplayName User's actual name
33
- * @param timeout How long (in ms) the user can take to complete attestation
34
- * @param attestationType Specific attestation statement
35
- * @param excludeCredentials Authenticators registered by the user so the user can't register the
36
- * same credential multiple times
37
- * @param authenticatorSelection Advanced criteria for restricting the types of authenticators that
38
- * may be used
39
- * @param extensions Additional plugins the authenticator or browser should use during attestation
40
- * @param supportedAlgorithmIDs Array of numeric COSE algorithm identifiers supported for
41
- * attestation by this RP. See https://www.iana.org/assignments/cose/cose.xhtml#algorithms
30
+ * @param rpName - User-visible, "friendly" website/service name
31
+ * @param rpID - Valid domain name (after `https://`)
32
+ * @param userName - User's website-specific username (email, etc...)
33
+ * @param userID **(Optional)** - User's website-specific unique ID. Defaults to generating a random identifier
34
+ * @param challenge **(Optional)** - Random value the authenticator needs to sign and pass back. Defaults to generating a random value
35
+ * @param userDisplayName **(Optional)** - User's actual name. Defaults to `""`
36
+ * @param timeout **(Optional)** - How long (in ms) the user can take to complete attestation. Defaults to `60000`
37
+ * @param attestationType **(Optional)** - Specific attestation statement. Defaults to `"none"`
38
+ * @param excludeCredentials **(Optional)** - Authenticators registered by the user so the user can't register the same credential multiple times. Defaults to `[]`
39
+ * @param authenticatorSelection **(Optional)** - Advanced criteria for restricting the types of authenticators that may be used. Defaults to `{ residentKey: 'preferred', userVerification: 'preferred' }`
40
+ * @param extensions **(Optional)** - Additional plugins the authenticator or browser should use during attestation
41
+ * @param supportedAlgorithmIDs **(Optional)** - Array of numeric COSE algorithm identifiers supported for attestation by this RP. See https://www.iana.org/assignments/cose/cose.xhtml#algorithms. Defaults to `[-8, -7, -257]`
42
42
  */
43
43
  export declare function generateRegistrationOptions(options: GenerateRegistrationOptionsOpts): Promise<PublicKeyCredentialCreationOptionsJSON>;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateRegistrationOptions = exports.supportedCOSEAlgorithmIdentifiers = void 0;
4
4
  const generateChallenge_js_1 = require("../helpers/generateChallenge.js");
5
+ const generateUserID_js_1 = require("../helpers/generateUserID.js");
5
6
  const index_js_1 = require("../helpers/iso/index.js");
6
7
  /**
7
8
  * Supported crypto algo identifiers
@@ -49,28 +50,25 @@ const defaultAuthenticatorSelection = {
49
50
  */
50
51
  const defaultSupportedAlgorithmIDs = [-8, -7, -257];
51
52
  /**
52
- * Prepare a value to pass into navigator.credentials.create(...) for authenticator "registration"
53
+ * Prepare a value to pass into navigator.credentials.create(...) for authenticator registration
53
54
  *
54
55
  * **Options:**
55
56
  *
56
- * @param rpName User-visible, "friendly" website/service name
57
- * @param rpID Valid domain name (after `https://`)
58
- * @param userID User's website-specific unique ID
59
- * @param userName User's website-specific username (email, etc...)
60
- * @param challenge Random value the authenticator needs to sign and pass back
61
- * @param userDisplayName User's actual name
62
- * @param timeout How long (in ms) the user can take to complete attestation
63
- * @param attestationType Specific attestation statement
64
- * @param excludeCredentials Authenticators registered by the user so the user can't register the
65
- * same credential multiple times
66
- * @param authenticatorSelection Advanced criteria for restricting the types of authenticators that
67
- * may be used
68
- * @param extensions Additional plugins the authenticator or browser should use during attestation
69
- * @param supportedAlgorithmIDs Array of numeric COSE algorithm identifiers supported for
70
- * attestation by this RP. See https://www.iana.org/assignments/cose/cose.xhtml#algorithms
57
+ * @param rpName - User-visible, "friendly" website/service name
58
+ * @param rpID - Valid domain name (after `https://`)
59
+ * @param userName - User's website-specific username (email, etc...)
60
+ * @param userID **(Optional)** - User's website-specific unique ID. Defaults to generating a random identifier
61
+ * @param challenge **(Optional)** - Random value the authenticator needs to sign and pass back. Defaults to generating a random value
62
+ * @param userDisplayName **(Optional)** - User's actual name. Defaults to `""`
63
+ * @param timeout **(Optional)** - How long (in ms) the user can take to complete attestation. Defaults to `60000`
64
+ * @param attestationType **(Optional)** - Specific attestation statement. Defaults to `"none"`
65
+ * @param excludeCredentials **(Optional)** - Authenticators registered by the user so the user can't register the same credential multiple times. Defaults to `[]`
66
+ * @param authenticatorSelection **(Optional)** - Advanced criteria for restricting the types of authenticators that may be used. Defaults to `{ residentKey: 'preferred', userVerification: 'preferred' }`
67
+ * @param extensions **(Optional)** - Additional plugins the authenticator or browser should use during attestation
68
+ * @param supportedAlgorithmIDs **(Optional)** - Array of numeric COSE algorithm identifiers supported for attestation by this RP. See https://www.iana.org/assignments/cose/cose.xhtml#algorithms. Defaults to `[-8, -7, -257]`
71
69
  */
72
70
  async function generateRegistrationOptions(options) {
73
- const { rpName, rpID, userID, userName, challenge = await (0, generateChallenge_js_1.generateChallenge)(), userDisplayName = userName, timeout = 60000, attestationType = 'none', excludeCredentials = [], authenticatorSelection = defaultAuthenticatorSelection, extensions, supportedAlgorithmIDs = defaultSupportedAlgorithmIDs, } = options;
71
+ const { rpName, rpID, userName, userID, challenge = await (0, generateChallenge_js_1.generateChallenge)(), userDisplayName = '', timeout = 60000, attestationType = 'none', excludeCredentials = [], authenticatorSelection = defaultAuthenticatorSelection, extensions, supportedAlgorithmIDs = defaultSupportedAlgorithmIDs, } = options;
74
72
  /**
75
73
  * Prepare pubKeyCredParams from the array of algorithm ID's
76
74
  */
@@ -118,6 +116,20 @@ async function generateRegistrationOptions(options) {
118
116
  if (typeof _challenge === 'string') {
119
117
  _challenge = index_js_1.isoUint8Array.fromUTF8String(_challenge);
120
118
  }
119
+ /**
120
+ * Explicitly disallow use of strings for userID anymore because `isoBase64URL.fromBuffer()` below
121
+ * will return an empty string if one gets through!
122
+ */
123
+ if (typeof userID === 'string') {
124
+ throw new Error(`String values for \`userID\` are no longer supported. See https://simplewebauthn.dev/docs/advanced/server/custom-user-ids`);
125
+ }
126
+ /**
127
+ * Generate a user ID if one is not provided
128
+ */
129
+ let _userID = userID;
130
+ if (!_userID) {
131
+ _userID = await (0, generateUserID_js_1.generateUserID)();
132
+ }
121
133
  return {
122
134
  challenge: index_js_1.isoBase64URL.fromBuffer(_challenge),
123
135
  rp: {
@@ -125,17 +137,23 @@ async function generateRegistrationOptions(options) {
125
137
  id: rpID,
126
138
  },
127
139
  user: {
128
- id: userID,
140
+ id: index_js_1.isoBase64URL.fromBuffer(_userID),
129
141
  name: userName,
130
142
  displayName: userDisplayName,
131
143
  },
132
144
  pubKeyCredParams,
133
145
  timeout,
134
146
  attestation: attestationType,
135
- excludeCredentials: excludeCredentials.map((cred) => ({
136
- ...cred,
137
- id: index_js_1.isoBase64URL.fromBuffer(cred.id),
138
- })),
147
+ excludeCredentials: excludeCredentials.map((cred) => {
148
+ if (!index_js_1.isoBase64URL.isBase64URL(cred.id)) {
149
+ throw new Error(`excludeCredential id "${cred.id}" is not a valid base64url string`);
150
+ }
151
+ return {
152
+ ...cred,
153
+ id: index_js_1.isoBase64URL.trimPadding(cred.id),
154
+ type: 'public-key',
155
+ };
156
+ }),
139
157
  authenticatorSelection,
140
158
  extensions: {
141
159
  ...extensions,
@@ -26,8 +26,8 @@ async function verifyAttestationAndroidSafetyNet(options) {
26
26
  // Prepare to verify a JWT
27
27
  const jwt = index_js_1.isoUint8Array.toUTF8String(response);
28
28
  const jwtParts = jwt.split('.');
29
- const HEADER = JSON.parse(index_js_1.isoBase64URL.toString(jwtParts[0]));
30
- const PAYLOAD = JSON.parse(index_js_1.isoBase64URL.toString(jwtParts[1]));
29
+ const HEADER = JSON.parse(index_js_1.isoBase64URL.toUTF8String(jwtParts[0]));
30
+ const PAYLOAD = JSON.parse(index_js_1.isoBase64URL.toUTF8String(jwtParts[1]));
31
31
  const SIGNATURE = jwtParts[2];
32
32
  /**
33
33
  * START Verify PAYLOAD
@@ -1,4 +1,4 @@
1
- import type { COSEAlgorithmIdentifier, CredentialDeviceType, RegistrationResponseJSON } from '../deps.js';
1
+ import type { Base64URLString, COSEAlgorithmIdentifier, CredentialDeviceType, RegistrationResponseJSON } from '../deps.js';
2
2
  import { AttestationFormat, AttestationStatement } from '../helpers/decodeAttestationObject.js';
3
3
  import { AuthenticationExtensionsAuthenticatorOutputs } from '../helpers/decodeAuthenticatorExtensions.js';
4
4
  export type VerifyRegistrationResponseOpts = {
@@ -15,16 +15,13 @@ export type VerifyRegistrationResponseOpts = {
15
15
  *
16
16
  * **Options:**
17
17
  *
18
- * @param response Response returned by **@simplewebauthn/browser**'s `startAuthentication()`
19
- * @param expectedChallenge The base64url-encoded `options.challenge` returned by
20
- * `generateRegistrationOptions()`
21
- * @param expectedOrigin Website URL (or array of URLs) that the registration should have occurred on
22
- * @param expectedRPID RP ID (or array of IDs) that was specified in the registration options
23
- * @param expectedType (Optional) The response type expected ('webauthn.create')
24
- * @param requireUserVerification (Optional) Enforce user verification by the authenticator
25
- * (via PIN, fingerprint, etc...)
26
- * @param supportedAlgorithmIDs Array of numeric COSE algorithm identifiers supported for
27
- * attestation by this RP. See https://www.iana.org/assignments/cose/cose.xhtml#algorithms
18
+ * @param response - Response returned by **@simplewebauthn/browser**'s `startAuthentication()`
19
+ * @param expectedChallenge - The base64url-encoded `options.challenge` returned by `generateRegistrationOptions()`
20
+ * @param expectedOrigin - Website URL (or array of URLs) that the registration should have occurred on
21
+ * @param expectedRPID - RP ID (or array of IDs) that was specified in the registration options
22
+ * @param expectedType **(Optional)** - The response type expected ('webauthn.create')
23
+ * @param requireUserVerification **(Optional)** - Enforce user verification by the authenticator (via PIN, fingerprint, etc...) Defaults to `true`
24
+ * @param supportedAlgorithmIDs **(Optional)** - Array of numeric COSE algorithm identifiers supported for attestation by this RP. See https://www.iana.org/assignments/cose/cose.xhtml#algorithms. Defaults to all supported algorithm IDs
28
25
  */
29
26
  export declare function verifyRegistrationResponse(options: VerifyRegistrationResponseOpts): Promise<VerifiedRegistrationResponse>;
30
27
  /**
@@ -59,7 +56,7 @@ export type VerifiedRegistrationResponse = {
59
56
  fmt: AttestationFormat;
60
57
  counter: number;
61
58
  aaguid: string;
62
- credentialID: Uint8Array;
59
+ credentialID: Base64URLString;
63
60
  credentialPublicKey: Uint8Array;
64
61
  credentialType: 'public-key';
65
62
  attestationObject: Uint8Array;
@@ -24,16 +24,13 @@ const verifyAttestationApple_js_1 = require("./verifications/verifyAttestationAp
24
24
  *
25
25
  * **Options:**
26
26
  *
27
- * @param response Response returned by **@simplewebauthn/browser**'s `startAuthentication()`
28
- * @param expectedChallenge The base64url-encoded `options.challenge` returned by
29
- * `generateRegistrationOptions()`
30
- * @param expectedOrigin Website URL (or array of URLs) that the registration should have occurred on
31
- * @param expectedRPID RP ID (or array of IDs) that was specified in the registration options
32
- * @param expectedType (Optional) The response type expected ('webauthn.create')
33
- * @param requireUserVerification (Optional) Enforce user verification by the authenticator
34
- * (via PIN, fingerprint, etc...)
35
- * @param supportedAlgorithmIDs Array of numeric COSE algorithm identifiers supported for
36
- * attestation by this RP. See https://www.iana.org/assignments/cose/cose.xhtml#algorithms
27
+ * @param response - Response returned by **@simplewebauthn/browser**'s `startAuthentication()`
28
+ * @param expectedChallenge - The base64url-encoded `options.challenge` returned by `generateRegistrationOptions()`
29
+ * @param expectedOrigin - Website URL (or array of URLs) that the registration should have occurred on
30
+ * @param expectedRPID - RP ID (or array of IDs) that was specified in the registration options
31
+ * @param expectedType **(Optional)** - The response type expected ('webauthn.create')
32
+ * @param requireUserVerification **(Optional)** - Enforce user verification by the authenticator (via PIN, fingerprint, etc...) Defaults to `true`
33
+ * @param supportedAlgorithmIDs **(Optional)** - Array of numeric COSE algorithm identifiers supported for attestation by this RP. See https://www.iana.org/assignments/cose/cose.xhtml#algorithms. Defaults to all supported algorithm IDs
37
34
  */
38
35
  async function verifyRegistrationResponse(options) {
39
36
  const { response, expectedChallenge, expectedOrigin, expectedRPID, expectedType, requireUserVerification = true, supportedAlgorithmIDs = generateRegistrationOptions_js_1.supportedCOSEAlgorithmIdentifiers, } = options;
@@ -197,7 +194,7 @@ async function verifyRegistrationResponse(options) {
197
194
  fmt,
198
195
  counter,
199
196
  aaguid: (0, convertAAGUIDToString_js_1.convertAAGUIDToString)(aaguid),
200
- credentialID,
197
+ credentialID: index_js_1.isoBase64URL.fromBuffer(credentialID),
201
198
  credentialPublicKey,
202
199
  credentialType,
203
200
  attestationObject,