@metamask-previews/seedless-onboarding-controller 2.5.0-preview-3f5f144a → 2.5.0-preview-848c8e7d

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.
@@ -9,11 +9,11 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _SeedlessOnboardingController_instances, _SeedlessOnboardingController_vaultEncryptor, _SeedlessOnboardingController_controllerOperationMutex, _SeedlessOnboardingController_vaultOperationMutex, _SeedlessOnboardingController_refreshJWTToken, _SeedlessOnboardingController_revokeRefreshToken, _SeedlessOnboardingController_isUnlocked, _SeedlessOnboardingController_passwordOutdatedCacheTTL, _SeedlessOnboardingController_submitGlobalPassword, _SeedlessOnboardingController_getAccessToken, _SeedlessOnboardingController_setUnlocked, _SeedlessOnboardingController_persistOprfKey, _SeedlessOnboardingController_persistAuthPubKey, _SeedlessOnboardingController_storeKeyringEncryptionKey, _SeedlessOnboardingController_loadKeyringEncryptionKey, _SeedlessOnboardingController_loadSeedlessEncryptionKey, _SeedlessOnboardingController_recoverAuthPubKey, _SeedlessOnboardingController_recoverEncKey, _SeedlessOnboardingController_fetchAllSecretDataFromMetadataStore, _SeedlessOnboardingController_changeEncryptionKey, _SeedlessOnboardingController_encryptAndStoreSecretData, _SeedlessOnboardingController_unlockVaultAndGetVaultData, _SeedlessOnboardingController_withPersistedSecretMetadataBackupsState, _SeedlessOnboardingController_filterDupesAndUpdateSocialBackupsMetadata, _SeedlessOnboardingController_createNewVaultWithAuthData, _SeedlessOnboardingController_updateVault, _SeedlessOnboardingController_withControllerLock, _SeedlessOnboardingController_withVaultLock, _SeedlessOnboardingController_serializeKeyData, _SeedlessOnboardingController_parseVaultData, _SeedlessOnboardingController_assertIsUnlocked, _SeedlessOnboardingController_assertIsAuthenticatedUser, _SeedlessOnboardingController_assertIsSRPBackedUpUser, _SeedlessOnboardingController_assertPasswordInSync, _SeedlessOnboardingController_resetPasswordOutdatedCache, _SeedlessOnboardingController_isTokenExpiredError, _SeedlessOnboardingController_isMaxKeyChainLengthError, _SeedlessOnboardingController_executeWithTokenRefresh;
12
+ var _SeedlessOnboardingController_instances, _SeedlessOnboardingController_vaultEncryptor, _SeedlessOnboardingController_controllerOperationMutex, _SeedlessOnboardingController_vaultOperationMutex, _SeedlessOnboardingController_refreshJWTToken, _SeedlessOnboardingController_revokeRefreshToken, _SeedlessOnboardingController_isUnlocked, _SeedlessOnboardingController_passwordOutdatedCacheTTL, _SeedlessOnboardingController_submitGlobalPassword, _SeedlessOnboardingController_getAccessToken, _SeedlessOnboardingController_setUnlocked, _SeedlessOnboardingController_persistOprfKey, _SeedlessOnboardingController_persistAuthPubKey, _SeedlessOnboardingController_storeKeyringEncryptionKey, _SeedlessOnboardingController_loadKeyringEncryptionKey, _SeedlessOnboardingController_loadSeedlessEncryptionKey, _SeedlessOnboardingController_recoverAuthPubKey, _SeedlessOnboardingController_recoverEncKey, _SeedlessOnboardingController_fetchAllSecretDataFromMetadataStore, _SeedlessOnboardingController_changeEncryptionKey, _SeedlessOnboardingController_encryptAndStoreSecretData, _SeedlessOnboardingController_unlockVaultAndGetVaultData, _SeedlessOnboardingController_withPersistedSecretMetadataBackupsState, _SeedlessOnboardingController_filterDupesAndUpdateSocialBackupsMetadata, _SeedlessOnboardingController_updateVault, _SeedlessOnboardingController_withControllerLock, _SeedlessOnboardingController_withVaultLock, _SeedlessOnboardingController_parseVaultData, _SeedlessOnboardingController_assertIsUnlocked, _SeedlessOnboardingController_assertIsAuthenticatedUser, _SeedlessOnboardingController_assertIsSRPBackedUpUser, _SeedlessOnboardingController_assertPasswordInSync, _SeedlessOnboardingController_resetPasswordOutdatedCache, _SeedlessOnboardingController_isTokenExpiredError, _SeedlessOnboardingController_isMaxKeyChainLengthError, _SeedlessOnboardingController_executeWithTokenRefresh;
13
13
  import { keccak256AndHexify } from "@metamask/auth-network-utils";
14
14
  import { BaseController } from "@metamask/base-controller";
15
15
  import { ToprfSecureBackup, TOPRFErrorCode, TOPRFError } from "@metamask/toprf-secure-backup";
16
- import { base64ToBytes, bytesToBase64, bigIntToHex } from "@metamask/utils";
16
+ import { base64ToBytes, bytesToBase64 } from "@metamask/utils";
17
17
  import { gcm } from "@noble/ciphers/aes";
18
18
  import { bytesToUtf8, utf8ToBytes } from "@noble/ciphers/utils";
19
19
  import { managedNonce } from "@noble/ciphers/webcrypto";
@@ -24,7 +24,7 @@ import { controllerName, PASSWORD_OUTDATED_CACHE_TTL_MS, SecretType, SeedlessOnb
24
24
  import { PasswordSyncError, RecoveryError } from "./errors.mjs";
25
25
  import { projectLogger, createModuleLogger } from "./logger.mjs";
26
26
  import { SecretMetadata } from "./SecretMetadata.mjs";
27
- import { decodeJWTToken, decodeNodeAuthToken } from "./utils.mjs";
27
+ import { decodeJWTToken, decodeNodeAuthToken, deserializAuthKeyPair, serializeAuthKeyPair } from "./utils.mjs";
28
28
  const log = createModuleLogger(projectLogger, controllerName);
29
29
  /**
30
30
  * Get the default state for the Seedless Onboarding Controller.
@@ -80,10 +80,6 @@ const seedlessOnboardingMetadata = {
80
80
  persist: false,
81
81
  anonymous: true,
82
82
  },
83
- vaultEncryptionSalt: {
84
- persist: false,
85
- anonymous: true,
86
- },
87
83
  authPubKey: {
88
84
  persist: true,
89
85
  anonymous: true,
@@ -119,6 +115,18 @@ const seedlessOnboardingMetadata = {
119
115
  persist: true,
120
116
  anonymous: true,
121
117
  },
118
+ toprfEncryptionKey: {
119
+ persist: false,
120
+ anonymous: true,
121
+ },
122
+ toprfPwEncryptionKey: {
123
+ persist: false,
124
+ anonymous: true,
125
+ },
126
+ toprfAuthKeyPair: {
127
+ persist: false,
128
+ anonymous: true,
129
+ },
122
130
  };
123
131
  export class SeedlessOnboardingController extends BaseController {
124
132
  /**
@@ -292,7 +300,7 @@ export class SeedlessOnboardingController extends BaseController {
292
300
  // to have an account but with no associated data.
293
301
  await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_persistOprfKey).call(this, oprfKey, authKeyPair.pk);
294
302
  // create a new vault with the resulting authentication data
295
- await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_createNewVaultWithAuthData).call(this, {
303
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_updateVault).call(this, {
296
304
  password,
297
305
  rawToprfEncryptionKey: encKey,
298
306
  rawToprfPwEncryptionKey: pwEncKey,
@@ -313,20 +321,22 @@ export class SeedlessOnboardingController extends BaseController {
313
321
  */
314
322
  async addNewSecretData(data, type, options) {
315
323
  return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
316
- __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this);
324
+ // assert that the controller is unlocked before adding new secret data
325
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
326
+ // get the TOPRF encryption key and authentication key pair from the state
327
+ const { toprfEncryptionKey, toprfAuthKeyPair } = this.state;
328
+ // assert that the password is in sync with the encryption key
317
329
  await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertPasswordInSync).call(this, {
318
330
  skipCache: true,
319
331
  skipLock: true, // skip lock since we already have the lock
320
332
  });
321
333
  const performBackup = async () => {
322
- // verify the password and unlock the vault
323
- const { toprfEncryptionKey, toprfAuthKeyPair } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this);
324
334
  // encrypt and store the secret data
325
335
  await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_encryptAndStoreSecretData).call(this, {
326
336
  data,
327
337
  type,
328
- encKey: toprfEncryptionKey,
329
- authKeyPair: toprfAuthKeyPair,
338
+ encKey: base64ToBytes(toprfEncryptionKey),
339
+ authKeyPair: deserializAuthKeyPair(toprfAuthKeyPair),
330
340
  options,
331
341
  });
332
342
  };
@@ -355,18 +365,17 @@ export class SeedlessOnboardingController extends BaseController {
355
365
  authKeyPair = recoverEncKeyResult.authKeyPair;
356
366
  }
357
367
  else {
358
- __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this);
359
- // verify the password and unlock the vault
360
- const keysFromVault = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this);
361
- encKey = keysFromVault.toprfEncryptionKey;
362
- pwEncKey = keysFromVault.toprfPwEncryptionKey;
363
- authKeyPair = keysFromVault.toprfAuthKeyPair;
368
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
369
+ const { toprfEncryptionKey, toprfPwEncryptionKey, toprfAuthKeyPair } = this.state;
370
+ encKey = base64ToBytes(toprfEncryptionKey);
371
+ pwEncKey = base64ToBytes(toprfPwEncryptionKey);
372
+ authKeyPair = deserializAuthKeyPair(toprfAuthKeyPair);
364
373
  }
365
374
  const performFetch = async () => {
366
375
  const secrets = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_fetchAllSecretDataFromMetadataStore).call(this, encKey, authKeyPair);
367
376
  if (password) {
368
377
  // if password is provided, we need to create a new vault with the auth data. (supposedly the user is trying to rehydrate the wallet)
369
- await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_createNewVaultWithAuthData).call(this, {
378
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_updateVault).call(this, {
370
379
  password,
371
380
  rawToprfEncryptionKey: encKey,
372
381
  rawToprfPwEncryptionKey: pwEncKey,
@@ -389,7 +398,8 @@ export class SeedlessOnboardingController extends BaseController {
389
398
  */
390
399
  async changePassword(newPassword, oldPassword) {
391
400
  return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
392
- __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this);
401
+ // assert that the controller is unlocked before changing the password
402
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
393
403
  // verify the old password of the encrypted vault
394
404
  await this.verifyVaultPassword(oldPassword, {
395
405
  skipLock: true, // skip lock since we already have the lock
@@ -411,7 +421,7 @@ export class SeedlessOnboardingController extends BaseController {
411
421
  latestKeyIndex,
412
422
  });
413
423
  // update and encrypt the vault with new password
414
- await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_createNewVaultWithAuthData).call(this, {
424
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_updateVault).call(this, {
415
425
  password: newPassword,
416
426
  rawToprfEncryptionKey: newEncKey,
417
427
  rawToprfPwEncryptionKey: newPwEncKey,
@@ -440,7 +450,7 @@ export class SeedlessOnboardingController extends BaseController {
440
450
  * @param secretData.data - The secret data to update the backup metadata state.
441
451
  */
442
452
  updateBackupMetadataState(secretData) {
443
- __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this);
453
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
444
454
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_filterDupesAndUpdateSocialBackupsMetadata).call(this, secretData);
445
455
  }
446
456
  /**
@@ -489,7 +499,7 @@ export class SeedlessOnboardingController extends BaseController {
489
499
  */
490
500
  async submitPassword(password) {
491
501
  return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
492
- await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, password);
502
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, { password });
493
503
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
494
504
  });
495
505
  }
@@ -501,7 +511,9 @@ export class SeedlessOnboardingController extends BaseController {
501
511
  setLocked() {
502
512
  this.update((state) => {
503
513
  delete state.vaultEncryptionKey;
504
- delete state.vaultEncryptionSalt;
514
+ delete state.toprfEncryptionKey;
515
+ delete state.toprfPwEncryptionKey;
516
+ delete state.toprfAuthKeyPair;
505
517
  delete state.revokeToken;
506
518
  delete state.accessToken;
507
519
  });
@@ -518,12 +530,12 @@ export class SeedlessOnboardingController extends BaseController {
518
530
  */
519
531
  async syncLatestGlobalPassword({ globalPassword, }) {
520
532
  return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
521
- __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this);
533
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
522
534
  const doSyncPassword = async () => {
523
535
  // update vault with latest globalPassword
524
536
  const { encKey, pwEncKey, authKeyPair } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_recoverEncKey).call(this, globalPassword);
525
537
  // update and encrypt the vault with new password
526
- await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_createNewVaultWithAuthData).call(this, {
538
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_updateVault).call(this, {
527
539
  password: globalPassword,
528
540
  rawToprfEncryptionKey: encKey,
529
541
  rawToprfPwEncryptionKey: pwEncKey,
@@ -624,7 +636,9 @@ export class SeedlessOnboardingController extends BaseController {
624
636
  * @param keyringEncryptionKey - The keyring encryption key.
625
637
  */
626
638
  async storeKeyringEncryptionKey(keyringEncryptionKey) {
627
- const { toprfPwEncryptionKey: encKey } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this);
639
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
640
+ const { toprfPwEncryptionKey } = this.state;
641
+ const encKey = base64ToBytes(toprfPwEncryptionKey);
628
642
  await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_storeKeyringEncryptionKey).call(this, encKey, keyringEncryptionKey);
629
643
  }
630
644
  /**
@@ -634,7 +648,9 @@ export class SeedlessOnboardingController extends BaseController {
634
648
  * @returns The keyring encryption key.
635
649
  */
636
650
  async loadKeyringEncryptionKey() {
637
- const { toprfPwEncryptionKey: encKey } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this);
651
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
652
+ const { toprfPwEncryptionKey } = this.state;
653
+ const encKey = base64ToBytes(toprfPwEncryptionKey);
638
654
  return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_loadKeyringEncryptionKey).call(this, encKey);
639
655
  }
640
656
  /**
@@ -683,7 +699,10 @@ export class SeedlessOnboardingController extends BaseController {
683
699
  return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
684
700
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
685
701
  const { vaultEncryptionKey } = this.state;
686
- const { toprfEncryptionKey: rawToprfEncryptionKey, toprfPwEncryptionKey: rawToprfPwEncryptionKey, toprfAuthKeyPair: rawToprfAuthKeyPair, revokeToken, } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, password, vaultEncryptionKey);
702
+ const { toprfEncryptionKey: rawToprfEncryptionKey, toprfPwEncryptionKey: rawToprfPwEncryptionKey, toprfAuthKeyPair: rawToprfAuthKeyPair, revokeToken, } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, {
703
+ password,
704
+ encryptionKey: vaultEncryptionKey,
705
+ });
687
706
  if (!revokeToken) {
688
707
  throw new Error(SeedlessOnboardingControllerErrorMessage.InvalidRevokeToken);
689
708
  }
@@ -697,7 +716,7 @@ export class SeedlessOnboardingController extends BaseController {
697
716
  // set new refresh token to persist in state
698
717
  state.refreshToken = newRefreshToken;
699
718
  });
700
- await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_createNewVaultWithAuthData).call(this, {
719
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_updateVault).call(this, {
701
720
  password,
702
721
  rawToprfEncryptionKey,
703
722
  rawToprfPwEncryptionKey,
@@ -784,7 +803,9 @@ async function _SeedlessOnboardingController_submitGlobalPassword({ targetAuthPu
784
803
  const { pwEncKey } = res;
785
804
  const vaultKey = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_loadSeedlessEncryptionKey).call(this, pwEncKey);
786
805
  // Unlock the controller
787
- await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, undefined, vaultKey);
806
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, {
807
+ encryptionKey: vaultKey,
808
+ });
788
809
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
789
810
  }
790
811
  catch (error) {
@@ -816,7 +837,10 @@ async function _SeedlessOnboardingController_getAccessToken(password) {
816
837
  if (!vault) {
817
838
  throw new Error(SeedlessOnboardingControllerErrorMessage.InvalidAccessToken);
818
839
  }
819
- const { accessToken: accessTokenFromVault } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, password);
840
+ const { accessToken: accessTokenFromVault } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, {
841
+ password,
842
+ skipVaultMutexLock: true,
843
+ });
820
844
  return accessTokenFromVault;
821
845
  }, _SeedlessOnboardingController_setUnlocked = function _SeedlessOnboardingController_setUnlocked() {
822
846
  __classPrivateFieldSet(this, _SeedlessOnboardingController_isUnlocked, true, "f");
@@ -935,7 +959,6 @@ async function _SeedlessOnboardingController_recoverEncKey(password) {
935
959
  });
936
960
  }
937
961
  catch (error) {
938
- log('Error fetching secret data', error);
939
962
  if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_isTokenExpiredError).call(this, error)) {
940
963
  throw error;
941
964
  }
@@ -978,11 +1001,12 @@ async function _SeedlessOnboardingController_changeEncryptionKey({ oldPassword,
978
1001
  } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_recoverEncKey).call(this, oldPassword));
979
1002
  }
980
1003
  else {
981
- ({
982
- toprfEncryptionKey: encKey,
983
- toprfPwEncryptionKey: pwEncKey,
984
- toprfAuthKeyPair: authKeyPair,
985
- } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, oldPassword));
1004
+ // get the TOPRF encryption key and authentication key pair from the state
1005
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
1006
+ const { toprfEncryptionKey, toprfPwEncryptionKey, toprfAuthKeyPair } = this.state;
1007
+ encKey = base64ToBytes(toprfEncryptionKey);
1008
+ pwEncKey = base64ToBytes(toprfPwEncryptionKey);
1009
+ authKeyPair = deserializAuthKeyPair(toprfAuthKeyPair);
986
1010
  }
987
1011
  const result = await this.toprfClient.changeEncKey({
988
1012
  nodeAuthTokens: this.state.nodeAuthTokens,
@@ -1048,11 +1072,15 @@ async function _SeedlessOnboardingController_encryptAndStoreSecretData(params) {
1048
1072
  }
1049
1073
  }, _SeedlessOnboardingController_unlockVaultAndGetVaultData =
1050
1074
  /**
1051
- * Unlocks the encrypted vault using the provided password and returns the decrypted vault data.
1075
+ * Unlocks the encrypted vault using the provided password or encryption key and returns the decrypted vault data.
1052
1076
  * This method ensures thread-safety by using a mutex lock when accessing the vault.
1053
1077
  *
1054
- * @param password - The optional password to unlock the vault.
1055
- * @param encryptionKey - The optional encryption key to unlock the vault.
1078
+ * Successfully unlocking the vault will update the controller state with the decrypted vault data.
1079
+ *
1080
+ * @param params - The parameters for unlocking the vault.
1081
+ * @param params.password - The optional password to unlock the vault.
1082
+ * @param params.encryptionKey - The optional encryption key to unlock the vault.
1083
+ * @param params.skipVaultMutexLock - Whether to skip the vault mutex lock.
1056
1084
  * @returns A promise that resolves to an object containing:
1057
1085
  * - toprfEncryptionKey: The decrypted TOPRF encryption key
1058
1086
  * - toprfAuthKeyPair: The decrypted TOPRF authentication key pair
@@ -1064,44 +1092,40 @@ async function _SeedlessOnboardingController_encryptAndStoreSecretData(params) {
1064
1092
  * - The password is incorrect (from encryptor.decrypt)
1065
1093
  * - The decrypted vault data is malformed
1066
1094
  */
1067
- async function _SeedlessOnboardingController_unlockVaultAndGetVaultData(password, encryptionKey) {
1068
- return __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withVaultLock).call(this, async () => {
1095
+ async function _SeedlessOnboardingController_unlockVaultAndGetVaultData(params) {
1096
+ const doUnlockVaultAndGetVaultData = async () => {
1069
1097
  let { vaultEncryptionKey } = this.state;
1070
- const { vault: encryptedVault, vaultEncryptionSalt } = this.state;
1098
+ const { vault: encryptedVault } = this.state;
1071
1099
  if (!encryptedVault) {
1072
1100
  throw new Error(SeedlessOnboardingControllerErrorMessage.VaultError);
1073
1101
  }
1074
- if (encryptionKey) {
1075
- vaultEncryptionKey = encryptionKey;
1102
+ if (params?.encryptionKey) {
1103
+ vaultEncryptionKey = params.encryptionKey;
1076
1104
  }
1077
1105
  let decryptedVaultData;
1078
1106
  const updatedState = {};
1079
- if (password) {
1080
- assertIsValidPassword(password);
1107
+ if (params?.password) {
1108
+ assertIsValidPassword(params.password);
1081
1109
  // Note that vault decryption using the password is a very costly operation as it involves deriving the encryption key
1082
1110
  // from the password using an intentionally slow key derivation function.
1083
1111
  // We should make sure that we only call it very intentionally.
1084
- const result = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").decryptWithDetail(password, encryptedVault);
1112
+ const result = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").decryptWithDetail(params.password, encryptedVault);
1085
1113
  decryptedVaultData = result.vault;
1086
1114
  updatedState.vaultEncryptionKey = result.exportedKeyString;
1087
- updatedState.vaultEncryptionSalt = result.salt;
1088
1115
  }
1089
1116
  else {
1090
1117
  assertIsVaultEncryptionKeyDefined(vaultEncryptionKey);
1091
1118
  const parsedEncryptedVault = JSON.parse(encryptedVault);
1092
- if (vaultEncryptionSalt &&
1093
- vaultEncryptionSalt !== parsedEncryptedVault.salt) {
1094
- throw new Error(SeedlessOnboardingControllerErrorMessage.ExpiredCredentials);
1095
- }
1096
1119
  const key = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").importKey(vaultEncryptionKey);
1097
1120
  decryptedVaultData = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").decryptWithKey(key, parsedEncryptedVault);
1098
1121
  updatedState.vaultEncryptionKey = vaultEncryptionKey;
1099
- updatedState.vaultEncryptionSalt = vaultEncryptionSalt;
1100
1122
  }
1101
1123
  const { toprfEncryptionKey, toprfPwEncryptionKey, toprfAuthKeyPair, revokeToken, accessToken, } = __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_parseVaultData).call(this, decryptedVaultData);
1102
1124
  this.update((state) => {
1103
1125
  state.vaultEncryptionKey = updatedState.vaultEncryptionKey;
1104
- state.vaultEncryptionSalt = updatedState.vaultEncryptionSalt;
1126
+ state.toprfEncryptionKey = bytesToBase64(toprfEncryptionKey);
1127
+ state.toprfPwEncryptionKey = bytesToBase64(toprfPwEncryptionKey);
1128
+ state.toprfAuthKeyPair = serializeAuthKeyPair(toprfAuthKeyPair);
1105
1129
  state.revokeToken = revokeToken;
1106
1130
  state.accessToken = accessToken;
1107
1131
  });
@@ -1112,7 +1136,10 @@ async function _SeedlessOnboardingController_unlockVaultAndGetVaultData(password
1112
1136
  revokeToken,
1113
1137
  accessToken,
1114
1138
  };
1115
- });
1139
+ };
1140
+ return params?.skipVaultMutexLock
1141
+ ? doUnlockVaultAndGetVaultData()
1142
+ : __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withVaultLock).call(this, doUnlockVaultAndGetVaultData);
1116
1143
  }, _SeedlessOnboardingController_withPersistedSecretMetadataBackupsState =
1117
1144
  /**
1118
1145
  * Executes a callback function that creates or restores secret data and persists their hashes in the controller state.
@@ -1169,65 +1196,54 @@ async function _SeedlessOnboardingController_withPersistedSecretMetadataBackupsS
1169
1196
  ];
1170
1197
  });
1171
1198
  }
1172
- }, _SeedlessOnboardingController_createNewVaultWithAuthData =
1173
- /**
1174
- * Create a new vault with the given authentication data.
1175
- *
1176
- * Serialize the authentication and key data which will be stored in the vault.
1177
- *
1178
- * @param params - The parameters for creating a new vault.
1179
- * @param params.password - The password to encrypt the vault.
1180
- * @param params.rawToprfEncryptionKey - The encryption key to encrypt the vault.
1181
- * @param params.rawToprfPwEncryptionKey - The encryption key to encrypt the password.
1182
- * @param params.rawToprfAuthKeyPair - The authentication key pair to encrypt the vault.
1183
- */
1184
- async function _SeedlessOnboardingController_createNewVaultWithAuthData({ password, rawToprfEncryptionKey, rawToprfPwEncryptionKey, rawToprfAuthKeyPair, }) {
1185
- __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
1186
- const accessToken = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_getAccessToken).call(this, password);
1187
- __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
1188
- const { toprfEncryptionKey, toprfPwEncryptionKey, toprfAuthKeyPair } = __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_serializeKeyData).call(this, rawToprfEncryptionKey, rawToprfPwEncryptionKey, rawToprfAuthKeyPair);
1189
- const serializedVaultData = JSON.stringify({
1190
- toprfEncryptionKey,
1191
- toprfPwEncryptionKey,
1192
- toprfAuthKeyPair,
1193
- revokeToken: this.state.revokeToken,
1194
- accessToken,
1195
- });
1196
- await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_updateVault).call(this, {
1197
- password,
1198
- serializedVaultData,
1199
- pwEncKey: rawToprfPwEncryptionKey,
1200
- });
1201
- // update the authPubKey in the state
1202
- __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_persistAuthPubKey).call(this, {
1203
- authPubKey: rawToprfAuthKeyPair.pk,
1204
- });
1205
1199
  }, _SeedlessOnboardingController_updateVault =
