@metamask-previews/seedless-onboarding-controller 2.2.0-preview-bfc59609 → 2.3.0-preview-3713f9f

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.
package/CHANGELOG.md CHANGED
@@ -7,15 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ## [2.2.0]
10
+ ## [2.3.0]
11
+
12
+ ### Uncategorized
13
+
14
+ - Seedless onboarding controller: Remove usage of `Buffer` ([#6140](https://github.com/MetaMask/core/pull/6140))
11
15
 
12
16
  ### Added
13
17
 
14
18
  - Added a optional param `maxKeyChainLength` in `submitGlobalPassword` function.([#6134](https://github.com/MetaMask/core/pull/6134))
19
+ - Separated vault update logic from `revokeRefreshToken`, `revokeRefreshToken` now accepts a revokeToken instead of password. ([#6134](https://github.com/MetaMask/core/pull/6134))
20
+
21
+ ### Changed
22
+
23
+ - `revokeRefreshToken` is removed and a private function named `revokeRefreshTokenAndUpdateState` is added as a replacement.([#6136](https://github.com/MetaMask/core/pull/6136))
24
+
25
+ ## [2.2.0]
15
26
 
16
27
  ### Fixed
17
28
 
18
- - remove `access_token` validation when the wallet is locked. ([#6133](https://github.com/MetaMask/core/pull/6133))
29
+ - Removed `access_token` validation when the wallet is locked. ([#6133](https://github.com/MetaMask/core/pull/6133))
30
+ - Removed `revoke_token` validation from `#parseVault` and `createNewVaultWithAuthData` to handle the case when max key chain length exceeds. ([#6136](https://github.com/MetaMask/core/pull/6136))
19
31
 
20
32
  ## [2.1.0]
21
33
 
@@ -96,7 +108,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
96
108
  - `checkIsPasswordOutdated`: Check if the password is current device is outdated, i.e. user changed password in another device.
97
109
  - `clearState`: Reset the state of the controller to the defaults.
98
110
 
99
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/seedless-onboarding-controller@2.2.0...HEAD
111
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/seedless-onboarding-controller@2.3.0...HEAD
112
+ [2.3.0]: https://github.com/MetaMask/core/compare/@metamask/seedless-onboarding-controller@2.2.0...@metamask/seedless-onboarding-controller@2.3.0
100
113
  [2.2.0]: https://github.com/MetaMask/core/compare/@metamask/seedless-onboarding-controller@2.1.0...@metamask/seedless-onboarding-controller@2.2.0
101
114
  [2.1.0]: https://github.com/MetaMask/core/compare/@metamask/seedless-onboarding-controller@2.0.1...@metamask/seedless-onboarding-controller@2.1.0
102
115
  [2.0.1]: https://github.com/MetaMask/core/compare/@metamask/seedless-onboarding-controller@2.0.0...@metamask/seedless-onboarding-controller@2.0.1
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  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");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _SeedlessOnboardingController_instances, _SeedlessOnboardingController_vaultEncryptor, _SeedlessOnboardingController_controllerOperationMutex, _SeedlessOnboardingController_vaultOperationMutex, _SeedlessOnboardingController_refreshJWTToken, _SeedlessOnboardingController_revokeRefreshToken, _SeedlessOnboardingController_isUnlocked, _SeedlessOnboardingController_submitGlobalPassword, _SeedlessOnboardingController_setUnlocked, _SeedlessOnboardingController_persistOprfKey, _SeedlessOnboardingController_persistAuthPubKey, _SeedlessOnboardingController_storeKeyringEncryptionKey, _SeedlessOnboardingController_loadKeyringEncryptionKey, _SeedlessOnboardingController_loadSeedlessEncryptionKey, _SeedlessOnboardingController_recoverAuthPubKey, _SeedlessOnboardingController_recoverEncKey, _SeedlessOnboardingController_fetchAllSecretDataFromMetadataStore, _SeedlessOnboardingController_changeEncryptionKey, _SeedlessOnboardingController_encryptAndStoreSecretData, _SeedlessOnboardingController_unlockVaultAndGetBackupEncKey, _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_assertIsValidVaultData, _SeedlessOnboardingController_isTokenExpiredError, _SeedlessOnboardingController_isMaxKeyChainLengthError, _SeedlessOnboardingController_executeWithTokenRefresh;
13
+ var _SeedlessOnboardingController_instances, _SeedlessOnboardingController_vaultEncryptor, _SeedlessOnboardingController_controllerOperationMutex, _SeedlessOnboardingController_vaultOperationMutex, _SeedlessOnboardingController_refreshJWTToken, _SeedlessOnboardingController_revokeRefreshToken, _SeedlessOnboardingController_isUnlocked, _SeedlessOnboardingController_submitGlobalPassword, _SeedlessOnboardingController_setUnlocked, _SeedlessOnboardingController_persistOprfKey, _SeedlessOnboardingController_persistAuthPubKey, _SeedlessOnboardingController_storeKeyringEncryptionKey, _SeedlessOnboardingController_loadKeyringEncryptionKey, _SeedlessOnboardingController_loadSeedlessEncryptionKey, _SeedlessOnboardingController_recoverAuthPubKey, _SeedlessOnboardingController_recoverEncKey, _SeedlessOnboardingController_fetchAllSecretDataFromMetadataStore, _SeedlessOnboardingController_changeEncryptionKey, _SeedlessOnboardingController_encryptAndStoreSecretData, _SeedlessOnboardingController_unlockVaultAndGetBackupEncKey, _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_revokeRefreshTokenAndUpdateState, _SeedlessOnboardingController_isTokenExpiredError, _SeedlessOnboardingController_isMaxKeyChainLengthError, _SeedlessOnboardingController_executeWithTokenRefresh;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.SeedlessOnboardingController = exports.getDefaultSeedlessOnboardingControllerState = void 0;
16
16
  const auth_network_utils_1 = require("@metamask/auth-network-utils");
@@ -22,6 +22,7 @@ const utils_2 = require("@noble/ciphers/utils");
22
22
  const webcrypto_1 = require("@noble/ciphers/webcrypto");
23
23
  const secp256k1_1 = require("@noble/curves/secp256k1");
24
24
  const async_mutex_1 = require("async-mutex");
25
+ const assertions_1 = require("./assertions.cjs");
25
26
  const constants_1 = require("./constants.cjs");
26
27
  const errors_1 = require("./errors.cjs");
27
28
  const logger_1 = require("./logger.cjs");
@@ -484,10 +485,18 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
484
485
  */
485
486
  async submitPassword(password) {
486
487
  return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
487
- await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetBackupEncKey).call(this, password);
488
+ const { toprfEncryptionKey, toprfPwEncryptionKey, toprfAuthKeyPair, revokeToken, } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetBackupEncKey).call(this, password);
488
489
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
489
- // revoke and recyle refresh token after unlock to keep refresh token fresh, avoid malicious use of leaked refresh token
490
- await this.revokeRefreshToken(password);
490
+ if (revokeToken) {
491
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_revokeRefreshTokenAndUpdateState).call(this, revokeToken);
492
+ // re-creating vault to persist the new revoke token
493
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_createNewVaultWithAuthData).call(this, {
494
+ password,
495
+ rawToprfEncryptionKey: toprfEncryptionKey,
496
+ rawToprfPwEncryptionKey: toprfPwEncryptionKey,
497
+ rawToprfAuthKeyPair: toprfAuthKeyPair,
498
+ });
499
+ }
491
500
  });
492
501
  }
493
502
  /**
@@ -657,34 +666,6 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
657
666
  throw new Error(constants_1.SeedlessOnboardingControllerErrorMessage.AuthenticationError);
658
667
  }
659
668
  }
660
- /**
661
- * Revoke the refresh token and get new refresh token and new revoke token.
662
- * This method is to be called after unlock
663
- *
664
- * @param password - The password to re-encrypt new token in the vault.
665
- */
666
- async revokeRefreshToken(password) {
667
- __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this);
668
- __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
669
- // get revoke token and backup encryption key from vault (should be unlocked already)
670
- const { revokeToken, toprfEncryptionKey, toprfPwEncryptionKey, toprfAuthKeyPair, } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetBackupEncKey).call(this);
671
- const { newRevokeToken, newRefreshToken } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_revokeRefreshToken, "f").call(this, {
672
- connection: this.state.authConnection,
673
- revokeToken,
674
- });
675
- this.update((state) => {
676
- // set new revoke token in state temporarily for persisting in vault
677
- state.revokeToken = newRevokeToken;
678
- // set new refresh token to persist in state
679
- state.refreshToken = newRefreshToken;
680
- });
681
- await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_createNewVaultWithAuthData).call(this, {
682
- password,
683
- rawToprfEncryptionKey: toprfEncryptionKey,
684
- rawToprfPwEncryptionKey: toprfPwEncryptionKey,
685
- rawToprfAuthKeyPair: toprfAuthKeyPair,
686
- });
687
- }
688
669
  /**
689
670
  * Check if the current node auth token is expired.
690
671
  *
@@ -765,10 +746,19 @@ async function _SeedlessOnboardingController_submitGlobalPassword({ targetAuthPu
765
746
  const { pwEncKey } = res;
766
747
  const vaultKey = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_loadSeedlessEncryptionKey).call(this, pwEncKey);
767
748
  // Unlock the controller
768
- await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetBackupEncKey).call(this, undefined, vaultKey);
749
+ const { revokeToken, toprfEncryptionKey, toprfPwEncryptionKey, toprfAuthKeyPair, } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetBackupEncKey).call(this, undefined, vaultKey);
769
750
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
770
- // revoke and recyle refresh token after unlock to keep refresh token fresh, avoid malicious use of leaked refresh token
771
- await this.revokeRefreshToken(globalPassword);
751
+ if (revokeToken) {
752
+ // revoke and recyle refresh token after unlock to keep refresh token fresh, avoid malicious use of leaked refresh token
753
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_revokeRefreshTokenAndUpdateState).call(this, revokeToken);
754
+ // re-creating vault to persist the new revoke token
755
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_createNewVaultWithAuthData).call(this, {
756
+ password: globalPassword,
757
+ rawToprfEncryptionKey: toprfEncryptionKey,
758
+ rawToprfPwEncryptionKey: toprfPwEncryptionKey,
759
+ rawToprfAuthKeyPair: toprfAuthKeyPair,
760
+ });
761
+ }
772
762
  }
773
763
  catch (error) {
774
764
  if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_isTokenExpiredError).call(this, error)) {
@@ -1123,9 +1113,6 @@ async function _SeedlessOnboardingController_withPersistedSecretMetadataBackupsS
1123
1113
  */
1124
1114
  async function _SeedlessOnboardingController_createNewVaultWithAuthData({ password, rawToprfEncryptionKey, rawToprfPwEncryptionKey, rawToprfAuthKeyPair, }) {
1125
1115
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
1126
- if (!this.state.revokeToken) {
1127
- throw new Error(constants_1.SeedlessOnboardingControllerErrorMessage.InvalidRevokeToken);
1128
- }
1129
1116
  if (!this.state.accessToken) {
1130
1117
  throw new Error(constants_1.SeedlessOnboardingControllerErrorMessage.InvalidAccessToken);
1131
1118
  }
@@ -1226,7 +1213,7 @@ async function _SeedlessOnboardingController_withVaultLock(callback) {
1226
1213
  catch {
1227
1214
  throw new Error(constants_1.SeedlessOnboardingControllerErrorMessage.InvalidVaultData);
1228
1215
  }
1229
- __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsValidVaultData).call(this, parsedVaultData);
1216
+ (0, assertions_1.assertIsValidVaultData)(parsedVaultData);
1230
1217
  const rawToprfEncryptionKey = (0, utils_1.base64ToBytes)(parsedVaultData.toprfEncryptionKey);
1231
1218
  const rawToprfPwEncryptionKey = (0, utils_1.base64ToBytes)(parsedVaultData.toprfPwEncryptionKey);
1232
1219
  const parsedToprfAuthKeyPair = JSON.parse(parsedVaultData.toprfAuthKeyPair);
@@ -1290,23 +1277,25 @@ async function _SeedlessOnboardingController_assertPasswordInSync(options) {
1290
1277
  this.update((state) => {
1291
1278
  delete state.passwordOutdatedCache;
1292
1279
  });
1293
- }, _SeedlessOnboardingController_assertIsValidVaultData = function _SeedlessOnboardingController_assertIsValidVaultData(value) {
1294
- // value is not valid vault data if any of the following conditions are true:
1295
- if (!value || // value is not defined
1296
- typeof value !== 'object' || // value is not an object
1297
- !('toprfEncryptionKey' in value) || // toprfEncryptionKey is not defined
1298
- typeof value.toprfEncryptionKey !== 'string' || // toprfEncryptionKey is not a string
1299
- !('toprfPwEncryptionKey' in value) || // toprfPwEncryptionKey is not defined
1300
- typeof value.toprfPwEncryptionKey !== 'string' || // toprfPwEncryptionKey is not a string
1301
- !('toprfAuthKeyPair' in value) || // toprfAuthKeyPair is not defined
1302
- typeof value.toprfAuthKeyPair !== 'string' || // toprfAuthKeyPair is not a string
1303
- !('revokeToken' in value) || // revokeToken is not defined
1304
- typeof value.revokeToken !== 'string' || // revokeToken is not a string
1305
- !('accessToken' in value) || // accessToken is not defined
1306
- typeof value.accessToken !== 'string' // accessToken is not a string
1307
- ) {
1308
- throw new Error(constants_1.SeedlessOnboardingControllerErrorMessage.VaultDataError);
1309
- }
1280
+ }, _SeedlessOnboardingController_revokeRefreshTokenAndUpdateState =
1281
+ /**
1282
+ * Revoke the refresh token and get new refresh token and new revoke token.
1283
+ * This method is to be called after user is authenticated.
1284
+ *
1285
+ * @param revokeToken - The revoke token to use for revoking the refresh token.
1286
+ */
1287
+ async function _SeedlessOnboardingController_revokeRefreshTokenAndUpdateState(revokeToken) {
1288
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
1289
+ const { newRevokeToken, newRefreshToken } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_revokeRefreshToken, "f").call(this, {
1290
+ connection: this.state.authConnection,
1291
+ revokeToken,
1292
+ });
1293
+ this.update((state) => {
1294
+ // set new revoke token in state temporarily for persisting in vault
1295
+ state.revokeToken = newRevokeToken;
1296
+ // set new refresh token to persist in state
1297
+ state.refreshToken = newRefreshToken;
1298
+ });
1310
1299
  }, _SeedlessOnboardingController_isTokenExpiredError = function _SeedlessOnboardingController_isTokenExpiredError(error) {
1311
1300
  if (error instanceof toprf_secure_backup_1.TOPRFError) {
1312
1301
  // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison