@metamask-previews/seedless-onboarding-controller 5.0.0-preview-8c66598b → 5.0.0-preview-e98a6769
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 +13 -0
- package/dist/SeedlessOnboardingController.cjs +61 -43
- package/dist/SeedlessOnboardingController.cjs.map +1 -1
- package/dist/SeedlessOnboardingController.d.cts +8 -2
- package/dist/SeedlessOnboardingController.d.cts.map +1 -1
- package/dist/SeedlessOnboardingController.d.mts +8 -2
- package/dist/SeedlessOnboardingController.d.mts.map +1 -1
- package/dist/SeedlessOnboardingController.mjs +61 -43
- package/dist/SeedlessOnboardingController.mjs.map +1 -1
- package/dist/constants.cjs +1 -0
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +2 -1
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +2 -1
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +1 -0
- package/dist/constants.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +4 -0
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +4 -0
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +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 new public method, `checkIsSeedlessOnboardingUserAuthenticated` to validate the controller authenticate tokens state. ([#6998](https://github.com/MetaMask/core/pull/6998))
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Refactor `refreshAuthTokens` method, separately catch refreshJWTToken and authenticate errors. ([#6998](https://github.com/MetaMask/core/pull/6998))
|
|
17
|
+
- Bump `@metamask/toprf-secure-backup` package to `0.9.0`. ([#6998](https://github.com/MetaMask/core/pull/6998))
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Fixed `Invalid Access Token` error during rehydration. ([#6998](https://github.com/MetaMask/core/pull/6998))
|
|
22
|
+
|
|
10
23
|
## [5.0.0]
|
|
11
24
|
|
|
12
25
|
### Changed
|
|
@@ -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_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,
|
|
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_isAuthTokenError, _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");
|
|
@@ -297,14 +297,10 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
|
|
|
297
297
|
state.authConnection = authConnection;
|
|
298
298
|
state.socialLoginEmail = socialLoginEmail;
|
|
299
299
|
state.metadataAccessToken = metadataAccessToken;
|
|
300
|
+
state.refreshToken = refreshToken;
|
|
301
|
+
// Temporarily store revoke token & access token in state for later vault creation
|
|
302
|
+
state.revokeToken = revokeToken;
|
|
300
303
|
state.accessToken = accessToken;
|
|
301
|
-
if (refreshToken) {
|
|
302
|
-
state.refreshToken = refreshToken;
|
|
303
|
-
}
|
|
304
|
-
if (revokeToken) {
|
|
305
|
-
// Temporarily store revoke token in state for later vault creation
|
|
306
|
-
state.revokeToken = revokeToken;
|
|
307
|
-
}
|
|
308
304
|
// we will check if the controller state is properly set with the authenticated user info
|
|
309
305
|
// before setting the isSeedlessOnboardingUserAuthenticated to true
|
|
310
306
|
(0, assertions_1.assertIsSeedlessOnboardingUserAuthenticated)(state);
|
|
@@ -406,26 +402,26 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
|
|
|
406
402
|
*/
|
|
407
403
|
async fetchAllSecretData(password) {
|
|
408
404
|
return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
405
|
+
return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_executeWithTokenRefresh).call(this, async () => {
|
|
406
|
+
// assert that the user is authenticated before fetching the secret data
|
|
407
|
+
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
|
|
408
|
+
let encKey;
|
|
409
|
+
let pwEncKey;
|
|
410
|
+
let authKeyPair;
|
|
411
|
+
if (password) {
|
|
412
|
+
const recoverEncKeyResult = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_recoverEncKey).call(this, password);
|
|
413
|
+
encKey = recoverEncKeyResult.encKey;
|
|
414
|
+
pwEncKey = recoverEncKeyResult.pwEncKey;
|
|
415
|
+
authKeyPair = recoverEncKeyResult.authKeyPair;
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this);
|
|
419
|
+
// verify the password and unlock the vault
|
|
420
|
+
const keysFromVault = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this);
|
|
421
|
+
encKey = keysFromVault.toprfEncryptionKey;
|
|
422
|
+
pwEncKey = keysFromVault.toprfPwEncryptionKey;
|
|
423
|
+
authKeyPair = keysFromVault.toprfAuthKeyPair;
|
|
424
|
+
}
|
|
429
425
|
const secrets = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_fetchAllSecretDataFromMetadataStore).call(this, encKey, authKeyPair);
|
|
430
426
|
if (password) {
|
|
431
427
|
// if password is provided, we need to create a new vault with the auth data. (supposedly the user is trying to rehydrate the wallet)
|
|
@@ -437,8 +433,7 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
|
|
|
437
433
|
});
|
|
438
434
|
}
|
|
439
435
|
return secrets;
|
|
440
|
-
};
|
|
441
|
-
return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_executeWithTokenRefresh).call(this, performFetch, 'fetchAllSecretData');
|
|
436
|
+
}, 'fetchAllSecretData');
|
|
442
437
|
});
|
|
443
438
|
}
|
|
444
439
|
/**
|
|
@@ -676,6 +671,21 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
|
|
|
676
671
|
? await doCheckIsPasswordExpired()
|
|
677
672
|
: await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, doCheckIsPasswordExpired), 'checkIsPasswordOutdated');
|
|
678
673
|
}
|
|
674
|
+
/**
|
|
675
|
+
* Check if the user is authenticated with the seedless onboarding flow by checking the token values in the state.
|
|
676
|
+
*
|
|
677
|
+
* @returns True if the user is authenticated, false otherwise.
|
|
678
|
+
*/
|
|
679
|
+
async checkIsSeedlessOnboardingUserAuthenticated() {
|
|
680
|
+
try {
|
|
681
|
+
(0, assertions_1.assertIsSeedlessOnboardingUserAuthenticated)(this.state);
|
|
682
|
+
// if accessToken is missing, the user needs to authenticate again
|
|
683
|
+
return Boolean(this.state.accessToken) && Boolean(this.state.revokeToken);
|
|
684
|
+
}
|
|
685
|
+
catch {
|
|
686
|
+
return false;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
679
689
|
/**
|
|
680
690
|
* Clears the current state of the SeedlessOnboardingController.
|
|
681
691
|
*/
|
|
@@ -715,12 +725,15 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
|
|
|
715
725
|
*/
|
|
716
726
|
async refreshAuthTokens() {
|
|
717
727
|
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
|
|
718
|
-
const { refreshToken } = this.state;
|
|
728
|
+
const { refreshToken, revokeToken } = this.state;
|
|
729
|
+
const res = await __classPrivateFieldGet(this, _SeedlessOnboardingController_refreshJWTToken, "f").call(this, {
|
|
730
|
+
connection: this.state.authConnection,
|
|
731
|
+
refreshToken,
|
|
732
|
+
}).catch((error) => {
|
|
733
|
+
log('Error refreshing JWT tokens', error);
|
|
734
|
+
throw new Error(constants_1.SeedlessOnboardingControllerErrorMessage.FailedToRefreshJWTTokens);
|
|
735
|
+
});
|
|
719
736
|
try {
|
|
720
|
-
const res = await __classPrivateFieldGet(this, _SeedlessOnboardingController_refreshJWTToken, "f").call(this, {
|
|
721
|
-
connection: this.state.authConnection,
|
|
722
|
-
refreshToken,
|
|
723
|
-
});
|
|
724
737
|
const { idTokens, accessToken, metadataAccessToken } = res;
|
|
725
738
|
// re-authenticate with the new id tokens to set new node auth tokens
|
|
726
739
|
await this.authenticate({
|
|
@@ -731,6 +744,8 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
|
|
|
731
744
|
authConnectionId: this.state.authConnectionId,
|
|
732
745
|
groupedAuthConnectionId: this.state.groupedAuthConnectionId,
|
|
733
746
|
userId: this.state.userId,
|
|
747
|
+
refreshToken,
|
|
748
|
+
revokeToken,
|
|
734
749
|
skipLock: true,
|
|
735
750
|
});
|
|
736
751
|
}
|
|
@@ -912,7 +927,7 @@ async function _SeedlessOnboardingController_submitGlobalPassword({ targetAuthPu
|
|
|
912
927
|
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
|
|
913
928
|
}
|
|
914
929
|
catch (error) {
|
|
915
|
-
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m",
|
|
930
|
+
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_isAuthTokenError).call(this, error)) {
|
|
916
931
|
throw error;
|
|
917
932
|
}
|
|
918
933
|
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_isMaxKeyChainLengthError).call(this, error)) {
|
|
@@ -968,7 +983,7 @@ async function _SeedlessOnboardingController_persistOprfKey(oprfKey, authPubKey)
|
|
|
968
983
|
});
|
|
969
984
|
}
|
|
970
985
|
catch (error) {
|
|
971
|
-
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m",
|
|
986
|
+
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_isAuthTokenError).call(this, error)) {
|
|
972
987
|
throw error;
|
|
973
988
|
}
|
|
974
989
|
log('Error persisting local encryption key', error);
|
|
@@ -1046,7 +1061,7 @@ async function _SeedlessOnboardingController_recoverEncKey(password) {
|
|
|
1046
1061
|
}
|
|
1047
1062
|
catch (error) {
|
|
1048
1063
|
// throw token expired error for token refresh handler
|
|
1049
|
-
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m",
|
|
1064
|
+
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_isAuthTokenError).call(this, error)) {
|
|
1050
1065
|
throw error;
|
|
1051
1066
|
}
|
|
1052
1067
|
throw errors_1.RecoveryError.getInstance(error);
|
|
@@ -1062,7 +1077,7 @@ async function _SeedlessOnboardingController_recoverEncKey(password) {
|
|
|
1062
1077
|
}
|
|
1063
1078
|
catch (error) {
|
|
1064
1079
|
log('Error fetching secret data', error);
|
|
1065
|
-
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m",
|
|
1080
|
+
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_isAuthTokenError).call(this, error)) {
|
|
1066
1081
|
throw error;
|
|
1067
1082
|
}
|
|
1068
1083
|
throw new Error(constants_1.SeedlessOnboardingControllerErrorMessage.FailedToFetchSecretMetadata);
|
|
@@ -1166,7 +1181,7 @@ async function _SeedlessOnboardingController_encryptAndStoreSecretData(params) {
|
|
|
1166
1181
|
});
|
|
1167
1182
|
}
|
|
1168
1183
|
catch (error) {
|
|
1169
|
-
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m",
|
|
1184
|
+
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_isAuthTokenError).call(this, error)) {
|
|
1170
1185
|
throw error;
|
|
1171
1186
|
}
|
|
1172
1187
|
log('Error encrypting and storing secret data backup', error);
|
|
@@ -1475,10 +1490,13 @@ async function _SeedlessOnboardingController_assertPasswordInSync(options) {
|
|
|
1475
1490
|
{ refreshToken, revokeToken },
|
|
1476
1491
|
];
|
|
1477
1492
|
});
|
|
1478
|
-
},
|
|
1493
|
+
}, _SeedlessOnboardingController_isAuthTokenError = function _SeedlessOnboardingController_isAuthTokenError(error) {
|
|
1479
1494
|
if (error instanceof toprf_secure_backup_1.TOPRFError) {
|
|
1495
|
+
return (
|
|
1480
1496
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
|
|
1481
|
-
|
|
1497
|
+
error.code === toprf_secure_backup_1.TOPRFErrorCode.AuthTokenExpired ||
|
|
1498
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
|
|
1499
|
+
error.code === toprf_secure_backup_1.TOPRFErrorCode.InvalidAuthToken);
|
|
1482
1500
|
}
|
|
1483
1501
|
return false;
|
|
1484
1502
|
}, _SeedlessOnboardingController_isMaxKeyChainLengthError = function _SeedlessOnboardingController_isMaxKeyChainLengthError(error) {
|
|
@@ -1521,7 +1539,7 @@ async function _SeedlessOnboardingController_executeWithTokenRefresh(operation,
|
|
|
1521
1539
|
}
|
|
1522
1540
|
catch (error) {
|
|
1523
1541
|
// Check if this is a token expiration error
|
|
1524
|
-
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m",
|
|
1542
|
+
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_isAuthTokenError).call(this, error)) {
|
|
1525
1543
|
log(`Token expired during ${operationName}, attempting to refresh tokens`, error);
|
|
1526
1544
|
try {
|
|
1527
1545
|
// Refresh the tokens
|