@metamask-previews/passkey-controller 0.0.0-preview-4c0846313

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 (156) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/LICENSE +21 -0
  3. package/README.md +155 -0
  4. package/dist/PasskeyController.cjs +448 -0
  5. package/dist/PasskeyController.cjs.map +1 -0
  6. package/dist/PasskeyController.d.cts +168 -0
  7. package/dist/PasskeyController.d.cts.map +1 -0
  8. package/dist/PasskeyController.d.mts +168 -0
  9. package/dist/PasskeyController.d.mts.map +1 -0
  10. package/dist/PasskeyController.mjs +443 -0
  11. package/dist/PasskeyController.mjs.map +1 -0
  12. package/dist/ceremony-manager.cjs +134 -0
  13. package/dist/ceremony-manager.cjs.map +1 -0
  14. package/dist/ceremony-manager.d.cts +71 -0
  15. package/dist/ceremony-manager.d.cts.map +1 -0
  16. package/dist/ceremony-manager.d.mts +71 -0
  17. package/dist/ceremony-manager.d.mts.map +1 -0
  18. package/dist/ceremony-manager.mjs +130 -0
  19. package/dist/ceremony-manager.mjs.map +1 -0
  20. package/dist/constants.cjs +33 -0
  21. package/dist/constants.cjs.map +1 -0
  22. package/dist/constants.d.cts +30 -0
  23. package/dist/constants.d.cts.map +1 -0
  24. package/dist/constants.d.mts +30 -0
  25. package/dist/constants.d.mts.map +1 -0
  26. package/dist/constants.mjs +30 -0
  27. package/dist/constants.mjs.map +1 -0
  28. package/dist/errors.cjs +57 -0
  29. package/dist/errors.cjs.map +1 -0
  30. package/dist/errors.d.cts +34 -0
  31. package/dist/errors.d.cts.map +1 -0
  32. package/dist/errors.d.mts +34 -0
  33. package/dist/errors.d.mts.map +1 -0
  34. package/dist/errors.mjs +53 -0
  35. package/dist/errors.mjs.map +1 -0
  36. package/dist/index.cjs +19 -0
  37. package/dist/index.cjs.map +1 -0
  38. package/dist/index.d.cts +9 -0
  39. package/dist/index.d.cts.map +1 -0
  40. package/dist/index.d.mts +9 -0
  41. package/dist/index.d.mts.map +1 -0
  42. package/dist/index.mjs +5 -0
  43. package/dist/index.mjs.map +1 -0
  44. package/dist/key-derivation.cjs +76 -0
  45. package/dist/key-derivation.cjs.map +1 -0
  46. package/dist/key-derivation.d.cts +43 -0
  47. package/dist/key-derivation.d.cts.map +1 -0
  48. package/dist/key-derivation.d.mts +43 -0
  49. package/dist/key-derivation.d.mts.map +1 -0
  50. package/dist/key-derivation.mjs +71 -0
  51. package/dist/key-derivation.mjs.map +1 -0
  52. package/dist/logger.cjs +9 -0
  53. package/dist/logger.cjs.map +1 -0
  54. package/dist/logger.d.cts +5 -0
  55. package/dist/logger.d.cts.map +1 -0
  56. package/dist/logger.d.mts +5 -0
  57. package/dist/logger.d.mts.map +1 -0
  58. package/dist/logger.mjs +6 -0
  59. package/dist/logger.mjs.map +1 -0
  60. package/dist/types.cjs +3 -0
  61. package/dist/types.cjs.map +1 -0
  62. package/dist/types.d.cts +92 -0
  63. package/dist/types.d.cts.map +1 -0
  64. package/dist/types.d.mts +92 -0
  65. package/dist/types.d.mts.map +1 -0
  66. package/dist/types.mjs +2 -0
  67. package/dist/types.mjs.map +1 -0
  68. package/dist/utils/crypto.cjs +55 -0
  69. package/dist/utils/crypto.cjs.map +1 -0
  70. package/dist/utils/crypto.d.cts +30 -0
  71. package/dist/utils/crypto.d.cts.map +1 -0
  72. package/dist/utils/crypto.d.mts +30 -0
  73. package/dist/utils/crypto.d.mts.map +1 -0
  74. package/dist/utils/crypto.mjs +49 -0
  75. package/dist/utils/crypto.mjs.map +1 -0
  76. package/dist/utils/encoding.cjs +42 -0
  77. package/dist/utils/encoding.cjs.map +1 -0
  78. package/dist/utils/encoding.d.cts +22 -0
  79. package/dist/utils/encoding.d.cts.map +1 -0
  80. package/dist/utils/encoding.d.mts +22 -0
  81. package/dist/utils/encoding.d.mts.map +1 -0
  82. package/dist/utils/encoding.mjs +36 -0
  83. package/dist/utils/encoding.mjs.map +1 -0
  84. package/dist/webauthn/constants.cjs +74 -0
  85. package/dist/webauthn/constants.cjs.map +1 -0
  86. package/dist/webauthn/constants.d.cts +68 -0
  87. package/dist/webauthn/constants.d.cts.map +1 -0
  88. package/dist/webauthn/constants.d.mts +68 -0
  89. package/dist/webauthn/constants.d.mts.map +1 -0
  90. package/dist/webauthn/constants.mjs +71 -0
  91. package/dist/webauthn/constants.mjs.map +1 -0
  92. package/dist/webauthn/decode-attestation-object.cjs +18 -0
  93. package/dist/webauthn/decode-attestation-object.cjs.map +1 -0
  94. package/dist/webauthn/decode-attestation-object.d.cts +10 -0
  95. package/dist/webauthn/decode-attestation-object.d.cts.map +1 -0
  96. package/dist/webauthn/decode-attestation-object.d.mts +10 -0
  97. package/dist/webauthn/decode-attestation-object.d.mts.map +1 -0
  98. package/dist/webauthn/decode-attestation-object.mjs +14 -0
  99. package/dist/webauthn/decode-attestation-object.mjs.map +1 -0
  100. package/dist/webauthn/decode-client-data-json.cjs +17 -0
  101. package/dist/webauthn/decode-client-data-json.cjs.map +1 -0
  102. package/dist/webauthn/decode-client-data-json.d.cts +9 -0
  103. package/dist/webauthn/decode-client-data-json.d.cts.map +1 -0
  104. package/dist/webauthn/decode-client-data-json.d.mts +9 -0
  105. package/dist/webauthn/decode-client-data-json.d.mts.map +1 -0
  106. package/dist/webauthn/decode-client-data-json.mjs +13 -0
  107. package/dist/webauthn/decode-client-data-json.mjs.map +1 -0
  108. package/dist/webauthn/match-expected-rp-id.cjs +43 -0
  109. package/dist/webauthn/match-expected-rp-id.cjs.map +1 -0
  110. package/dist/webauthn/match-expected-rp-id.d.cts +11 -0
  111. package/dist/webauthn/match-expected-rp-id.d.cts.map +1 -0
  112. package/dist/webauthn/match-expected-rp-id.d.mts +11 -0
  113. package/dist/webauthn/match-expected-rp-id.d.mts.map +1 -0
  114. package/dist/webauthn/match-expected-rp-id.mjs +39 -0
  115. package/dist/webauthn/match-expected-rp-id.mjs.map +1 -0
  116. package/dist/webauthn/parse-authenticator-data.cjs +69 -0
  117. package/dist/webauthn/parse-authenticator-data.cjs.map +1 -0
  118. package/dist/webauthn/parse-authenticator-data.d.cts +10 -0
  119. package/dist/webauthn/parse-authenticator-data.d.cts.map +1 -0
  120. package/dist/webauthn/parse-authenticator-data.d.mts +10 -0
  121. package/dist/webauthn/parse-authenticator-data.d.mts.map +1 -0
  122. package/dist/webauthn/parse-authenticator-data.mjs +65 -0
  123. package/dist/webauthn/parse-authenticator-data.mjs.map +1 -0
  124. package/dist/webauthn/types.cjs +3 -0
  125. package/dist/webauthn/types.cjs.map +1 -0
  126. package/dist/webauthn/types.d.cts +113 -0
  127. package/dist/webauthn/types.d.cts.map +1 -0
  128. package/dist/webauthn/types.d.mts +113 -0
  129. package/dist/webauthn/types.d.mts.map +1 -0
  130. package/dist/webauthn/types.mjs +2 -0
  131. package/dist/webauthn/types.mjs.map +1 -0
  132. package/dist/webauthn/verify-authentication-response.cjs +134 -0
  133. package/dist/webauthn/verify-authentication-response.cjs.map +1 -0
  134. package/dist/webauthn/verify-authentication-response.d.cts +63 -0
  135. package/dist/webauthn/verify-authentication-response.d.cts.map +1 -0
  136. package/dist/webauthn/verify-authentication-response.d.mts +63 -0
  137. package/dist/webauthn/verify-authentication-response.d.mts.map +1 -0
  138. package/dist/webauthn/verify-authentication-response.mjs +130 -0
  139. package/dist/webauthn/verify-authentication-response.mjs.map +1 -0
  140. package/dist/webauthn/verify-registration-response.cjs +205 -0
  141. package/dist/webauthn/verify-registration-response.cjs.map +1 -0
  142. package/dist/webauthn/verify-registration-response.d.cts +60 -0
  143. package/dist/webauthn/verify-registration-response.d.cts.map +1 -0
  144. package/dist/webauthn/verify-registration-response.d.mts +60 -0
  145. package/dist/webauthn/verify-registration-response.d.mts.map +1 -0
  146. package/dist/webauthn/verify-registration-response.mjs +201 -0
  147. package/dist/webauthn/verify-registration-response.mjs.map +1 -0
  148. package/dist/webauthn/verify-signature.cjs +176 -0
  149. package/dist/webauthn/verify-signature.cjs.map +1 -0
  150. package/dist/webauthn/verify-signature.d.cts +21 -0
  151. package/dist/webauthn/verify-signature.d.cts.map +1 -0
  152. package/dist/webauthn/verify-signature.d.mts +21 -0
  153. package/dist/webauthn/verify-signature.d.mts.map +1 -0
  154. package/dist/webauthn/verify-signature.mjs +172 -0
  155. package/dist/webauthn/verify-signature.mjs.map +1 -0
  156. package/package.json +78 -0
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Error class for PasskeyController-related errors.
3
+ */
4
+ export class PasskeyControllerError extends Error {
5
+ /**
6
+ * @param message - The error message.
7
+ * @param options - Error options or an `Error` instance used as `cause` (Keyring-style overload).
8
+ */
9
+ constructor(message, options) {
10
+ super(message);
11
+ this.name = 'PasskeyControllerError';
12
+ const cause = options instanceof Error ? options : options?.cause;
13
+ const code = options instanceof Error ? undefined : options?.code;
14
+ const context = options instanceof Error ? undefined : options?.context;
15
+ if (cause) {
16
+ this.cause = cause;
17
+ }
18
+ if (code) {
19
+ this.code = code;
20
+ }
21
+ if (context) {
22
+ this.context = context;
23
+ }
24
+ Object.setPrototypeOf(this, PasskeyControllerError.prototype);
25
+ }
26
+ toJSON() {
27
+ return {
28
+ name: this.name,
29
+ message: this.message,
30
+ code: this.code,
31
+ context: this.context,
32
+ stack: this.stack,
33
+ cause: this.cause
34
+ ? {
35
+ name: this.cause.name,
36
+ message: this.cause.message,
37
+ stack: this.cause.stack,
38
+ }
39
+ : undefined,
40
+ };
41
+ }
42
+ toString() {
43
+ let result = `${this.name}: ${this.message}`;
44
+ if (this.code) {
45
+ result += ` [${this.code}]`;
46
+ }
47
+ if (this.cause) {
48
+ result += `\n Caused by: ${this.cause}`;
49
+ }
50
+ return result;
51
+ }
52
+ }
53
+ //# sourceMappingURL=errors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.mjs","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAoBA;;GAEG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAO/C;;;OAGG;IACH,YACE,OAAe,EACf,OAA+C;QAE/C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QAErC,MAAM,KAAK,GAAG,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC;QAClE,MAAM,IAAI,GAAG,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC;QAClE,MAAM,OAAO,GAAG,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC;QAExE,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACrB,CAAC;QACD,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACzB,CAAC;QAED,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;IAED,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACf,CAAC,CAAC;oBACE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;oBACrB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;oBAC3B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK;iBACxB;gBACH,CAAC,CAAC,SAAS;SACd,CAAC;IACJ,CAAC;IAEQ,QAAQ;QACf,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;QAC7C,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC;QAC9B,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,kBAAkB,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF","sourcesContent":["import type { PasskeyControllerErrorCode as PasskeyControllerErrorCodeType } from './constants';\n\n/**\n * Options for creating a {@link PasskeyControllerError}.\n */\nexport type PasskeyControllerErrorOptions = {\n /**\n * The underlying error that caused this error (for error chaining).\n */\n cause?: Error;\n /**\n * Stable code for programmatic handling (see {@link PasskeyControllerErrorCode}).\n */\n code?: PasskeyControllerErrorCodeType;\n /**\n * Additional context for debugging or reporting.\n */\n context?: Record<string, unknown>;\n};\n\n/**\n * Error class for PasskeyController-related errors.\n */\nexport class PasskeyControllerError extends Error {\n code?: PasskeyControllerErrorCodeType;\n\n context?: Record<string, unknown>;\n\n cause?: Error;\n\n /**\n * @param message - The error message.\n * @param options - Error options or an `Error` instance used as `cause` (Keyring-style overload).\n */\n constructor(\n message: string,\n options?: PasskeyControllerErrorOptions | Error,\n ) {\n super(message);\n this.name = 'PasskeyControllerError';\n\n const cause = options instanceof Error ? options : options?.cause;\n const code = options instanceof Error ? undefined : options?.code;\n const context = options instanceof Error ? undefined : options?.context;\n\n if (cause) {\n this.cause = cause;\n }\n if (code) {\n this.code = code;\n }\n if (context) {\n this.context = context;\n }\n\n Object.setPrototypeOf(this, PasskeyControllerError.prototype);\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n context: this.context,\n stack: this.stack,\n cause: this.cause\n ? {\n name: this.cause.name,\n message: this.cause.message,\n stack: this.cause.stack,\n }\n : undefined,\n };\n }\n\n override toString(): string {\n let result = `${this.name}: ${this.message}`;\n if (this.code) {\n result += ` [${this.code}]`;\n }\n if (this.cause) {\n result += `\\n Caused by: ${this.cause}`;\n }\n return result;\n }\n}\n"]}
package/dist/index.cjs ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_CONCURRENT_PASSKEY_CEREMONIES = exports.CEREMONY_MAX_AGE_MS = exports.CEREMONY_TTL_SLACK_MS = exports.WEBAUTHN_TIMEOUT_MS = exports.passkeyControllerSelectors = exports.getDefaultPasskeyControllerState = exports.PasskeyController = exports.PasskeyControllerError = exports.PasskeyControllerErrorMessage = exports.PasskeyControllerErrorCode = exports.controllerName = void 0;
4
+ var constants_1 = require("./constants.cjs");
5
+ Object.defineProperty(exports, "controllerName", { enumerable: true, get: function () { return constants_1.controllerName; } });
6
+ Object.defineProperty(exports, "PasskeyControllerErrorCode", { enumerable: true, get: function () { return constants_1.PasskeyControllerErrorCode; } });
7
+ Object.defineProperty(exports, "PasskeyControllerErrorMessage", { enumerable: true, get: function () { return constants_1.PasskeyControllerErrorMessage; } });
8
+ var errors_1 = require("./errors.cjs");
9
+ Object.defineProperty(exports, "PasskeyControllerError", { enumerable: true, get: function () { return errors_1.PasskeyControllerError; } });
10
+ var PasskeyController_1 = require("./PasskeyController.cjs");
11
+ Object.defineProperty(exports, "PasskeyController", { enumerable: true, get: function () { return PasskeyController_1.PasskeyController; } });
12
+ Object.defineProperty(exports, "getDefaultPasskeyControllerState", { enumerable: true, get: function () { return PasskeyController_1.getDefaultPasskeyControllerState; } });
13
+ Object.defineProperty(exports, "passkeyControllerSelectors", { enumerable: true, get: function () { return PasskeyController_1.passkeyControllerSelectors; } });
14
+ var ceremony_manager_1 = require("./ceremony-manager.cjs");
15
+ Object.defineProperty(exports, "WEBAUTHN_TIMEOUT_MS", { enumerable: true, get: function () { return ceremony_manager_1.WEBAUTHN_TIMEOUT_MS; } });
16
+ Object.defineProperty(exports, "CEREMONY_TTL_SLACK_MS", { enumerable: true, get: function () { return ceremony_manager_1.CEREMONY_TTL_SLACK_MS; } });
17
+ Object.defineProperty(exports, "CEREMONY_MAX_AGE_MS", { enumerable: true, get: function () { return ceremony_manager_1.CEREMONY_MAX_AGE_MS; } });
18
+ Object.defineProperty(exports, "MAX_CONCURRENT_PASSKEY_CEREMONIES", { enumerable: true, get: function () { return ceremony_manager_1.MAX_CONCURRENT_PASSKEY_CEREMONIES; } });
19
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,6CAIqB;AAHnB,2GAAA,cAAc,OAAA;AACd,uHAAA,0BAA0B,OAAA;AAC1B,0HAAA,6BAA6B,OAAA;AAE/B,uCAAkD;AAAzC,gHAAA,sBAAsB,OAAA;AAE/B,6DAI6B;AAH3B,sHAAA,iBAAiB,OAAA;AACjB,qIAAA,gCAAgC,OAAA;AAChC,+HAAA,0BAA0B,OAAA;AAE5B,2DAK4B;AAJ1B,uHAAA,mBAAmB,OAAA;AACnB,yHAAA,qBAAqB,OAAA;AACrB,uHAAA,mBAAmB,OAAA;AACnB,qIAAA,iCAAiC,OAAA","sourcesContent":["export {\n controllerName,\n PasskeyControllerErrorCode,\n PasskeyControllerErrorMessage,\n} from './constants';\nexport { PasskeyControllerError } from './errors';\nexport type { PasskeyControllerErrorOptions } from './errors';\nexport {\n PasskeyController,\n getDefaultPasskeyControllerState,\n passkeyControllerSelectors,\n} from './PasskeyController';\nexport {\n WEBAUTHN_TIMEOUT_MS,\n CEREMONY_TTL_SLACK_MS,\n CEREMONY_MAX_AGE_MS,\n MAX_CONCURRENT_PASSKEY_CEREMONIES,\n} from './ceremony-manager';\nexport type {\n PasskeyControllerState,\n PasskeyControllerMessenger,\n PasskeyControllerGetStateAction,\n PasskeyControllerActions,\n PasskeyControllerStateChangedEvent,\n PasskeyControllerEvents,\n} from './PasskeyController';\nexport type {\n EncryptedVaultKey,\n PasskeyCredentialInfo,\n PasskeyDerivationMethod,\n PasskeyKeyDerivation,\n PasskeyRecord,\n PrfEvalExtension,\n PrfClientExtensionResults,\n} from './types';\nexport type {\n PasskeyRegistrationOptions,\n PasskeyRegistrationResponse,\n PasskeyAuthenticationOptions,\n PasskeyAuthenticationResponse,\n PublicKeyCredentialHint,\n} from './webauthn/types';\n"]}
@@ -0,0 +1,9 @@
1
+ export { controllerName, PasskeyControllerErrorCode, PasskeyControllerErrorMessage, } from "./constants.cjs";
2
+ export { PasskeyControllerError } from "./errors.cjs";
3
+ export type { PasskeyControllerErrorOptions } from "./errors.cjs";
4
+ export { PasskeyController, getDefaultPasskeyControllerState, passkeyControllerSelectors, } from "./PasskeyController.cjs";
5
+ export { WEBAUTHN_TIMEOUT_MS, CEREMONY_TTL_SLACK_MS, CEREMONY_MAX_AGE_MS, MAX_CONCURRENT_PASSKEY_CEREMONIES, } from "./ceremony-manager.cjs";
6
+ export type { PasskeyControllerState, PasskeyControllerMessenger, PasskeyControllerGetStateAction, PasskeyControllerActions, PasskeyControllerStateChangedEvent, PasskeyControllerEvents, } from "./PasskeyController.cjs";
7
+ export type { EncryptedVaultKey, PasskeyCredentialInfo, PasskeyDerivationMethod, PasskeyKeyDerivation, PasskeyRecord, PrfEvalExtension, PrfClientExtensionResults, } from "./types.cjs";
8
+ export type { PasskeyRegistrationOptions, PasskeyRegistrationResponse, PasskeyAuthenticationOptions, PasskeyAuthenticationResponse, PublicKeyCredentialHint, } from "./webauthn/types.cjs";
9
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,6BAA6B,GAC9B,wBAAoB;AACrB,OAAO,EAAE,sBAAsB,EAAE,qBAAiB;AAClD,YAAY,EAAE,6BAA6B,EAAE,qBAAiB;AAC9D,OAAO,EACL,iBAAiB,EACjB,gCAAgC,EAChC,0BAA0B,GAC3B,gCAA4B;AAC7B,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,iCAAiC,GAClC,+BAA2B;AAC5B,YAAY,EACV,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,EAC/B,wBAAwB,EACxB,kCAAkC,EAClC,uBAAuB,GACxB,gCAA4B;AAC7B,YAAY,EACV,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,yBAAyB,GAC1B,oBAAgB;AACjB,YAAY,EACV,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC5B,6BAA6B,EAC7B,uBAAuB,GACxB,6BAAyB"}
@@ -0,0 +1,9 @@
1
+ export { controllerName, PasskeyControllerErrorCode, PasskeyControllerErrorMessage, } from "./constants.mjs";
2
+ export { PasskeyControllerError } from "./errors.mjs";
3
+ export type { PasskeyControllerErrorOptions } from "./errors.mjs";
4
+ export { PasskeyController, getDefaultPasskeyControllerState, passkeyControllerSelectors, } from "./PasskeyController.mjs";
5
+ export { WEBAUTHN_TIMEOUT_MS, CEREMONY_TTL_SLACK_MS, CEREMONY_MAX_AGE_MS, MAX_CONCURRENT_PASSKEY_CEREMONIES, } from "./ceremony-manager.mjs";
6
+ export type { PasskeyControllerState, PasskeyControllerMessenger, PasskeyControllerGetStateAction, PasskeyControllerActions, PasskeyControllerStateChangedEvent, PasskeyControllerEvents, } from "./PasskeyController.mjs";
7
+ export type { EncryptedVaultKey, PasskeyCredentialInfo, PasskeyDerivationMethod, PasskeyKeyDerivation, PasskeyRecord, PrfEvalExtension, PrfClientExtensionResults, } from "./types.mjs";
8
+ export type { PasskeyRegistrationOptions, PasskeyRegistrationResponse, PasskeyAuthenticationOptions, PasskeyAuthenticationResponse, PublicKeyCredentialHint, } from "./webauthn/types.mjs";
9
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,6BAA6B,GAC9B,wBAAoB;AACrB,OAAO,EAAE,sBAAsB,EAAE,qBAAiB;AAClD,YAAY,EAAE,6BAA6B,EAAE,qBAAiB;AAC9D,OAAO,EACL,iBAAiB,EACjB,gCAAgC,EAChC,0BAA0B,GAC3B,gCAA4B;AAC7B,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,iCAAiC,GAClC,+BAA2B;AAC5B,YAAY,EACV,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,EAC/B,wBAAwB,EACxB,kCAAkC,EAClC,uBAAuB,GACxB,gCAA4B;AAC7B,YAAY,EACV,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,yBAAyB,GAC1B,oBAAgB;AACjB,YAAY,EACV,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC5B,6BAA6B,EAC7B,uBAAuB,GACxB,6BAAyB"}
package/dist/index.mjs ADDED
@@ -0,0 +1,5 @@
1
+ export { controllerName, PasskeyControllerErrorCode, PasskeyControllerErrorMessage } from "./constants.mjs";
2
+ export { PasskeyControllerError } from "./errors.mjs";
3
+ export { PasskeyController, getDefaultPasskeyControllerState, passkeyControllerSelectors } from "./PasskeyController.mjs";
4
+ export { WEBAUTHN_TIMEOUT_MS, CEREMONY_TTL_SLACK_MS, CEREMONY_MAX_AGE_MS, MAX_CONCURRENT_PASSKEY_CEREMONIES } from "./ceremony-manager.mjs";
5
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,6BAA6B,EAC9B,wBAAoB;AACrB,OAAO,EAAE,sBAAsB,EAAE,qBAAiB;AAElD,OAAO,EACL,iBAAiB,EACjB,gCAAgC,EAChC,0BAA0B,EAC3B,gCAA4B;AAC7B,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,iCAAiC,EAClC,+BAA2B","sourcesContent":["export {\n controllerName,\n PasskeyControllerErrorCode,\n PasskeyControllerErrorMessage,\n} from './constants';\nexport { PasskeyControllerError } from './errors';\nexport type { PasskeyControllerErrorOptions } from './errors';\nexport {\n PasskeyController,\n getDefaultPasskeyControllerState,\n passkeyControllerSelectors,\n} from './PasskeyController';\nexport {\n WEBAUTHN_TIMEOUT_MS,\n CEREMONY_TTL_SLACK_MS,\n CEREMONY_MAX_AGE_MS,\n MAX_CONCURRENT_PASSKEY_CEREMONIES,\n} from './ceremony-manager';\nexport type {\n PasskeyControllerState,\n PasskeyControllerMessenger,\n PasskeyControllerGetStateAction,\n PasskeyControllerActions,\n PasskeyControllerStateChangedEvent,\n PasskeyControllerEvents,\n} from './PasskeyController';\nexport type {\n EncryptedVaultKey,\n PasskeyCredentialInfo,\n PasskeyDerivationMethod,\n PasskeyKeyDerivation,\n PasskeyRecord,\n PrfEvalExtension,\n PrfClientExtensionResults,\n} from './types';\nexport type {\n PasskeyRegistrationOptions,\n PasskeyRegistrationResponse,\n PasskeyAuthenticationOptions,\n PasskeyAuthenticationResponse,\n PublicKeyCredentialHint,\n} from './webauthn/types';\n"]}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deriveKeyFromAuthenticationResponse = exports.deriveKeyFromRegistrationResponse = void 0;
4
+ const constants_1 = require("./constants.cjs");
5
+ const errors_1 = require("./errors.cjs");
6
+ const crypto_1 = require("./utils/crypto.cjs");
7
+ const encoding_1 = require("./utils/encoding.cjs");
8
+ /**
9
+ * Derives an AES-256 wrapping key from a WebAuthn registration ceremony
10
+ * response.
11
+ *
12
+ * Uses the PRF output as HKDF input key material when
13
+ * `clientExtensionResults.prf.results.first` is a non-empty string;
14
+ * otherwise falls back to the random `userHandle` created during option
15
+ * generation (including when PRF is enabled but no output is present).
16
+ *
17
+ * @param registrationResponse - The registration credential result from
18
+ * `navigator.credentials.create()`.
19
+ * @param registrationCeremony - In-flight registration ceremony state from
20
+ * when `generateRegistrationOptions()` was called.
21
+ * @param verifiedCredentialId - Base64url credential id from verified
22
+ * authenticator data (same value as persisted `credential.id` after
23
+ * `verifyRegistrationResponse`), not the client wrapper field alone.
24
+ * @returns The derived 32-byte AES wrapping key and the
25
+ * {@link PasskeyKeyDerivation} parameters needed to reproduce it.
26
+ */
27
+ function deriveKeyFromRegistrationResponse(registrationResponse, registrationCeremony, verifiedCredentialId) {
28
+ const prfFirst = registrationResponse.clientExtensionResults?.prf?.results?.first;
29
+ const hasPrfOutput = typeof prfFirst === 'string' && prfFirst.length > 0;
30
+ const keyDerivation = hasPrfOutput
31
+ ? { method: 'prf', prfSalt: registrationCeremony.prfSalt }
32
+ : { method: 'userHandle' };
33
+ const ikm = keyDerivation.method === 'prf'
34
+ ? (0, encoding_1.base64URLToBytes)(prfFirst)
35
+ : (0, encoding_1.base64URLToBytes)(registrationCeremony.userHandle);
36
+ const encKey = (0, crypto_1.deriveEncryptionKey)(ikm, (0, encoding_1.base64URLToBytes)(verifiedCredentialId));
37
+ return { encKey, keyDerivation };
38
+ }
39
+ exports.deriveKeyFromRegistrationResponse = deriveKeyFromRegistrationResponse;
40
+ /**
41
+ * Derives an AES-256 wrapping key from a WebAuthn authentication ceremony
42
+ * response.
43
+ *
44
+ * The derivation method is determined by `record.keyDerivation`:
45
+ * - `prf` -- uses the PRF evaluation result from `clientExtensionResults`.
46
+ * - `userHandle` -- uses the `userHandle` returned in the assertion.
47
+ *
48
+ * @param authenticationResponse - The authentication credential result
49
+ * from `navigator.credentials.get()`.
50
+ * @param record - The persisted passkey record that was created during
51
+ * enrollment.
52
+ * @returns The derived 32-byte AES wrapping key.
53
+ * @throws {@link PasskeyControllerError} with code `missing_key_material` if the
54
+ * required key material (PRF result or userHandle) is missing from the response.
55
+ */
56
+ function deriveKeyFromAuthenticationResponse(authenticationResponse, record) {
57
+ const { userHandle } = authenticationResponse.response;
58
+ const prfFirst = authenticationResponse.clientExtensionResults?.prf?.results?.first;
59
+ const hasPrfOutput = typeof prfFirst === 'string' && prfFirst.length > 0;
60
+ let ikm;
61
+ if (record.keyDerivation.method === 'prf') {
62
+ if (!hasPrfOutput) {
63
+ throw new errors_1.PasskeyControllerError(constants_1.PasskeyControllerErrorMessage.MissingKeyMaterial, { code: constants_1.PasskeyControllerErrorCode.MissingKeyMaterial });
64
+ }
65
+ ikm = (0, encoding_1.base64URLToBytes)(prfFirst);
66
+ }
67
+ else if (userHandle) {
68
+ ikm = (0, encoding_1.base64URLToBytes)(userHandle);
69
+ }
70
+ else {
71
+ throw new errors_1.PasskeyControllerError(constants_1.PasskeyControllerErrorMessage.MissingKeyMaterial, { code: constants_1.PasskeyControllerErrorCode.MissingKeyMaterial });
72
+ }
73
+ return (0, crypto_1.deriveEncryptionKey)(ikm, (0, encoding_1.base64URLToBytes)(record.credential.id));
74
+ }
75
+ exports.deriveKeyFromAuthenticationResponse = deriveKeyFromAuthenticationResponse;
76
+ //# sourceMappingURL=key-derivation.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-derivation.cjs","sourceRoot":"","sources":["../src/key-derivation.ts"],"names":[],"mappings":";;;AAAA,+CAGqB;AACrB,yCAAkD;AAOlD,+CAAqD;AACrD,mDAAoD;AAMpD;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,iCAAiC,CAC/C,oBAAiD,EACjD,oBAAiD,EACjD,oBAA4B;IAK5B,MAAM,QAAQ,GACZ,oBAAoB,CAAC,sBACtB,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC;IACvB,MAAM,YAAY,GAAG,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAEzE,MAAM,aAAa,GAAyB,YAAY;QACtD,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,oBAAoB,CAAC,OAAO,EAAE;QAC1D,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAC7B,MAAM,GAAG,GACP,aAAa,CAAC,MAAM,KAAK,KAAK;QAC5B,CAAC,CAAC,IAAA,2BAAgB,EAAC,QAAkB,CAAC;QACtC,CAAC,CAAC,IAAA,2BAAgB,EAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,IAAA,4BAAmB,EAChC,GAAG,EACH,IAAA,2BAAgB,EAAC,oBAAoB,CAAC,CACvC,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AACnC,CAAC;AA1BD,8EA0BC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,mCAAmC,CACjD,sBAAqD,EACrD,MAAqB;IAErB,MAAM,EAAE,UAAU,EAAE,GAAG,sBAAsB,CAAC,QAAQ,CAAC;IACvD,MAAM,QAAQ,GACZ,sBAAsB,CAAC,sBACxB,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC;IACvB,MAAM,YAAY,GAAG,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAEzE,IAAI,GAAe,CAAC;IACpB,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC1C,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,+BAAsB,CAC9B,yCAA6B,CAAC,kBAAkB,EAChD,EAAE,IAAI,EAAE,sCAA0B,CAAC,kBAAkB,EAAE,CACxD,CAAC;QACJ,CAAC;QACD,GAAG,GAAG,IAAA,2BAAgB,EAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;SAAM,IAAI,UAAU,EAAE,CAAC;QACtB,GAAG,GAAG,IAAA,2BAAgB,EAAC,UAAU,CAAC,CAAC;IACrC,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,+BAAsB,CAC9B,yCAA6B,CAAC,kBAAkB,EAChD,EAAE,IAAI,EAAE,sCAA0B,CAAC,kBAAkB,EAAE,CACxD,CAAC;IACJ,CAAC;IAED,OAAO,IAAA,4BAAmB,EAAC,GAAG,EAAE,IAAA,2BAAgB,EAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;AAC1E,CAAC;AA7BD,kFA6BC","sourcesContent":["import {\n PasskeyControllerErrorCode,\n PasskeyControllerErrorMessage,\n} from './constants';\nimport { PasskeyControllerError } from './errors';\nimport type {\n PasskeyKeyDerivation,\n PasskeyRecord,\n PasskeyRegistrationCeremony,\n PrfClientExtensionResults,\n} from './types';\nimport { deriveEncryptionKey } from './utils/crypto';\nimport { base64URLToBytes } from './utils/encoding';\nimport type {\n PasskeyAuthenticationResponse,\n PasskeyRegistrationResponse,\n} from './webauthn/types';\n\n/**\n * Derives an AES-256 wrapping key from a WebAuthn registration ceremony\n * response.\n *\n * Uses the PRF output as HKDF input key material when\n * `clientExtensionResults.prf.results.first` is a non-empty string;\n * otherwise falls back to the random `userHandle` created during option\n * generation (including when PRF is enabled but no output is present).\n *\n * @param registrationResponse - The registration credential result from\n * `navigator.credentials.create()`.\n * @param registrationCeremony - In-flight registration ceremony state from\n * when `generateRegistrationOptions()` was called.\n * @param verifiedCredentialId - Base64url credential id from verified\n * authenticator data (same value as persisted `credential.id` after\n * `verifyRegistrationResponse`), not the client wrapper field alone.\n * @returns The derived 32-byte AES wrapping key and the\n * {@link PasskeyKeyDerivation} parameters needed to reproduce it.\n */\nexport function deriveKeyFromRegistrationResponse(\n registrationResponse: PasskeyRegistrationResponse,\n registrationCeremony: PasskeyRegistrationCeremony,\n verifiedCredentialId: string,\n): {\n encKey: Uint8Array;\n keyDerivation: PasskeyKeyDerivation;\n} {\n const prfFirst = (\n registrationResponse.clientExtensionResults as PrfClientExtensionResults\n )?.prf?.results?.first;\n const hasPrfOutput = typeof prfFirst === 'string' && prfFirst.length > 0;\n\n const keyDerivation: PasskeyKeyDerivation = hasPrfOutput\n ? { method: 'prf', prfSalt: registrationCeremony.prfSalt }\n : { method: 'userHandle' };\n const ikm =\n keyDerivation.method === 'prf'\n ? base64URLToBytes(prfFirst as string)\n : base64URLToBytes(registrationCeremony.userHandle);\n const encKey = deriveEncryptionKey(\n ikm,\n base64URLToBytes(verifiedCredentialId),\n );\n\n return { encKey, keyDerivation };\n}\n\n/**\n * Derives an AES-256 wrapping key from a WebAuthn authentication ceremony\n * response.\n *\n * The derivation method is determined by `record.keyDerivation`:\n * - `prf` -- uses the PRF evaluation result from `clientExtensionResults`.\n * - `userHandle` -- uses the `userHandle` returned in the assertion.\n *\n * @param authenticationResponse - The authentication credential result\n * from `navigator.credentials.get()`.\n * @param record - The persisted passkey record that was created during\n * enrollment.\n * @returns The derived 32-byte AES wrapping key.\n * @throws {@link PasskeyControllerError} with code `missing_key_material` if the\n * required key material (PRF result or userHandle) is missing from the response.\n */\nexport function deriveKeyFromAuthenticationResponse(\n authenticationResponse: PasskeyAuthenticationResponse,\n record: PasskeyRecord,\n): Uint8Array {\n const { userHandle } = authenticationResponse.response;\n const prfFirst = (\n authenticationResponse.clientExtensionResults as PrfClientExtensionResults\n )?.prf?.results?.first;\n const hasPrfOutput = typeof prfFirst === 'string' && prfFirst.length > 0;\n\n let ikm: Uint8Array;\n if (record.keyDerivation.method === 'prf') {\n if (!hasPrfOutput) {\n throw new PasskeyControllerError(\n PasskeyControllerErrorMessage.MissingKeyMaterial,\n { code: PasskeyControllerErrorCode.MissingKeyMaterial },\n );\n }\n ikm = base64URLToBytes(prfFirst);\n } else if (userHandle) {\n ikm = base64URLToBytes(userHandle);\n } else {\n throw new PasskeyControllerError(\n PasskeyControllerErrorMessage.MissingKeyMaterial,\n { code: PasskeyControllerErrorCode.MissingKeyMaterial },\n );\n }\n\n return deriveEncryptionKey(ikm, base64URLToBytes(record.credential.id));\n}\n"]}
@@ -0,0 +1,43 @@
1
+ import type { PasskeyKeyDerivation, PasskeyRecord, PasskeyRegistrationCeremony } from "./types.cjs";
2
+ import type { PasskeyAuthenticationResponse, PasskeyRegistrationResponse } from "./webauthn/types.cjs";
3
+ /**
4
+ * Derives an AES-256 wrapping key from a WebAuthn registration ceremony
5
+ * response.
6
+ *
7
+ * Uses the PRF output as HKDF input key material when
8
+ * `clientExtensionResults.prf.results.first` is a non-empty string;
9
+ * otherwise falls back to the random `userHandle` created during option
10
+ * generation (including when PRF is enabled but no output is present).
11
+ *
12
+ * @param registrationResponse - The registration credential result from
13
+ * `navigator.credentials.create()`.
14
+ * @param registrationCeremony - In-flight registration ceremony state from
15
+ * when `generateRegistrationOptions()` was called.
16
+ * @param verifiedCredentialId - Base64url credential id from verified
17
+ * authenticator data (same value as persisted `credential.id` after
18
+ * `verifyRegistrationResponse`), not the client wrapper field alone.
19
+ * @returns The derived 32-byte AES wrapping key and the
20
+ * {@link PasskeyKeyDerivation} parameters needed to reproduce it.
21
+ */
22
+ export declare function deriveKeyFromRegistrationResponse(registrationResponse: PasskeyRegistrationResponse, registrationCeremony: PasskeyRegistrationCeremony, verifiedCredentialId: string): {
23
+ encKey: Uint8Array;
24
+ keyDerivation: PasskeyKeyDerivation;
25
+ };
26
+ /**
27
+ * Derives an AES-256 wrapping key from a WebAuthn authentication ceremony
28
+ * response.
29
+ *
30
+ * The derivation method is determined by `record.keyDerivation`:
31
+ * - `prf` -- uses the PRF evaluation result from `clientExtensionResults`.
32
+ * - `userHandle` -- uses the `userHandle` returned in the assertion.
33
+ *
34
+ * @param authenticationResponse - The authentication credential result
35
+ * from `navigator.credentials.get()`.
36
+ * @param record - The persisted passkey record that was created during
37
+ * enrollment.
38
+ * @returns The derived 32-byte AES wrapping key.
39
+ * @throws {@link PasskeyControllerError} with code `missing_key_material` if the
40
+ * required key material (PRF result or userHandle) is missing from the response.
41
+ */
42
+ export declare function deriveKeyFromAuthenticationResponse(authenticationResponse: PasskeyAuthenticationResponse, record: PasskeyRecord): Uint8Array;
43
+ //# sourceMappingURL=key-derivation.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-derivation.d.cts","sourceRoot":"","sources":["../src/key-derivation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,2BAA2B,EAE5B,oBAAgB;AAGjB,OAAO,KAAK,EACV,6BAA6B,EAC7B,2BAA2B,EAC5B,6BAAyB;AAE1B;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iCAAiC,CAC/C,oBAAoB,EAAE,2BAA2B,EACjD,oBAAoB,EAAE,2BAA2B,EACjD,oBAAoB,EAAE,MAAM,GAC3B;IACD,MAAM,EAAE,UAAU,CAAC;IACnB,aAAa,EAAE,oBAAoB,CAAC;CACrC,CAmBA;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mCAAmC,CACjD,sBAAsB,EAAE,6BAA6B,EACrD,MAAM,EAAE,aAAa,GACpB,UAAU,CA0BZ"}
@@ -0,0 +1,43 @@
1
+ import type { PasskeyKeyDerivation, PasskeyRecord, PasskeyRegistrationCeremony } from "./types.mjs";
2
+ import type { PasskeyAuthenticationResponse, PasskeyRegistrationResponse } from "./webauthn/types.mjs";
3
+ /**
4
+ * Derives an AES-256 wrapping key from a WebAuthn registration ceremony
5
+ * response.
6
+ *
7
+ * Uses the PRF output as HKDF input key material when
8
+ * `clientExtensionResults.prf.results.first` is a non-empty string;
9
+ * otherwise falls back to the random `userHandle` created during option
10
+ * generation (including when PRF is enabled but no output is present).
11
+ *
12
+ * @param registrationResponse - The registration credential result from
13
+ * `navigator.credentials.create()`.
14
+ * @param registrationCeremony - In-flight registration ceremony state from
15
+ * when `generateRegistrationOptions()` was called.
16
+ * @param verifiedCredentialId - Base64url credential id from verified
17
+ * authenticator data (same value as persisted `credential.id` after
18
+ * `verifyRegistrationResponse`), not the client wrapper field alone.
19
+ * @returns The derived 32-byte AES wrapping key and the
20
+ * {@link PasskeyKeyDerivation} parameters needed to reproduce it.
21
+ */
22
+ export declare function deriveKeyFromRegistrationResponse(registrationResponse: PasskeyRegistrationResponse, registrationCeremony: PasskeyRegistrationCeremony, verifiedCredentialId: string): {
23
+ encKey: Uint8Array;
24
+ keyDerivation: PasskeyKeyDerivation;
25
+ };
26
+ /**
27
+ * Derives an AES-256 wrapping key from a WebAuthn authentication ceremony
28
+ * response.
29
+ *
30
+ * The derivation method is determined by `record.keyDerivation`:
31
+ * - `prf` -- uses the PRF evaluation result from `clientExtensionResults`.
32
+ * - `userHandle` -- uses the `userHandle` returned in the assertion.
33
+ *
34
+ * @param authenticationResponse - The authentication credential result
35
+ * from `navigator.credentials.get()`.
36
+ * @param record - The persisted passkey record that was created during
37
+ * enrollment.
38
+ * @returns The derived 32-byte AES wrapping key.
39
+ * @throws {@link PasskeyControllerError} with code `missing_key_material` if the
40
+ * required key material (PRF result or userHandle) is missing from the response.
41
+ */
42
+ export declare function deriveKeyFromAuthenticationResponse(authenticationResponse: PasskeyAuthenticationResponse, record: PasskeyRecord): Uint8Array;
43
+ //# sourceMappingURL=key-derivation.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-derivation.d.mts","sourceRoot":"","sources":["../src/key-derivation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,2BAA2B,EAE5B,oBAAgB;AAGjB,OAAO,KAAK,EACV,6BAA6B,EAC7B,2BAA2B,EAC5B,6BAAyB;AAE1B;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iCAAiC,CAC/C,oBAAoB,EAAE,2BAA2B,EACjD,oBAAoB,EAAE,2BAA2B,EACjD,oBAAoB,EAAE,MAAM,GAC3B;IACD,MAAM,EAAE,UAAU,CAAC;IACnB,aAAa,EAAE,oBAAoB,CAAC;CACrC,CAmBA;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mCAAmC,CACjD,sBAAsB,EAAE,6BAA6B,EACrD,MAAM,EAAE,aAAa,GACpB,UAAU,CA0BZ"}
@@ -0,0 +1,71 @@
1
+ import { PasskeyControllerErrorCode, PasskeyControllerErrorMessage } from "./constants.mjs";
2
+ import { PasskeyControllerError } from "./errors.mjs";
3
+ import { deriveEncryptionKey } from "./utils/crypto.mjs";
4
+ import { base64URLToBytes } from "./utils/encoding.mjs";
5
+ /**
6
+ * Derives an AES-256 wrapping key from a WebAuthn registration ceremony
7
+ * response.
8
+ *
9
+ * Uses the PRF output as HKDF input key material when
10
+ * `clientExtensionResults.prf.results.first` is a non-empty string;
11
+ * otherwise falls back to the random `userHandle` created during option
12
+ * generation (including when PRF is enabled but no output is present).
13
+ *
14
+ * @param registrationResponse - The registration credential result from
15
+ * `navigator.credentials.create()`.
16
+ * @param registrationCeremony - In-flight registration ceremony state from
17
+ * when `generateRegistrationOptions()` was called.
18
+ * @param verifiedCredentialId - Base64url credential id from verified
19
+ * authenticator data (same value as persisted `credential.id` after
20
+ * `verifyRegistrationResponse`), not the client wrapper field alone.
21
+ * @returns The derived 32-byte AES wrapping key and the
22
+ * {@link PasskeyKeyDerivation} parameters needed to reproduce it.
23
+ */
24
+ export function deriveKeyFromRegistrationResponse(registrationResponse, registrationCeremony, verifiedCredentialId) {
25
+ const prfFirst = registrationResponse.clientExtensionResults?.prf?.results?.first;
26
+ const hasPrfOutput = typeof prfFirst === 'string' && prfFirst.length > 0;
27
+ const keyDerivation = hasPrfOutput
28
+ ? { method: 'prf', prfSalt: registrationCeremony.prfSalt }
29
+ : { method: 'userHandle' };
30
+ const ikm = keyDerivation.method === 'prf'
31
+ ? base64URLToBytes(prfFirst)
32
+ : base64URLToBytes(registrationCeremony.userHandle);
33
+ const encKey = deriveEncryptionKey(ikm, base64URLToBytes(verifiedCredentialId));
34
+ return { encKey, keyDerivation };
35
+ }
36
+ /**
37
+ * Derives an AES-256 wrapping key from a WebAuthn authentication ceremony
38
+ * response.
39
+ *
40
+ * The derivation method is determined by `record.keyDerivation`:
41
+ * - `prf` -- uses the PRF evaluation result from `clientExtensionResults`.
42
+ * - `userHandle` -- uses the `userHandle` returned in the assertion.
43
+ *
44
+ * @param authenticationResponse - The authentication credential result
45
+ * from `navigator.credentials.get()`.
46
+ * @param record - The persisted passkey record that was created during
47
+ * enrollment.
48
+ * @returns The derived 32-byte AES wrapping key.
49
+ * @throws {@link PasskeyControllerError} with code `missing_key_material` if the
50
+ * required key material (PRF result or userHandle) is missing from the response.
51
+ */
52
+ export function deriveKeyFromAuthenticationResponse(authenticationResponse, record) {
53
+ const { userHandle } = authenticationResponse.response;
54
+ const prfFirst = authenticationResponse.clientExtensionResults?.prf?.results?.first;
55
+ const hasPrfOutput = typeof prfFirst === 'string' && prfFirst.length > 0;
56
+ let ikm;
57
+ if (record.keyDerivation.method === 'prf') {
58
+ if (!hasPrfOutput) {
59
+ throw new PasskeyControllerError(PasskeyControllerErrorMessage.MissingKeyMaterial, { code: PasskeyControllerErrorCode.MissingKeyMaterial });
60
+ }
61
+ ikm = base64URLToBytes(prfFirst);
62
+ }
63
+ else if (userHandle) {
64
+ ikm = base64URLToBytes(userHandle);
65
+ }
66
+ else {
67
+ throw new PasskeyControllerError(PasskeyControllerErrorMessage.MissingKeyMaterial, { code: PasskeyControllerErrorCode.MissingKeyMaterial });
68
+ }
69
+ return deriveEncryptionKey(ikm, base64URLToBytes(record.credential.id));
70
+ }
71
+ //# sourceMappingURL=key-derivation.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-derivation.mjs","sourceRoot":"","sources":["../src/key-derivation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,6BAA6B,EAC9B,wBAAoB;AACrB,OAAO,EAAE,sBAAsB,EAAE,qBAAiB;AAOlD,OAAO,EAAE,mBAAmB,EAAE,2BAAuB;AACrD,OAAO,EAAE,gBAAgB,EAAE,6BAAyB;AAMpD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,iCAAiC,CAC/C,oBAAiD,EACjD,oBAAiD,EACjD,oBAA4B;IAK5B,MAAM,QAAQ,GACZ,oBAAoB,CAAC,sBACtB,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC;IACvB,MAAM,YAAY,GAAG,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAEzE,MAAM,aAAa,GAAyB,YAAY;QACtD,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,oBAAoB,CAAC,OAAO,EAAE;QAC1D,CAAC,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAC7B,MAAM,GAAG,GACP,aAAa,CAAC,MAAM,KAAK,KAAK;QAC5B,CAAC,CAAC,gBAAgB,CAAC,QAAkB,CAAC;QACtC,CAAC,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,mBAAmB,CAChC,GAAG,EACH,gBAAgB,CAAC,oBAAoB,CAAC,CACvC,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,mCAAmC,CACjD,sBAAqD,EACrD,MAAqB;IAErB,MAAM,EAAE,UAAU,EAAE,GAAG,sBAAsB,CAAC,QAAQ,CAAC;IACvD,MAAM,QAAQ,GACZ,sBAAsB,CAAC,sBACxB,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC;IACvB,MAAM,YAAY,GAAG,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAEzE,IAAI,GAAe,CAAC;IACpB,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC1C,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,sBAAsB,CAC9B,6BAA6B,CAAC,kBAAkB,EAChD,EAAE,IAAI,EAAE,0BAA0B,CAAC,kBAAkB,EAAE,CACxD,CAAC;QACJ,CAAC;QACD,GAAG,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;SAAM,IAAI,UAAU,EAAE,CAAC;QACtB,GAAG,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,sBAAsB,CAC9B,6BAA6B,CAAC,kBAAkB,EAChD,EAAE,IAAI,EAAE,0BAA0B,CAAC,kBAAkB,EAAE,CACxD,CAAC;IACJ,CAAC;IAED,OAAO,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;AAC1E,CAAC","sourcesContent":["import {\n PasskeyControllerErrorCode,\n PasskeyControllerErrorMessage,\n} from './constants';\nimport { PasskeyControllerError } from './errors';\nimport type {\n PasskeyKeyDerivation,\n PasskeyRecord,\n PasskeyRegistrationCeremony,\n PrfClientExtensionResults,\n} from './types';\nimport { deriveEncryptionKey } from './utils/crypto';\nimport { base64URLToBytes } from './utils/encoding';\nimport type {\n PasskeyAuthenticationResponse,\n PasskeyRegistrationResponse,\n} from './webauthn/types';\n\n/**\n * Derives an AES-256 wrapping key from a WebAuthn registration ceremony\n * response.\n *\n * Uses the PRF output as HKDF input key material when\n * `clientExtensionResults.prf.results.first` is a non-empty string;\n * otherwise falls back to the random `userHandle` created during option\n * generation (including when PRF is enabled but no output is present).\n *\n * @param registrationResponse - The registration credential result from\n * `navigator.credentials.create()`.\n * @param registrationCeremony - In-flight registration ceremony state from\n * when `generateRegistrationOptions()` was called.\n * @param verifiedCredentialId - Base64url credential id from verified\n * authenticator data (same value as persisted `credential.id` after\n * `verifyRegistrationResponse`), not the client wrapper field alone.\n * @returns The derived 32-byte AES wrapping key and the\n * {@link PasskeyKeyDerivation} parameters needed to reproduce it.\n */\nexport function deriveKeyFromRegistrationResponse(\n registrationResponse: PasskeyRegistrationResponse,\n registrationCeremony: PasskeyRegistrationCeremony,\n verifiedCredentialId: string,\n): {\n encKey: Uint8Array;\n keyDerivation: PasskeyKeyDerivation;\n} {\n const prfFirst = (\n registrationResponse.clientExtensionResults as PrfClientExtensionResults\n )?.prf?.results?.first;\n const hasPrfOutput = typeof prfFirst === 'string' && prfFirst.length > 0;\n\n const keyDerivation: PasskeyKeyDerivation = hasPrfOutput\n ? { method: 'prf', prfSalt: registrationCeremony.prfSalt }\n : { method: 'userHandle' };\n const ikm =\n keyDerivation.method === 'prf'\n ? base64URLToBytes(prfFirst as string)\n : base64URLToBytes(registrationCeremony.userHandle);\n const encKey = deriveEncryptionKey(\n ikm,\n base64URLToBytes(verifiedCredentialId),\n );\n\n return { encKey, keyDerivation };\n}\n\n/**\n * Derives an AES-256 wrapping key from a WebAuthn authentication ceremony\n * response.\n *\n * The derivation method is determined by `record.keyDerivation`:\n * - `prf` -- uses the PRF evaluation result from `clientExtensionResults`.\n * - `userHandle` -- uses the `userHandle` returned in the assertion.\n *\n * @param authenticationResponse - The authentication credential result\n * from `navigator.credentials.get()`.\n * @param record - The persisted passkey record that was created during\n * enrollment.\n * @returns The derived 32-byte AES wrapping key.\n * @throws {@link PasskeyControllerError} with code `missing_key_material` if the\n * required key material (PRF result or userHandle) is missing from the response.\n */\nexport function deriveKeyFromAuthenticationResponse(\n authenticationResponse: PasskeyAuthenticationResponse,\n record: PasskeyRecord,\n): Uint8Array {\n const { userHandle } = authenticationResponse.response;\n const prfFirst = (\n authenticationResponse.clientExtensionResults as PrfClientExtensionResults\n )?.prf?.results?.first;\n const hasPrfOutput = typeof prfFirst === 'string' && prfFirst.length > 0;\n\n let ikm: Uint8Array;\n if (record.keyDerivation.method === 'prf') {\n if (!hasPrfOutput) {\n throw new PasskeyControllerError(\n PasskeyControllerErrorMessage.MissingKeyMaterial,\n { code: PasskeyControllerErrorCode.MissingKeyMaterial },\n );\n }\n ikm = base64URLToBytes(prfFirst);\n } else if (userHandle) {\n ikm = base64URLToBytes(userHandle);\n } else {\n throw new PasskeyControllerError(\n PasskeyControllerErrorMessage.MissingKeyMaterial,\n { code: PasskeyControllerErrorCode.MissingKeyMaterial },\n );\n }\n\n return deriveEncryptionKey(ikm, base64URLToBytes(record.credential.id));\n}\n"]}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ /* istanbul ignore file */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.createModuleLogger = exports.projectLogger = void 0;
5
+ const utils_1 = require("@metamask/utils");
6
+ Object.defineProperty(exports, "createModuleLogger", { enumerable: true, get: function () { return utils_1.createModuleLogger; } });
7
+ const constants_1 = require("./constants.cjs");
8
+ exports.projectLogger = (0, utils_1.createProjectLogger)(constants_1.controllerName);
9
+ //# sourceMappingURL=logger.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.cjs","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";AAAA,0BAA0B;;;AAE1B,2CAA0E;AAMjE,mGANqB,0BAAkB,OAMrB;AAJ3B,+CAA6C;AAEhC,QAAA,aAAa,GAAG,IAAA,2BAAmB,EAAC,0BAAc,CAAC,CAAC","sourcesContent":["/* istanbul ignore file */\n\nimport { createProjectLogger, createModuleLogger } from '@metamask/utils';\n\nimport { controllerName } from './constants';\n\nexport const projectLogger = createProjectLogger(controllerName);\n\nexport { createModuleLogger };\n"]}
@@ -0,0 +1,5 @@
1
+ /// <reference types="debug" />
2
+ import { createModuleLogger } from "@metamask/utils";
3
+ export declare const projectLogger: import("debug").Debugger;
4
+ export { createModuleLogger };
5
+ //# sourceMappingURL=logger.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.cts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";AAEA,OAAO,EAAuB,kBAAkB,EAAE,wBAAwB;AAI1E,eAAO,MAAM,aAAa,0BAAsC,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ /// <reference types="debug" />
2
+ import { createModuleLogger } from "@metamask/utils";
3
+ export declare const projectLogger: import("debug").Debugger;
4
+ export { createModuleLogger };
5
+ //# sourceMappingURL=logger.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.mts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";AAEA,OAAO,EAAuB,kBAAkB,EAAE,wBAAwB;AAI1E,eAAO,MAAM,aAAa,0BAAsC,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ /* istanbul ignore file */
2
+ import { createProjectLogger, createModuleLogger } from "@metamask/utils";
3
+ import { controllerName } from "./constants.mjs";
4
+ export const projectLogger = createProjectLogger(controllerName);
5
+ export { createModuleLogger };
6
+ //# sourceMappingURL=logger.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.mjs","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAE1B,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,wBAAwB;AAE1E,OAAO,EAAE,cAAc,EAAE,wBAAoB;AAE7C,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,CAAC","sourcesContent":["/* istanbul ignore file */\n\nimport { createProjectLogger, createModuleLogger } from '@metamask/utils';\n\nimport { controllerName } from './constants';\n\nexport const projectLogger = createProjectLogger(controllerName);\n\nexport { createModuleLogger };\n"]}
package/dist/types.cjs ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export type Base64String = string;\n\nexport type Base64URLString = string;\n\nexport type AuthenticatorTransportFuture =\n | 'ble'\n | 'cable'\n | 'hybrid'\n | 'internal'\n | 'nfc'\n | 'smart-card'\n | 'usb';\n\n/**\n * WebAuthn credential metadata used to identify the passkey and verify\n * subsequent assertions.\n */\nexport type PasskeyCredentialInfo = {\n /** WebAuthn credential ID (base64url). */\n id: Base64URLString;\n /** COSE-encoded credential public key (base64url) used to verify assertions. */\n publicKey: Base64URLString;\n /** Authenticator signature counter for replay/clone detection. */\n counter: number;\n /** Authenticator transports hint for `allowCredentials`. */\n transports?: AuthenticatorTransportFuture[];\n};\n\n/**\n * Vault key wrapped under the passkey-derived AES-256-GCM key.\n */\nexport type EncryptedVaultKey = {\n /** Base64-encoded AES-256-GCM ciphertext of the vault key. */\n ciphertext: Base64String;\n /** Base64-encoded AES-GCM IV used during encryption. */\n iv: Base64String;\n};\n\n/**\n * Parameters needed to reproduce the AES-256 wrapping key at unlock time.\n *\n * Encoded as a discriminated union so PRF-only fields (e.g. `prfSalt`) can\n * only exist on the PRF branch, removing the \"optional but actually\n * required\" footgun.\n */\nexport type PasskeyKeyDerivation =\n | {\n method: 'prf';\n /**\n * PRF salt sent in `get()` extension options to reproduce the same PRF\n * output that was generated at registration.\n */\n prfSalt: Base64URLString;\n }\n | { method: 'userHandle' };\n\n/** Discriminator value for {@link PasskeyKeyDerivation}. */\nexport type PasskeyDerivationMethod = PasskeyKeyDerivation['method'];\n\nexport type PasskeyRecord = {\n /** WebAuthn credential metadata used for assertion verification & re-discovery. */\n credential: PasskeyCredentialInfo;\n /** Vault key wrapped under the passkey-derived key. */\n encryptedVaultKey: EncryptedVaultKey;\n /** How the wrapping key is reconstructed at unlock time. */\n keyDerivation: PasskeyKeyDerivation;\n};\n\n/**\n * In-memory state for one **in-flight** WebAuthn **registration** ceremony\n * (from `create()` options until `protectVaultKeyWithPasskey` completes). This is\n * not a user login session; it is keyed by challenge and distinct from the full\n * spec ceremony (which includes the authenticator round-trip).\n */\nexport type PasskeyRegistrationCeremony = {\n userHandle: Base64URLString;\n prfSalt: Base64URLString;\n challenge: Base64URLString;\n /** When this ceremony was started (ms since epoch); used for TTL pruning. */\n createdAt: number;\n};\n\n/**\n * In-memory state for one **in-flight** WebAuthn **authentication** ceremony\n * (`get()` options until the assertion is verified). Not a user login session.\n */\nexport type PasskeyAuthenticationCeremony = {\n challenge: Base64URLString;\n /** When this ceremony was started (ms since epoch); used for TTL pruning. */\n createdAt: number;\n};\n\n/**\n * PRF extension types not covered by DOM typings.\n */\nexport type PrfEvalExtension = {\n eval: {\n first: Base64URLString;\n };\n};\n\nexport type PrfClientExtensionResults = {\n prf?: {\n enabled?: boolean;\n results?: { first?: Base64URLString };\n };\n};\n"]}
@@ -0,0 +1,92 @@
1
+ export type Base64String = string;
2
+ export type Base64URLString = string;
3
+ export type AuthenticatorTransportFuture = 'ble' | 'cable' | 'hybrid' | 'internal' | 'nfc' | 'smart-card' | 'usb';
4
+ /**
5
+ * WebAuthn credential metadata used to identify the passkey and verify
6
+ * subsequent assertions.
7
+ */
8
+ export type PasskeyCredentialInfo = {
9
+ /** WebAuthn credential ID (base64url). */
10
+ id: Base64URLString;
11
+ /** COSE-encoded credential public key (base64url) used to verify assertions. */
12
+ publicKey: Base64URLString;
13
+ /** Authenticator signature counter for replay/clone detection. */
14
+ counter: number;
15
+ /** Authenticator transports hint for `allowCredentials`. */
16
+ transports?: AuthenticatorTransportFuture[];
17
+ };
18
+ /**
19
+ * Vault key wrapped under the passkey-derived AES-256-GCM key.
20
+ */
21
+ export type EncryptedVaultKey = {
22
+ /** Base64-encoded AES-256-GCM ciphertext of the vault key. */
23
+ ciphertext: Base64String;
24
+ /** Base64-encoded AES-GCM IV used during encryption. */
25
+ iv: Base64String;
26
+ };
27
+ /**
28
+ * Parameters needed to reproduce the AES-256 wrapping key at unlock time.
29
+ *
30
+ * Encoded as a discriminated union so PRF-only fields (e.g. `prfSalt`) can
31
+ * only exist on the PRF branch, removing the "optional but actually
32
+ * required" footgun.
33
+ */
34
+ export type PasskeyKeyDerivation = {
35
+ method: 'prf';
36
+ /**
37
+ * PRF salt sent in `get()` extension options to reproduce the same PRF
38
+ * output that was generated at registration.
39
+ */
40
+ prfSalt: Base64URLString;
41
+ } | {
42
+ method: 'userHandle';
43
+ };
44
+ /** Discriminator value for {@link PasskeyKeyDerivation}. */
45
+ export type PasskeyDerivationMethod = PasskeyKeyDerivation['method'];
46
+ export type PasskeyRecord = {
47
+ /** WebAuthn credential metadata used for assertion verification & re-discovery. */
48
+ credential: PasskeyCredentialInfo;
49
+ /** Vault key wrapped under the passkey-derived key. */
50
+ encryptedVaultKey: EncryptedVaultKey;
51
+ /** How the wrapping key is reconstructed at unlock time. */
52
+ keyDerivation: PasskeyKeyDerivation;
53
+ };
54
+ /**
55
+ * In-memory state for one **in-flight** WebAuthn **registration** ceremony
56
+ * (from `create()` options until `protectVaultKeyWithPasskey` completes). This is
57
+ * not a user login session; it is keyed by challenge and distinct from the full
58
+ * spec ceremony (which includes the authenticator round-trip).
59
+ */
60
+ export type PasskeyRegistrationCeremony = {
61
+ userHandle: Base64URLString;
62
+ prfSalt: Base64URLString;
63
+ challenge: Base64URLString;
64
+ /** When this ceremony was started (ms since epoch); used for TTL pruning. */
65
+ createdAt: number;
66
+ };
67
+ /**
68
+ * In-memory state for one **in-flight** WebAuthn **authentication** ceremony
69
+ * (`get()` options until the assertion is verified). Not a user login session.
70
+ */
71
+ export type PasskeyAuthenticationCeremony = {
72
+ challenge: Base64URLString;
73
+ /** When this ceremony was started (ms since epoch); used for TTL pruning. */
74
+ createdAt: number;
75
+ };
76
+ /**
77
+ * PRF extension types not covered by DOM typings.
78
+ */
79
+ export type PrfEvalExtension = {
80
+ eval: {
81
+ first: Base64URLString;
82
+ };
83
+ };
84
+ export type PrfClientExtensionResults = {
85
+ prf?: {
86
+ enabled?: boolean;
87
+ results?: {
88
+ first?: Base64URLString;
89
+ };
90
+ };
91
+ };
92
+ //# sourceMappingURL=types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC;AAErC,MAAM,MAAM,4BAA4B,GACpC,KAAK,GACL,OAAO,GACP,QAAQ,GACR,UAAU,GACV,KAAK,GACL,YAAY,GACZ,KAAK,CAAC;AAEV;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,0CAA0C;IAC1C,EAAE,EAAE,eAAe,CAAC;IACpB,gFAAgF;IAChF,SAAS,EAAE,eAAe,CAAC;IAC3B,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,4BAA4B,EAAE,CAAC;CAC7C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,8DAA8D;IAC9D,UAAU,EAAE,YAAY,CAAC;IACzB,wDAAwD;IACxD,EAAE,EAAE,YAAY,CAAC;CAClB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IACE,MAAM,EAAE,KAAK,CAAC;IACd;;;OAGG;IACH,OAAO,EAAE,eAAe,CAAC;CAC1B,GACD;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,CAAC;AAE7B,4DAA4D;AAC5D,MAAM,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;AAErE,MAAM,MAAM,aAAa,GAAG;IAC1B,mFAAmF;IACnF,UAAU,EAAE,qBAAqB,CAAC;IAClC,uDAAuD;IACvD,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,4DAA4D;IAC5D,aAAa,EAAE,oBAAoB,CAAC;CACrC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,2BAA2B,GAAG;IACxC,UAAU,EAAE,eAAe,CAAC;IAC5B,OAAO,EAAE,eAAe,CAAC;IACzB,SAAS,EAAE,eAAe,CAAC;IAC3B,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,eAAe,CAAC;IAC3B,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE;QACJ,KAAK,EAAE,eAAe,CAAC;KACxB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,GAAG,CAAC,EAAE;QACJ,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,eAAe,CAAA;SAAE,CAAC;KACvC,CAAC;CACH,CAAC"}