1206
1200
  /**
1207
1201
  * Encrypt and update the vault with the given authentication data.
1208
1202
  *
1209
1203
  * @param params - The parameters for updating the vault.
1210
1204
  * @param params.password - The password to encrypt the vault.
1211
- * @param params.serializedVaultData - The serialized authentication data to update the vault with.
1212
- * @param params.pwEncKey - The global password encryption key.
1205
+ * @param params.rawToprfEncryptionKey - The TOPRF encryption key.
1206
+ * @param params.rawToprfPwEncryptionKey - The TOPRF password encryption key.
1207
+ * @param params.rawToprfAuthKeyPair - The TOPRF authentication key pair.
1213
1208
  * @returns A promise that resolves to the updated vault.
1214
1209
  */
1215
- async function _SeedlessOnboardingController_updateVault({ password, serializedVaultData, pwEncKey, }) {
1210
+ async function _SeedlessOnboardingController_updateVault({ password, rawToprfEncryptionKey, rawToprfPwEncryptionKey, rawToprfAuthKeyPair, }) {
1216
1211
  await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withVaultLock).call(this, async () => {
1212
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
1217
1213
  assertIsValidPassword(password);
1214
+ const accessToken = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_getAccessToken).call(this, password);
1215
+ const toprfEncryptionKey = bytesToBase64(rawToprfEncryptionKey);
1216
+ const toprfPwEncryptionKey = bytesToBase64(rawToprfPwEncryptionKey);
1217
+ const toprfAuthKeyPair = serializeAuthKeyPair(rawToprfAuthKeyPair);
1218
+ const serializedVaultData = JSON.stringify({
1219
+ toprfEncryptionKey,
1220
+ toprfPwEncryptionKey,
1221
+ toprfAuthKeyPair,
1222
+ revokeToken: this.state.revokeToken,
1223
+ accessToken,
1224
+ });
1218
1225
  // Note that vault encryption using the password is a very costly operation as it involves deriving the encryption key
1219
1226
  // from the password using an intentionally slow key derivation function.
1220
1227
  // We should make sure that we only call it very intentionally.
1221
1228
  const { vault, exportedKeyString } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").encryptWithDetail(password, serializedVaultData);
1222
1229
  // Encrypt vault key.
1223
- const aes = managedNonce(gcm)(pwEncKey);
1230
+ const aes = managedNonce(gcm)(rawToprfPwEncryptionKey);
1224
1231
  const encryptedKey = aes.encrypt(utf8ToBytes(exportedKeyString));
1232
+ // update the controller state after updating the vault
1225
1233
  this.update((state) => {
1226
1234
  state.vault = vault;
1227
1235
  state.vaultEncryptionKey = exportedKeyString;
1228
- state.vaultEncryptionSalt = JSON.parse(vault).salt;
1229
1236
  state.encryptedSeedlessEncryptionKey = bytesToBase64(encryptedKey);
1237
+ state.toprfEncryptionKey = toprfEncryptionKey;
1238
+ state.toprfPwEncryptionKey = toprfPwEncryptionKey;
1239
+ state.toprfAuthKeyPair = toprfAuthKeyPair;
1240
+ });
1241
+ // update the authPubKey in the state
1242
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_persistAuthPubKey).call(this, {
1243
+ authPubKey: rawToprfAuthKeyPair.pk,
1230
1244
  });
1245
+ // unlock the controller
1246
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
1231
1247
  });
