@metamask-previews/seedless-onboarding-controller 0.0.0-preview-7aa27646 → 0.0.0-preview-8a04e037

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.
@@ -126,12 +126,12 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
126
126
  return (0, utils_1.remove0x)((0, auth_network_utils_1.keccak256AndHexify)((0, utils_1.stringToBytes)(idToken)));
127
127
  });
128
128
  const authenticationResult = await this.toprfClient.authenticate({
129
- verifier: groupedAuthConnectionId || authConnectionId,
130
- verifierId: userId,
129
+ authConnectionId: groupedAuthConnectionId || authConnectionId,
130
+ userId,
131
131
  idTokens: hashedIdTokenHexes,
132
- singleIdVerifierParams: {
133
- subVerifier: authConnectionId,
134
- subVerifierIdTokens: idTokens,
132
+ groupedAuthConnectionParams: {
133
+ authConnectionId,
134
+ idTokens,
135
135
  },
136
136
  });
137
137
  // update the state with the authenticated user info
@@ -267,6 +267,15 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
267
267
  const seedPhraseHash = (0, auth_network_utils_1.keccak256AndHexify)(seedPhrase);
268
268
  return this.state.socialBackupsMetadata.find((backup) => backup.hash === seedPhraseHash);
269
269
  }
270
+ /**
271
+ * Clears the current state of the SeedlessOnboardingController.
272
+ */
273
+ clearState() {
274
+ const defaultState = getDefaultSeedlessOnboardingControllerState();
275
+ this.update(() => {
276
+ return defaultState;
277
+ });
278
+ }
270
279
  }
271
280
  exports.SeedlessOnboardingController = SeedlessOnboardingController;
272
281
  _SeedlessOnboardingController_vaultEncryptor = new WeakMap(), _SeedlessOnboardingController_vaultOperationMutex = new WeakMap(), _SeedlessOnboardingController_instances = new WeakSet(), _SeedlessOnboardingController_persistOprfKey =
@@ -279,12 +288,12 @@ _SeedlessOnboardingController_vaultEncryptor = new WeakMap(), _SeedlessOnboardin
279
288
  */
