@metamask-previews/seedless-onboarding-controller 3.0.0-preview-236bab4a → 3.0.0-preview-3734aa94

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,9 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+
12
+ - Added `renewRefreshToken` options in SeedlessOnboardingController constructor - A function to renew the refresh token and get new revoke token. ([#6275](https://github.com/MetaMask/core/pull/6275))
13
+ - Added `renewRefreshToken` method to renew refresh token from client ([#6275](https://github.com/MetaMask/core/pull/6275))
14
+ - Added `revokePendingRefreshTokens` method to revoke all pending old refresh tokens instead from client ([#6275](https://github.com/MetaMask/core/pull/6275))
15
+
10
16
  ### Changed
11
17
 
12
- - Bump `@metamask/base-controller` from `^8.1.0` to `^8.2.0` ([#6355](https://github.com/MetaMask/core/pull/6355))
18
+ - Bump `@metamask/base-controller` from `^8.1.0` to `^8.3.0` ([#6355](https://github.com/MetaMask/core/pull/6355), [#6465](https://github.com/MetaMask/core/pull/6465))
19
+
20
+ ### Removed
21
+
22
+ - Removed `revokeRefreshToken` method ([#6275](https://github.com/MetaMask/core/pull/6275))
13
23
 
14
24
  ## [3.0.0]
15
25
 
@@ -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_passwordOutdatedCacheTTL, _SeedlessOnboardingController_isUnlocked, _SeedlessOnboardingController_cachedDecryptedVaultData, _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_decryptAndParseVaultData, _SeedlessOnboardingController_withPersistedSecretMetadataBackupsState, _SeedlessOnboardingController_filterDupesAndUpdateSocialBackupsMetadata, _SeedlessOnboardingController_createNewVaultWithAuthData, _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
+ var _SeedlessOnboardingController_instances, _SeedlessOnboardingController_vaultEncryptor, _SeedlessOnboardingController_controllerOperationMutex, _SeedlessOnboardingController_vaultOperationMutex, _SeedlessOnboardingController_refreshJWTToken, _SeedlessOnboardingController_revokeRefreshToken, _SeedlessOnboardingController_renewRefreshToken, _SeedlessOnboardingController_passwordOutdatedCacheTTL, _SeedlessOnboardingController_isUnlocked, _SeedlessOnboardingController_cachedDecryptedVaultData, _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_decryptAndParseVaultData, _SeedlessOnboardingController_withPersistedSecretMetadataBackupsState, _SeedlessOnboardingController_filterDupesAndUpdateSocialBackupsMetadata, _SeedlessOnboardingController_createNewVaultWithAuthData, _SeedlessOnboardingController_updateVault, _SeedlessOnboardingController_withControllerLock, _SeedlessOnboardingController_withVaultLock, _SeedlessOnboardingController_parseVaultData, _SeedlessOnboardingController_assertIsUnlocked, _SeedlessOnboardingController_assertIsAuthenticatedUser, _SeedlessOnboardingController_assertIsSRPBackedUpUser, _SeedlessOnboardingController_assertPasswordInSync, _SeedlessOnboardingController_resetPasswordOutdatedCache, _SeedlessOnboardingController_addRefreshTokenToRevokeList, _SeedlessOnboardingController_isTokenExpiredError, _SeedlessOnboardingController_isMaxKeyChainLengthError, _SeedlessOnboardingController_executeWithTokenRefresh;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.SeedlessOnboardingController = exports.getInitialSeedlessOnboardingControllerStateWithDefaults = void 0;
16
16
  const auth_network_utils_1 = require("@metamask/auth-network-utils");
@@ -116,6 +116,10 @@ const seedlessOnboardingMetadata = {
116
116
  persist: false,
117
117
  anonymous: false,
118
118
  },
119
+ pendingToBeRevokedTokens: {
120
+ persist: true,
121
+ anonymous: false,
122
+ },
119
123
  // stays in vault
120
124
  accessToken: {
121
125
  persist: false,
@@ -152,9 +156,10 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
152
156
  * @param options.network - The network to be used for the Seedless Onboarding flow.
153
157
  * @param options.refreshJWTToken - A function to get a new jwt token using refresh token.
154
158
  * @param options.revokeRefreshToken - A function to revoke the refresh token.
159
+ * @param options.renewRefreshToken - A function to renew the refresh token and get new revoke token.
155
160
  * @param options.passwordOutdatedCacheTTL - The TTL of the password outdated cache in milliseconds.,
156
161
  */
157
- constructor({ messenger, state, encryptor, toprfKeyDeriver, network = constants_1.Web3AuthNetwork.Mainnet, refreshJWTToken, revokeRefreshToken, passwordOutdatedCacheTTL = constants_1.PASSWORD_OUTDATED_CACHE_TTL_MS, }) {
162
+ constructor({ messenger, state, encryptor, toprfKeyDeriver, network = constants_1.Web3AuthNetwork.Mainnet, refreshJWTToken, revokeRefreshToken, renewRefreshToken, passwordOutdatedCacheTTL = constants_1.PASSWORD_OUTDATED_CACHE_TTL_MS, }) {
158
163
  super({
159
164
  name: constants_1.controllerName,
160
165
  metadata: seedlessOnboardingMetadata,
@@ -167,6 +172,7 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
167
172
  _SeedlessOnboardingController_vaultOperationMutex.set(this, new async_mutex_1.Mutex());
168
173
  _SeedlessOnboardingController_refreshJWTToken.set(this, void 0);
169
174
  _SeedlessOnboardingController_revokeRefreshToken.set(this, void 0);
175
+ _SeedlessOnboardingController_renewRefreshToken.set(this, void 0);
170
176
  /**
171
177
  * The TTL of the password outdated cache in milliseconds.
172
178
  */
@@ -193,6 +199,7 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
193
199
  });
194
200
  __classPrivateFieldSet(this, _SeedlessOnboardingController_refreshJWTToken, refreshJWTToken, "f");
195
201
  __classPrivateFieldSet(this, _SeedlessOnboardingController_revokeRefreshToken, revokeRefreshToken, "f");
202
+ __classPrivateFieldSet(this, _SeedlessOnboardingController_renewRefreshToken, renewRefreshToken, "f");
196
203
  // setup subscriptions to the keyring lock event
197
204
  // when the keyring is locked (wallet is locked), the controller will be cleared of its credentials
198
205
  this.messagingSystem.subscribe('KeyringController:lock', () => {
@@ -696,17 +703,17 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
696
703
  }
697
704
  }
698
705
  /**
699
- * Revoke the refresh token and get new refresh token and new revoke token
706
+ * Renew the refresh token - get new refresh token and new revoke token
700
707
  * and also updates the vault with the new revoke token.
701
708
  * This method is to be called after user is authenticated.
702
709
  *
703
710
  * @param password - The password to encrypt the vault.
704
711
  * @returns A Promise that resolves to void.
705
712
  */
706
- async revokeRefreshToken(password) {
713
+ async renewRefreshToken(password) {
707
714
  return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
708
715
  __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
709
- const { vaultEncryptionKey } = this.state;
716
+ const { refreshToken, vaultEncryptionKey } = this.state;
710
717
  const { toprfEncryptionKey: rawToprfEncryptionKey, toprfPwEncryptionKey: rawToprfPwEncryptionKey, toprfAuthKeyPair: rawToprfAuthKeyPair, revokeToken, } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, {
711
718
  password,
712
719
  encryptionKey: vaultEncryptionKey,
@@ -714,7 +721,7 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
714
721
  if (!revokeToken) {
715
722
  throw new Error(constants_1.SeedlessOnboardingControllerErrorMessage.InvalidRevokeToken);
716
723
  }
717
- const { newRevokeToken, newRefreshToken } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_revokeRefreshToken, "f").call(this, {
724
+ const { newRevokeToken, newRefreshToken } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_renewRefreshToken, "f").call(this, {
718
725
  connection: this.state.authConnection,
719
726
  revokeToken,
720
727
  });
@@ -725,6 +732,11 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
725
732
  // set new refresh token to persist in state
726
733
  state.refreshToken = newRefreshToken;
727
734
  });
735
+ // add the old refresh token to the list to be revoked later when possible
736
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_addRefreshTokenToRevokeList).call(this, {
737
+ refreshToken,
738
+ revokeToken,
739
+ });
728
740
  await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_createNewVaultWithAuthData).call(this, {
729
741
  password,
730
742
  rawToprfEncryptionKey,
@@ -734,6 +746,49 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
734
746
  }
735
747
  });
736
748
  }
749
+ /**
750
+ * Revoke all pending refresh tokens.
751
+ *
752
+ * This method is to be called after user is authenticated.
753
+ *
754
+ * @returns A Promise that resolves to void.
755
+ */
756
+ async revokePendingRefreshTokens() {
757
+ return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
758
+ __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
759
+ const { pendingToBeRevokedTokens } = this.state;
760
+ if (!pendingToBeRevokedTokens || pendingToBeRevokedTokens.length === 0) {
761
+ return;
762
+ }
763
+ // revoke all pending refresh tokens in parallel
764
+ const promises = pendingToBeRevokedTokens.map(({ revokeToken }) => {
765
+ const revokePromise = async () => {
766
+ try {
767
+ await __classPrivateFieldGet(this, _SeedlessOnboardingController_revokeRefreshToken, "f").call(this, {
768
+ connection: this.state.authConnection,
769
+ revokeToken,
770
+ });
771
+ return revokeToken;
772
+ }
773
+ catch (error) {
774
+ log('Error revoking refresh token', error);
775
+ return null;
776
+ }
777
+ };
778
+ return revokePromise();
779
+ });
780
+ const result = await Promise.all(promises); // no need to do Promise.allSettled because the promise already handle try catch
781
+ // filter out the null values
782
+ const revokedTokens = result.filter((token) => token !== null);
783
+ if (revokedTokens.length > 0) {
784
+ // update the state to remove the revoked tokens once all concurrent token revoke finish
785
+ this.update((state) => {
786
+ state.pendingToBeRevokedTokens =
787
+ state.pendingToBeRevokedTokens?.filter((token) => !revokedTokens.includes(token.revokeToken));
788
+ });
789
+ }
790
+ });
791
+ }
737
792
  /**
738
793
  * Check if the current node auth token is expired.
739
794
  *
@@ -788,7 +843,7 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
788
843
  }
789
844
  }
790
845
  exports.SeedlessOnboardingController = SeedlessOnboardingController;
791
- _SeedlessOnboardingController_vaultEncryptor = new WeakMap(), _SeedlessOnboardingController_controllerOperationMutex = new WeakMap(), _SeedlessOnboardingController_vaultOperationMutex = new WeakMap(), _SeedlessOnboardingController_refreshJWTToken = new WeakMap(), _SeedlessOnboardingController_revokeRefreshToken = new WeakMap(), _SeedlessOnboardingController_passwordOutdatedCacheTTL = new WeakMap(), _SeedlessOnboardingController_isUnlocked = new WeakMap(), _SeedlessOnboardingController_cachedDecryptedVaultData = new WeakMap(), _SeedlessOnboardingController_instances = new WeakSet(), _SeedlessOnboardingController_submitGlobalPassword =
846
+ _SeedlessOnboardingController_vaultEncryptor = new WeakMap(), _SeedlessOnboardingController_controllerOperationMutex = new WeakMap(), _SeedlessOnboardingController_vaultOperationMutex = new WeakMap(), _SeedlessOnboardingController_refreshJWTToken = new WeakMap(), _SeedlessOnboardingController_revokeRefreshToken = new WeakMap(), _SeedlessOnboardingController_renewRefreshToken = new WeakMap(), _SeedlessOnboardingController_passwordOutdatedCacheTTL = new WeakMap(), _SeedlessOnboardingController_isUnlocked = new WeakMap(), _SeedlessOnboardingController_cachedDecryptedVaultData = new WeakMap(), _SeedlessOnboardingController_instances = new WeakSet(), _SeedlessOnboardingController_submitGlobalPassword =
792
847
  /**
793
848
  * @description Submit the global password to the controller, verify the
794
849
  * password validity and unlock the controller.
@@ -1378,6 +1433,13 @@ async function _SeedlessOnboardingController_assertPasswordInSync(options) {
1378
1433
  this.update((state) => {
1379
1434
  delete state.passwordOutdatedCache;
1380
1435
  });
1436
+ }, _SeedlessOnboardingController_addRefreshTokenToRevokeList = function _SeedlessOnboardingController_addRefreshTokenToRevokeList({ refreshToken, revokeToken, }) {
1437
+ this.update((state) => {
1438
+ state.pendingToBeRevokedTokens = [
1439
+ ...(state.pendingToBeRevokedTokens || []),
1440
+ { refreshToken, revokeToken },
1441
+ ];
1442
+ });
1381
1443
  }, _SeedlessOnboardingController_isTokenExpiredError = function _SeedlessOnboardingController_isTokenExpiredError(error) {
1382
1444
  if (error instanceof toprf_secure_backup_1.TOPRFError) {
1383
1445
  // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison