@metamask/passkey-controller 3.1.0 → 4.0.0

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 (209) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/dist/{PasskeyController-method-action-types.d.mts → PasskeyController-method-action-types.d.ts} +2 -2
  3. package/dist/PasskeyController-method-action-types.d.ts.map +1 -0
  4. package/dist/{PasskeyController-method-action-types.mjs → PasskeyController-method-action-types.js} +1 -1
  5. package/dist/PasskeyController-method-action-types.js.map +1 -0
  6. package/dist/{PasskeyController.d.cts → PasskeyController.d.ts} +6 -6
  7. package/dist/PasskeyController.d.ts.map +1 -0
  8. package/dist/PasskeyController.js +680 -0
  9. package/dist/PasskeyController.js.map +1 -0
  10. package/dist/{ceremony-manager.d.cts → ceremony-manager.d.ts} +2 -2
  11. package/dist/ceremony-manager.d.ts.map +1 -0
  12. package/dist/ceremony-manager.js +135 -0
  13. package/dist/ceremony-manager.js.map +1 -0
  14. package/dist/{constants.d.mts → constants.d.ts} +12 -12
  15. package/dist/constants.d.ts.map +1 -0
  16. package/dist/{constants.mjs → constants.js} +1 -1
  17. package/dist/constants.js.map +1 -0
  18. package/dist/{errors.d.mts → errors.d.ts} +2 -2
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/{errors.mjs → errors.js} +4 -1
  21. package/dist/errors.js.map +1 -0
  22. package/dist/{index.d.cts → index.d.ts} +8 -8
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +5 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/{key-derivation.d.cts → key-derivation.d.ts} +3 -3
  27. package/dist/key-derivation.d.ts.map +1 -0
  28. package/dist/{key-derivation.mjs → key-derivation.js} +5 -5
  29. package/dist/key-derivation.js.map +1 -0
  30. package/dist/logger.d.ts +4 -0
  31. package/dist/logger.d.ts.map +1 -0
  32. package/dist/logger.js +6 -0
  33. package/dist/logger.js.map +1 -0
  34. package/dist/{types.d.mts → types.d.ts} +6 -6
  35. package/dist/types.d.ts.map +1 -0
  36. package/dist/types.js +2 -0
  37. package/dist/types.js.map +1 -0
  38. package/dist/utils/{crypto.d.mts → crypto.d.ts} +1 -1
  39. package/dist/utils/crypto.d.ts.map +1 -0
  40. package/dist/utils/{crypto.mjs → crypto.js} +7 -7
  41. package/dist/utils/crypto.js.map +1 -0
  42. package/dist/utils/{encoding.d.cts → encoding.d.ts} +1 -1
  43. package/dist/utils/encoding.d.ts.map +1 -0
  44. package/dist/utils/{encoding.mjs → encoding.js} +2 -2
  45. package/dist/utils/encoding.js.map +1 -0
  46. package/dist/webauthn/{constants.d.mts → constants.d.ts} +1 -1
  47. package/dist/webauthn/constants.d.ts.map +1 -0
  48. package/dist/webauthn/{constants.mjs → constants.js} +1 -1
  49. package/dist/webauthn/constants.js.map +1 -0
  50. package/dist/webauthn/{decode-attestation-object.d.mts → decode-attestation-object.d.ts} +2 -2
  51. package/dist/webauthn/decode-attestation-object.d.ts.map +1 -0
  52. package/dist/webauthn/{decode-attestation-object.mjs → decode-attestation-object.js} +2 -2
  53. package/dist/webauthn/decode-attestation-object.js.map +1 -0
  54. package/dist/webauthn/{decode-client-data-json.d.cts → decode-client-data-json.d.ts} +2 -2
  55. package/dist/webauthn/decode-client-data-json.d.ts.map +1 -0
  56. package/dist/webauthn/{decode-client-data-json.mjs → decode-client-data-json.js} +2 -2
  57. package/dist/webauthn/decode-client-data-json.js.map +1 -0
  58. package/dist/webauthn/{match-expected-rp-id.d.cts → match-expected-rp-id.d.ts} +1 -1
  59. package/dist/webauthn/match-expected-rp-id.d.ts.map +1 -0
  60. package/dist/webauthn/{match-expected-rp-id.mjs → match-expected-rp-id.js} +4 -4
  61. package/dist/webauthn/match-expected-rp-id.js.map +1 -0
  62. package/dist/webauthn/{parse-authenticator-data.d.cts → parse-authenticator-data.d.ts} +2 -2
  63. package/dist/webauthn/parse-authenticator-data.d.ts.map +1 -0
  64. package/dist/webauthn/{parse-authenticator-data.mjs → parse-authenticator-data.js} +2 -2
  65. package/dist/webauthn/parse-authenticator-data.js.map +1 -0
  66. package/dist/webauthn/{types.d.mts → types.d.ts} +2 -2
  67. package/dist/webauthn/types.d.ts.map +1 -0
  68. package/dist/webauthn/types.js +2 -0
  69. package/dist/webauthn/types.js.map +1 -0
  70. package/dist/webauthn/{verify-authentication-response.d.cts → verify-authentication-response.d.ts} +3 -3
  71. package/dist/webauthn/verify-authentication-response.d.ts.map +1 -0
  72. package/dist/webauthn/{verify-authentication-response.mjs → verify-authentication-response.js} +9 -9
  73. package/dist/webauthn/verify-authentication-response.js.map +1 -0
  74. package/dist/webauthn/{verify-registration-response.d.mts → verify-registration-response.d.ts} +3 -3
  75. package/dist/webauthn/verify-registration-response.d.ts.map +1 -0
  76. package/dist/webauthn/{verify-registration-response.mjs → verify-registration-response.js} +11 -11
  77. package/dist/webauthn/verify-registration-response.js.map +1 -0
  78. package/dist/webauthn/{verify-signature.d.cts → verify-signature.d.ts} +1 -1
  79. package/dist/webauthn/verify-signature.d.ts.map +1 -0
  80. package/dist/webauthn/{verify-signature.mjs → verify-signature.js} +7 -7
  81. package/dist/webauthn/verify-signature.js.map +1 -0
  82. package/package.json +16 -21
  83. package/dist/PasskeyController-method-action-types.cjs +0 -7
  84. package/dist/PasskeyController-method-action-types.cjs.map +0 -1
  85. package/dist/PasskeyController-method-action-types.d.cts +0 -204
  86. package/dist/PasskeyController-method-action-types.d.cts.map +0 -1
  87. package/dist/PasskeyController-method-action-types.d.mts.map +0 -1
  88. package/dist/PasskeyController-method-action-types.mjs.map +0 -1
  89. package/dist/PasskeyController.cjs +0 -685
  90. package/dist/PasskeyController.cjs.map +0 -1
  91. package/dist/PasskeyController.d.cts.map +0 -1
  92. package/dist/PasskeyController.d.mts +0 -208
  93. package/dist/PasskeyController.d.mts.map +0 -1
  94. package/dist/PasskeyController.mjs +0 -680
  95. package/dist/PasskeyController.mjs.map +0 -1
  96. package/dist/ceremony-manager.cjs +0 -135
  97. package/dist/ceremony-manager.cjs.map +0 -1
  98. package/dist/ceremony-manager.d.cts.map +0 -1
  99. package/dist/ceremony-manager.d.mts +0 -72
  100. package/dist/ceremony-manager.d.mts.map +0 -1
  101. package/dist/ceremony-manager.mjs +0 -131
  102. package/dist/ceremony-manager.mjs.map +0 -1
  103. package/dist/constants.cjs +0 -39
  104. package/dist/constants.cjs.map +0 -1
  105. package/dist/constants.d.cts +0 -36
  106. package/dist/constants.d.cts.map +0 -1
  107. package/dist/constants.d.mts.map +0 -1
  108. package/dist/constants.mjs.map +0 -1
  109. package/dist/errors.cjs +0 -57
  110. package/dist/errors.cjs.map +0 -1
  111. package/dist/errors.d.cts +0 -34
  112. package/dist/errors.d.cts.map +0 -1
  113. package/dist/errors.d.mts.map +0 -1
  114. package/dist/errors.mjs.map +0 -1
  115. package/dist/index.cjs +0 -15
  116. package/dist/index.cjs.map +0 -1
  117. package/dist/index.d.cts.map +0 -1
  118. package/dist/index.d.mts +0 -8
  119. package/dist/index.d.mts.map +0 -1
  120. package/dist/index.mjs +0 -5
  121. package/dist/index.mjs.map +0 -1
  122. package/dist/key-derivation.cjs +0 -44
  123. package/dist/key-derivation.cjs.map +0 -1
  124. package/dist/key-derivation.d.cts.map +0 -1
  125. package/dist/key-derivation.d.mts +0 -20
  126. package/dist/key-derivation.d.mts.map +0 -1
  127. package/dist/key-derivation.mjs.map +0 -1
  128. package/dist/logger.cjs +0 -9
  129. package/dist/logger.cjs.map +0 -1
  130. package/dist/logger.d.cts +0 -5
  131. package/dist/logger.d.cts.map +0 -1
  132. package/dist/logger.d.mts +0 -5
  133. package/dist/logger.d.mts.map +0 -1
  134. package/dist/logger.mjs +0 -6
  135. package/dist/logger.mjs.map +0 -1
  136. package/dist/types.cjs +0 -4
  137. package/dist/types.cjs.map +0 -1
  138. package/dist/types.d.cts +0 -132
  139. package/dist/types.d.cts.map +0 -1
  140. package/dist/types.d.mts.map +0 -1
  141. package/dist/types.mjs +0 -2
  142. package/dist/types.mjs.map +0 -1
  143. package/dist/utils/crypto.cjs +0 -66
  144. package/dist/utils/crypto.cjs.map +0 -1
  145. package/dist/utils/crypto.d.cts +0 -37
  146. package/dist/utils/crypto.d.cts.map +0 -1
  147. package/dist/utils/crypto.d.mts.map +0 -1
  148. package/dist/utils/crypto.mjs.map +0 -1
  149. package/dist/utils/encoding.cjs +0 -42
  150. package/dist/utils/encoding.cjs.map +0 -1
  151. package/dist/utils/encoding.d.cts.map +0 -1
  152. package/dist/utils/encoding.d.mts +0 -22
  153. package/dist/utils/encoding.d.mts.map +0 -1
  154. package/dist/utils/encoding.mjs.map +0 -1
  155. package/dist/webauthn/constants.cjs +0 -74
  156. package/dist/webauthn/constants.cjs.map +0 -1
  157. package/dist/webauthn/constants.d.cts +0 -68
  158. package/dist/webauthn/constants.d.cts.map +0 -1
  159. package/dist/webauthn/constants.d.mts.map +0 -1
  160. package/dist/webauthn/constants.mjs.map +0 -1
  161. package/dist/webauthn/decode-attestation-object.cjs +0 -18
  162. package/dist/webauthn/decode-attestation-object.cjs.map +0 -1
  163. package/dist/webauthn/decode-attestation-object.d.cts +0 -10
  164. package/dist/webauthn/decode-attestation-object.d.cts.map +0 -1
  165. package/dist/webauthn/decode-attestation-object.d.mts.map +0 -1
  166. package/dist/webauthn/decode-attestation-object.mjs.map +0 -1
  167. package/dist/webauthn/decode-client-data-json.cjs +0 -17
  168. package/dist/webauthn/decode-client-data-json.cjs.map +0 -1
  169. package/dist/webauthn/decode-client-data-json.d.cts.map +0 -1
  170. package/dist/webauthn/decode-client-data-json.d.mts +0 -9
  171. package/dist/webauthn/decode-client-data-json.d.mts.map +0 -1
  172. package/dist/webauthn/decode-client-data-json.mjs.map +0 -1
  173. package/dist/webauthn/match-expected-rp-id.cjs +0 -26
  174. package/dist/webauthn/match-expected-rp-id.cjs.map +0 -1
  175. package/dist/webauthn/match-expected-rp-id.d.cts.map +0 -1
  176. package/dist/webauthn/match-expected-rp-id.d.mts +0 -11
  177. package/dist/webauthn/match-expected-rp-id.d.mts.map +0 -1
  178. package/dist/webauthn/match-expected-rp-id.mjs.map +0 -1
  179. package/dist/webauthn/parse-authenticator-data.cjs +0 -69
  180. package/dist/webauthn/parse-authenticator-data.cjs.map +0 -1
  181. package/dist/webauthn/parse-authenticator-data.d.cts.map +0 -1
  182. package/dist/webauthn/parse-authenticator-data.d.mts +0 -10
  183. package/dist/webauthn/parse-authenticator-data.d.mts.map +0 -1
  184. package/dist/webauthn/parse-authenticator-data.mjs.map +0 -1
  185. package/dist/webauthn/types.cjs +0 -3
  186. package/dist/webauthn/types.cjs.map +0 -1
  187. package/dist/webauthn/types.d.cts +0 -113
  188. package/dist/webauthn/types.d.cts.map +0 -1
  189. package/dist/webauthn/types.d.mts.map +0 -1
  190. package/dist/webauthn/types.mjs +0 -2
  191. package/dist/webauthn/types.mjs.map +0 -1
  192. package/dist/webauthn/verify-authentication-response.cjs +0 -133
  193. package/dist/webauthn/verify-authentication-response.cjs.map +0 -1
  194. package/dist/webauthn/verify-authentication-response.d.cts.map +0 -1
  195. package/dist/webauthn/verify-authentication-response.d.mts +0 -64
  196. package/dist/webauthn/verify-authentication-response.d.mts.map +0 -1
  197. package/dist/webauthn/verify-authentication-response.mjs.map +0 -1
  198. package/dist/webauthn/verify-registration-response.cjs +0 -242
  199. package/dist/webauthn/verify-registration-response.cjs.map +0 -1
  200. package/dist/webauthn/verify-registration-response.d.cts +0 -81
  201. package/dist/webauthn/verify-registration-response.d.cts.map +0 -1
  202. package/dist/webauthn/verify-registration-response.d.mts.map +0 -1
  203. package/dist/webauthn/verify-registration-response.mjs.map +0 -1
  204. package/dist/webauthn/verify-signature.cjs +0 -176
  205. package/dist/webauthn/verify-signature.cjs.map +0 -1
  206. package/dist/webauthn/verify-signature.d.cts.map +0 -1
  207. package/dist/webauthn/verify-signature.d.mts +0 -21
  208. package/dist/webauthn/verify-signature.d.mts.map +0 -1
  209. package/dist/webauthn/verify-signature.mjs.map +0 -1
@@ -1,680 +0,0 @@
1
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
- if (kind === "m") throw new TypeError("Private method is not writable");
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
- };
7
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
- };
12
- var _PasskeyController_instances, _PasskeyController_ceremonyManager, _PasskeyController_expectedRPIDs, _PasskeyController_rpId, _PasskeyController_rpName, _PasskeyController_expectedOrigin, _PasskeyController_userName, _PasskeyController_userDisplayName, _PasskeyController_getIsOnboardingCompleted, _PasskeyController_operationMutex, _PasskeyController_protectVaultKeyWithPasskey, _PasskeyController_retrieveVaultKeyWithPasskey, _PasskeyController_verifyPasskeyAuthentication, _PasskeyController_renewVaultKeyProtection, _PasskeyController_changePasswordWithPasskeyVerification, _PasskeyController_removePasskeyWithPasskeyVerification, _PasskeyController_removePasskeyWithPasswordVerification, _PasskeyController_verifyAuthenticationResponse, _PasskeyController_withOperationLock, _PasskeyController_assertEnrollmentAllowed, _PasskeyController_requireEnrolled, _PasskeyController_getChallengeFromClientData, _PasskeyController_removePasskey;
13
- import { BaseController } from "@metamask/base-controller";
14
- import { areUint8ArraysEqual, stringToBytes } from "@metamask/utils";
15
- import { Mutex } from "async-mutex";
16
- import { WEBAUTHN_TIMEOUT_MS, CeremonyManager } from "./ceremony-manager.mjs";
17
- import { controllerName, PasskeyControllerErrorCode, PasskeyControllerErrorMessage } from "./constants.mjs";
18
- import { PasskeyControllerError } from "./errors.mjs";
19
- import { deriveKeyFromAuthenticationResponse } from "./key-derivation.mjs";
20
- import { createModuleLogger, projectLogger } from "./logger.mjs";
21
- import { decryptWithKey, encryptWithKey, randomBytesToBase64URL } from "./utils/crypto.mjs";
22
- import { base64URLToBytes, bytesToBase64URL } from "./utils/encoding.mjs";
23
- import { COSEALG } from "./webauthn/constants.mjs";
24
- import { decodeClientDataJSON } from "./webauthn/decode-client-data-json.mjs";
25
- import { verifyAuthenticationResponse } from "./webauthn/verify-authentication-response.mjs";
26
- import { verifyRegistrationResponse } from "./webauthn/verify-registration-response.mjs";
27
- /**
28
- * Returns the default (empty) state for {@link PasskeyController}.
29
- *
30
- * @returns A fresh state object with no enrolled passkey.
31
- */
32
- export function getDefaultPasskeyControllerState() {
33
- return { passkeyRecord: null };
34
- }
35
- const passkeyControllerMetadata = {
36
- passkeyRecord: {
37
- persist: true,
38
- includeInDebugSnapshot: false,
39
- includeInStateLogs: false,
40
- usedInUi: true,
41
- },
42
- };
43
- const log = createModuleLogger(projectLogger, controllerName);
44
- /**
45
- * Selectors for {@link PasskeyControllerState}.
46
- *
47
- * Use these instead of dedicated getter methods on the controller, so that
48
- * derived values can be consumed from Redux selectors and other places that
49
- * only have access to a state object.
50
- */
51
- export const passkeyControllerSelectors = {
52
- selectIsPasskeyEnrolled: (state) => state.passkeyRecord !== null,
53
- };
54
- const MESSENGER_EXPOSED_METHODS = [
55
- 'isPasskeyEnrolled',
56
- 'generateRegistrationOptions',
57
- 'generatePostRegistrationAuthenticationOptions',
58
- 'generateAuthenticationOptions',
59
- 'protectVaultKeyWithPasskey',
60
- 'retrieveVaultKeyWithPasskey',
61
- 'unlockWithPasskey',
62
- 'verifyPasskeyAuthentication',
63
- 'renewVaultKeyProtection',
64
- 'changePasswordWithPasskeyVerification',
65
- 'exportSeedPhraseWithPasskey',
66
- 'exportAccountsWithPasskey',
67
- 'removePasskeyWithPasskeyVerification',
68
- 'removePasskeyWithPasswordVerification',
69
- 'clearState',
70
- 'destroy',
71
- ];
72
- /**
73
- * Controller that enrolls a WebAuthn passkey and uses it to protect and unlock
74
- * the vault encryption key.
75
- */
76
- export class PasskeyController extends BaseController {
77
- /**
78
- * Creates a passkey controller with WebAuthn relying-party settings.
79
- *
80
- * @param options - Constructor options.
81
- * @param options.messenger - The messenger to use for communication.
82
- * @param options.state - The initial state of the controller.
83
- * @param options.rpId - The relying party ID to use for the passkey.
84
- * @param options.expectedRPID - The expected relying party ID to use for the passkey.
85
- * @param options.rpName - The relying party name to use for the passkey.
86
- * @param options.expectedOrigin - The expected origin to use for the passkey.
87
- * @param options.userName - The user name to use for the passkey.
88
- * @param options.userDisplayName - The user display name to use for the passkey.
89
- * @param options.getIsOnboardingCompleted - The callback to use to check if onboarding is complete.
90
- */
91
- constructor({ messenger, state = {}, rpId, expectedRPID, rpName, expectedOrigin, userName, userDisplayName, getIsOnboardingCompleted, }) {
92
- super({
93
- messenger,
94
- metadata: passkeyControllerMetadata,
95
- name: controllerName,
96
- state: { ...getDefaultPasskeyControllerState(), ...state },
97
- });
98
- _PasskeyController_instances.add(this);
99
- _PasskeyController_ceremonyManager.set(this, new CeremonyManager());
100
- _PasskeyController_expectedRPIDs.set(this, void 0);
101
- _PasskeyController_rpId.set(this, void 0);
102
- _PasskeyController_rpName.set(this, void 0);
103
- _PasskeyController_expectedOrigin.set(this, void 0);
104
- _PasskeyController_userName.set(this, void 0);
105
- _PasskeyController_userDisplayName.set(this, void 0);
106
- _PasskeyController_getIsOnboardingCompleted.set(this, void 0);
107
- _PasskeyController_operationMutex.set(this, new Mutex());
108
- const expectedRPIDs = Array.isArray(expectedRPID)
109
- ? expectedRPID
110
- : [expectedRPID];
111
- __classPrivateFieldSet(this, _PasskeyController_expectedRPIDs, [...expectedRPIDs], "f");
112
- __classPrivateFieldSet(this, _PasskeyController_rpId, rpId, "f");
113
- __classPrivateFieldSet(this, _PasskeyController_rpName, rpName, "f");
114
- __classPrivateFieldSet(this, _PasskeyController_expectedOrigin, expectedOrigin, "f");
115
- __classPrivateFieldSet(this, _PasskeyController_userName, userName ?? rpName, "f");
116
- __classPrivateFieldSet(this, _PasskeyController_userDisplayName, userDisplayName ?? rpName, "f");
117
- __classPrivateFieldSet(this, _PasskeyController_getIsOnboardingCompleted, getIsOnboardingCompleted, "f");
118
- this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
119
- }
120
- /**
121
- * Whether a passkey is enrolled and vault key material is stored.
122
- *
123
- * @returns `true` if enrolled, otherwise `false`.
124
- */
125
- isPasskeyEnrolled() {
126
- return passkeyControllerSelectors.selectIsPasskeyEnrolled(this.state);
127
- }
128
- /**
129
- * Builds WebAuthn credential creation options for passkey enrollment.
130
- *
131
- * @param creationOptionsConfig - Optional creation behavior.
132
- * @param creationOptionsConfig.prfAvailable - Request the PRF extension unless `false`. Defaults to `true`.
133
- * @returns Public key credential creation options for `navigator.credentials.create()`.
134
- */
135
- generateRegistrationOptions(creationOptionsConfig) {
136
- if (this.isPasskeyEnrolled()) {
137
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.AlreadyEnrolled, { code: PasskeyControllerErrorCode.AlreadyEnrolled });
138
- }
139
- const includePrf = creationOptionsConfig?.prfAvailable !== false;
140
- const prfSalt = includePrf ? randomBytesToBase64URL(32) : undefined;
141
- const userHandle = randomBytesToBase64URL(64);
142
- const challenge = randomBytesToBase64URL(32);
143
- const extensions = {};
144
- if (prfSalt) {
145
- extensions.prf = { eval: { first: prfSalt } };
146
- }
147
- const options = {
148
- rp: {
149
- name: __classPrivateFieldGet(this, _PasskeyController_rpName, "f"),
150
- id: __classPrivateFieldGet(this, _PasskeyController_rpId, "f"),
151
- },
152
- user: {
153
- id: userHandle,
154
- name: __classPrivateFieldGet(this, _PasskeyController_userName, "f"),
155
- displayName: __classPrivateFieldGet(this, _PasskeyController_userDisplayName, "f"),
156
- },
157
- challenge,
158
- pubKeyCredParams: [
159
- { alg: COSEALG.EdDSA, type: 'public-key' },
160
- { alg: COSEALG.ES256, type: 'public-key' },
161
- { alg: COSEALG.RS256, type: 'public-key' },
162
- ],
163
- timeout: WEBAUTHN_TIMEOUT_MS,
164
- authenticatorSelection: {
165
- userVerification: 'required',
166
- authenticatorAttachment: 'platform',
167
- residentKey: 'preferred',
168
- },
169
- hints: ['client-device', 'hybrid'],
170
- attestation: 'none',
171
- ...(Object.keys(extensions).length > 0 ? { extensions } : {}),
172
- };
173
- __classPrivateFieldGet(this, _PasskeyController_ceremonyManager, "f").saveRegistrationCeremony(challenge, {
174
- userHandle,
175
- prfSalt,
176
- challenge,
177
- createdAt: Date.now(),
178
- });
179
- return options;
180
- }
181
- /**
182
- * Builds WebAuthn credential request options for the post-registration
183
- * authentication step (between `create` and {@link protectVaultKeyWithPasskey}).
184
- *
185
- * @param params - Input for the pending registration ceremony.
186
- * @param params.registrationResponse - Result of `navigator.credentials.create()`.
187
- * @returns Public key credential request options for `navigator.credentials.get()`.
188
- */
189
- generatePostRegistrationAuthenticationOptions(params) {
190
- // get registration ceremony
191
- const { registrationResponse } = params;
192
- const regChallenge = __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_getChallengeFromClientData).call(this, registrationResponse.response.clientDataJSON);
193
- const registrationCeremony = __classPrivateFieldGet(this, _PasskeyController_ceremonyManager, "f").getRegistrationCeremony(regChallenge);
194
- if (!registrationCeremony) {
195
- log('No active passkey registration ceremony for challenge');
196
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.NoRegistrationCeremony, { code: PasskeyControllerErrorCode.NoRegistrationCeremony });
197
- }
198
- // build auth options
199
- const challenge = randomBytesToBase64URL(32);
200
- const extensions = {};
201
- if (registrationCeremony.prfSalt) {
202
- extensions.prf = { eval: { first: registrationCeremony.prfSalt } };
203
- }
204
- const options = {
205
- challenge,
206
- rpId: __classPrivateFieldGet(this, _PasskeyController_rpId, "f"),
207
- allowCredentials: [
208
- {
209
- id: registrationResponse.id,
210
- type: 'public-key',
211
- transports: registrationResponse.response.transports,
212
- },
213
- ],
214
- userVerification: 'required',
215
- hints: ['client-device', 'hybrid'],
216
- timeout: WEBAUTHN_TIMEOUT_MS,
217
- extensions,
218
- };
219
- // save auth ceremony
220
- __classPrivateFieldGet(this, _PasskeyController_ceremonyManager, "f").saveAuthenticationCeremony(challenge, {
221
- challenge,
222
- createdAt: Date.now(),
223
- });
224
- return options;
225
- }
226
- /**
227
- * Builds WebAuthn credential request options for the enrolled passkey.
228
- *
229
- * @returns Public key credential request options for `navigator.credentials.get()`.
230
- */
231
- generateAuthenticationOptions() {
232
- const record = __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_requireEnrolled).call(this);
233
- const challenge = randomBytesToBase64URL(32);
234
- const extensions = {};
235
- if (record.keyDerivation.method === 'prf') {
236
- extensions.prf = { eval: { first: record.keyDerivation.prfSalt } };
237
- }
238
- const options = {
239
- challenge,
240
- rpId: __classPrivateFieldGet(this, _PasskeyController_rpId, "f"),
241
- allowCredentials: [
242
- {
243
- id: record.credential.id,
244
- type: 'public-key',
245
- transports: record.credential.transports,
246
- },
247
- ],
248
- userVerification: 'required',
249
- hints: ['client-device', 'hybrid'],
250
- timeout: WEBAUTHN_TIMEOUT_MS,
251
- extensions,
252
- };
253
- __classPrivateFieldGet(this, _PasskeyController_ceremonyManager, "f").saveAuthenticationCeremony(challenge, {
254
- challenge,
255
- createdAt: Date.now(),
256
- });
257
- return options;
258
- }
259
- /**
260
- * Verifies registration and post-registration authentication, then stores the
261
- * vault key encrypted under the new passkey.
262
- *
263
- * Fetches the current vault encryption key from KeyringController before wrapping.
264
- * When onboarding is complete, requires `password` for step-up verification first.
265
- *
266
- * @param params - Enrollment completion inputs.
267
- * @param params.registrationResponse - Result of `navigator.credentials.create()`.
268
- * @param params.authenticationResponse - Result of `navigator.credentials.get()` after {@link generatePostRegistrationAuthenticationOptions}.
269
- * @param params.password - Wallet password when onboarding is complete (step-up).
270
- * @returns Resolves when enrollment completes.
271
- */
272
- async protectVaultKeyWithPasskey(params) {
273
- return __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_withOperationLock).call(this, () => __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_protectVaultKeyWithPasskey).call(this, params));
274
- }
275
- /**
276
- * Verifies an authentication assertion and returns the decrypted vault key.
277
- *
278
- * Prefer orchestrated methods ({@link unlockWithPasskey},
279
- * {@link exportSeedPhraseWithPasskey}, {@link exportAccountsWithPasskey}) for product
280
- * flows instead of calling KeyringController with the returned key manually.
281
- *
282
- * @param authenticationResponse - Result of `navigator.credentials.get()`.
283
- * @returns The plaintext vault encryption key.
284
- */
285
- async retrieveVaultKeyWithPasskey(authenticationResponse) {
286
- return __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_withOperationLock).call(this, () => __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_retrieveVaultKeyWithPasskey).call(this, authenticationResponse));
287
- }
288
- /**
289
- * Unlocks the keyring using a passkey authentication assertion.
290
- *
291
- * @param authenticationResponse - Result of `navigator.credentials.get()`.
292
- * @returns Resolves when the keyring is unlocked.
293
- */
294
- async unlockWithPasskey(authenticationResponse) {
295
- return __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_withOperationLock).call(this, async () => {
296
- const vaultKey = await __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_retrieveVaultKeyWithPasskey).call(this, authenticationResponse);
297
- await this.messenger.call('KeyringController:submitEncryptionKey', vaultKey);
298
- });
299
- }
300
- /**
301
- * Exports the seed phrase after passkey step-up authentication.
302
- *
303
- * @param authenticationResponse - Result of `navigator.credentials.get()`.
304
- * @param keyringId - Optional keyring id; defaults to the primary HD keyring.
305
- * @returns Raw seed phrase bytes from KeyringController.
306
- */
307
- async exportSeedPhraseWithPasskey(authenticationResponse, keyringId) {
308
- return __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_withOperationLock).call(this, async () => {
309
- const vaultKey = await __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_retrieveVaultKeyWithPasskey).call(this, authenticationResponse);
310
- return await this.messenger.call('KeyringController:exportSeedPhrase', { encryptionKey: vaultKey }, keyringId);
311
- });
312
- }
313
- /**
314
- * Exports private keys for the given addresses after passkey step-up authentication.
315
- *
316
- * @param authenticationResponse - Result of `navigator.credentials.get()`.
317
- * @param addresses - Account addresses to export.
318
- * @returns Private keys in the same order as `addresses`.
319
- */
320
- async exportAccountsWithPasskey(authenticationResponse, addresses) {
321
- return __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_withOperationLock).call(this, async () => {
322
- const vaultKey = await __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_retrieveVaultKeyWithPasskey).call(this, authenticationResponse);
323
- const privateKeys = [];
324
- for (const address of addresses) {
325
- privateKeys.push(await this.messenger.call('KeyringController:exportAccount', { encryptionKey: vaultKey }, address));
326
- }
327
- return privateKeys;
328
- });
329
- }
330
- /**
331
- * Checks whether the given authentication assertion is valid for the enrolled passkey.
332
- *
333
- * On failure, returns `false` for {@link PasskeyControllerError} with a `code`;
334
- * other errors propagate.
335
- *
336
- * @param authenticationResponse - Result of `navigator.credentials.get()`.
337
- * @returns `true` if verification succeeds, otherwise `false`.
338
- */
339
- async verifyPasskeyAuthentication(authenticationResponse) {
340
- return __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_withOperationLock).call(this, () => __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_verifyPasskeyAuthentication).call(this, authenticationResponse));
341
- }
342
- /**
343
- * Re-wraps the vault key after rotation. Updates persisted `encryptedVaultKey` on success.
344
- *
345
- * Does not verify WebAuthn or ceremony state—call only after your layer has authenticated
346
- * the user (passkey `get()` + verified assertion, or verified password). On passkey paths,
347
- * pass the same `authenticationResponse` you just verified (e.g. from
348
- * {@link retrieveVaultKeyWithPasskey} / {@link verifyPasskeyAuthentication}).
349
- *
350
- * For password change with passkey step-up, prefer
351
- * {@link changePasswordWithPasskeyVerification}, which orchestrates keyring export,
352
- * `changePassword`, and re-wrap in one call.
353
- *
354
- * @param params - Re-wrap inputs.
355
- * @param params.authenticationResponse - Used to derive the wrapping key.
356
- * @param params.oldVaultKey - Expected current vault key.
357
- * @param params.newVaultKey - New vault key to encrypt under the passkey.
358
- * @returns Resolves when the passkey record is updated.
359
- */
360
- async renewVaultKeyProtection(params) {
361
- return __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_withOperationLock).call(this, () => __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_renewVaultKeyProtection).call(this, params));
362
- }
363
- /**
364
- * Changes the wallet password after passkey step-up authentication.
365
- *
366
- * When `renewVaultKeyProtection` is `true` (default), re-wraps the vault key under the
367
- * passkey after rotation. When `false`, removes the passkey instead.
368
- *
369
- * @param params - Change-password inputs.
370
- * @param params.newPassword - New wallet password.
371
- * @param params.authenticationResponse - Result of `navigator.credentials.get()`.
372
- * @param params.options - Optional flow controls.
373
- * @param params.options.renewVaultKeyProtection - Re-wrap vault key after password change.
374
- * @returns Resolves when the password change completes.
375
- */
376
- async changePasswordWithPasskeyVerification(params) {
377
- return __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_withOperationLock).call(this, () => __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_changePasswordWithPasskeyVerification).call(this, params));
378
- }
379
- /**
380
- * Removes the enrolled passkey after verifying a passkey authentication assertion.
381
- *
382
- * @param authenticationResponse - Result of `navigator.credentials.get()`.
383
- * @returns Resolves when the passkey is removed.
384
- */
385
- async removePasskeyWithPasskeyVerification(authenticationResponse) {
386
- return __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_withOperationLock).call(this, () => __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_removePasskeyWithPasskeyVerification).call(this, authenticationResponse));
387
- }
388
- /**
389
- * Removes the enrolled passkey after verifying the wallet password.
390
- *
391
- * @param password - Wallet password for step-up verification.
392
- * @returns Resolves when the passkey is removed.
393
- */
394
- async removePasskeyWithPasswordVerification(password) {
395
- return __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_withOperationLock).call(this, () => __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_removePasskeyWithPasswordVerification).call(this, password));
396
- }
397
- /**
398
- * Resets state and clears in-flight registration/authentication ceremonies.
399
- *
400
- * For user-facing passkey removal with step-up, use
401
- * {@link removePasskeyWithPasskeyVerification} or
402
- * {@link removePasskeyWithPasswordVerification}.
403
- */
404
- clearState() {
405
- __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_removePasskey).call(this);
406
- }
407
- /**
408
- * Releases all in-flight ceremony state and tears down the messenger.
409
- */
410
- destroy() {
411
- __classPrivateFieldGet(this, _PasskeyController_ceremonyManager, "f").clear();
412
- super.destroy();
413
- }
414
- }
415
- _PasskeyController_ceremonyManager = new WeakMap(), _PasskeyController_expectedRPIDs = new WeakMap(), _PasskeyController_rpId = new WeakMap(), _PasskeyController_rpName = new WeakMap(), _PasskeyController_expectedOrigin = new WeakMap(), _PasskeyController_userName = new WeakMap(), _PasskeyController_userDisplayName = new WeakMap(), _PasskeyController_getIsOnboardingCompleted = new WeakMap(), _PasskeyController_operationMutex = new WeakMap(), _PasskeyController_instances = new WeakSet(), _PasskeyController_protectVaultKeyWithPasskey = async function _PasskeyController_protectVaultKeyWithPasskey(params) {
416
- if (this.isPasskeyEnrolled()) {
417
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.AlreadyEnrolled, { code: PasskeyControllerErrorCode.AlreadyEnrolled });
418
- }
419
- await __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_assertEnrollmentAllowed).call(this, params.password);
420
- const vaultKey = await this.messenger.call('KeyringController:exportEncryptionKey');
421
- const { registrationResponse, authenticationResponse } = params;
422
- // get registration ceremony
423
- const challenge = __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_getChallengeFromClientData).call(this, registrationResponse.response.clientDataJSON);
424
- const registrationCeremony = __classPrivateFieldGet(this, _PasskeyController_ceremonyManager, "f").getRegistrationCeremony(challenge);
425
- if (!registrationCeremony) {
426
- log('No active passkey registration ceremony for challenge');
427
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.NoRegistrationCeremony, { code: PasskeyControllerErrorCode.NoRegistrationCeremony });
428
- }
429
- try {
430
- // verify registration response
431
- const { verified, registrationInfo } = await verifyRegistrationResponse({
432
- response: registrationResponse,
433
- expectedChallenge: registrationCeremony.challenge,
434
- expectedOrigin: __classPrivateFieldGet(this, _PasskeyController_expectedOrigin, "f"),
435
- expectedRPIDs: __classPrivateFieldGet(this, _PasskeyController_expectedRPIDs, "f"),
436
- requireUserVerification: true,
437
- }).catch((error) => {
438
- log('Error verifying passkey registration response', error);
439
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.RegistrationVerificationFailed, {
440
- code: PasskeyControllerErrorCode.RegistrationVerificationFailed,
441
- cause: error instanceof Error ? error : new Error(String(error)),
442
- });
443
- });
444
- if (!verified || !registrationInfo) {
445
- log('Passkey registration verification returned unverified or missing registration info');
446
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.RegistrationVerificationFailed, { code: PasskeyControllerErrorCode.RegistrationVerificationFailed });
447
- }
448
- // verify authentication response
449
- const credential = {
450
- id: registrationInfo.credentialId,
451
- publicKey: bytesToBase64URL(registrationInfo.publicKey),
452
- counter: registrationInfo.counter,
453
- transports: registrationInfo.transports,
454
- aaguid: registrationInfo.aaguid,
455
- };
456
- const { newCounter } = await __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_verifyAuthenticationResponse).call(this, authenticationResponse, credential);
457
- // determine key derivation method
458
- const prfFirst = authenticationResponse.clientExtensionResults?.prf?.results?.first;
459
- const authHasPrfOutput = typeof prfFirst === 'string' && prfFirst.length > 0;
460
- const keyDerivation = authHasPrfOutput && registrationCeremony.prfSalt
461
- ? { method: 'prf', prfSalt: registrationCeremony.prfSalt }
462
- : { method: 'userHandle' };
463
- if (keyDerivation.method === 'userHandle' &&
464
- authenticationResponse.response.userHandle !==
465
- registrationCeremony.userHandle) {
466
- log('Post-registration assertion userHandle does not match registration ceremony');
467
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.AuthenticationVerificationFailed, { code: PasskeyControllerErrorCode.AuthenticationVerificationFailed });
468
- }
469
- // derive key and encrypt vault key
470
- const encKey = deriveKeyFromAuthenticationResponse(authenticationResponse, { credential, keyDerivation });
471
- const { ciphertext, iv } = encryptWithKey(vaultKey, encKey);
472
- // persist passkey record
473
- this.update((state) => {
474
- state.passkeyRecord = {
475
- credential: {
476
- ...credential,
477
- counter: Math.max(newCounter, credential.counter),
478
- },
479
- encryptedVaultKey: { ciphertext, iv },
480
- keyDerivation,
481
- };
482
- });
483
- }
484
- finally {
485
- // delete registration ceremony
486
- __classPrivateFieldGet(this, _PasskeyController_ceremonyManager, "f").deleteRegistrationCeremony(challenge);
487
- }
488
- }, _PasskeyController_retrieveVaultKeyWithPasskey = async function _PasskeyController_retrieveVaultKeyWithPasskey(authenticationResponse) {
489
- const passkeyRecord = __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_requireEnrolled).call(this);
490
- // verify authentication response and update counter
491
- const { newCounter } = await __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_verifyAuthenticationResponse).call(this, authenticationResponse, passkeyRecord.credential);
492
- this.update((state) => {
493
- if (!state.passkeyRecord) {
494
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.NotEnrolled, { code: PasskeyControllerErrorCode.NotEnrolled });
495
- }
496
- state.passkeyRecord.credential.counter = Math.max(newCounter, state.passkeyRecord.credential.counter);
497
- });
498
- // derive key
499
- const encKey = deriveKeyFromAuthenticationResponse(authenticationResponse, passkeyRecord);
500
- // decrypt vault key
501
- try {
502
- const vaultKey = decryptWithKey(passkeyRecord.encryptedVaultKey.ciphertext, passkeyRecord.encryptedVaultKey.iv, encKey);
503
- return vaultKey;
504
- }
505
- catch (cause) {
506
- log('Error decrypting vault key with passkey', cause instanceof Error ? cause : new Error(String(cause)));
507
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.VaultKeyDecryptionFailed, {
508
- code: PasskeyControllerErrorCode.VaultKeyDecryptionFailed,
509
- cause: cause instanceof Error ? cause : new Error(String(cause)),
510
- });
511
- }
512
- }, _PasskeyController_verifyPasskeyAuthentication = async function _PasskeyController_verifyPasskeyAuthentication(authenticationResponse) {
513
- try {
514
- await __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_retrieveVaultKeyWithPasskey).call(this, authenticationResponse);
515
- return true;
516
- }
517
- catch (error) {
518
- if (error instanceof PasskeyControllerError && error.code !== undefined) {
519
- return false;
520
- }
521
- throw error;
522
- }
523
- }, _PasskeyController_renewVaultKeyProtection = async function _PasskeyController_renewVaultKeyProtection(params) {
524
- const { authenticationResponse } = params;
525
- const passkeyRecord = __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_requireEnrolled).call(this);
526
- // derive key
527
- const encKey = deriveKeyFromAuthenticationResponse(authenticationResponse, passkeyRecord);
528
- // decrypt vault key
529
- let decryptedVaultKey;
530
- try {
531
- decryptedVaultKey = decryptWithKey(passkeyRecord.encryptedVaultKey.ciphertext, passkeyRecord.encryptedVaultKey.iv, encKey);
532
- }
533
- catch (error) {
534
- log('Error decrypting vault key during passkey vault key renewal', error instanceof Error ? error : new Error(String(error)));
535
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.VaultKeyDecryptionFailed, {
536
- code: PasskeyControllerErrorCode.VaultKeyDecryptionFailed,
537
- cause: error instanceof Error ? error : new Error(String(error)),
538
- });
539
- }
540
- // check if vault key matches
541
- const { oldVaultKey, newVaultKey } = params;
542
- if (!areUint8ArraysEqual(stringToBytes(decryptedVaultKey), stringToBytes(oldVaultKey))) {
543
- log('Passkey renewal rejected: decrypted vault key does not match oldVaultKey');
544
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.VaultKeyMismatch, { code: PasskeyControllerErrorCode.VaultKeyMismatch });
545
- }
546
- // encrypt new vault key
547
- const { ciphertext, iv } = encryptWithKey(newVaultKey, encKey);
548
- // persist passkey record (mutate current state only for vault key material)
549
- this.update((state) => {
550
- if (!state.passkeyRecord) {
551
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.NotEnrolled, {
552
- code: PasskeyControllerErrorCode.NotEnrolled,
553
- });
554
- }
555
- state.passkeyRecord.encryptedVaultKey = { ciphertext, iv };
556
- });
557
- }, _PasskeyController_changePasswordWithPasskeyVerification = async function _PasskeyController_changePasswordWithPasskeyVerification(params) {
558
- __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_requireEnrolled).call(this);
559
- const verified = await __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_verifyPasskeyAuthentication).call(this, params.authenticationResponse);
560
- if (!verified) {
561
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.AuthenticationVerificationFailed, { code: PasskeyControllerErrorCode.AuthenticationVerificationFailed });
562
- }
563
- const renewVaultKeyProtection = params.options?.renewVaultKeyProtection ?? true;
564
- if (!renewVaultKeyProtection) {
565
- await this.messenger.call('KeyringController:changePassword', params.newPassword);
566
- __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_removePasskey).call(this);
567
- return;
568
- }
569
- const vaultKeyBefore = await this.messenger.call('KeyringController:exportEncryptionKey');
570
- await this.messenger.call('KeyringController:changePassword', params.newPassword);
571
- try {
572
- const vaultKeyAfter = await this.messenger.call('KeyringController:exportEncryptionKey');
573
- await __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_renewVaultKeyProtection).call(this, {
574
- authenticationResponse: params.authenticationResponse,
575
- oldVaultKey: vaultKeyBefore,
576
- newVaultKey: vaultKeyAfter,
577
- });
578
- }
579
- catch (error) {
580
- __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_removePasskey).call(this);
581
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.VaultKeyRenewalFailed, {
582
- code: PasskeyControllerErrorCode.VaultKeyRenewalFailed,
583
- cause: error instanceof Error ? error : new Error(String(error)),
584
- });
585
- }
586
- }, _PasskeyController_removePasskeyWithPasskeyVerification = async function _PasskeyController_removePasskeyWithPasskeyVerification(authenticationResponse) {
587
- __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_requireEnrolled).call(this);
588
- const verified = await __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_verifyPasskeyAuthentication).call(this, authenticationResponse);
589
- if (!verified) {
590
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.AuthenticationVerificationFailed, { code: PasskeyControllerErrorCode.AuthenticationVerificationFailed });
591
- }
592
- __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_removePasskey).call(this);
593
- }, _PasskeyController_removePasskeyWithPasswordVerification = async function _PasskeyController_removePasskeyWithPasswordVerification(password) {
594
- __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_requireEnrolled).call(this);
595
- await this.messenger.call('KeyringController:verifyPassword', password);
596
- __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_removePasskey).call(this);
597
- }, _PasskeyController_verifyAuthenticationResponse =
598
- /**
599
- * Validates a WebAuthn authentication response against stored credential data.
600
- *
601
- * @param authenticationResponse - Parsed authentication response from the client.
602
- * @param credential - Credential identifiers and public key material for verification.
603
- * @returns Updated authenticator signature counter.
604
- */
605
- async function _PasskeyController_verifyAuthenticationResponse(authenticationResponse, credential) {
606
- // get challenge
607
- const challenge = __classPrivateFieldGet(this, _PasskeyController_instances, "m", _PasskeyController_getChallengeFromClientData).call(this, authenticationResponse.response.clientDataJSON);
608
- // get authentication ceremony
609
- const authenticationCeremony = __classPrivateFieldGet(this, _PasskeyController_ceremonyManager, "f").getAuthenticationCeremony(challenge);
610
- if (!authenticationCeremony) {
611
- log('No active passkey authentication ceremony for challenge');
612
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.NoAuthenticationCeremony, { code: PasskeyControllerErrorCode.NoAuthenticationCeremony });
613
- }
614
- try {
615
- // verify authentication response
616
- const result = await verifyAuthenticationResponse({
617
- response: authenticationResponse,
618
- expectedChallenge: authenticationCeremony.challenge,
619
- expectedOrigin: __classPrivateFieldGet(this, _PasskeyController_expectedOrigin, "f"),
620
- expectedRPIDs: __classPrivateFieldGet(this, _PasskeyController_expectedRPIDs, "f"),
621
- credential: {
622
- id: credential.id,
623
- publicKey: base64URLToBytes(credential.publicKey),
624
- counter: credential.counter,
625
- transports: credential.transports,
626
- },
627
- requireUserVerification: true,
628
- }).catch((error) => {
629
- log('Error verifying passkey authentication response', error instanceof Error ? error : new Error(String(error)));
630
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.AuthenticationVerificationFailed, {
631
- code: PasskeyControllerErrorCode.AuthenticationVerificationFailed,
632
- cause: error instanceof Error ? error : new Error(String(error)),
633
- });
634
- });
635
- if (!result.verified) {
636
- log('Passkey authentication verification returned unverified');
637
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.AuthenticationVerificationFailed, {
638
- code: PasskeyControllerErrorCode.AuthenticationVerificationFailed,
639
- });
640
- }
641
- return { newCounter: result.authenticationInfo.newCounter };
642
- }
643
- finally {
644
- // delete authentication ceremony
645
- __classPrivateFieldGet(this, _PasskeyController_ceremonyManager, "f").deleteAuthenticationCeremony(challenge);
646
- }
647
- }, _PasskeyController_withOperationLock =
648
- /**
649
- * Serializes orchestrated passkey operations that mutate state or call KeyringController.
650
- *
651
- * @param callback - Operation to run while the mutex is held.
652
- * @returns The result of the callback.
653
- */
654
- async function _PasskeyController_withOperationLock(callback) {
655
- return __classPrivateFieldGet(this, _PasskeyController_operationMutex, "f").runExclusive(callback);
656
- }, _PasskeyController_assertEnrollmentAllowed = async function _PasskeyController_assertEnrollmentAllowed(password) {
657
- if (!__classPrivateFieldGet(this, _PasskeyController_getIsOnboardingCompleted, "f").call(this)) {
658
- return;
659
- }
660
- if (!password) {
661
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.EnrollmentPasswordRequired, {
662
- code: PasskeyControllerErrorCode.EnrollmentPasswordRequired,
663
- });
664
- }
665
- await this.messenger.call('KeyringController:verifyPassword', password);
666
- }, _PasskeyController_requireEnrolled = function _PasskeyController_requireEnrolled() {
667
- const record = this.state.passkeyRecord;
668
- if (!record) {
669
- throw new PasskeyControllerError(PasskeyControllerErrorMessage.NotEnrolled, {
670
- code: PasskeyControllerErrorCode.NotEnrolled,
671
- });
672
- }
673
- return record;
674
- }, _PasskeyController_getChallengeFromClientData = function _PasskeyController_getChallengeFromClientData(clientDataJSON) {
675
- return decodeClientDataJSON(clientDataJSON).challenge;
676
- }, _PasskeyController_removePasskey = function _PasskeyController_removePasskey() {
677
- this.update(() => getDefaultPasskeyControllerState());
678
- __classPrivateFieldGet(this, _PasskeyController_ceremonyManager, "f").clear();
679
- };
680
- //# sourceMappingURL=PasskeyController.mjs.map