280
289
  async function _SeedlessOnboardingController_persistOprfKey(oprfKey, authPubKey) {
281
290
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
282
- const verifier = this.state.groupedAuthConnectionId || this.state.authConnectionId;
291
+ const authConnectionId = this.state.groupedAuthConnectionId || this.state.authConnectionId;
283
292
  try {
284
293
  await this.toprfClient.persistLocalKey({
285
294
  nodeAuthTokens: this.state.nodeAuthTokens,
286
- verifier,
287
- verifierId: this.state.userId,
295
+ authConnectionId,
296
+ userId: this.state.userId,
288
297
  oprfKey,
289
298
  authPubKey,
290
299
  });
@@ -303,13 +312,13 @@ async function _SeedlessOnboardingController_persistOprfKey(oprfKey, authPubKey)
303
312
  */
304
313
  async function _SeedlessOnboardingController_recoverEncKey(password) {
305
314
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
306
- const verifier = this.state.groupedAuthConnectionId || this.state.authConnectionId;
315
+ const authConnectionId = this.state.groupedAuthConnectionId || this.state.authConnectionId;
307
316
  try {
308
317
  const recoverEncKeyResult = await this.toprfClient.recoverEncKey({
309
318
  nodeAuthTokens: this.state.nodeAuthTokens,
310
319
  password,
311
- verifier,
312
- verifierId: this.state.userId,
320
+ authConnectionId,
321
+ userId: this.state.userId,
313
322
  });
314
323
  return recoverEncKeyResult;
315
324
  }
@@ -326,15 +335,16 @@ async function _SeedlessOnboardingController_recoverEncKey(password) {
326
335
  */
327
336
  async function _SeedlessOnboardingController_changeEncryptionKey(newPassword, oldPassword) {
328
337
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
329
- const verifier = this.state.groupedAuthConnectionId || this.state.authConnectionId;
338
+ const authConnectionId = this.state.groupedAuthConnectionId || this.state.authConnectionId;
330
339
  const { encKey, authKeyPair, keyShareIndex: newKeyShareIndex, } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_recoverEncKey).call(this, oldPassword);
331
340
  return await this.toprfClient.changeEncKey({
332
341
  nodeAuthTokens: this.state.nodeAuthTokens,
333
- verifier,
334
- verifierId: this.state.userId,
342
+ authConnectionId,
343
+ userId: this.state.userId,
335
344
  oldEncKey: encKey,
336
345
  oldAuthKeyPair: authKeyPair,
337
346
  newKeyShareIndex,
347
+ oldPassword,
338
348
  newPassword,
339
349
  });
340
350
  }, _SeedlessOnboardingController_encryptAndStoreSeedPhraseBackup =
@@ -1 +1 @@
1
- {"version":3,"file":"SeedlessOnboardingController.cjs","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"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","sourcesContent":["import { keccak256AndHexify } from '@metamask/auth-network-utils';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { encrypt, decrypt } from '@metamask/browser-passworder';\nimport type {\n KeyPair,\n NodeAuthTokens,\n SEC1EncodedPublicKey,\n} from '@metamask/toprf-secure-backup';\nimport { ToprfSecureBackup } from '@metamask/toprf-secure-backup';\nimport {\n base64ToBytes,\n bytesToBase64,\n stringToBytes,\n remove0x,\n bigIntToHex,\n} from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n\nimport {\n type AuthConnection,\n controllerName,\n SeedlessOnboardingControllerError,\n Web3AuthNetwork,\n} from './constants';\nimport { RecoveryError } from './errors';\nimport { projectLogger, createModuleLogger } from './logger';\nimport { SeedPhraseMetadata } from './SeedPhraseMetadata';\nimport type {\n VaultEncryptor,\n MutuallyExclusiveCallback,\n SeedlessOnboardingControllerMessenger,\n SeedlessOnboardingControllerOptions,\n SeedlessOnboardingControllerState,\n VaultData,\n AuthenticatedUserDetails,\n SocialBackupsMetadata,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, controllerName);\n\n/**\n * Get the default state for the Seedless Onboarding Controller.\n *\n * @returns The default state for the Seedless Onboarding Controller.\n */\nexport function getDefaultSeedlessOnboardingControllerState(): SeedlessOnboardingControllerState {\n return {\n socialBackupsMetadata: [],\n };\n}\n\n/**\n * Seedless Onboarding Controller State Metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst seedlessOnboardingMetadata: StateMetadata<SeedlessOnboardingControllerState> =\n {\n vault: {\n persist: true,\n anonymous: false,\n },\n socialBackupsMetadata: {\n persist: true,\n anonymous: true,\n },\n nodeAuthTokens: {\n persist: false,\n anonymous: true,\n },\n authConnection: {\n persist: true,\n anonymous: true,\n },\n authConnectionId: {\n persist: true,\n anonymous: true,\n },\n groupedAuthConnectionId: {\n persist: true,\n anonymous: true,\n },\n userId: {\n persist: true,\n anonymous: true,\n },\n socialLoginEmail: {\n persist: true,\n anonymous: true,\n },\n };\n\nexport class SeedlessOnboardingController extends BaseController<\n typeof controllerName,\n SeedlessOnboardingControllerState,\n SeedlessOnboardingControllerMessenger\n> {\n readonly #vaultEncryptor: VaultEncryptor;\n\n readonly #vaultOperationMutex = new Mutex();\n\n readonly toprfClient: ToprfSecureBackup;\n\n /**\n * Creates a new SeedlessOnboardingController instance.\n *\n * @param options - The options for the SeedlessOnboardingController.\n * @param options.messenger - A restricted messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.encryptor - An optional encryptor to use for encrypting and decrypting seedless onboarding vault.\n * @param options.network - The network to be used for the Seedless Onboarding flow.\n */\n constructor({\n messenger,\n state,\n encryptor = { encrypt, decrypt }, // default to `encrypt` and `decrypt` from `@metamask/browser-passworder`\n network = Web3AuthNetwork.Mainnet,\n }: SeedlessOnboardingControllerOptions) {\n super({\n name: controllerName,\n metadata: seedlessOnboardingMetadata,\n state: {\n ...getDefaultSeedlessOnboardingControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#vaultEncryptor = encryptor;\n this.toprfClient = new ToprfSecureBackup({\n network,\n });\n }\n\n /**\n * Authenticate OAuth user using the seedless onboarding flow\n * and determine if the user is already registered or not.\n *\n * @param params - The parameters for authenticate OAuth user.\n * @param params.idTokens - The ID token(s) issued by OAuth verification service. Currently this array only contains a single idToken which is verified by all the nodes, in future we are considering to issue a unique idToken for each node.\n * @param params.authConnection - The social login provider.\n * @param params.authConnectionId - OAuth authConnectionId from dashboard\n * @param params.userId - user email or id from Social login\n * @param params.groupedAuthConnectionId - Optional grouped authConnectionId to be used for the authenticate request.\n * @param params.socialLoginEmail - The user email from Social login.\n * You can pass this to use aggregate multiple OAuth connections. Useful when you want user to have same account while using different OAuth connections.\n * @returns A promise that resolves to the authentication result.\n */\n async authenticate(params: {\n idTokens: string[];\n authConnection: AuthConnection;\n authConnectionId: string;\n userId: string;\n groupedAuthConnectionId?: string;\n socialLoginEmail?: string;\n }) {\n try {\n const {\n idTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n authConnection,\n socialLoginEmail,\n } = params;\n const hashedIdTokenHexes = idTokens.map((idToken) => {\n return remove0x(keccak256AndHexify(stringToBytes(idToken)));\n });\n const authenticationResult = await this.toprfClient.authenticate({\n verifier: groupedAuthConnectionId || authConnectionId,\n verifierId: userId,\n idTokens: hashedIdTokenHexes,\n singleIdVerifierParams: {\n subVerifier: authConnectionId,\n subVerifierIdTokens: idTokens,\n },\n });\n // update the state with the authenticated user info\n this.update((state) => {\n state.nodeAuthTokens = authenticationResult.nodeAuthTokens;\n state.authConnectionId = authConnectionId;\n state.groupedAuthConnectionId = groupedAuthConnectionId;\n state.userId = userId;\n state.authConnection = authConnection;\n state.socialLoginEmail = socialLoginEmail;\n });\n return authenticationResult;\n } catch (error) {\n log('Error authenticating user', error);\n throw new Error(SeedlessOnboardingControllerError.AuthenticationError);\n }\n }\n\n /**\n * Create a new TOPRF encryption key using given password and backups the provided seed phrase.\n *\n * @param password - The password used to create new wallet and seedphrase\n * @param seedPhrase - The seed phrase to backup\n * @param keyringId - The keyring id of the backup seed phrase\n * @returns A promise that resolves to the encrypted seed phrase and the encryption key.\n */\n async createToprfKeyAndBackupSeedPhrase(\n password: string,\n seedPhrase: Uint8Array,\n keyringId: string,\n ): Promise<void> {\n // to make sure that fail fast,\n // assert that the user is authenticated before creating the TOPRF key and backing up the seed phrase\n this.#assertIsAuthenticatedUser(this.state);\n\n // locally evaluate the encryption key from the password\n const { encKey, authKeyPair, oprfKey } = this.toprfClient.createLocalKey({\n password,\n });\n\n // encrypt and store the seed phrase backup\n await this.#encryptAndStoreSeedPhraseBackup({\n keyringId,\n seedPhrase,\n encKey,\n authKeyPair,\n });\n\n // store/persist the encryption key shares\n // We store the seed phrase metadata in the metadata store first. If this operation fails,\n // we avoid persisting the encryption key shares to prevent a situation where a user appears\n // to have an account but with no associated data.\n await this.#persistOprfKey(oprfKey, authKeyPair.pk);\n // create a new vault with the resulting authentication data\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n }\n\n /**\n * Fetches all encrypted seed phrases and metadata for user's account from the metadata store.\n *\n * Decrypts the seed phrases and returns the decrypted seed phrases using the recovered encryption key from the password.\n *\n * @param password - The password used to create new wallet and seedphrase\n * @returns A promise that resolves to the seed phrase metadata.\n */\n async fetchAllSeedPhrases(password: string): Promise<Uint8Array[]> {\n // assert that the user is authenticated before fetching the seed phrases\n this.#assertIsAuthenticatedUser(this.state);\n\n const { encKey, authKeyPair } = await this.#recoverEncKey(password);\n\n try {\n const secretData = await this.toprfClient.fetchAllSecretDataItems({\n decKey: encKey,\n authKeyPair,\n });\n\n if (secretData?.length > 0) {\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n }\n\n return SeedPhraseMetadata.parseSeedPhraseFromMetadataStore(secretData);\n } catch (error) {\n log('Error fetching seed phrase metadata', error);\n throw new Error(\n SeedlessOnboardingControllerError.FailedToFetchSeedPhraseMetadata,\n );\n }\n }\n\n /**\n * Update the password of the seedless onboarding flow.\n *\n * Changing password will also update the encryption key, metadata store and the vault with new encrypted values.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n */\n async changePassword(newPassword: string, oldPassword: string) {\n // verify the old password of the encrypted vault\n await this.#unlockVaultWithPassword(oldPassword);\n\n try {\n // update the encryption key with new password and update the Metadata Store\n const { encKey: newEncKey, authKeyPair: newAuthKeyPair } =\n await this.#changeEncryptionKey(newPassword, oldPassword);\n\n // update and encrypt the vault with new password\n await this.#createNewVaultWithAuthData({\n password: newPassword,\n rawToprfEncryptionKey: newEncKey,\n rawToprfAuthKeyPair: newAuthKeyPair,\n });\n } catch (error) {\n log('Error changing password', error);\n throw new Error(SeedlessOnboardingControllerError.FailedToChangePassword);\n }\n }\n\n /**\n * Update the backup metadata state for the given seed phrase.\n *\n * @param keyringId - The keyring id of the backup seed phrase.\n * @param seedPhrase - The seed phrase to update the backup metadata for.\n */\n updateBackupMetadataState(keyringId: string, seedPhrase: Uint8Array) {\n const newBackupMetadata = {\n id: keyringId,\n hash: keccak256AndHexify(seedPhrase),\n };\n\n this.#updateSocialBackupsMetadata(newBackupMetadata);\n }\n\n /**\n * Get the hash of the seed phrase backup for the given seed phrase, from the state.\n *\n * If the given seed phrase is not backed up and not found in the state, it will return `undefined`.\n *\n * @param seedPhrase - The seed phrase to get the hash of.\n * @returns A promise that resolves to the hash of the seed phrase backup.\n */\n getSeedPhraseBackupHash(\n seedPhrase: Uint8Array,\n ): SocialBackupsMetadata | undefined {\n const seedPhraseHash = keccak256AndHexify(seedPhrase);\n return this.state.socialBackupsMetadata.find(\n (backup) => backup.hash === seedPhraseHash,\n );\n }\n\n /**\n * Persist the encryption key for the seedless onboarding flow.\n *\n * @param oprfKey - The OPRF key to be splited and persisted.\n * @param authPubKey - The authentication public key.\n * @returns A promise that resolves to the success of the operation.\n */\n async #persistOprfKey(oprfKey: bigint, authPubKey: SEC1EncodedPublicKey) {\n this.#assertIsAuthenticatedUser(this.state);\n const verifier =\n this.state.groupedAuthConnectionId || this.state.authConnectionId;\n\n try {\n await this.toprfClient.persistLocalKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n verifier,\n verifierId: this.state.userId,\n oprfKey,\n authPubKey,\n });\n } catch (error) {\n log('Error persisting local encryption key', error);\n throw new Error(SeedlessOnboardingControllerError.FailedToPersistOprfKey);\n }\n }\n\n /**\n * Recover the encryption key from password.\n *\n * @param password - The password used to derive/recover the encryption key.\n * @returns A promise that resolves to the encryption key and authentication key pair.\n * @throws RecoveryError - If failed to recover the encryption key.\n */\n async #recoverEncKey(password: string) {\n this.#assertIsAuthenticatedUser(this.state);\n const verifier =\n this.state.groupedAuthConnectionId || this.state.authConnectionId;\n\n try {\n const recoverEncKeyResult = await this.toprfClient.recoverEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n password,\n verifier,\n verifierId: this.state.userId,\n });\n return recoverEncKeyResult;\n } catch (error) {\n throw RecoveryError.getInstance(error);\n }\n }\n\n /**\n * Update the encryption key with new password and update the Metadata Store with new encryption key.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n * @returns A promise that resolves to new encryption key and authentication key pair.\n */\n async #changeEncryptionKey(newPassword: string, oldPassword: string) {\n this.#assertIsAuthenticatedUser(this.state);\n const verifier =\n this.state.groupedAuthConnectionId || this.state.authConnectionId;\n\n const {\n encKey,\n authKeyPair,\n keyShareIndex: newKeyShareIndex,\n } = await this.#recoverEncKey(oldPassword);\n\n return await this.toprfClient.changeEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n verifier,\n verifierId: this.state.userId,\n oldEncKey: encKey,\n oldAuthKeyPair: authKeyPair,\n newKeyShareIndex,\n newPassword,\n });\n }\n\n /**\n * Encrypt and store the seed phrase backup in the metadata store.\n *\n * @param params - The parameters for encrypting and storing the seed phrase backup.\n * @param params.keyringId - The keyring id of the backup seed phrase.\n * @param params.seedPhrase - The seed phrase to store.\n * @param params.encKey - The encryption key to store.\n * @param params.authKeyPair - The authentication key pair to store.\n *\n * @returns A promise that resolves to the success of the operation.\n */\n async #encryptAndStoreSeedPhraseBackup(params: {\n keyringId: string;\n seedPhrase: Uint8Array;\n encKey: Uint8Array;\n authKeyPair: KeyPair;\n }): Promise<void> {\n try {\n const { keyringId, seedPhrase, encKey, authKeyPair } = params;\n\n const seedPhraseMetadata = new SeedPhraseMetadata(seedPhrase);\n const secretData = seedPhraseMetadata.toBytes();\n await this.#withPersistedSeedPhraseBackupsState(async () => {\n await this.toprfClient.addSecretDataItem({\n encKey,\n secretData,\n authKeyPair,\n });\n return {\n id: keyringId,\n seedPhrase,\n };\n });\n } catch (error) {\n log('Error encrypting and storing seed phrase backup', error);\n throw new Error(\n SeedlessOnboardingControllerError.FailedToEncryptAndStoreSeedPhraseBackup,\n );\n }\n }\n\n /**\n * Unlocks the encrypted vault using the provided password and returns the decrypted vault data.\n * This method ensures thread-safety by using a mutex lock when accessing the vault.\n *\n * @param password - The password to decrypt the vault.\n * @returns A promise that resolves to an object containing:\n * - nodeAuthTokens: Authentication tokens to communicate with the TOPRF service\n * - toprfEncryptionKey: The decrypted TOPRF encryption key\n * - toprfAuthKeyPair: The decrypted TOPRF authentication key pair\n * @throws {Error} If:\n * - The password is invalid or empty\n * - The vault is not initialized\n * - The password is incorrect (from encryptor.decrypt)\n * - The decrypted vault data is malformed\n */\n async #unlockVaultWithPassword(password: string): Promise<{\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n }> {\n return this.#withVaultLock(async () => {\n assertIsValidPassword(password);\n\n const encryptedVault = this.state.vault;\n if (!encryptedVault) {\n throw new Error(SeedlessOnboardingControllerError.VaultError);\n }\n // Note that vault decryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n const decryptedVaultData = await this.#vaultEncryptor.decrypt(\n password,\n encryptedVault,\n );\n\n const { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair } =\n this.#parseVaultData(decryptedVaultData);\n\n // update the state with the restored nodeAuthTokens\n this.update((state) => {\n state.nodeAuthTokens = nodeAuthTokens;\n });\n\n return { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair };\n });\n }\n\n /**\n * Executes a callback function that creates or restores seed phrases and persists their hashes in the controller state.\n *\n * This method:\n * 1. Executes the provided callback to create/restore seed phrases\n * 2. Generates keccak256 hashes of the seed phrases\n * 3. Merges new hashes with existing ones in the state, ensuring uniqueness\n * 4. Updates the controller state with the combined hashes\n *\n * This is a wrapper method that should be used around any operation that creates\n * or restores seed phrases to ensure their hashes are properly tracked.\n *\n * @param createSeedPhraseBackupCallback - function that returns either a single seed phrase\n * or an array of seed phrases as Uint8Array(s)\n * @returns The original seed phrase(s) returned by the callback\n * @throws Rethrows any errors from the callback with additional logging\n */\n async #withPersistedSeedPhraseBackupsState(\n createSeedPhraseBackupCallback: () => Promise<{\n id: string;\n seedPhrase: Uint8Array;\n }>,\n ): Promise<{\n id: string;\n seedPhrase: Uint8Array;\n }> {\n try {\n const backUps = await createSeedPhraseBackupCallback();\n const newBackupMetadata = {\n id: backUps.id,\n hash: keccak256AndHexify(backUps.seedPhrase),\n };\n\n this.#updateSocialBackupsMetadata(newBackupMetadata);\n\n return backUps;\n } catch (error) {\n log('Error persisting seed phrase backups', error);\n throw error;\n }\n }\n\n #updateSocialBackupsMetadata(newSocialBackupMetadata: SocialBackupsMetadata) {\n // filter out the backed up metadata that already exists in the state\n // to prevent duplicates\n const existingBackupsMetadata = this.state.socialBackupsMetadata.find(\n (backup) => backup.id === newSocialBackupMetadata.id,\n );\n\n if (!existingBackupsMetadata) {\n this.update((state) => {\n state.socialBackupsMetadata = [\n ...state.socialBackupsMetadata,\n newSocialBackupMetadata,\n ];\n });\n }\n }\n\n /**\n * Create a new vault with the given authentication data.\n *\n * Serialize the authentication and key data which will be stored in the vault.\n *\n * @param params - The parameters for creating a new vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.rawToprfEncryptionKey - The encryption key to encrypt the vault.\n * @param params.rawToprfAuthKeyPair - The authentication key pair to encrypt the vault.\n */\n async #createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n }: {\n password: string;\n rawToprfEncryptionKey: Uint8Array;\n rawToprfAuthKeyPair: KeyPair;\n }): Promise<void> {\n this.#assertIsAuthenticatedUser(this.state);\n\n const { toprfEncryptionKey, toprfAuthKeyPair } = this.#serializeKeyData(\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n );\n\n const serializedVaultData = JSON.stringify({\n authTokens: this.state.nodeAuthTokens,\n toprfEncryptionKey,\n toprfAuthKeyPair,\n });\n\n await this.#updateVault({\n password,\n serializedVaultData,\n });\n }\n\n /**\n * Encrypt and update the vault with the given authentication data.\n *\n * @param params - The parameters for updating the vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.serializedVaultData - The serialized authentication data to update the vault with.\n * @returns A promise that resolves to the updated vault.\n */\n async #updateVault({\n password,\n serializedVaultData,\n }: {\n password: string;\n serializedVaultData: string;\n }): Promise<void> {\n await this.#withVaultLock(async () => {\n assertIsValidPassword(password);\n\n const updatedState: Partial<SeedlessOnboardingControllerState> = {};\n\n // Note that vault encryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n updatedState.vault = await this.#vaultEncryptor.encrypt(\n password,\n serializedVaultData,\n );\n\n this.update((state) => {\n state.vault = updatedState.vault;\n });\n });\n }\n\n /**\n * Lock the vault mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This ensures that each operation that interacts with the vault\n * is executed in a mutually exclusive way.\n *\n * @param callback - The function to execute while the vault mutex is locked.\n * @returns The result of the function.\n */\n async #withVaultLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return await withLock(this.#vaultOperationMutex, callback);\n }\n\n /**\n * Serialize the encryption key and authentication key pair.\n *\n * @param encKey - The encryption key to serialize.\n * @param authKeyPair - The authentication key pair to serialize.\n * @returns The serialized encryption key and authentication key pair.\n */\n #serializeKeyData(\n encKey: Uint8Array,\n authKeyPair: KeyPair,\n ): {\n toprfEncryptionKey: string;\n toprfAuthKeyPair: string;\n } {\n const b64EncodedEncKey = bytesToBase64(encKey);\n const b64EncodedAuthKeyPair = JSON.stringify({\n sk: bigIntToHex(authKeyPair.sk), // Convert BigInt to hex string\n pk: bytesToBase64(authKeyPair.pk),\n });\n\n return {\n toprfEncryptionKey: b64EncodedEncKey,\n toprfAuthKeyPair: b64EncodedAuthKeyPair,\n };\n }\n\n /**\n * Parse and deserialize the authentication data from the vault.\n *\n * @param data - The decrypted vault data.\n * @returns The parsed authentication data.\n * @throws If the vault data is not valid.\n */\n #parseVaultData(data: unknown): {\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n } {\n if (typeof data !== 'string') {\n throw new Error(SeedlessOnboardingControllerError.InvalidVaultData);\n }\n\n let parsedVaultData: unknown;\n try {\n parsedVaultData = JSON.parse(data);\n } catch {\n throw new Error(SeedlessOnboardingControllerError.InvalidVaultData);\n }\n\n this.#assertIsValidVaultData(parsedVaultData);\n\n const rawToprfEncryptionKey = base64ToBytes(\n parsedVaultData.toprfEncryptionKey,\n );\n const parsedToprfAuthKeyPair = JSON.parse(parsedVaultData.toprfAuthKeyPair);\n const rawToprfAuthKeyPair = {\n sk: BigInt(parsedToprfAuthKeyPair.sk),\n pk: base64ToBytes(parsedToprfAuthKeyPair.pk),\n };\n\n return {\n nodeAuthTokens: parsedVaultData.authTokens,\n toprfEncryptionKey: rawToprfEncryptionKey,\n toprfAuthKeyPair: rawToprfAuthKeyPair,\n };\n }\n\n /**\n * Assert that the provided value contains valid authenticated user information.\n *\n * This method checks that the value is an object containing:\n * - nodeAuthTokens: A non-empty array of authentication tokens\n * - authConnectionId: A string identifier for the OAuth connection\n * - groupedAuthConnectionId: A string identifier for grouped OAuth connections\n * - userId: A string identifier for the authenticated user\n *\n * @param value - The value to validate.\n * @throws {Error} If the value does not contain valid authenticated user information.\n */\n #assertIsAuthenticatedUser(\n value: unknown,\n ): asserts value is AuthenticatedUserDetails {\n if (\n !value ||\n typeof value !== 'object' ||\n !('authConnectionId' in value) ||\n typeof value.authConnectionId !== 'string' ||\n !('userId' in value) ||\n typeof value.userId !== 'string'\n ) {\n throw new Error(SeedlessOnboardingControllerError.MissingAuthUserInfo);\n }\n\n if (\n !('nodeAuthTokens' in value) ||\n typeof value.nodeAuthTokens !== 'object' ||\n !Array.isArray(value.nodeAuthTokens) ||\n value.nodeAuthTokens.length < 3 // At least 3 auth tokens are required for Threshold OPRF service\n ) {\n throw new Error(SeedlessOnboardingControllerError.InsufficientAuthToken);\n }\n }\n\n /**\n * Check if the provided value is a valid vault data.\n *\n * @param value - The value to check.\n * @throws If the value is not a valid vault data.\n */\n #assertIsValidVaultData(value: unknown): asserts value is VaultData {\n // value is not valid vault data if any of the following conditions are true:\n if (\n !value || // value is not defined\n typeof value !== 'object' || // value is not an object\n !('authTokens' in value) || // authTokens is not defined\n typeof value.authTokens !== 'object' || // authTokens is not an object\n !('toprfEncryptionKey' in value) || // toprfEncryptionKey is not defined\n typeof value.toprfEncryptionKey !== 'string' || // toprfEncryptionKey is not a string\n !('toprfAuthKeyPair' in value) || // toprfAuthKeyPair is not defined\n typeof value.toprfAuthKeyPair !== 'string' // toprfAuthKeyPair is not a string\n ) {\n throw new Error(SeedlessOnboardingControllerError.VaultDataError);\n }\n }\n}\n\n/**\n * Assert that the provided password is a valid non-empty string.\n *\n * @param password - The password to check.\n * @throws If the password is not a valid string.\n */\nfunction assertIsValidPassword(password: unknown): asserts password is string {\n if (typeof password !== 'string') {\n throw new Error(SeedlessOnboardingControllerError.WrongPasswordType);\n }\n\n if (!password || !password.length) {\n throw new Error(SeedlessOnboardingControllerError.InvalidEmptyPassword);\n }\n}\n\n/**\n * Lock the given mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * @param mutex - The mutex to lock.\n * @param callback - The function to execute while the mutex is locked.\n * @returns The result of the function.\n */\nasync function withLock<Result>(\n mutex: Mutex,\n callback: MutuallyExclusiveCallback<Result>,\n): Promise<Result> {\n const releaseLock = await mutex.acquire();\n\n try {\n return await callback({ releaseLock });\n } finally {\n releaseLock();\n }\n}\n"]}
1
+ {"version":3,"file":"SeedlessOnboardingController.cjs","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"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","sourcesContent":["import { keccak256AndHexify } from '@metamask/auth-network-utils';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { encrypt, decrypt } from '@metamask/browser-passworder';\nimport type {\n KeyPair,\n NodeAuthTokens,\n SEC1EncodedPublicKey,\n} from '@metamask/toprf-secure-backup';\nimport { ToprfSecureBackup } from '@metamask/toprf-secure-backup';\nimport {\n base64ToBytes,\n bytesToBase64,\n stringToBytes,\n remove0x,\n bigIntToHex,\n} from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n\nimport {\n type AuthConnection,\n controllerName,\n SeedlessOnboardingControllerError,\n Web3AuthNetwork,\n} from './constants';\nimport { RecoveryError } from './errors';\nimport { projectLogger, createModuleLogger } from './logger';\nimport { SeedPhraseMetadata } from './SeedPhraseMetadata';\nimport type {\n VaultEncryptor,\n MutuallyExclusiveCallback,\n SeedlessOnboardingControllerMessenger,\n SeedlessOnboardingControllerOptions,\n SeedlessOnboardingControllerState,\n VaultData,\n AuthenticatedUserDetails,\n SocialBackupsMetadata,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, controllerName);\n\n/**\n * Get the default state for the Seedless Onboarding Controller.\n *\n * @returns The default state for the Seedless Onboarding Controller.\n */\nexport function getDefaultSeedlessOnboardingControllerState(): SeedlessOnboardingControllerState {\n return {\n socialBackupsMetadata: [],\n };\n}\n\n/**\n * Seedless Onboarding Controller State Metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst seedlessOnboardingMetadata: StateMetadata<SeedlessOnboardingControllerState> =\n {\n vault: {\n persist: true,\n anonymous: false,\n },\n socialBackupsMetadata: {\n persist: true,\n anonymous: true,\n },\n nodeAuthTokens: {\n persist: false,\n anonymous: true,\n },\n authConnection: {\n persist: true,\n anonymous: true,\n },\n authConnectionId: {\n persist: true,\n anonymous: true,\n },\n groupedAuthConnectionId: {\n persist: true,\n anonymous: true,\n },\n userId: {\n persist: true,\n anonymous: true,\n },\n socialLoginEmail: {\n persist: true,\n anonymous: true,\n },\n };\n\nexport class SeedlessOnboardingController extends BaseController<\n typeof controllerName,\n SeedlessOnboardingControllerState,\n SeedlessOnboardingControllerMessenger\n> {\n readonly #vaultEncryptor: VaultEncryptor;\n\n readonly #vaultOperationMutex = new Mutex();\n\n readonly toprfClient: ToprfSecureBackup;\n\n /**\n * Creates a new SeedlessOnboardingController instance.\n *\n * @param options - The options for the SeedlessOnboardingController.\n * @param options.messenger - A restricted messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.encryptor - An optional encryptor to use for encrypting and decrypting seedless onboarding vault.\n * @param options.network - The network to be used for the Seedless Onboarding flow.\n */\n constructor({\n messenger,\n state,\n encryptor = { encrypt, decrypt }, // default to `encrypt` and `decrypt` from `@metamask/browser-passworder`\n network = Web3AuthNetwork.Mainnet,\n }: SeedlessOnboardingControllerOptions) {\n super({\n name: controllerName,\n metadata: seedlessOnboardingMetadata,\n state: {\n ...getDefaultSeedlessOnboardingControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#vaultEncryptor = encryptor;\n this.toprfClient = new ToprfSecureBackup({\n network,\n });\n }\n\n /**\n * Authenticate OAuth user using the seedless onboarding flow\n * and determine if the user is already registered or not.\n *\n * @param params - The parameters for authenticate OAuth user.\n * @param params.idTokens - The ID token(s) issued by OAuth verification service. Currently this array only contains a single idToken which is verified by all the nodes, in future we are considering to issue a unique idToken for each node.\n * @param params.authConnection - The social login provider.\n * @param params.authConnectionId - OAuth authConnectionId from dashboard\n * @param params.userId - user email or id from Social login\n * @param params.groupedAuthConnectionId - Optional grouped authConnectionId to be used for the authenticate request.\n * @param params.socialLoginEmail - The user email from Social login.\n * You can pass this to use aggregate multiple OAuth connections. Useful when you want user to have same account while using different OAuth connections.\n * @returns A promise that resolves to the authentication result.\n */\n async authenticate(params: {\n idTokens: string[];\n authConnection: AuthConnection;\n authConnectionId: string;\n userId: string;\n groupedAuthConnectionId?: string;\n socialLoginEmail?: string;\n }) {\n try {\n const {\n idTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n authConnection,\n socialLoginEmail,\n } = params;\n const hashedIdTokenHexes = idTokens.map((idToken) => {\n return remove0x(keccak256AndHexify(stringToBytes(idToken)));\n });\n const authenticationResult = await this.toprfClient.authenticate({\n authConnectionId: groupedAuthConnectionId || authConnectionId,\n userId,\n idTokens: hashedIdTokenHexes,\n groupedAuthConnectionParams: {\n authConnectionId,\n idTokens,\n },\n });\n // update the state with the authenticated user info\n this.update((state) => {\n state.nodeAuthTokens = authenticationResult.nodeAuthTokens;\n state.authConnectionId = authConnectionId;\n state.groupedAuthConnectionId = groupedAuthConnectionId;\n state.userId = userId;\n state.authConnection = authConnection;\n state.socialLoginEmail = socialLoginEmail;\n });\n return authenticationResult;\n } catch (error) {\n log('Error authenticating user', error);\n throw new Error(SeedlessOnboardingControllerError.AuthenticationError);\n }\n }\n\n /**\n * Create a new TOPRF encryption key using given password and backups the provided seed phrase.\n *\n * @param password - The password used to create new wallet and seedphrase\n * @param seedPhrase - The seed phrase to backup\n * @param keyringId - The keyring id of the backup seed phrase\n * @returns A promise that resolves to the encrypted seed phrase and the encryption key.\n */\n async createToprfKeyAndBackupSeedPhrase(\n password: string,\n seedPhrase: Uint8Array,\n keyringId: string,\n ): Promise<void> {\n // to make sure that fail fast,\n // assert that the user is authenticated before creating the TOPRF key and backing up the seed phrase\n this.#assertIsAuthenticatedUser(this.state);\n\n // locally evaluate the encryption key from the password\n const { encKey, authKeyPair, oprfKey } = this.toprfClient.createLocalKey({\n password,\n });\n\n // encrypt and store the seed phrase backup\n await this.#encryptAndStoreSeedPhraseBackup({\n keyringId,\n seedPhrase,\n encKey,\n authKeyPair,\n });\n\n // store/persist the encryption key shares\n // We store the seed phrase metadata in the metadata store first. If this operation fails,\n // we avoid persisting the encryption key shares to prevent a situation where a user appears\n // to have an account but with no associated data.\n await this.#persistOprfKey(oprfKey, authKeyPair.pk);\n // create a new vault with the resulting authentication data\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n }\n\n /**\n * Fetches all encrypted seed phrases and metadata for user's account from the metadata store.\n *\n * Decrypts the seed phrases and returns the decrypted seed phrases using the recovered encryption key from the password.\n *\n * @param password - The password used to create new wallet and seedphrase\n * @returns A promise that resolves to the seed phrase metadata.\n */\n async fetchAllSeedPhrases(password: string): Promise<Uint8Array[]> {\n // assert that the user is authenticated before fetching the seed phrases\n this.#assertIsAuthenticatedUser(this.state);\n\n const { encKey, authKeyPair } = await this.#recoverEncKey(password);\n\n try {\n const secretData = await this.toprfClient.fetchAllSecretDataItems({\n decKey: encKey,\n authKeyPair,\n });\n\n if (secretData?.length > 0) {\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n }\n\n return SeedPhraseMetadata.parseSeedPhraseFromMetadataStore(secretData);\n } catch (error) {\n log('Error fetching seed phrase metadata', error);\n throw new Error(\n SeedlessOnboardingControllerError.FailedToFetchSeedPhraseMetadata,\n );\n }\n }\n\n /**\n * Update the password of the seedless onboarding flow.\n *\n * Changing password will also update the encryption key, metadata store and the vault with new encrypted values.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n */\n async changePassword(newPassword: string, oldPassword: string) {\n // verify the old password of the encrypted vault\n await this.#unlockVaultWithPassword(oldPassword);\n\n try {\n // update the encryption key with new password and update the Metadata Store\n const { encKey: newEncKey, authKeyPair: newAuthKeyPair } =\n await this.#changeEncryptionKey(newPassword, oldPassword);\n\n // update and encrypt the vault with new password\n await this.#createNewVaultWithAuthData({\n password: newPassword,\n rawToprfEncryptionKey: newEncKey,\n rawToprfAuthKeyPair: newAuthKeyPair,\n });\n } catch (error) {\n log('Error changing password', error);\n throw new Error(SeedlessOnboardingControllerError.FailedToChangePassword);\n }\n }\n\n /**\n * Update the backup metadata state for the given seed phrase.\n *\n * @param keyringId - The keyring id of the backup seed phrase.\n * @param seedPhrase - The seed phrase to update the backup metadata for.\n */\n updateBackupMetadataState(keyringId: string, seedPhrase: Uint8Array) {\n const newBackupMetadata = {\n id: keyringId,\n hash: keccak256AndHexify(seedPhrase),\n };\n\n this.#updateSocialBackupsMetadata(newBackupMetadata);\n }\n\n /**\n * Get the hash of the seed phrase backup for the given seed phrase, from the state.\n *\n * If the given seed phrase is not backed up and not found in the state, it will return `undefined`.\n *\n * @param seedPhrase - The seed phrase to get the hash of.\n * @returns A promise that resolves to the hash of the seed phrase backup.\n */\n getSeedPhraseBackupHash(\n seedPhrase: Uint8Array,\n ): SocialBackupsMetadata | undefined {\n const seedPhraseHash = keccak256AndHexify(seedPhrase);\n return this.state.socialBackupsMetadata.find(\n (backup) => backup.hash === seedPhraseHash,\n );\n }\n\n /**\n * Clears the current state of the SeedlessOnboardingController.\n */\n clearState() {\n const defaultState = getDefaultSeedlessOnboardingControllerState();\n this.update(() => {\n return defaultState;\n });\n }\n\n /**\n * Persist the encryption key for the seedless onboarding flow.\n *\n * @param oprfKey - The OPRF key to be splited and persisted.\n * @param authPubKey - The authentication public key.\n * @returns A promise that resolves to the success of the operation.\n */\n async #persistOprfKey(oprfKey: bigint, authPubKey: SEC1EncodedPublicKey) {\n this.#assertIsAuthenticatedUser(this.state);\n const authConnectionId =\n this.state.groupedAuthConnectionId || this.state.authConnectionId;\n\n try {\n await this.toprfClient.persistLocalKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n authConnectionId,\n userId: this.state.userId,\n oprfKey,\n authPubKey,\n });\n } catch (error) {\n log('Error persisting local encryption key', error);\n throw new Error(SeedlessOnboardingControllerError.FailedToPersistOprfKey);\n }\n }\n\n /**\n * Recover the encryption key from password.\n *\n * @param password - The password used to derive/recover the encryption key.\n * @returns A promise that resolves to the encryption key and authentication key pair.\n * @throws RecoveryError - If failed to recover the encryption key.\n */\n async #recoverEncKey(password: string) {\n this.#assertIsAuthenticatedUser(this.state);\n const authConnectionId =\n this.state.groupedAuthConnectionId || this.state.authConnectionId;\n\n try {\n const recoverEncKeyResult = await this.toprfClient.recoverEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n password,\n authConnectionId,\n userId: this.state.userId,\n });\n return recoverEncKeyResult;\n } catch (error) {\n throw RecoveryError.getInstance(error);\n }\n }\n\n /**\n * Update the encryption key with new password and update the Metadata Store with new encryption key.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n * @returns A promise that resolves to new encryption key and authentication key pair.\n */\n async #changeEncryptionKey(newPassword: string, oldPassword: string) {\n this.#assertIsAuthenticatedUser(this.state);\n const authConnectionId =\n this.state.groupedAuthConnectionId || this.state.authConnectionId;\n\n const {\n encKey,\n authKeyPair,\n keyShareIndex: newKeyShareIndex,\n } = await this.#recoverEncKey(oldPassword);\n\n return await this.toprfClient.changeEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n authConnectionId,\n userId: this.state.userId,\n oldEncKey: encKey,\n oldAuthKeyPair: authKeyPair,\n newKeyShareIndex,\n oldPassword,\n newPassword,\n });\n }\n\n /**\n * Encrypt and store the seed phrase backup in the metadata store.\n *\n * @param params - The parameters for encrypting and storing the seed phrase backup.\n * @param params.keyringId - The keyring id of the backup seed phrase.\n * @param params.seedPhrase - The seed phrase to store.\n * @param params.encKey - The encryption key to store.\n * @param params.authKeyPair - The authentication key pair to store.\n *\n * @returns A promise that resolves to the success of the operation.\n */\n async #encryptAndStoreSeedPhraseBackup(params: {\n keyringId: string;\n seedPhrase: Uint8Array;\n encKey: Uint8Array;\n authKeyPair: KeyPair;\n }): Promise<void> {\n try {\n const { keyringId, seedPhrase, encKey, authKeyPair } = params;\n\n const seedPhraseMetadata = new SeedPhraseMetadata(seedPhrase);\n const secretData = seedPhraseMetadata.toBytes();\n await this.#withPersistedSeedPhraseBackupsState(async () => {\n await this.toprfClient.addSecretDataItem({\n encKey,\n secretData,\n authKeyPair,\n });\n return {\n id: keyringId,\n seedPhrase,\n };\n });\n } catch (error) {\n log('Error encrypting and storing seed phrase backup', error);\n throw new Error(\n SeedlessOnboardingControllerError.FailedToEncryptAndStoreSeedPhraseBackup,\n );\n }\n }\n\n /**\n * Unlocks the encrypted vault using the provided password and returns the decrypted vault data.\n * This method ensures thread-safety by using a mutex lock when accessing the vault.\n *\n * @param password - The password to decrypt the vault.\n * @returns A promise that resolves to an object containing:\n * - nodeAuthTokens: Authentication tokens to communicate with the TOPRF service\n * - toprfEncryptionKey: The decrypted TOPRF encryption key\n * - toprfAuthKeyPair: The decrypted TOPRF authentication key pair\n * @throws {Error} If:\n * - The password is invalid or empty\n * - The vault is not initialized\n * - The password is incorrect (from encryptor.decrypt)\n * - The decrypted vault data is malformed\n */\n async #unlockVaultWithPassword(password: string): Promise<{\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n }> {\n return this.#withVaultLock(async () => {\n assertIsValidPassword(password);\n\n const encryptedVault = this.state.vault;\n if (!encryptedVault) {\n throw new Error(SeedlessOnboardingControllerError.VaultError);\n }\n // Note that vault decryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n const decryptedVaultData = await this.#vaultEncryptor.decrypt(\n password,\n encryptedVault,\n );\n\n const { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair } =\n this.#parseVaultData(decryptedVaultData);\n\n // update the state with the restored nodeAuthTokens\n this.update((state) => {\n state.nodeAuthTokens = nodeAuthTokens;\n });\n\n return { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair };\n });\n }\n\n /**\n * Executes a callback function that creates or restores seed phrases and persists their hashes in the controller state.\n *\n * This method:\n * 1. Executes the provided callback to create/restore seed phrases\n * 2. Generates keccak256 hashes of the seed phrases\n * 3. Merges new hashes with existing ones in the state, ensuring uniqueness\n * 4. Updates the controller state with the combined hashes\n *\n * This is a wrapper method that should be used around any operation that creates\n * or restores seed phrases to ensure their hashes are properly tracked.\n *\n * @param createSeedPhraseBackupCallback - function that returns either a single seed phrase\n * or an array of seed phrases as Uint8Array(s)\n * @returns The original seed phrase(s) returned by the callback\n * @throws Rethrows any errors from the callback with additional logging\n */\n async #withPersistedSeedPhraseBackupsState(\n createSeedPhraseBackupCallback: () => Promise<{\n id: string;\n seedPhrase: Uint8Array;\n }>,\n ): Promise<{\n id: string;\n seedPhrase: Uint8Array;\n }> {\n try {\n const backUps = await createSeedPhraseBackupCallback();\n const newBackupMetadata = {\n id: backUps.id,\n hash: keccak256AndHexify(backUps.seedPhrase),\n };\n\n this.#updateSocialBackupsMetadata(newBackupMetadata);\n\n return backUps;\n } catch (error) {\n log('Error persisting seed phrase backups', error);\n throw error;\n }\n }\n\n #updateSocialBackupsMetadata(newSocialBackupMetadata: SocialBackupsMetadata) {\n // filter out the backed up metadata that already exists in the state\n // to prevent duplicates\n const existingBackupsMetadata = this.state.socialBackupsMetadata.find(\n (backup) => backup.id === newSocialBackupMetadata.id,\n );\n\n if (!existingBackupsMetadata) {\n this.update((state) => {\n state.socialBackupsMetadata = [\n ...state.socialBackupsMetadata,\n newSocialBackupMetadata,\n ];\n });\n }\n }\n\n /**\n * Create a new vault with the given authentication data.\n *\n * Serialize the authentication and key data which will be stored in the vault.\n *\n * @param params - The parameters for creating a new vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.rawToprfEncryptionKey - The encryption key to encrypt the vault.\n * @param params.rawToprfAuthKeyPair - The authentication key pair to encrypt the vault.\n */\n async #createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n }: {\n password: string;\n rawToprfEncryptionKey: Uint8Array;\n rawToprfAuthKeyPair: KeyPair;\n }): Promise<void> {\n this.#assertIsAuthenticatedUser(this.state);\n\n const { toprfEncryptionKey, toprfAuthKeyPair } = this.#serializeKeyData(\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n );\n\n const serializedVaultData = JSON.stringify({\n authTokens: this.state.nodeAuthTokens,\n toprfEncryptionKey,\n toprfAuthKeyPair,\n });\n\n await this.#updateVault({\n password,\n serializedVaultData,\n });\n }\n\n /**\n * Encrypt and update the vault with the given authentication data.\n *\n * @param params - The parameters for updating the vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.serializedVaultData - The serialized authentication data to update the vault with.\n * @returns A promise that resolves to the updated vault.\n */\n async #updateVault({\n password,\n serializedVaultData,\n }: {\n password: string;\n serializedVaultData: string;\n }): Promise<void> {\n await this.#withVaultLock(async () => {\n assertIsValidPassword(password);\n\n const updatedState: Partial<SeedlessOnboardingControllerState> = {};\n\n // Note that vault encryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n updatedState.vault = await this.#vaultEncryptor.encrypt(\n password,\n serializedVaultData,\n );\n\n this.update((state) => {\n state.vault = updatedState.vault;\n });\n });\n }\n\n /**\n * Lock the vault mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This ensures that each operation that interacts with the vault\n * is executed in a mutually exclusive way.\n *\n * @param callback - The function to execute while the vault mutex is locked.\n * @returns The result of the function.\n */\n async #withVaultLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return await withLock(this.#vaultOperationMutex, callback);\n }\n\n /**\n * Serialize the encryption key and authentication key pair.\n *\n * @param encKey - The encryption key to serialize.\n * @param authKeyPair - The authentication key pair to serialize.\n * @returns The serialized encryption key and authentication key pair.\n */\n #serializeKeyData(\n encKey: Uint8Array,\n authKeyPair: KeyPair,\n ): {\n toprfEncryptionKey: string;\n toprfAuthKeyPair: string;\n } {\n const b64EncodedEncKey = bytesToBase64(encKey);\n const b64EncodedAuthKeyPair = JSON.stringify({\n sk: bigIntToHex(authKeyPair.sk), // Convert BigInt to hex string\n pk: bytesToBase64(authKeyPair.pk),\n });\n\n return {\n toprfEncryptionKey: b64EncodedEncKey,\n toprfAuthKeyPair: b64EncodedAuthKeyPair,\n };\n }\n\n /**\n * Parse and deserialize the authentication data from the vault.\n *\n * @param data - The decrypted vault data.\n * @returns The parsed authentication data.\n * @throws If the vault data is not valid.\n */\n #parseVaultData(data: unknown): {\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n } {\n if (typeof data !== 'string') {\n throw new Error(SeedlessOnboardingControllerError.InvalidVaultData);\n }\n\n let parsedVaultData: unknown;\n try {\n parsedVaultData = JSON.parse(data);\n } catch {\n throw new Error(SeedlessOnboardingControllerError.InvalidVaultData);\n }\n\n this.#assertIsValidVaultData(parsedVaultData);\n\n const rawToprfEncryptionKey = base64ToBytes(\n parsedVaultData.toprfEncryptionKey,\n );\n const parsedToprfAuthKeyPair = JSON.parse(parsedVaultData.toprfAuthKeyPair);\n const rawToprfAuthKeyPair = {\n sk: BigInt(parsedToprfAuthKeyPair.sk),\n pk: base64ToBytes(parsedToprfAuthKeyPair.pk),\n };\n\n return {\n nodeAuthTokens: parsedVaultData.authTokens,\n toprfEncryptionKey: rawToprfEncryptionKey,\n toprfAuthKeyPair: rawToprfAuthKeyPair,\n };\n }\n\n /**\n * Assert that the provided value contains valid authenticated user information.\n *\n * This method checks that the value is an object containing:\n * - nodeAuthTokens: A non-empty array of authentication tokens\n * - authConnectionId: A string identifier for the OAuth connection\n * - groupedAuthConnectionId: A string identifier for grouped OAuth connections\n * - userId: A string identifier for the authenticated user\n *\n * @param value - The value to validate.\n * @throws {Error} If the value does not contain valid authenticated user information.\n */\n #assertIsAuthenticatedUser(\n value: unknown,\n ): asserts value is AuthenticatedUserDetails {\n if (\n !value ||\n typeof value !== 'object' ||\n !('authConnectionId' in value) ||\n typeof value.authConnectionId !== 'string' ||\n !('userId' in value) ||\n typeof value.userId !== 'string'\n ) {\n throw new Error(SeedlessOnboardingControllerError.MissingAuthUserInfo);\n }\n\n if (\n !('nodeAuthTokens' in value) ||\n typeof value.nodeAuthTokens !== 'object' ||\n !Array.isArray(value.nodeAuthTokens) ||\n value.nodeAuthTokens.length < 3 // At least 3 auth tokens are required for Threshold OPRF service\n ) {\n throw new Error(SeedlessOnboardingControllerError.InsufficientAuthToken);\n }\n }\n\n /**\n * Check if the provided value is a valid vault data.\n *\n * @param value - The value to check.\n * @throws If the value is not a valid vault data.\n */\n #assertIsValidVaultData(value: unknown): asserts value is VaultData {\n // value is not valid vault data if any of the following conditions are true:\n if (\n !value || // value is not defined\n typeof value !== 'object' || // value is not an object\n !('authTokens' in value) || // authTokens is not defined\n typeof value.authTokens !== 'object' || // authTokens is not an object\n !('toprfEncryptionKey' in value) || // toprfEncryptionKey is not defined\n typeof value.toprfEncryptionKey !== 'string' || // toprfEncryptionKey is not a string\n !('toprfAuthKeyPair' in value) || // toprfAuthKeyPair is not defined\n typeof value.toprfAuthKeyPair !== 'string' // toprfAuthKeyPair is not a string\n ) {\n throw new Error(SeedlessOnboardingControllerError.VaultDataError);\n }\n }\n}\n\n/**\n * Assert that the provided password is a valid non-empty string.\n *\n * @param password - The password to check.\n * @throws If the password is not a valid string.\n */\nfunction assertIsValidPassword(password: unknown): asserts password is string {\n if (typeof password !== 'string') {\n throw new Error(SeedlessOnboardingControllerError.WrongPasswordType);\n }\n\n if (!password || !password.length) {\n throw new Error(SeedlessOnboardingControllerError.InvalidEmptyPassword);\n }\n}\n\n/**\n * Lock the given mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * @param mutex - The mutex to lock.\n * @param callback - The function to execute while the mutex is locked.\n * @returns The result of the function.\n */\nasync function withLock<Result>(\n mutex: Mutex,\n callback: MutuallyExclusiveCallback<Result>,\n): Promise<Result> {\n const releaseLock = await mutex.acquire();\n\n try {\n return await callback({ releaseLock });\n } finally {\n releaseLock();\n }\n}\n"]}
@@ -87,5 +87,9 @@ export declare class SeedlessOnboardingController extends BaseController<typeof
87
87
  * @returns A promise that resolves to the hash of the seed phrase backup.
88
88
  */
89
89
  getSeedPhraseBackupHash(seedPhrase: Uint8Array): SocialBackupsMetadata | undefined;
90
+ /**
91
+ * Clears the current state of the SeedlessOnboardingController.
92
+ */
93
+ clearState(): void;
90
94
  }
91
95
  //# sourceMappingURL=SeedlessOnboardingController.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SeedlessOnboardingController.d.cts","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAO3D,OAAO,EAAE,iBAAiB,EAAE,sCAAsC;AAUlE,OAAO,EACL,KAAK,cAAc,EACnB,cAAc,EAGf,wBAAoB;AAIrB,OAAO,KAAK,EAGV,qCAAqC,EACrC,mCAAmC,EACnC,iCAAiC,EAGjC,qBAAqB,EACtB,oBAAgB;AAIjB;;;;GAIG;AACH,wBAAgB,2CAA2C,IAAI,iCAAiC,CAI/F;AA6CD,qBAAa,4BAA6B,SAAQ,cAAc,CAC9D,OAAO,cAAc,EACrB,iCAAiC,EACjC,qCAAqC,CACtC;;IAKC,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IAExC;;;;;;;;OAQG;gBACS,EACV,SAAS,EACT,KAAK,EACL,SAAgC,EAAE,yEAAyE;IAC3G,OAAiC,GAClC,EAAE,mCAAmC;IAiBtC;;;;;;;;;;;;;OAaG;IACG,YAAY,CAAC,MAAM,EAAE;QACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,cAAc,EAAE,cAAc,CAAC;QAC/B,gBAAgB,EAAE,MAAM,CAAC;QACzB,MAAM,EAAE,MAAM,CAAC;QACf,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B;IAsCD;;;;;;;OAOG;IACG,iCAAiC,CACrC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IA+BhB;;;;;;;OAOG;IACG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IA6BlE;;;;;;;OAOG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAqB7D;;;;;OAKG;IACH,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;IASnE;;;;;;;OAOG;IACH,uBAAuB,CACrB,UAAU,EAAE,UAAU,GACrB,qBAAqB,GAAG,SAAS;CA+brC"}
1
+ {"version":3,"file":"SeedlessOnboardingController.d.cts","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAO3D,OAAO,EAAE,iBAAiB,EAAE,sCAAsC;AAUlE,OAAO,EACL,KAAK,cAAc,EACnB,cAAc,EAGf,wBAAoB;AAIrB,OAAO,KAAK,EAGV,qCAAqC,EACrC,mCAAmC,EACnC,iCAAiC,EAGjC,qBAAqB,EACtB,oBAAgB;AAIjB;;;;GAIG;AACH,wBAAgB,2CAA2C,IAAI,iCAAiC,CAI/F;AA6CD,qBAAa,4BAA6B,SAAQ,cAAc,CAC9D,OAAO,cAAc,EACrB,iCAAiC,EACjC,qCAAqC,CACtC;;IAKC,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IAExC;;;;;;;;OAQG;gBACS,EACV,SAAS,EACT,KAAK,EACL,SAAgC,EAAE,yEAAyE;IAC3G,OAAiC,GAClC,EAAE,mCAAmC;IAiBtC;;;;;;;;;;;;;OAaG;IACG,YAAY,CAAC,MAAM,EAAE;QACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,cAAc,EAAE,cAAc,CAAC;QAC/B,gBAAgB,EAAE,MAAM,CAAC;QACzB,MAAM,EAAE,MAAM,CAAC;QACf,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B;IAsCD;;;;;;;OAOG;IACG,iCAAiC,CACrC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IA+BhB;;;;;;;OAOG;IACG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IA6BlE;;;;;;;OAOG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAqB7D;;;;;OAKG;IACH,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;IASnE;;;;;;;OAOG;IACH,uBAAuB,CACrB,UAAU,EAAE,UAAU,GACrB,qBAAqB,GAAG,SAAS;IAOpC;;OAEG;IACH,UAAU;CAgcX"}
@@ -87,5 +87,9 @@ export declare class SeedlessOnboardingController extends BaseController<typeof
87
87
  * @returns A promise that resolves to the hash of the seed phrase backup.
88
88
  */
89
89
  getSeedPhraseBackupHash(seedPhrase: Uint8Array): SocialBackupsMetadata | undefined;
90
+ /**
91
+ * Clears the current state of the SeedlessOnboardingController.
92
+ */
93
+ clearState(): void;
90
94
  }
91
95
  //# sourceMappingURL=SeedlessOnboardingController.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SeedlessOnboardingController.d.mts","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAO3D,OAAO,EAAE,iBAAiB,EAAE,sCAAsC;AAUlE,OAAO,EACL,KAAK,cAAc,EACnB,cAAc,EAGf,wBAAoB;AAIrB,OAAO,KAAK,EAGV,qCAAqC,EACrC,mCAAmC,EACnC,iCAAiC,EAGjC,qBAAqB,EACtB,oBAAgB;AAIjB;;;;GAIG;AACH,wBAAgB,2CAA2C,IAAI,iCAAiC,CAI/F;AA6CD,qBAAa,4BAA6B,SAAQ,cAAc,CAC9D,OAAO,cAAc,EACrB,iCAAiC,EACjC,qCAAqC,CACtC;;IAKC,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IAExC;;;;;;;;OAQG;gBACS,EACV,SAAS,EACT,KAAK,EACL,SAAgC,EAAE,yEAAyE;IAC3G,OAAiC,GAClC,EAAE,mCAAmC;IAiBtC;;;;;;;;;;;;;OAaG;IACG,YAAY,CAAC,MAAM,EAAE;QACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,cAAc,EAAE,cAAc,CAAC;QAC/B,gBAAgB,EAAE,MAAM,CAAC;QACzB,MAAM,EAAE,MAAM,CAAC;QACf,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B;IAsCD;;;;;;;OAOG;IACG,iCAAiC,CACrC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IA+BhB;;;;;;;OAOG;IACG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IA6BlE;;;;;;;OAOG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAqB7D;;;;;OAKG;IACH,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;IASnE;;;;;;;OAOG;IACH,uBAAuB,CACrB,UAAU,EAAE,UAAU,GACrB,qBAAqB,GAAG,SAAS;CA+brC"}
1
+ {"version":3,"file":"SeedlessOnboardingController.d.mts","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAO3D,OAAO,EAAE,iBAAiB,EAAE,sCAAsC;AAUlE,OAAO,EACL,KAAK,cAAc,EACnB,cAAc,EAGf,wBAAoB;AAIrB,OAAO,KAAK,EAGV,qCAAqC,EACrC,mCAAmC,EACnC,iCAAiC,EAGjC,qBAAqB,EACtB,oBAAgB;AAIjB;;;;GAIG;AACH,wBAAgB,2CAA2C,IAAI,iCAAiC,CAI/F;AA6CD,qBAAa,4BAA6B,SAAQ,cAAc,CAC9D,OAAO,cAAc,EACrB,iCAAiC,EACjC,qCAAqC,CACtC;;IAKC,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IAExC;;;;;;;;OAQG;gBACS,EACV,SAAS,EACT,KAAK,EACL,SAAgC,EAAE,yEAAyE;IAC3G,OAAiC,GAClC,EAAE,mCAAmC;IAiBtC;;;;;;;;;;;;;OAaG;IACG,YAAY,CAAC,MAAM,EAAE;QACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,cAAc,EAAE,cAAc,CAAC;QAC/B,gBAAgB,EAAE,MAAM,CAAC;QACzB,MAAM,EAAE,MAAM,CAAC;QACf,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B;IAsCD;;;;;;;OAOG;IACG,iCAAiC,CACrC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IA+BhB;;;;;;;OAOG;IACG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IA6BlE;;;;;;;OAOG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAqB7D;;;;;OAKG;IACH,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;IASnE;;;;;;;OAOG;IACH,uBAAuB,CACrB,UAAU,EAAE,UAAU,GACrB,qBAAqB,GAAG,SAAS;IAOpC;;OAEG;IACH,UAAU;CAgcX"}
@@ -122,12 +122,12 @@ export class SeedlessOnboardingController extends BaseController {
122
122
  return remove0x(keccak256AndHexify(stringToBytes(idToken)));
123
123
  });
124
124
  const authenticationResult = await this.toprfClient.authenticate({
125
- verifier: groupedAuthConnectionId || authConnectionId,
126
- verifierId: userId,
125
+ authConnectionId: groupedAuthConnectionId || authConnectionId,
126
+ userId,
127
127
  idTokens: hashedIdTokenHexes,
128
- singleIdVerifierParams: {
129
- subVerifier: authConnectionId,
130
- subVerifierIdTokens: idTokens,
128
+ groupedAuthConnectionParams: {
129
+ authConnectionId,
130
+ idTokens,
131
131
  },
132
132
  });
133
133
  // update the state with the authenticated user info
@@ -263,6 +263,15 @@ export class SeedlessOnboardingController extends BaseController {
263
263
  const seedPhraseHash = keccak256AndHexify(seedPhrase);
264
264
  return this.state.socialBackupsMetadata.find((backup) => backup.hash === seedPhraseHash);
265
265
  }
266
+ /**
267
+ * Clears the current state of the SeedlessOnboardingController.
268
+ */
269
+ clearState() {
270
+ const defaultState = getDefaultSeedlessOnboardingControllerState();
271
+ this.update(() => {
272
+ return defaultState;
273
+ });
274
+ }
266
275
  }
267
276
  _SeedlessOnboardingController_vaultEncryptor = new WeakMap(), _SeedlessOnboardingController_vaultOperationMutex = new WeakMap(), _SeedlessOnboardingController_instances = new WeakSet(), _SeedlessOnboardingController_persistOprfKey =
268
277
  /**
@@ -274,12 +283,12 @@ _SeedlessOnboardingController_vaultEncryptor = new WeakMap(), _SeedlessOnboardin
274
283
  */
275
284
  async function _SeedlessOnboardingController_persistOprfKey(oprfKey, authPubKey) {
276
285
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
277
- const verifier = this.state.groupedAuthConnectionId || this.state.authConnectionId;
286
+ const authConnectionId = this.state.groupedAuthConnectionId || this.state.authConnectionId;
278
287
  try {
279
288
  await this.toprfClient.persistLocalKey({
280
289
  nodeAuthTokens: this.state.nodeAuthTokens,
281
- verifier,
282
- verifierId: this.state.userId,
290
+ authConnectionId,
291
+ userId: this.state.userId,
283
292
  oprfKey,
284
293
  authPubKey,
285
294
  });
@@ -298,13 +307,13 @@ async function _SeedlessOnboardingController_persistOprfKey(oprfKey, authPubKey)
298
307
  */
299
308
  async function _SeedlessOnboardingController_recoverEncKey(password) {
300
309
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
301
- const verifier = this.state.groupedAuthConnectionId || this.state.authConnectionId;
310
+ const authConnectionId = this.state.groupedAuthConnectionId || this.state.authConnectionId;
302
311
  try {
303
312
  const recoverEncKeyResult = await this.toprfClient.recoverEncKey({
304
313
  nodeAuthTokens: this.state.nodeAuthTokens,
305
314
  password,
306
- verifier,
307
- verifierId: this.state.userId,
315
+ authConnectionId,
316
+ userId: this.state.userId,
308
317
  });
309
318
  return recoverEncKeyResult;
310
319
  }
@@ -321,15 +330,16 @@ async function _SeedlessOnboardingController_recoverEncKey(password) {
321
330
  */
322
331
  async function _SeedlessOnboardingController_changeEncryptionKey(newPassword, oldPassword) {
323
332
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
324
- const verifier = this.state.groupedAuthConnectionId || this.state.authConnectionId;
333
+ const authConnectionId = this.state.groupedAuthConnectionId || this.state.authConnectionId;
325
334
  const { encKey, authKeyPair, keyShareIndex: newKeyShareIndex, } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_recoverEncKey).call(this, oldPassword);
326
335
  return await this.toprfClient.changeEncKey({
327
336
  nodeAuthTokens: this.state.nodeAuthTokens,
328
- verifier,
329
- verifierId: this.state.userId,
337
+ authConnectionId,
338
+ userId: this.state.userId,
330
339
  oldEncKey: encKey,
331
340
  oldAuthKeyPair: authKeyPair,
332
341
  newKeyShareIndex,
342
+ oldPassword,
333
343
  newPassword,
334
344
  });
335
345
  }, _SeedlessOnboardingController_encryptAndStoreSeedPhraseBackup =
@@ -1 +1 @@
1
- {"version":3,"file":"SeedlessOnboardingController.mjs","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"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","sourcesContent":["import { keccak256AndHexify } from '@metamask/auth-network-utils';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { encrypt, decrypt } from '@metamask/browser-passworder';\nimport type {\n KeyPair,\n NodeAuthTokens,\n SEC1EncodedPublicKey,\n} from '@metamask/toprf-secure-backup';\nimport { ToprfSecureBackup } from '@metamask/toprf-secure-backup';\nimport {\n base64ToBytes,\n bytesToBase64,\n stringToBytes,\n remove0x,\n bigIntToHex,\n} from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n\nimport {\n type AuthConnection,\n controllerName,\n SeedlessOnboardingControllerError,\n Web3AuthNetwork,\n} from './constants';\nimport { RecoveryError } from './errors';\nimport { projectLogger, createModuleLogger } from './logger';\nimport { SeedPhraseMetadata } from './SeedPhraseMetadata';\nimport type {\n VaultEncryptor,\n MutuallyExclusiveCallback,\n SeedlessOnboardingControllerMessenger,\n SeedlessOnboardingControllerOptions,\n SeedlessOnboardingControllerState,\n VaultData,\n AuthenticatedUserDetails,\n SocialBackupsMetadata,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, controllerName);\n\n/**\n * Get the default state for the Seedless Onboarding Controller.\n *\n * @returns The default state for the Seedless Onboarding Controller.\n */\nexport function getDefaultSeedlessOnboardingControllerState(): SeedlessOnboardingControllerState {\n return {\n socialBackupsMetadata: [],\n };\n}\n\n/**\n * Seedless Onboarding Controller State Metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst seedlessOnboardingMetadata: StateMetadata<SeedlessOnboardingControllerState> =\n {\n vault: {\n persist: true,\n anonymous: false,\n },\n socialBackupsMetadata: {\n persist: true,\n anonymous: true,\n },\n nodeAuthTokens: {\n persist: false,\n anonymous: true,\n },\n authConnection: {\n persist: true,\n anonymous: true,\n },\n authConnectionId: {\n persist: true,\n anonymous: true,\n },\n groupedAuthConnectionId: {\n persist: true,\n anonymous: true,\n },\n userId: {\n persist: true,\n anonymous: true,\n },\n socialLoginEmail: {\n persist: true,\n anonymous: true,\n },\n };\n\nexport class SeedlessOnboardingController extends BaseController<\n typeof controllerName,\n SeedlessOnboardingControllerState,\n SeedlessOnboardingControllerMessenger\n> {\n readonly #vaultEncryptor: VaultEncryptor;\n\n readonly #vaultOperationMutex = new Mutex();\n\n readonly toprfClient: ToprfSecureBackup;\n\n /**\n * Creates a new SeedlessOnboardingController instance.\n *\n * @param options - The options for the SeedlessOnboardingController.\n * @param options.messenger - A restricted messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.encryptor - An optional encryptor to use for encrypting and decrypting seedless onboarding vault.\n * @param options.network - The network to be used for the Seedless Onboarding flow.\n */\n constructor({\n messenger,\n state,\n encryptor = { encrypt, decrypt }, // default to `encrypt` and `decrypt` from `@metamask/browser-passworder`\n network = Web3AuthNetwork.Mainnet,\n }: SeedlessOnboardingControllerOptions) {\n super({\n name: controllerName,\n metadata: seedlessOnboardingMetadata,\n state: {\n ...getDefaultSeedlessOnboardingControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#vaultEncryptor = encryptor;\n this.toprfClient = new ToprfSecureBackup({\n network,\n });\n }\n\n /**\n * Authenticate OAuth user using the seedless onboarding flow\n * and determine if the user is already registered or not.\n *\n * @param params - The parameters for authenticate OAuth user.\n * @param params.idTokens - The ID token(s) issued by OAuth verification service. Currently this array only contains a single idToken which is verified by all the nodes, in future we are considering to issue a unique idToken for each node.\n * @param params.authConnection - The social login provider.\n * @param params.authConnectionId - OAuth authConnectionId from dashboard\n * @param params.userId - user email or id from Social login\n * @param params.groupedAuthConnectionId - Optional grouped authConnectionId to be used for the authenticate request.\n * @param params.socialLoginEmail - The user email from Social login.\n * You can pass this to use aggregate multiple OAuth connections. Useful when you want user to have same account while using different OAuth connections.\n * @returns A promise that resolves to the authentication result.\n */\n async authenticate(params: {\n idTokens: string[];\n authConnection: AuthConnection;\n authConnectionId: string;\n userId: string;\n groupedAuthConnectionId?: string;\n socialLoginEmail?: string;\n }) {\n try {\n const {\n idTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n authConnection,\n socialLoginEmail,\n } = params;\n const hashedIdTokenHexes = idTokens.map((idToken) => {\n return remove0x(keccak256AndHexify(stringToBytes(idToken)));\n });\n const authenticationResult = await this.toprfClient.authenticate({\n verifier: groupedAuthConnectionId || authConnectionId,\n verifierId: userId,\n idTokens: hashedIdTokenHexes,\n singleIdVerifierParams: {\n subVerifier: authConnectionId,\n subVerifierIdTokens: idTokens,\n },\n });\n // update the state with the authenticated user info\n this.update((state) => {\n state.nodeAuthTokens = authenticationResult.nodeAuthTokens;\n state.authConnectionId = authConnectionId;\n state.groupedAuthConnectionId = groupedAuthConnectionId;\n state.userId = userId;\n state.authConnection = authConnection;\n state.socialLoginEmail = socialLoginEmail;\n });\n return authenticationResult;\n } catch (error) {\n log('Error authenticating user', error);\n throw new Error(SeedlessOnboardingControllerError.AuthenticationError);\n }\n }\n\n /**\n * Create a new TOPRF encryption key using given password and backups the provided seed phrase.\n *\n * @param password - The password used to create new wallet and seedphrase\n * @param seedPhrase - The seed phrase to backup\n * @param keyringId - The keyring id of the backup seed phrase\n * @returns A promise that resolves to the encrypted seed phrase and the encryption key.\n */\n async createToprfKeyAndBackupSeedPhrase(\n password: string,\n seedPhrase: Uint8Array,\n keyringId: string,\n ): Promise<void> {\n // to make sure that fail fast,\n // assert that the user is authenticated before creating the TOPRF key and backing up the seed phrase\n this.#assertIsAuthenticatedUser(this.state);\n\n // locally evaluate the encryption key from the password\n const { encKey, authKeyPair, oprfKey } = this.toprfClient.createLocalKey({\n password,\n });\n\n // encrypt and store the seed phrase backup\n await this.#encryptAndStoreSeedPhraseBackup({\n keyringId,\n seedPhrase,\n encKey,\n authKeyPair,\n });\n\n // store/persist the encryption key shares\n // We store the seed phrase metadata in the metadata store first. If this operation fails,\n // we avoid persisting the encryption key shares to prevent a situation where a user appears\n // to have an account but with no associated data.\n await this.#persistOprfKey(oprfKey, authKeyPair.pk);\n // create a new vault with the resulting authentication data\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n }\n\n /**\n * Fetches all encrypted seed phrases and metadata for user's account from the metadata store.\n *\n * Decrypts the seed phrases and returns the decrypted seed phrases using the recovered encryption key from the password.\n *\n * @param password - The password used to create new wallet and seedphrase\n * @returns A promise that resolves to the seed phrase metadata.\n */\n async fetchAllSeedPhrases(password: string): Promise<Uint8Array[]> {\n // assert that the user is authenticated before fetching the seed phrases\n this.#assertIsAuthenticatedUser(this.state);\n\n const { encKey, authKeyPair } = await this.#recoverEncKey(password);\n\n try {\n const secretData = await this.toprfClient.fetchAllSecretDataItems({\n decKey: encKey,\n authKeyPair,\n });\n\n if (secretData?.length > 0) {\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n }\n\n return SeedPhraseMetadata.parseSeedPhraseFromMetadataStore(secretData);\n } catch (error) {\n log('Error fetching seed phrase metadata', error);\n throw new Error(\n SeedlessOnboardingControllerError.FailedToFetchSeedPhraseMetadata,\n );\n }\n }\n\n /**\n * Update the password of the seedless onboarding flow.\n *\n * Changing password will also update the encryption key, metadata store and the vault with new encrypted values.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n */\n async changePassword(newPassword: string, oldPassword: string) {\n // verify the old password of the encrypted vault\n await this.#unlockVaultWithPassword(oldPassword);\n\n try {\n // update the encryption key with new password and update the Metadata Store\n const { encKey: newEncKey, authKeyPair: newAuthKeyPair } =\n await this.#changeEncryptionKey(newPassword, oldPassword);\n\n // update and encrypt the vault with new password\n await this.#createNewVaultWithAuthData({\n password: newPassword,\n rawToprfEncryptionKey: newEncKey,\n rawToprfAuthKeyPair: newAuthKeyPair,\n });\n } catch (error) {\n log('Error changing password', error);\n throw new Error(SeedlessOnboardingControllerError.FailedToChangePassword);\n }\n }\n\n /**\n * Update the backup metadata state for the given seed phrase.\n *\n * @param keyringId - The keyring id of the backup seed phrase.\n * @param seedPhrase - The seed phrase to update the backup metadata for.\n */\n updateBackupMetadataState(keyringId: string, seedPhrase: Uint8Array) {\n const newBackupMetadata = {\n id: keyringId,\n hash: keccak256AndHexify(seedPhrase),\n };\n\n this.#updateSocialBackupsMetadata(newBackupMetadata);\n }\n\n /**\n * Get the hash of the seed phrase backup for the given seed phrase, from the state.\n *\n * If the given seed phrase is not backed up and not found in the state, it will return `undefined`.\n *\n * @param seedPhrase - The seed phrase to get the hash of.\n * @returns A promise that resolves to the hash of the seed phrase backup.\n */\n getSeedPhraseBackupHash(\n seedPhrase: Uint8Array,\n ): SocialBackupsMetadata | undefined {\n const seedPhraseHash = keccak256AndHexify(seedPhrase);\n return this.state.socialBackupsMetadata.find(\n (backup) => backup.hash === seedPhraseHash,\n );\n }\n\n /**\n * Persist the encryption key for the seedless onboarding flow.\n *\n * @param oprfKey - The OPRF key to be splited and persisted.\n * @param authPubKey - The authentication public key.\n * @returns A promise that resolves to the success of the operation.\n */\n async #persistOprfKey(oprfKey: bigint, authPubKey: SEC1EncodedPublicKey) {\n this.#assertIsAuthenticatedUser(this.state);\n const verifier =\n this.state.groupedAuthConnectionId || this.state.authConnectionId;\n\n try {\n await this.toprfClient.persistLocalKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n verifier,\n verifierId: this.state.userId,\n oprfKey,\n authPubKey,\n });\n } catch (error) {\n log('Error persisting local encryption key', error);\n throw new Error(SeedlessOnboardingControllerError.FailedToPersistOprfKey);\n }\n }\n\n /**\n * Recover the encryption key from password.\n *\n * @param password - The password used to derive/recover the encryption key.\n * @returns A promise that resolves to the encryption key and authentication key pair.\n * @throws RecoveryError - If failed to recover the encryption key.\n */\n async #recoverEncKey(password: string) {\n this.#assertIsAuthenticatedUser(this.state);\n const verifier =\n this.state.groupedAuthConnectionId || this.state.authConnectionId;\n\n try {\n const recoverEncKeyResult = await this.toprfClient.recoverEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n password,\n verifier,\n verifierId: this.state.userId,\n });\n return recoverEncKeyResult;\n } catch (error) {\n throw RecoveryError.getInstance(error);\n }\n }\n\n /**\n * Update the encryption key with new password and update the Metadata Store with new encryption key.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n * @returns A promise that resolves to new encryption key and authentication key pair.\n */\n async #changeEncryptionKey(newPassword: string, oldPassword: string) {\n this.#assertIsAuthenticatedUser(this.state);\n const verifier =\n this.state.groupedAuthConnectionId || this.state.authConnectionId;\n\n const {\n encKey,\n authKeyPair,\n keyShareIndex: newKeyShareIndex,\n } = await this.#recoverEncKey(oldPassword);\n\n return await this.toprfClient.changeEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n verifier,\n verifierId: this.state.userId,\n oldEncKey: encKey,\n oldAuthKeyPair: authKeyPair,\n newKeyShareIndex,\n newPassword,\n });\n }\n\n /**\n * Encrypt and store the seed phrase backup in the metadata store.\n *\n * @param params - The parameters for encrypting and storing the seed phrase backup.\n * @param params.keyringId - The keyring id of the backup seed phrase.\n * @param params.seedPhrase - The seed phrase to store.\n * @param params.encKey - The encryption key to store.\n * @param params.authKeyPair - The authentication key pair to store.\n *\n * @returns A promise that resolves to the success of the operation.\n */\n async #encryptAndStoreSeedPhraseBackup(params: {\n keyringId: string;\n seedPhrase: Uint8Array;\n encKey: Uint8Array;\n authKeyPair: KeyPair;\n }): Promise<void> {\n try {\n const { keyringId, seedPhrase, encKey, authKeyPair } = params;\n\n const seedPhraseMetadata = new SeedPhraseMetadata(seedPhrase);\n const secretData = seedPhraseMetadata.toBytes();\n await this.#withPersistedSeedPhraseBackupsState(async () => {\n await this.toprfClient.addSecretDataItem({\n encKey,\n secretData,\n authKeyPair,\n });\n return {\n id: keyringId,\n seedPhrase,\n };\n });\n } catch (error) {\n log('Error encrypting and storing seed phrase backup', error);\n throw new Error(\n SeedlessOnboardingControllerError.FailedToEncryptAndStoreSeedPhraseBackup,\n );\n }\n }\n\n /**\n * Unlocks the encrypted vault using the provided password and returns the decrypted vault data.\n * This method ensures thread-safety by using a mutex lock when accessing the vault.\n *\n * @param password - The password to decrypt the vault.\n * @returns A promise that resolves to an object containing:\n * - nodeAuthTokens: Authentication tokens to communicate with the TOPRF service\n * - toprfEncryptionKey: The decrypted TOPRF encryption key\n * - toprfAuthKeyPair: The decrypted TOPRF authentication key pair\n * @throws {Error} If:\n * - The password is invalid or empty\n * - The vault is not initialized\n * - The password is incorrect (from encryptor.decrypt)\n * - The decrypted vault data is malformed\n */\n async #unlockVaultWithPassword(password: string): Promise<{\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n }> {\n return this.#withVaultLock(async () => {\n assertIsValidPassword(password);\n\n const encryptedVault = this.state.vault;\n if (!encryptedVault) {\n throw new Error(SeedlessOnboardingControllerError.VaultError);\n }\n // Note that vault decryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n const decryptedVaultData = await this.#vaultEncryptor.decrypt(\n password,\n encryptedVault,\n );\n\n const { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair } =\n this.#parseVaultData(decryptedVaultData);\n\n // update the state with the restored nodeAuthTokens\n this.update((state) => {\n state.nodeAuthTokens = nodeAuthTokens;\n });\n\n return { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair };\n });\n }\n\n /**\n * Executes a callback function that creates or restores seed phrases and persists their hashes in the controller state.\n *\n * This method:\n * 1. Executes the provided callback to create/restore seed phrases\n * 2. Generates keccak256 hashes of the seed phrases\n * 3. Merges new hashes with existing ones in the state, ensuring uniqueness\n * 4. Updates the controller state with the combined hashes\n *\n * This is a wrapper method that should be used around any operation that creates\n * or restores seed phrases to ensure their hashes are properly tracked.\n *\n * @param createSeedPhraseBackupCallback - function that returns either a single seed phrase\n * or an array of seed phrases as Uint8Array(s)\n * @returns The original seed phrase(s) returned by the callback\n * @throws Rethrows any errors from the callback with additional logging\n */\n async #withPersistedSeedPhraseBackupsState(\n createSeedPhraseBackupCallback: () => Promise<{\n id: string;\n seedPhrase: Uint8Array;\n }>,\n ): Promise<{\n id: string;\n seedPhrase: Uint8Array;\n }> {\n try {\n const backUps = await createSeedPhraseBackupCallback();\n const newBackupMetadata = {\n id: backUps.id,\n hash: keccak256AndHexify(backUps.seedPhrase),\n };\n\n this.#updateSocialBackupsMetadata(newBackupMetadata);\n\n return backUps;\n } catch (error) {\n log('Error persisting seed phrase backups', error);\n throw error;\n }\n }\n\n #updateSocialBackupsMetadata(newSocialBackupMetadata: SocialBackupsMetadata) {\n // filter out the backed up metadata that already exists in the state\n // to prevent duplicates\n const existingBackupsMetadata = this.state.socialBackupsMetadata.find(\n (backup) => backup.id === newSocialBackupMetadata.id,\n );\n\n if (!existingBackupsMetadata) {\n this.update((state) => {\n state.socialBackupsMetadata = [\n ...state.socialBackupsMetadata,\n newSocialBackupMetadata,\n ];\n });\n }\n }\n\n /**\n * Create a new vault with the given authentication data.\n *\n * Serialize the authentication and key data which will be stored in the vault.\n *\n * @param params - The parameters for creating a new vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.rawToprfEncryptionKey - The encryption key to encrypt the vault.\n * @param params.rawToprfAuthKeyPair - The authentication key pair to encrypt the vault.\n */\n async #createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n }: {\n password: string;\n rawToprfEncryptionKey: Uint8Array;\n rawToprfAuthKeyPair: KeyPair;\n }): Promise<void> {\n this.#assertIsAuthenticatedUser(this.state);\n\n const { toprfEncryptionKey, toprfAuthKeyPair } = this.#serializeKeyData(\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n );\n\n const serializedVaultData = JSON.stringify({\n authTokens: this.state.nodeAuthTokens,\n toprfEncryptionKey,\n toprfAuthKeyPair,\n });\n\n await this.#updateVault({\n password,\n serializedVaultData,\n });\n }\n\n /**\n * Encrypt and update the vault with the given authentication data.\n *\n * @param params - The parameters for updating the vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.serializedVaultData - The serialized authentication data to update the vault with.\n * @returns A promise that resolves to the updated vault.\n */\n async #updateVault({\n password,\n serializedVaultData,\n }: {\n password: string;\n serializedVaultData: string;\n }): Promise<void> {\n await this.#withVaultLock(async () => {\n assertIsValidPassword(password);\n\n const updatedState: Partial<SeedlessOnboardingControllerState> = {};\n\n // Note that vault encryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n updatedState.vault = await this.#vaultEncryptor.encrypt(\n password,\n serializedVaultData,\n );\n\n this.update((state) => {\n state.vault = updatedState.vault;\n });\n });\n }\n\n /**\n * Lock the vault mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This ensures that each operation that interacts with the vault\n * is executed in a mutually exclusive way.\n *\n * @param callback - The function to execute while the vault mutex is locked.\n * @returns The result of the function.\n */\n async #withVaultLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return await withLock(this.#vaultOperationMutex, callback);\n }\n\n /**\n * Serialize the encryption key and authentication key pair.\n *\n * @param encKey - The encryption key to serialize.\n * @param authKeyPair - The authentication key pair to serialize.\n * @returns The serialized encryption key and authentication key pair.\n */\n #serializeKeyData(\n encKey: Uint8Array,\n authKeyPair: KeyPair,\n ): {\n toprfEncryptionKey: string;\n toprfAuthKeyPair: string;\n } {\n const b64EncodedEncKey = bytesToBase64(encKey);\n const b64EncodedAuthKeyPair = JSON.stringify({\n sk: bigIntToHex(authKeyPair.sk), // Convert BigInt to hex string\n pk: bytesToBase64(authKeyPair.pk),\n });\n\n return {\n toprfEncryptionKey: b64EncodedEncKey,\n toprfAuthKeyPair: b64EncodedAuthKeyPair,\n };\n }\n\n /**\n * Parse and deserialize the authentication data from the vault.\n *\n * @param data - The decrypted vault data.\n * @returns The parsed authentication data.\n * @throws If the vault data is not valid.\n */\n #parseVaultData(data: unknown): {\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n } {\n if (typeof data !== 'string') {\n throw new Error(SeedlessOnboardingControllerError.InvalidVaultData);\n }\n\n let parsedVaultData: unknown;\n try {\n parsedVaultData = JSON.parse(data);\n } catch {\n throw new Error(SeedlessOnboardingControllerError.InvalidVaultData);\n }\n\n this.#assertIsValidVaultData(parsedVaultData);\n\n const rawToprfEncryptionKey = base64ToBytes(\n parsedVaultData.toprfEncryptionKey,\n );\n const parsedToprfAuthKeyPair = JSON.parse(parsedVaultData.toprfAuthKeyPair);\n const rawToprfAuthKeyPair = {\n sk: BigInt(parsedToprfAuthKeyPair.sk),\n pk: base64ToBytes(parsedToprfAuthKeyPair.pk),\n };\n\n return {\n nodeAuthTokens: parsedVaultData.authTokens,\n toprfEncryptionKey: rawToprfEncryptionKey,\n toprfAuthKeyPair: rawToprfAuthKeyPair,\n };\n }\n\n /**\n * Assert that the provided value contains valid authenticated user information.\n *\n * This method checks that the value is an object containing:\n * - nodeAuthTokens: A non-empty array of authentication tokens\n * - authConnectionId: A string identifier for the OAuth connection\n * - groupedAuthConnectionId: A string identifier for grouped OAuth connections\n * - userId: A string identifier for the authenticated user\n *\n * @param value - The value to validate.\n * @throws {Error} If the value does not contain valid authenticated user information.\n */\n #assertIsAuthenticatedUser(\n value: unknown,\n ): asserts value is AuthenticatedUserDetails {\n if (\n !value ||\n typeof value !== 'object' ||\n !('authConnectionId' in value) ||\n typeof value.authConnectionId !== 'string' ||\n !('userId' in value) ||\n typeof value.userId !== 'string'\n ) {\n throw new Error(SeedlessOnboardingControllerError.MissingAuthUserInfo);\n }\n\n if (\n !('nodeAuthTokens' in value) ||\n typeof value.nodeAuthTokens !== 'object' ||\n !Array.isArray(value.nodeAuthTokens) ||\n value.nodeAuthTokens.length < 3 // At least 3 auth tokens are required for Threshold OPRF service\n ) {\n throw new Error(SeedlessOnboardingControllerError.InsufficientAuthToken);\n }\n }\n\n /**\n * Check if the provided value is a valid vault data.\n *\n * @param value - The value to check.\n * @throws If the value is not a valid vault data.\n */\n #assertIsValidVaultData(value: unknown): asserts value is VaultData {\n // value is not valid vault data if any of the following conditions are true:\n if (\n !value || // value is not defined\n typeof value !== 'object' || // value is not an object\n !('authTokens' in value) || // authTokens is not defined\n typeof value.authTokens !== 'object' || // authTokens is not an object\n !('toprfEncryptionKey' in value) || // toprfEncryptionKey is not defined\n typeof value.toprfEncryptionKey !== 'string' || // toprfEncryptionKey is not a string\n !('toprfAuthKeyPair' in value) || // toprfAuthKeyPair is not defined\n typeof value.toprfAuthKeyPair !== 'string' // toprfAuthKeyPair is not a string\n ) {\n throw new Error(SeedlessOnboardingControllerError.VaultDataError);\n }\n }\n}\n\n/**\n * Assert that the provided password is a valid non-empty string.\n *\n * @param password - The password to check.\n * @throws If the password is not a valid string.\n */\nfunction assertIsValidPassword(password: unknown): asserts password is string {\n if (typeof password !== 'string') {\n throw new Error(SeedlessOnboardingControllerError.WrongPasswordType);\n }\n\n if (!password || !password.length) {\n throw new Error(SeedlessOnboardingControllerError.InvalidEmptyPassword);\n }\n}\n\n/**\n * Lock the given mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * @param mutex - The mutex to lock.\n * @param callback - The function to execute while the mutex is locked.\n * @returns The result of the function.\n */\nasync function withLock<Result>(\n mutex: Mutex,\n callback: MutuallyExclusiveCallback<Result>,\n): Promise<Result> {\n const releaseLock = await mutex.acquire();\n\n try {\n return await callback({ releaseLock });\n } finally {\n releaseLock();\n }\n}\n"]}
1
+ {"version":3,"file":"SeedlessOnboardingController.mjs","sourceRoot":"","sources":["../src/SeedlessOnboardingController.ts"],"names":[],"mappings":"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","sourcesContent":["import { keccak256AndHexify } from '@metamask/auth-network-utils';\nimport type { StateMetadata } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { encrypt, decrypt } from '@metamask/browser-passworder';\nimport type {\n KeyPair,\n NodeAuthTokens,\n SEC1EncodedPublicKey,\n} from '@metamask/toprf-secure-backup';\nimport { ToprfSecureBackup } from '@metamask/toprf-secure-backup';\nimport {\n base64ToBytes,\n bytesToBase64,\n stringToBytes,\n remove0x,\n bigIntToHex,\n} from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\n\nimport {\n type AuthConnection,\n controllerName,\n SeedlessOnboardingControllerError,\n Web3AuthNetwork,\n} from './constants';\nimport { RecoveryError } from './errors';\nimport { projectLogger, createModuleLogger } from './logger';\nimport { SeedPhraseMetadata } from './SeedPhraseMetadata';\nimport type {\n VaultEncryptor,\n MutuallyExclusiveCallback,\n SeedlessOnboardingControllerMessenger,\n SeedlessOnboardingControllerOptions,\n SeedlessOnboardingControllerState,\n VaultData,\n AuthenticatedUserDetails,\n SocialBackupsMetadata,\n} from './types';\n\nconst log = createModuleLogger(projectLogger, controllerName);\n\n/**\n * Get the default state for the Seedless Onboarding Controller.\n *\n * @returns The default state for the Seedless Onboarding Controller.\n */\nexport function getDefaultSeedlessOnboardingControllerState(): SeedlessOnboardingControllerState {\n return {\n socialBackupsMetadata: [],\n };\n}\n\n/**\n * Seedless Onboarding Controller State Metadata.\n *\n * This allows us to choose if fields of the state should be persisted or not\n * using the `persist` flag; and if they can be sent to Sentry or not, using\n * the `anonymous` flag.\n */\nconst seedlessOnboardingMetadata: StateMetadata<SeedlessOnboardingControllerState> =\n {\n vault: {\n persist: true,\n anonymous: false,\n },\n socialBackupsMetadata: {\n persist: true,\n anonymous: true,\n },\n nodeAuthTokens: {\n persist: false,\n anonymous: true,\n },\n authConnection: {\n persist: true,\n anonymous: true,\n },\n authConnectionId: {\n persist: true,\n anonymous: true,\n },\n groupedAuthConnectionId: {\n persist: true,\n anonymous: true,\n },\n userId: {\n persist: true,\n anonymous: true,\n },\n socialLoginEmail: {\n persist: true,\n anonymous: true,\n },\n };\n\nexport class SeedlessOnboardingController extends BaseController<\n typeof controllerName,\n SeedlessOnboardingControllerState,\n SeedlessOnboardingControllerMessenger\n> {\n readonly #vaultEncryptor: VaultEncryptor;\n\n readonly #vaultOperationMutex = new Mutex();\n\n readonly toprfClient: ToprfSecureBackup;\n\n /**\n * Creates a new SeedlessOnboardingController instance.\n *\n * @param options - The options for the SeedlessOnboardingController.\n * @param options.messenger - A restricted messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.encryptor - An optional encryptor to use for encrypting and decrypting seedless onboarding vault.\n * @param options.network - The network to be used for the Seedless Onboarding flow.\n */\n constructor({\n messenger,\n state,\n encryptor = { encrypt, decrypt }, // default to `encrypt` and `decrypt` from `@metamask/browser-passworder`\n network = Web3AuthNetwork.Mainnet,\n }: SeedlessOnboardingControllerOptions) {\n super({\n name: controllerName,\n metadata: seedlessOnboardingMetadata,\n state: {\n ...getDefaultSeedlessOnboardingControllerState(),\n ...state,\n },\n messenger,\n });\n\n this.#vaultEncryptor = encryptor;\n this.toprfClient = new ToprfSecureBackup({\n network,\n });\n }\n\n /**\n * Authenticate OAuth user using the seedless onboarding flow\n * and determine if the user is already registered or not.\n *\n * @param params - The parameters for authenticate OAuth user.\n * @param params.idTokens - The ID token(s) issued by OAuth verification service. Currently this array only contains a single idToken which is verified by all the nodes, in future we are considering to issue a unique idToken for each node.\n * @param params.authConnection - The social login provider.\n * @param params.authConnectionId - OAuth authConnectionId from dashboard\n * @param params.userId - user email or id from Social login\n * @param params.groupedAuthConnectionId - Optional grouped authConnectionId to be used for the authenticate request.\n * @param params.socialLoginEmail - The user email from Social login.\n * You can pass this to use aggregate multiple OAuth connections. Useful when you want user to have same account while using different OAuth connections.\n * @returns A promise that resolves to the authentication result.\n */\n async authenticate(params: {\n idTokens: string[];\n authConnection: AuthConnection;\n authConnectionId: string;\n userId: string;\n groupedAuthConnectionId?: string;\n socialLoginEmail?: string;\n }) {\n try {\n const {\n idTokens,\n authConnectionId,\n groupedAuthConnectionId,\n userId,\n authConnection,\n socialLoginEmail,\n } = params;\n const hashedIdTokenHexes = idTokens.map((idToken) => {\n return remove0x(keccak256AndHexify(stringToBytes(idToken)));\n });\n const authenticationResult = await this.toprfClient.authenticate({\n authConnectionId: groupedAuthConnectionId || authConnectionId,\n userId,\n idTokens: hashedIdTokenHexes,\n groupedAuthConnectionParams: {\n authConnectionId,\n idTokens,\n },\n });\n // update the state with the authenticated user info\n this.update((state) => {\n state.nodeAuthTokens = authenticationResult.nodeAuthTokens;\n state.authConnectionId = authConnectionId;\n state.groupedAuthConnectionId = groupedAuthConnectionId;\n state.userId = userId;\n state.authConnection = authConnection;\n state.socialLoginEmail = socialLoginEmail;\n });\n return authenticationResult;\n } catch (error) {\n log('Error authenticating user', error);\n throw new Error(SeedlessOnboardingControllerError.AuthenticationError);\n }\n }\n\n /**\n * Create a new TOPRF encryption key using given password and backups the provided seed phrase.\n *\n * @param password - The password used to create new wallet and seedphrase\n * @param seedPhrase - The seed phrase to backup\n * @param keyringId - The keyring id of the backup seed phrase\n * @returns A promise that resolves to the encrypted seed phrase and the encryption key.\n */\n async createToprfKeyAndBackupSeedPhrase(\n password: string,\n seedPhrase: Uint8Array,\n keyringId: string,\n ): Promise<void> {\n // to make sure that fail fast,\n // assert that the user is authenticated before creating the TOPRF key and backing up the seed phrase\n this.#assertIsAuthenticatedUser(this.state);\n\n // locally evaluate the encryption key from the password\n const { encKey, authKeyPair, oprfKey } = this.toprfClient.createLocalKey({\n password,\n });\n\n // encrypt and store the seed phrase backup\n await this.#encryptAndStoreSeedPhraseBackup({\n keyringId,\n seedPhrase,\n encKey,\n authKeyPair,\n });\n\n // store/persist the encryption key shares\n // We store the seed phrase metadata in the metadata store first. If this operation fails,\n // we avoid persisting the encryption key shares to prevent a situation where a user appears\n // to have an account but with no associated data.\n await this.#persistOprfKey(oprfKey, authKeyPair.pk);\n // create a new vault with the resulting authentication data\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n }\n\n /**\n * Fetches all encrypted seed phrases and metadata for user's account from the metadata store.\n *\n * Decrypts the seed phrases and returns the decrypted seed phrases using the recovered encryption key from the password.\n *\n * @param password - The password used to create new wallet and seedphrase\n * @returns A promise that resolves to the seed phrase metadata.\n */\n async fetchAllSeedPhrases(password: string): Promise<Uint8Array[]> {\n // assert that the user is authenticated before fetching the seed phrases\n this.#assertIsAuthenticatedUser(this.state);\n\n const { encKey, authKeyPair } = await this.#recoverEncKey(password);\n\n try {\n const secretData = await this.toprfClient.fetchAllSecretDataItems({\n decKey: encKey,\n authKeyPair,\n });\n\n if (secretData?.length > 0) {\n await this.#createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey: encKey,\n rawToprfAuthKeyPair: authKeyPair,\n });\n }\n\n return SeedPhraseMetadata.parseSeedPhraseFromMetadataStore(secretData);\n } catch (error) {\n log('Error fetching seed phrase metadata', error);\n throw new Error(\n SeedlessOnboardingControllerError.FailedToFetchSeedPhraseMetadata,\n );\n }\n }\n\n /**\n * Update the password of the seedless onboarding flow.\n *\n * Changing password will also update the encryption key, metadata store and the vault with new encrypted values.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n */\n async changePassword(newPassword: string, oldPassword: string) {\n // verify the old password of the encrypted vault\n await this.#unlockVaultWithPassword(oldPassword);\n\n try {\n // update the encryption key with new password and update the Metadata Store\n const { encKey: newEncKey, authKeyPair: newAuthKeyPair } =\n await this.#changeEncryptionKey(newPassword, oldPassword);\n\n // update and encrypt the vault with new password\n await this.#createNewVaultWithAuthData({\n password: newPassword,\n rawToprfEncryptionKey: newEncKey,\n rawToprfAuthKeyPair: newAuthKeyPair,\n });\n } catch (error) {\n log('Error changing password', error);\n throw new Error(SeedlessOnboardingControllerError.FailedToChangePassword);\n }\n }\n\n /**\n * Update the backup metadata state for the given seed phrase.\n *\n * @param keyringId - The keyring id of the backup seed phrase.\n * @param seedPhrase - The seed phrase to update the backup metadata for.\n */\n updateBackupMetadataState(keyringId: string, seedPhrase: Uint8Array) {\n const newBackupMetadata = {\n id: keyringId,\n hash: keccak256AndHexify(seedPhrase),\n };\n\n this.#updateSocialBackupsMetadata(newBackupMetadata);\n }\n\n /**\n * Get the hash of the seed phrase backup for the given seed phrase, from the state.\n *\n * If the given seed phrase is not backed up and not found in the state, it will return `undefined`.\n *\n * @param seedPhrase - The seed phrase to get the hash of.\n * @returns A promise that resolves to the hash of the seed phrase backup.\n */\n getSeedPhraseBackupHash(\n seedPhrase: Uint8Array,\n ): SocialBackupsMetadata | undefined {\n const seedPhraseHash = keccak256AndHexify(seedPhrase);\n return this.state.socialBackupsMetadata.find(\n (backup) => backup.hash === seedPhraseHash,\n );\n }\n\n /**\n * Clears the current state of the SeedlessOnboardingController.\n */\n clearState() {\n const defaultState = getDefaultSeedlessOnboardingControllerState();\n this.update(() => {\n return defaultState;\n });\n }\n\n /**\n * Persist the encryption key for the seedless onboarding flow.\n *\n * @param oprfKey - The OPRF key to be splited and persisted.\n * @param authPubKey - The authentication public key.\n * @returns A promise that resolves to the success of the operation.\n */\n async #persistOprfKey(oprfKey: bigint, authPubKey: SEC1EncodedPublicKey) {\n this.#assertIsAuthenticatedUser(this.state);\n const authConnectionId =\n this.state.groupedAuthConnectionId || this.state.authConnectionId;\n\n try {\n await this.toprfClient.persistLocalKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n authConnectionId,\n userId: this.state.userId,\n oprfKey,\n authPubKey,\n });\n } catch (error) {\n log('Error persisting local encryption key', error);\n throw new Error(SeedlessOnboardingControllerError.FailedToPersistOprfKey);\n }\n }\n\n /**\n * Recover the encryption key from password.\n *\n * @param password - The password used to derive/recover the encryption key.\n * @returns A promise that resolves to the encryption key and authentication key pair.\n * @throws RecoveryError - If failed to recover the encryption key.\n */\n async #recoverEncKey(password: string) {\n this.#assertIsAuthenticatedUser(this.state);\n const authConnectionId =\n this.state.groupedAuthConnectionId || this.state.authConnectionId;\n\n try {\n const recoverEncKeyResult = await this.toprfClient.recoverEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n password,\n authConnectionId,\n userId: this.state.userId,\n });\n return recoverEncKeyResult;\n } catch (error) {\n throw RecoveryError.getInstance(error);\n }\n }\n\n /**\n * Update the encryption key with new password and update the Metadata Store with new encryption key.\n *\n * @param newPassword - The new password to update.\n * @param oldPassword - The old password to verify.\n * @returns A promise that resolves to new encryption key and authentication key pair.\n */\n async #changeEncryptionKey(newPassword: string, oldPassword: string) {\n this.#assertIsAuthenticatedUser(this.state);\n const authConnectionId =\n this.state.groupedAuthConnectionId || this.state.authConnectionId;\n\n const {\n encKey,\n authKeyPair,\n keyShareIndex: newKeyShareIndex,\n } = await this.#recoverEncKey(oldPassword);\n\n return await this.toprfClient.changeEncKey({\n nodeAuthTokens: this.state.nodeAuthTokens,\n authConnectionId,\n userId: this.state.userId,\n oldEncKey: encKey,\n oldAuthKeyPair: authKeyPair,\n newKeyShareIndex,\n oldPassword,\n newPassword,\n });\n }\n\n /**\n * Encrypt and store the seed phrase backup in the metadata store.\n *\n * @param params - The parameters for encrypting and storing the seed phrase backup.\n * @param params.keyringId - The keyring id of the backup seed phrase.\n * @param params.seedPhrase - The seed phrase to store.\n * @param params.encKey - The encryption key to store.\n * @param params.authKeyPair - The authentication key pair to store.\n *\n * @returns A promise that resolves to the success of the operation.\n */\n async #encryptAndStoreSeedPhraseBackup(params: {\n keyringId: string;\n seedPhrase: Uint8Array;\n encKey: Uint8Array;\n authKeyPair: KeyPair;\n }): Promise<void> {\n try {\n const { keyringId, seedPhrase, encKey, authKeyPair } = params;\n\n const seedPhraseMetadata = new SeedPhraseMetadata(seedPhrase);\n const secretData = seedPhraseMetadata.toBytes();\n await this.#withPersistedSeedPhraseBackupsState(async () => {\n await this.toprfClient.addSecretDataItem({\n encKey,\n secretData,\n authKeyPair,\n });\n return {\n id: keyringId,\n seedPhrase,\n };\n });\n } catch (error) {\n log('Error encrypting and storing seed phrase backup', error);\n throw new Error(\n SeedlessOnboardingControllerError.FailedToEncryptAndStoreSeedPhraseBackup,\n );\n }\n }\n\n /**\n * Unlocks the encrypted vault using the provided password and returns the decrypted vault data.\n * This method ensures thread-safety by using a mutex lock when accessing the vault.\n *\n * @param password - The password to decrypt the vault.\n * @returns A promise that resolves to an object containing:\n * - nodeAuthTokens: Authentication tokens to communicate with the TOPRF service\n * - toprfEncryptionKey: The decrypted TOPRF encryption key\n * - toprfAuthKeyPair: The decrypted TOPRF authentication key pair\n * @throws {Error} If:\n * - The password is invalid or empty\n * - The vault is not initialized\n * - The password is incorrect (from encryptor.decrypt)\n * - The decrypted vault data is malformed\n */\n async #unlockVaultWithPassword(password: string): Promise<{\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n }> {\n return this.#withVaultLock(async () => {\n assertIsValidPassword(password);\n\n const encryptedVault = this.state.vault;\n if (!encryptedVault) {\n throw new Error(SeedlessOnboardingControllerError.VaultError);\n }\n // Note that vault decryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n const decryptedVaultData = await this.#vaultEncryptor.decrypt(\n password,\n encryptedVault,\n );\n\n const { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair } =\n this.#parseVaultData(decryptedVaultData);\n\n // update the state with the restored nodeAuthTokens\n this.update((state) => {\n state.nodeAuthTokens = nodeAuthTokens;\n });\n\n return { nodeAuthTokens, toprfEncryptionKey, toprfAuthKeyPair };\n });\n }\n\n /**\n * Executes a callback function that creates or restores seed phrases and persists their hashes in the controller state.\n *\n * This method:\n * 1. Executes the provided callback to create/restore seed phrases\n * 2. Generates keccak256 hashes of the seed phrases\n * 3. Merges new hashes with existing ones in the state, ensuring uniqueness\n * 4. Updates the controller state with the combined hashes\n *\n * This is a wrapper method that should be used around any operation that creates\n * or restores seed phrases to ensure their hashes are properly tracked.\n *\n * @param createSeedPhraseBackupCallback - function that returns either a single seed phrase\n * or an array of seed phrases as Uint8Array(s)\n * @returns The original seed phrase(s) returned by the callback\n * @throws Rethrows any errors from the callback with additional logging\n */\n async #withPersistedSeedPhraseBackupsState(\n createSeedPhraseBackupCallback: () => Promise<{\n id: string;\n seedPhrase: Uint8Array;\n }>,\n ): Promise<{\n id: string;\n seedPhrase: Uint8Array;\n }> {\n try {\n const backUps = await createSeedPhraseBackupCallback();\n const newBackupMetadata = {\n id: backUps.id,\n hash: keccak256AndHexify(backUps.seedPhrase),\n };\n\n this.#updateSocialBackupsMetadata(newBackupMetadata);\n\n return backUps;\n } catch (error) {\n log('Error persisting seed phrase backups', error);\n throw error;\n }\n }\n\n #updateSocialBackupsMetadata(newSocialBackupMetadata: SocialBackupsMetadata) {\n // filter out the backed up metadata that already exists in the state\n // to prevent duplicates\n const existingBackupsMetadata = this.state.socialBackupsMetadata.find(\n (backup) => backup.id === newSocialBackupMetadata.id,\n );\n\n if (!existingBackupsMetadata) {\n this.update((state) => {\n state.socialBackupsMetadata = [\n ...state.socialBackupsMetadata,\n newSocialBackupMetadata,\n ];\n });\n }\n }\n\n /**\n * Create a new vault with the given authentication data.\n *\n * Serialize the authentication and key data which will be stored in the vault.\n *\n * @param params - The parameters for creating a new vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.rawToprfEncryptionKey - The encryption key to encrypt the vault.\n * @param params.rawToprfAuthKeyPair - The authentication key pair to encrypt the vault.\n */\n async #createNewVaultWithAuthData({\n password,\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n }: {\n password: string;\n rawToprfEncryptionKey: Uint8Array;\n rawToprfAuthKeyPair: KeyPair;\n }): Promise<void> {\n this.#assertIsAuthenticatedUser(this.state);\n\n const { toprfEncryptionKey, toprfAuthKeyPair } = this.#serializeKeyData(\n rawToprfEncryptionKey,\n rawToprfAuthKeyPair,\n );\n\n const serializedVaultData = JSON.stringify({\n authTokens: this.state.nodeAuthTokens,\n toprfEncryptionKey,\n toprfAuthKeyPair,\n });\n\n await this.#updateVault({\n password,\n serializedVaultData,\n });\n }\n\n /**\n * Encrypt and update the vault with the given authentication data.\n *\n * @param params - The parameters for updating the vault.\n * @param params.password - The password to encrypt the vault.\n * @param params.serializedVaultData - The serialized authentication data to update the vault with.\n * @returns A promise that resolves to the updated vault.\n */\n async #updateVault({\n password,\n serializedVaultData,\n }: {\n password: string;\n serializedVaultData: string;\n }): Promise<void> {\n await this.#withVaultLock(async () => {\n assertIsValidPassword(password);\n\n const updatedState: Partial<SeedlessOnboardingControllerState> = {};\n\n // Note that vault encryption using the password is a very costly operation as it involves deriving the encryption key\n // from the password using an intentionally slow key derivation function.\n // We should make sure that we only call it very intentionally.\n updatedState.vault = await this.#vaultEncryptor.encrypt(\n password,\n serializedVaultData,\n );\n\n this.update((state) => {\n state.vault = updatedState.vault;\n });\n });\n }\n\n /**\n * Lock the vault mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * This ensures that each operation that interacts with the vault\n * is executed in a mutually exclusive way.\n *\n * @param callback - The function to execute while the vault mutex is locked.\n * @returns The result of the function.\n */\n async #withVaultLock<Result>(\n callback: MutuallyExclusiveCallback<Result>,\n ): Promise<Result> {\n return await withLock(this.#vaultOperationMutex, callback);\n }\n\n /**\n * Serialize the encryption key and authentication key pair.\n *\n * @param encKey - The encryption key to serialize.\n * @param authKeyPair - The authentication key pair to serialize.\n * @returns The serialized encryption key and authentication key pair.\n */\n #serializeKeyData(\n encKey: Uint8Array,\n authKeyPair: KeyPair,\n ): {\n toprfEncryptionKey: string;\n toprfAuthKeyPair: string;\n } {\n const b64EncodedEncKey = bytesToBase64(encKey);\n const b64EncodedAuthKeyPair = JSON.stringify({\n sk: bigIntToHex(authKeyPair.sk), // Convert BigInt to hex string\n pk: bytesToBase64(authKeyPair.pk),\n });\n\n return {\n toprfEncryptionKey: b64EncodedEncKey,\n toprfAuthKeyPair: b64EncodedAuthKeyPair,\n };\n }\n\n /**\n * Parse and deserialize the authentication data from the vault.\n *\n * @param data - The decrypted vault data.\n * @returns The parsed authentication data.\n * @throws If the vault data is not valid.\n */\n #parseVaultData(data: unknown): {\n nodeAuthTokens: NodeAuthTokens;\n toprfEncryptionKey: Uint8Array;\n toprfAuthKeyPair: KeyPair;\n } {\n if (typeof data !== 'string') {\n throw new Error(SeedlessOnboardingControllerError.InvalidVaultData);\n }\n\n let parsedVaultData: unknown;\n try {\n parsedVaultData = JSON.parse(data);\n } catch {\n throw new Error(SeedlessOnboardingControllerError.InvalidVaultData);\n }\n\n this.#assertIsValidVaultData(parsedVaultData);\n\n const rawToprfEncryptionKey = base64ToBytes(\n parsedVaultData.toprfEncryptionKey,\n );\n const parsedToprfAuthKeyPair = JSON.parse(parsedVaultData.toprfAuthKeyPair);\n const rawToprfAuthKeyPair = {\n sk: BigInt(parsedToprfAuthKeyPair.sk),\n pk: base64ToBytes(parsedToprfAuthKeyPair.pk),\n };\n\n return {\n nodeAuthTokens: parsedVaultData.authTokens,\n toprfEncryptionKey: rawToprfEncryptionKey,\n toprfAuthKeyPair: rawToprfAuthKeyPair,\n };\n }\n\n /**\n * Assert that the provided value contains valid authenticated user information.\n *\n * This method checks that the value is an object containing:\n * - nodeAuthTokens: A non-empty array of authentication tokens\n * - authConnectionId: A string identifier for the OAuth connection\n * - groupedAuthConnectionId: A string identifier for grouped OAuth connections\n * - userId: A string identifier for the authenticated user\n *\n * @param value - The value to validate.\n * @throws {Error} If the value does not contain valid authenticated user information.\n */\n #assertIsAuthenticatedUser(\n value: unknown,\n ): asserts value is AuthenticatedUserDetails {\n if (\n !value ||\n typeof value !== 'object' ||\n !('authConnectionId' in value) ||\n typeof value.authConnectionId !== 'string' ||\n !('userId' in value) ||\n typeof value.userId !== 'string'\n ) {\n throw new Error(SeedlessOnboardingControllerError.MissingAuthUserInfo);\n }\n\n if (\n !('nodeAuthTokens' in value) ||\n typeof value.nodeAuthTokens !== 'object' ||\n !Array.isArray(value.nodeAuthTokens) ||\n value.nodeAuthTokens.length < 3 // At least 3 auth tokens are required for Threshold OPRF service\n ) {\n throw new Error(SeedlessOnboardingControllerError.InsufficientAuthToken);\n }\n }\n\n /**\n * Check if the provided value is a valid vault data.\n *\n * @param value - The value to check.\n * @throws If the value is not a valid vault data.\n */\n #assertIsValidVaultData(value: unknown): asserts value is VaultData {\n // value is not valid vault data if any of the following conditions are true:\n if (\n !value || // value is not defined\n typeof value !== 'object' || // value is not an object\n !('authTokens' in value) || // authTokens is not defined\n typeof value.authTokens !== 'object' || // authTokens is not an object\n !('toprfEncryptionKey' in value) || // toprfEncryptionKey is not defined\n typeof value.toprfEncryptionKey !== 'string' || // toprfEncryptionKey is not a string\n !('toprfAuthKeyPair' in value) || // toprfAuthKeyPair is not defined\n typeof value.toprfAuthKeyPair !== 'string' // toprfAuthKeyPair is not a string\n ) {\n throw new Error(SeedlessOnboardingControllerError.VaultDataError);\n }\n }\n}\n\n/**\n * Assert that the provided password is a valid non-empty string.\n *\n * @param password - The password to check.\n * @throws If the password is not a valid string.\n */\nfunction assertIsValidPassword(password: unknown): asserts password is string {\n if (typeof password !== 'string') {\n throw new Error(SeedlessOnboardingControllerError.WrongPasswordType);\n }\n\n if (!password || !password.length) {\n throw new Error(SeedlessOnboardingControllerError.InvalidEmptyPassword);\n }\n}\n\n/**\n * Lock the given mutex before executing the given function,\n * and release it after the function is resolved or after an\n * error is thrown.\n *\n * @param mutex - The mutex to lock.\n * @param callback - The function to execute while the mutex is locked.\n * @returns The result of the function.\n */\nasync function withLock<Result>(\n mutex: Mutex,\n callback: MutuallyExclusiveCallback<Result>,\n): Promise<Result> {\n const releaseLock = await mutex.acquire();\n\n try {\n return await callback({ releaseLock });\n } finally {\n releaseLock();\n }\n}\n"]}
package/dist/errors.cjs CHANGED
@@ -12,9 +12,9 @@ const constants_1 = require("./constants.cjs");
12
12
  */
13
13
  function getErrorMessageFromTOPRFErrorCode(errorCode, defaultMessage) {
14
14
  switch (errorCode) {
15
- case toprf_secure_backup_1.TORPFErrorCode.RateLimitExceeded:
15
+ case toprf_secure_backup_1.TOPRFErrorCode.RateLimitExceeded:
16
16
  return constants_1.SeedlessOnboardingControllerError.TooManyLoginAttempts;
17
- case toprf_secure_backup_1.TORPFErrorCode.CouldNotDeriveEncryptionKey:
17
+ case toprf_secure_backup_1.TOPRFErrorCode.CouldNotDeriveEncryptionKey:
18
18
  return constants_1.SeedlessOnboardingControllerError.IncorrectPassword;
19
19
  default:
20
20
  return defaultMessage;
@@ -54,7 +54,7 @@ class RecoveryError extends Error {
54
54
  */
55
55
  static getRateLimitErrorData(error) {
56
56
  if (error.meta && // error metadata must be present
57
- error.code === toprf_secure_backup_1.TORPFErrorCode.RateLimitExceeded &&
57
+ error.code === toprf_secure_backup_1.TOPRFErrorCode.RateLimitExceeded &&
58
58
  typeof error.meta.rateLimitDetails === 'object' &&
59
59
  error.meta.rateLimitDetails !== null &&
60
60
  'remainingTime' in error.meta.rateLimitDetails &&
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA,uEAIuC;AAEvC,+CAAgE;AAEhE;;;;;;GAMG;AACH,SAAS,iCAAiC,CACxC,SAAyB,EACzB,cAAsB;IAEtB,QAAQ,SAAS,EAAE;QACjB,KAAK,oCAAc,CAAC,iBAAiB;YACnC,OAAO,6CAAiC,CAAC,oBAAoB,CAAC;QAChE,KAAK,oCAAc,CAAC,2BAA2B;YAC7C,OAAO,6CAAiC,CAAC,iBAAiB,CAAC;QAC7D;YACE,OAAO,cAAc,CAAC;KACzB;AACH,CAAC;AAED;;;GAGG;AACH,MAAa,aAAc,SAAQ,KAAK;IAGtC,YAAY,OAAe,EAAE,IAAyB;QACpD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,8CAA8C,CAAC;IAC7D,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,KAAc;QAC/B,IAAI,KAAK,YAAY,gCAAU,EAAE;YAC/B,MAAM,kBAAkB,GAAG,aAAa,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;YACtE,MAAM,YAAY,GAAG,iCAAiC,CACpD,KAAK,CAAC,IAAI,EACV,6CAAiC,CAAC,gBAAgB,CACnD,CAAC;YACF,OAAO,IAAI,aAAa,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;SAC5D;QACD,OAAO,IAAI,aAAa,CACtB,6CAAiC,CAAC,gBAAgB,CACnD,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,qBAAqB,CAC1B,KAAiB;QAEjB,IACE,KAAK,CAAC,IAAI,IAAI,iCAAiC;YAC/C,KAAK,CAAC,IAAI,KAAK,oCAAc,CAAC,iBAAiB;YAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,QAAQ;YAC/C,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,IAAI;YACpC,eAAe,IAAI,KAAK,CAAC,IAAI,CAAC,gBAAgB;YAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,aAAa,KAAK,QAAQ;YAC7D,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,gBAAgB;YACxC,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,KAAK,QAAQ,EACvD;YACA,OAAO;gBACL,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,aAAa;gBACxD,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO;aAC7C,CAAC;SACH;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;CACF;AAzDD,sCAyDC","sourcesContent":["import {\n type RateLimitErrorData,\n TOPRFError,\n TORPFErrorCode,\n} from '@metamask/toprf-secure-backup';\n\nimport { SeedlessOnboardingControllerError } from './constants';\n\n/**\n * Get the error message from the TOPRF error code.\n *\n * @param errorCode - The TOPRF error code.\n * @param defaultMessage - The default error message if the error code is not found.\n * @returns The error message.\n */\nfunction getErrorMessageFromTOPRFErrorCode(\n errorCode: TORPFErrorCode,\n defaultMessage: string,\n): string {\n switch (errorCode) {\n case TORPFErrorCode.RateLimitExceeded:\n return SeedlessOnboardingControllerError.TooManyLoginAttempts;\n case TORPFErrorCode.CouldNotDeriveEncryptionKey:\n return SeedlessOnboardingControllerError.IncorrectPassword;\n default:\n return defaultMessage;\n }\n}\n\n/**\n * The RecoveryError class is used to handle errors that occur during the recover encryption key process from the passwrord.\n * It extends the Error class and includes a data property that can be used to store additional information.\n */\nexport class RecoveryError extends Error {\n data: RateLimitErrorData | undefined;\n\n constructor(message: string, data?: RateLimitErrorData) {\n super(message);\n this.data = data;\n this.name = 'SeedlessOnboardingController - RecoveryError';\n }\n\n /**\n * Get an instance of the RecoveryError class.\n *\n * @param error - The error to get the instance of.\n * @returns The instance of the RecoveryError class.\n */\n static getInstance(error: unknown): RecoveryError {\n if (error instanceof TOPRFError) {\n const rateLimitErrorData = RecoveryError.getRateLimitErrorData(error);\n const errorMessage = getErrorMessageFromTOPRFErrorCode(\n error.code,\n SeedlessOnboardingControllerError.LoginFailedError,\n );\n return new RecoveryError(errorMessage, rateLimitErrorData);\n }\n return new RecoveryError(\n SeedlessOnboardingControllerError.LoginFailedError,\n );\n }\n\n /**\n * Check if the provided error is a rate limit error triggered by too many login attempts.\n *\n * Return a new TooManyLoginAttemptsError if the error is a rate limit error, otherwise undefined.\n *\n * @param error - The error to check.\n * @returns The rate limit error if the error is a rate limit error, otherwise undefined.\n */\n static getRateLimitErrorData(\n error: TOPRFError,\n ): RateLimitErrorData | undefined {\n if (\n error.meta && // error metadata must be present\n error.code === TORPFErrorCode.RateLimitExceeded &&\n typeof error.meta.rateLimitDetails === 'object' &&\n error.meta.rateLimitDetails !== null &&\n 'remainingTime' in error.meta.rateLimitDetails &&\n typeof error.meta.rateLimitDetails.remainingTime === 'number' &&\n 'message' in error.meta.rateLimitDetails &&\n typeof error.meta.rateLimitDetails.message === 'string'\n ) {\n return {\n remainingTime: error.meta.rateLimitDetails.remainingTime,\n message: error.meta.rateLimitDetails.message,\n };\n }\n return undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"errors.cjs","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA,uEAIuC;AAEvC,+CAAgE;AAEhE;;;;;;GAMG;AACH,SAAS,iCAAiC,CACxC,SAAyB,EACzB,cAAsB;IAEtB,QAAQ,SAAS,EAAE;QACjB,KAAK,oCAAc,CAAC,iBAAiB;YACnC,OAAO,6CAAiC,CAAC,oBAAoB,CAAC;QAChE,KAAK,oCAAc,CAAC,2BAA2B;YAC7C,OAAO,6CAAiC,CAAC,iBAAiB,CAAC;QAC7D;YACE,OAAO,cAAc,CAAC;KACzB;AACH,CAAC;AAED;;;GAGG;AACH,MAAa,aAAc,SAAQ,KAAK;IAGtC,YAAY,OAAe,EAAE,IAAyB;QACpD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,8CAA8C,CAAC;IAC7D,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,KAAc;QAC/B,IAAI,KAAK,YAAY,gCAAU,EAAE;YAC/B,MAAM,kBAAkB,GAAG,aAAa,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;YACtE,MAAM,YAAY,GAAG,iCAAiC,CACpD,KAAK,CAAC,IAAI,EACV,6CAAiC,CAAC,gBAAgB,CACnD,CAAC;YACF,OAAO,IAAI,aAAa,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;SAC5D;QACD,OAAO,IAAI,aAAa,CACtB,6CAAiC,CAAC,gBAAgB,CACnD,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,qBAAqB,CAC1B,KAAiB;QAEjB,IACE,KAAK,CAAC,IAAI,IAAI,iCAAiC;YAC/C,KAAK,CAAC,IAAI,KAAK,oCAAc,CAAC,iBAAiB;YAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,QAAQ;YAC/C,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,IAAI;YACpC,eAAe,IAAI,KAAK,CAAC,IAAI,CAAC,gBAAgB;YAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,aAAa,KAAK,QAAQ;YAC7D,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,gBAAgB;YACxC,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,KAAK,QAAQ,EACvD;YACA,OAAO;gBACL,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,aAAa;gBACxD,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO;aAC7C,CAAC;SACH;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;CACF;AAzDD,sCAyDC","sourcesContent":["import {\n type RateLimitErrorData,\n TOPRFError,\n TOPRFErrorCode,\n} from '@metamask/toprf-secure-backup';\n\nimport { SeedlessOnboardingControllerError } from './constants';\n\n/**\n * Get the error message from the TOPRF error code.\n *\n * @param errorCode - The TOPRF error code.\n * @param defaultMessage - The default error message if the error code is not found.\n * @returns The error message.\n */\nfunction getErrorMessageFromTOPRFErrorCode(\n errorCode: TOPRFErrorCode,\n defaultMessage: string,\n): string {\n switch (errorCode) {\n case TOPRFErrorCode.RateLimitExceeded:\n return SeedlessOnboardingControllerError.TooManyLoginAttempts;\n case TOPRFErrorCode.CouldNotDeriveEncryptionKey:\n return SeedlessOnboardingControllerError.IncorrectPassword;\n default:\n return defaultMessage;\n }\n}\n\n/**\n * The RecoveryError class is used to handle errors that occur during the recover encryption key process from the passwrord.\n * It extends the Error class and includes a data property that can be used to store additional information.\n */\nexport class RecoveryError extends Error {\n data: RateLimitErrorData | undefined;\n\n constructor(message: string, data?: RateLimitErrorData) {\n super(message);\n this.data = data;\n this.name = 'SeedlessOnboardingController - RecoveryError';\n }\n\n /**\n * Get an instance of the RecoveryError class.\n *\n * @param error - The error to get the instance of.\n * @returns The instance of the RecoveryError class.\n */\n static getInstance(error: unknown): RecoveryError {\n if (error instanceof TOPRFError) {\n const rateLimitErrorData = RecoveryError.getRateLimitErrorData(error);\n const errorMessage = getErrorMessageFromTOPRFErrorCode(\n error.code,\n SeedlessOnboardingControllerError.LoginFailedError,\n );\n return new RecoveryError(errorMessage, rateLimitErrorData);\n }\n return new RecoveryError(\n SeedlessOnboardingControllerError.LoginFailedError,\n );\n }\n\n /**\n * Check if the provided error is a rate limit error triggered by too many login attempts.\n *\n * Return a new TooManyLoginAttemptsError if the error is a rate limit error, otherwise undefined.\n *\n * @param error - The error to check.\n * @returns The rate limit error if the error is a rate limit error, otherwise undefined.\n */\n static getRateLimitErrorData(\n error: TOPRFError,\n ): RateLimitErrorData | undefined {\n if (\n error.meta && // error metadata must be present\n error.code === TOPRFErrorCode.RateLimitExceeded &&\n typeof error.meta.rateLimitDetails === 'object' &&\n error.meta.rateLimitDetails !== null &&\n 'remainingTime' in error.meta.rateLimitDetails &&\n typeof error.meta.rateLimitDetails.remainingTime === 'number' &&\n 'message' in error.meta.rateLimitDetails &&\n typeof error.meta.rateLimitDetails.message === 'string'\n ) {\n return {\n remainingTime: error.meta.rateLimitDetails.remainingTime,\n message: error.meta.rateLimitDetails.message,\n };\n }\n return undefined;\n }\n}\n"]}
package/dist/errors.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { TOPRFError, TORPFErrorCode } from "@metamask/toprf-secure-backup";
1
+ import { TOPRFError, TOPRFErrorCode } from "@metamask/toprf-secure-backup";
2
2
  import { SeedlessOnboardingControllerError } from "./constants.mjs";
3
3
  /**
4
4
  * Get the error message from the TOPRF error code.
@@ -9,9 +9,9 @@ import { SeedlessOnboardingControllerError } from "./constants.mjs";
9
9
  */
10
10
  function getErrorMessageFromTOPRFErrorCode(errorCode, defaultMessage) {
11
11
  switch (errorCode) {
12
- case TORPFErrorCode.RateLimitExceeded:
12
+ case TOPRFErrorCode.RateLimitExceeded:
13
13
  return SeedlessOnboardingControllerError.TooManyLoginAttempts;
14
- case TORPFErrorCode.CouldNotDeriveEncryptionKey:
14
+ case TOPRFErrorCode.CouldNotDeriveEncryptionKey:
15
15
  return SeedlessOnboardingControllerError.IncorrectPassword;
16
16
  default:
17
17
  return defaultMessage;
@@ -51,7 +51,7 @@ export class RecoveryError extends Error {
51
51
  */
52
52
  static getRateLimitErrorData(error) {
53
53
  if (error.meta && // error metadata must be present
54
- error.code === TORPFErrorCode.RateLimitExceeded &&
54
+ error.code === TOPRFErrorCode.RateLimitExceeded &&
55
55
  typeof error.meta.rateLimitDetails === 'object' &&
56
56
  error.meta.rateLimitDetails !== null &&
57
57
  'remainingTime' in error.meta.rateLimitDetails &&
@@ -1 +1 @@
1
- {"version":3,"file":"errors.mjs","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,cAAc,EACf,sCAAsC;AAEvC,OAAO,EAAE,iCAAiC,EAAE,wBAAoB;AAEhE;;;;;;GAMG;AACH,SAAS,iCAAiC,CACxC,SAAyB,EACzB,cAAsB;IAEtB,QAAQ,SAAS,EAAE;QACjB,KAAK,cAAc,CAAC,iBAAiB;YACnC,OAAO,iCAAiC,CAAC,oBAAoB,CAAC;QAChE,KAAK,cAAc,CAAC,2BAA2B;YAC7C,OAAO,iCAAiC,CAAC,iBAAiB,CAAC;QAC7D;YACE,OAAO,cAAc,CAAC;KACzB;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IAGtC,YAAY,OAAe,EAAE,IAAyB;QACpD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,8CAA8C,CAAC;IAC7D,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,KAAc;QAC/B,IAAI,KAAK,YAAY,UAAU,EAAE;YAC/B,MAAM,kBAAkB,GAAG,aAAa,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;YACtE,MAAM,YAAY,GAAG,iCAAiC,CACpD,KAAK,CAAC,IAAI,EACV,iCAAiC,CAAC,gBAAgB,CACnD,CAAC;YACF,OAAO,IAAI,aAAa,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;SAC5D;QACD,OAAO,IAAI,aAAa,CACtB,iCAAiC,CAAC,gBAAgB,CACnD,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,qBAAqB,CAC1B,KAAiB;QAEjB,IACE,KAAK,CAAC,IAAI,IAAI,iCAAiC;YAC/C,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,iBAAiB;YAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,QAAQ;YAC/C,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,IAAI;YACpC,eAAe,IAAI,KAAK,CAAC,IAAI,CAAC,gBAAgB;YAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,aAAa,KAAK,QAAQ;YAC7D,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,gBAAgB;YACxC,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,KAAK,QAAQ,EACvD;YACA,OAAO;gBACL,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,aAAa;gBACxD,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO;aAC7C,CAAC;SACH;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;CACF","sourcesContent":["import {\n type RateLimitErrorData,\n TOPRFError,\n TORPFErrorCode,\n} from '@metamask/toprf-secure-backup';\n\nimport { SeedlessOnboardingControllerError } from './constants';\n\n/**\n * Get the error message from the TOPRF error code.\n *\n * @param errorCode - The TOPRF error code.\n * @param defaultMessage - The default error message if the error code is not found.\n * @returns The error message.\n */\nfunction getErrorMessageFromTOPRFErrorCode(\n errorCode: TORPFErrorCode,\n defaultMessage: string,\n): string {\n switch (errorCode) {\n case TORPFErrorCode.RateLimitExceeded:\n return SeedlessOnboardingControllerError.TooManyLoginAttempts;\n case TORPFErrorCode.CouldNotDeriveEncryptionKey:\n return SeedlessOnboardingControllerError.IncorrectPassword;\n default:\n return defaultMessage;\n }\n}\n\n/**\n * The RecoveryError class is used to handle errors that occur during the recover encryption key process from the passwrord.\n * It extends the Error class and includes a data property that can be used to store additional information.\n */\nexport class RecoveryError extends Error {\n data: RateLimitErrorData | undefined;\n\n constructor(message: string, data?: RateLimitErrorData) {\n super(message);\n this.data = data;\n this.name = 'SeedlessOnboardingController - RecoveryError';\n }\n\n /**\n * Get an instance of the RecoveryError class.\n *\n * @param error - The error to get the instance of.\n * @returns The instance of the RecoveryError class.\n */\n static getInstance(error: unknown): RecoveryError {\n if (error instanceof TOPRFError) {\n const rateLimitErrorData = RecoveryError.getRateLimitErrorData(error);\n const errorMessage = getErrorMessageFromTOPRFErrorCode(\n error.code,\n SeedlessOnboardingControllerError.LoginFailedError,\n );\n return new RecoveryError(errorMessage, rateLimitErrorData);\n }\n return new RecoveryError(\n SeedlessOnboardingControllerError.LoginFailedError,\n );\n }\n\n /**\n * Check if the provided error is a rate limit error triggered by too many login attempts.\n *\n * Return a new TooManyLoginAttemptsError if the error is a rate limit error, otherwise undefined.\n *\n * @param error - The error to check.\n * @returns The rate limit error if the error is a rate limit error, otherwise undefined.\n */\n static getRateLimitErrorData(\n error: TOPRFError,\n ): RateLimitErrorData | undefined {\n if (\n error.meta && // error metadata must be present\n error.code === TORPFErrorCode.RateLimitExceeded &&\n typeof error.meta.rateLimitDetails === 'object' &&\n error.meta.rateLimitDetails !== null &&\n 'remainingTime' in error.meta.rateLimitDetails &&\n typeof error.meta.rateLimitDetails.remainingTime === 'number' &&\n 'message' in error.meta.rateLimitDetails &&\n typeof error.meta.rateLimitDetails.message === 'string'\n ) {\n return {\n remainingTime: error.meta.rateLimitDetails.remainingTime,\n message: error.meta.rateLimitDetails.message,\n };\n }\n return undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"errors.mjs","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,cAAc,EACf,sCAAsC;AAEvC,OAAO,EAAE,iCAAiC,EAAE,wBAAoB;AAEhE;;;;;;GAMG;AACH,SAAS,iCAAiC,CACxC,SAAyB,EACzB,cAAsB;IAEtB,QAAQ,SAAS,EAAE;QACjB,KAAK,cAAc,CAAC,iBAAiB;YACnC,OAAO,iCAAiC,CAAC,oBAAoB,CAAC;QAChE,KAAK,cAAc,CAAC,2BAA2B;YAC7C,OAAO,iCAAiC,CAAC,iBAAiB,CAAC;QAC7D;YACE,OAAO,cAAc,CAAC;KACzB;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IAGtC,YAAY,OAAe,EAAE,IAAyB;QACpD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,8CAA8C,CAAC;IAC7D,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,KAAc;QAC/B,IAAI,KAAK,YAAY,UAAU,EAAE;YAC/B,MAAM,kBAAkB,GAAG,aAAa,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;YACtE,MAAM,YAAY,GAAG,iCAAiC,CACpD,KAAK,CAAC,IAAI,EACV,iCAAiC,CAAC,gBAAgB,CACnD,CAAC;YACF,OAAO,IAAI,aAAa,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;SAC5D;QACD,OAAO,IAAI,aAAa,CACtB,iCAAiC,CAAC,gBAAgB,CACnD,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,qBAAqB,CAC1B,KAAiB;QAEjB,IACE,KAAK,CAAC,IAAI,IAAI,iCAAiC;YAC/C,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,iBAAiB;YAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,QAAQ;YAC/C,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,IAAI;YACpC,eAAe,IAAI,KAAK,CAAC,IAAI,CAAC,gBAAgB;YAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,aAAa,KAAK,QAAQ;YAC7D,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,gBAAgB;YACxC,OAAO,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,KAAK,QAAQ,EACvD;YACA,OAAO;gBACL,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,aAAa;gBACxD,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO;aAC7C,CAAC;SACH;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;CACF","sourcesContent":["import {\n type RateLimitErrorData,\n TOPRFError,\n TOPRFErrorCode,\n} from '@metamask/toprf-secure-backup';\n\nimport { SeedlessOnboardingControllerError } from './constants';\n\n/**\n * Get the error message from the TOPRF error code.\n *\n * @param errorCode - The TOPRF error code.\n * @param defaultMessage - The default error message if the error code is not found.\n * @returns The error message.\n */\nfunction getErrorMessageFromTOPRFErrorCode(\n errorCode: TOPRFErrorCode,\n defaultMessage: string,\n): string {\n switch (errorCode) {\n case TOPRFErrorCode.RateLimitExceeded:\n return SeedlessOnboardingControllerError.TooManyLoginAttempts;\n case TOPRFErrorCode.CouldNotDeriveEncryptionKey:\n return SeedlessOnboardingControllerError.IncorrectPassword;\n default:\n return defaultMessage;\n }\n}\n\n/**\n * The RecoveryError class is used to handle errors that occur during the recover encryption key process from the passwrord.\n * It extends the Error class and includes a data property that can be used to store additional information.\n */\nexport class RecoveryError extends Error {\n data: RateLimitErrorData | undefined;\n\n constructor(message: string, data?: RateLimitErrorData) {\n super(message);\n this.data = data;\n this.name = 'SeedlessOnboardingController - RecoveryError';\n }\n\n /**\n * Get an instance of the RecoveryError class.\n *\n * @param error - The error to get the instance of.\n * @returns The instance of the RecoveryError class.\n */\n static getInstance(error: unknown): RecoveryError {\n if (error instanceof TOPRFError) {\n const rateLimitErrorData = RecoveryError.getRateLimitErrorData(error);\n const errorMessage = getErrorMessageFromTOPRFErrorCode(\n error.code,\n SeedlessOnboardingControllerError.LoginFailedError,\n );\n return new RecoveryError(errorMessage, rateLimitErrorData);\n }\n return new RecoveryError(\n SeedlessOnboardingControllerError.LoginFailedError,\n );\n }\n\n /**\n * Check if the provided error is a rate limit error triggered by too many login attempts.\n *\n * Return a new TooManyLoginAttemptsError if the error is a rate limit error, otherwise undefined.\n *\n * @param error - The error to check.\n * @returns The rate limit error if the error is a rate limit error, otherwise undefined.\n */\n static getRateLimitErrorData(\n error: TOPRFError,\n ): RateLimitErrorData | undefined {\n if (\n error.meta && // error metadata must be present\n error.code === TOPRFErrorCode.RateLimitExceeded &&\n typeof error.meta.rateLimitDetails === 'object' &&\n error.meta.rateLimitDetails !== null &&\n 'remainingTime' in error.meta.rateLimitDetails &&\n typeof error.meta.rateLimitDetails.remainingTime === 'number' &&\n 'message' in error.meta.rateLimitDetails &&\n typeof error.meta.rateLimitDetails.message === 'string'\n ) {\n return {\n remainingTime: error.meta.rateLimitDetails.remainingTime,\n message: error.meta.rateLimitDetails.message,\n };\n }\n return undefined;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/seedless-onboarding-controller",
3
- "version": "0.0.0-preview-7aa27646",
3
+ "version": "0.0.0-preview-8a04e037",
4
4
  "description": "Backup and rehydrate SRP(s) using social login and password",
5
5
  "keywords": [
6
6
  "MetaMask",
@@ -47,14 +47,16 @@
47
47
  "since-latest-release": "../../scripts/since-latest-release.sh"
48
48
  },
49
49
  "dependencies": {
50
- "@metamask/auth-network-utils": "./auth-network-utils.tgz",
51
- "@metamask/base-controller": "^8.0.0",
50
+ "@metamask/auth-network-utils": "^0.1.0",
51
+ "@metamask/base-controller": "^8.0.1",
52
52
  "@metamask/browser-passworder": "^4.3.0",
53
- "@metamask/toprf-secure-backup": "./toprf-secure-backup.tgz",
53
+ "@metamask/toprf-secure-backup": "^0.1.0",
54
54
  "@metamask/utils": "^11.2.0",
55
55
  "async-mutex": "^0.5.0"
56
56
  },
57
57
  "devDependencies": {
58
+ "@lavamoat/allow-scripts": "^3.0.4",
59
+ "@lavamoat/preinstall-always-fail": "^2.1.0",
58
60
  "@metamask/auto-changelog": "^3.4.4",
59
61
  "@noble/ciphers": "^0.5.2",
60
62
  "@noble/curves": "^1.2.0",
@@ -76,5 +78,11 @@
76
78
  "publishConfig": {
77
79
  "access": "public",
78
80
  "registry": "https://registry.npmjs.org/"
81
+ },
82
+ "lavamoat": {
83
+ "allowScripts": {
84
+ "@lavamoat/preinstall-always-fail": false,
85
+ "@metamask/toprf-secure-backup": true
86
+ }
79
87
  }
80
88
  }