1232
1248
  }, _SeedlessOnboardingController_withControllerLock =
1233
1249
  /**
@@ -1258,18 +1274,6 @@ async function _SeedlessOnboardingController_withControllerLock(callback) {
1258
1274
  */
1259
1275
  async function _SeedlessOnboardingController_withVaultLock(callback) {
1260
1276
  return await withLock(__classPrivateFieldGet(this, _SeedlessOnboardingController_vaultOperationMutex, "f"), callback);
1261
- }, _SeedlessOnboardingController_serializeKeyData = function _SeedlessOnboardingController_serializeKeyData(encKey, pwEncKey, authKeyPair) {
1262
- const b64EncodedEncKey = bytesToBase64(encKey);
1263
- const b64EncodedPwEncKey = bytesToBase64(pwEncKey);
1264
- const b64EncodedAuthKeyPair = JSON.stringify({
1265
- sk: bigIntToHex(authKeyPair.sk),
1266
- pk: bytesToBase64(authKeyPair.pk),
1267
- });
1268
- return {
1269
- toprfEncryptionKey: b64EncodedEncKey,
1270
- toprfPwEncryptionKey: b64EncodedPwEncKey,
1271
- toprfAuthKeyPair: b64EncodedAuthKeyPair,
1272
- };
1273
1277
  }, _SeedlessOnboardingController_parseVaultData = function _SeedlessOnboardingController_parseVaultData(data) {
1274
1278
  if (typeof data !== 'string') {
1275
1279
  throw new Error(SeedlessOnboardingControllerErrorMessage.InvalidVaultData);
@@ -1284,11 +1288,7 @@ async function _SeedlessOnboardingController_withVaultLock(callback) {
1284
1288
  assertIsValidVaultData(parsedVaultData);
1285
1289
  const rawToprfEncryptionKey = base64ToBytes(parsedVaultData.toprfEncryptionKey);
1286
1290
  const rawToprfPwEncryptionKey = base64ToBytes(parsedVaultData.toprfPwEncryptionKey);
1287
- const parsedToprfAuthKeyPair = JSON.parse(parsedVaultData.toprfAuthKeyPair);
1288
- const rawToprfAuthKeyPair = {
1289
- sk: BigInt(parsedToprfAuthKeyPair.sk),
1290
- pk: base64ToBytes(parsedToprfAuthKeyPair.pk),
1291
- };
1291
+ const rawToprfAuthKeyPair = deserializAuthKeyPair(parsedVaultData.toprfAuthKeyPair);
1292
1292
  return {
1293
1293
  toprfEncryptionKey: rawToprfEncryptionKey,
1294
1294
  toprfPwEncryptionKey: rawToprfPwEncryptionKey,
@@ -1296,10 +1296,17 @@ async function _SeedlessOnboardingController_withVaultLock(callback) {
1296
1296
  revokeToken: parsedVaultData.revokeToken,
1297
1297
  accessToken: parsedVaultData.accessToken,
1298
1298
  };
1299
- }, _SeedlessOnboardingController_assertIsUnlocked = function _SeedlessOnboardingController_assertIsUnlocked() {
1299
+ }, _SeedlessOnboardingController_assertIsUnlocked = function _SeedlessOnboardingController_assertIsUnlocked(value) {
1300
1300
  if (!__classPrivateFieldGet(this, _SeedlessOnboardingController_isUnlocked, "f")) {
1301
1301
  throw new Error(SeedlessOnboardingControllerErrorMessage.ControllerLocked);
1302
1302
  }
1303
+ if (!value ||
1304
+ typeof value !== 'object' ||
1305
+ !('toprfEncryptionKey' in value) ||
1306
+ !('toprfPwEncryptionKey' in value) ||
1307
+ !('toprfAuthKeyPair' in value)) {
1308
+ throw new Error(SeedlessOnboardingControllerErrorMessage.VaultLocked);
1309
+ }
1303
1310
  }, _SeedlessOnboardingController_assertIsAuthenticatedUser = function _SeedlessOnboardingController_assertIsAuthenticatedUser(value) {
1304
1311
  if (!value ||
1305
1312
  typeof value !== 'object' ||