@metamask-previews/profile-sync-controller 28.0.2-preview-6961bc96f → 28.0.2-preview-498809ee9
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 +22 -3
- package/dist/controllers/authentication/AuthenticationController-method-action-types.cjs.map +1 -1
- package/dist/controllers/authentication/AuthenticationController-method-action-types.d.cts +45 -6
- package/dist/controllers/authentication/AuthenticationController-method-action-types.d.cts.map +1 -1
- package/dist/controllers/authentication/AuthenticationController-method-action-types.d.mts +45 -6
- package/dist/controllers/authentication/AuthenticationController-method-action-types.d.mts.map +1 -1
- package/dist/controllers/authentication/AuthenticationController-method-action-types.mjs.map +1 -1
- package/dist/controllers/authentication/AuthenticationController.cjs +169 -7
- package/dist/controllers/authentication/AuthenticationController.cjs.map +1 -1
- package/dist/controllers/authentication/AuthenticationController.d.cts +61 -7
- package/dist/controllers/authentication/AuthenticationController.d.cts.map +1 -1
- package/dist/controllers/authentication/AuthenticationController.d.mts +61 -7
- package/dist/controllers/authentication/AuthenticationController.d.mts.map +1 -1
- package/dist/controllers/authentication/AuthenticationController.mjs +169 -7
- package/dist/controllers/authentication/AuthenticationController.mjs.map +1 -1
- package/dist/controllers/authentication/index.cjs.map +1 -1
- package/dist/controllers/authentication/index.d.cts +1 -1
- package/dist/controllers/authentication/index.d.cts.map +1 -1
- package/dist/controllers/authentication/index.d.mts +1 -1
- package/dist/controllers/authentication/index.d.mts.map +1 -1
- package/dist/controllers/authentication/index.mjs.map +1 -1
- package/dist/controllers/authentication/mocks/mockResponses.cjs +10 -1
- package/dist/controllers/authentication/mocks/mockResponses.cjs.map +1 -1
- package/dist/controllers/authentication/mocks/mockResponses.d.cts +17 -32
- package/dist/controllers/authentication/mocks/mockResponses.d.cts.map +1 -1
- package/dist/controllers/authentication/mocks/mockResponses.d.mts +17 -32
- package/dist/controllers/authentication/mocks/mockResponses.d.mts.map +1 -1
- package/dist/controllers/authentication/mocks/mockResponses.mjs +9 -1
- package/dist/controllers/authentication/mocks/mockResponses.mjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.cjs +28 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.cjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.d.cts +2 -0
- package/dist/sdk/authentication-jwt-bearer/flow-srp.d.cts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.d.mts +2 -0
- package/dist/sdk/authentication-jwt-bearer/flow-srp.d.mts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.mjs +29 -2
- package/dist/sdk/authentication-jwt-bearer/flow-srp.mjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/services.cjs +59 -1
- package/dist/sdk/authentication-jwt-bearer/services.cjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/services.d.cts +17 -1
- package/dist/sdk/authentication-jwt-bearer/services.d.cts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/services.d.mts +17 -1
- package/dist/sdk/authentication-jwt-bearer/services.d.mts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/services.mjs +56 -0
- package/dist/sdk/authentication-jwt-bearer/services.mjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/types.cjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/types.d.cts +20 -1
- package/dist/sdk/authentication-jwt-bearer/types.d.cts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/types.d.mts +20 -1
- package/dist/sdk/authentication-jwt-bearer/types.d.mts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/types.mjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.cjs +27 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.cjs.map +1 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.d.cts +13 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.d.cts.map +1 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.d.mts +13 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.d.mts.map +1 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.mjs +23 -0
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.mjs.map +1 -0
- package/dist/sdk/authentication.cjs +4 -0
- package/dist/sdk/authentication.cjs.map +1 -1
- package/dist/sdk/authentication.d.cts +2 -0
- package/dist/sdk/authentication.d.cts.map +1 -1
- package/dist/sdk/authentication.d.mts +2 -0
- package/dist/sdk/authentication.d.mts.map +1 -1
- package/dist/sdk/authentication.mjs +4 -0
- package/dist/sdk/authentication.mjs.map +1 -1
- package/dist/sdk/mocks/auth.cjs +11 -1
- package/dist/sdk/mocks/auth.cjs.map +1 -1
- package/dist/sdk/mocks/auth.d.cts +10 -0
- package/dist/sdk/mocks/auth.d.cts.map +1 -1
- package/dist/sdk/mocks/auth.d.mts +10 -0
- package/dist/sdk/mocks/auth.d.mts.map +1 -1
- package/dist/sdk/mocks/auth.mjs +11 -1
- package/dist/sdk/mocks/auth.mjs.map +1 -1
- package/dist/sdk/user-storage.cjs +26 -3
- package/dist/sdk/user-storage.cjs.map +1 -1
- package/dist/sdk/user-storage.d.cts +7 -0
- package/dist/sdk/user-storage.d.cts.map +1 -1
- package/dist/sdk/user-storage.d.mts +7 -0
- package/dist/sdk/user-storage.d.mts.map +1 -1
- package/dist/sdk/user-storage.mjs +26 -3
- package/dist/sdk/user-storage.mjs.map +1 -1
- package/dist/sdk/utils/validate-pair-response.cjs +29 -0
- package/dist/sdk/utils/validate-pair-response.cjs.map +1 -0
- package/dist/sdk/utils/validate-pair-response.d.cts +26 -0
- package/dist/sdk/utils/validate-pair-response.d.cts.map +1 -0
- package/dist/sdk/utils/validate-pair-response.d.mts +26 -0
- package/dist/sdk/utils/validate-pair-response.d.mts.map +1 -0
- package/dist/sdk/utils/validate-pair-response.mjs +25 -0
- package/dist/sdk/utils/validate-pair-response.mjs.map +1 -0
- package/dist/shared/types/services.cjs.map +1 -1
- package/dist/shared/types/services.d.cts +7 -0
- package/dist/shared/types/services.d.cts.map +1 -1
- package/dist/shared/types/services.d.mts +7 -0
- package/dist/shared/types/services.d.mts.map +1 -1
- package/dist/shared/types/services.mjs.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
###
|
|
10
|
+
### Added
|
|
11
11
|
|
|
12
|
-
-
|
|
13
|
-
-
|
|
12
|
+
- Add SRP profile pairing support (Accounts ADR 0006) ([#8504](https://github.com/MetaMask/core/pull/8504), [#8642](https://github.com/MetaMask/core/pull/8642))
|
|
13
|
+
- Pairing runs at the end of `performSignIn`; pair failures are swallowed and retried on the next gate fire.
|
|
14
|
+
- Add `needsProfilePairing?: boolean` to state (defaults `true`, cleared on successful pair, re-armed via `requestProfilePairing()`). Optional in the type to keep partial-state selectors assignable; treat `undefined` as `true`.
|
|
15
|
+
- Add `requestProfilePairing()` (and `AuthenticationController:requestProfilePairing` action) for clients to signal SRP-set changes so the next auto-sign-in cycle re-pairs.
|
|
16
|
+
- Upgrade path: existing signed-in users re-pair automatically on the first auto-sign-in cycle. Pre-pairing sessions miss `canonicalProfileId` and re-login on the next `getAccessToken`, so the pair call runs against fresh v2 JWTs — no client migration needed.
|
|
17
|
+
- JWT staleness note: a newly added SRP's JWT keeps `sub = alias_id` until that SRP's session is re-logged-in. User storage is unaffected (it keys on `x-profile-id`, not `sub`).
|
|
18
|
+
- Add `canonicalProfileId` to `UserProfile` — the unified profile ID across paired SRPs
|
|
19
|
+
- Add `ProfileAlias` type for transient alias data returned by the pairing API
|
|
20
|
+
- Add `pairSrpProfiles` method to `SRPJwtBearerAuth` and `JwtBearerAuth`
|
|
21
|
+
- Add `ProfileSignInEvent` (`AuthenticationController:profileSignIn`) emitted after successful pairing when the canonical profile ID changes or new aliases are returned
|
|
22
|
+
- Send `X-MetaMask-Profile-Pairing: enabled` header on all `/srp/login` requests
|
|
23
|
+
- Resolve original per-SRP `profileId` from `profile_aliases` using `computeIdentifierId`
|
|
24
|
+
- Propagate canonical profile ID to all `srpSessionData` entries after pairing
|
|
25
|
+
- Add `refreshCanonicalProfileId` method — forces a fresh canonical retrieval from the server (1 primary SRP login) and propagates it to all cached SRP sessions. For best-effort reads, use `getSessionProfile().canonicalProfileId` instead.
|
|
26
|
+
- Force re-login when cached session is missing `canonicalProfileId`
|
|
27
|
+
- Add optional `getAppVersion` callback to `MetaMetricsAuth`, forwarded as `metametrics.app_version` in the `POST /api/v2/srp/login` payload. ([#8626](https://github.com/MetaMask/core/pull/8626))
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- Bump `@metamask/keyring-controller` from `^25.1.1` to `^25.4.0` ([#8363](https://github.com/MetaMask/core/pull/8363), [#8634](https://github.com/MetaMask/core/pull/8634), [#8665](https://github.com/MetaMask/core/pull/8665))
|
|
32
|
+
- Bump `@metamask/messenger` from `^1.0.0` to `^1.2.0` ([#8364](https://github.com/MetaMask/core/pull/8364), [#8373](https://github.com/MetaMask/core/pull/8373), [#8632](https://github.com/MetaMask/core/pull/8632))
|
|
14
33
|
- Bump `@metamask/base-controller` from `^9.0.1` to `^9.1.0` ([#8457](https://github.com/MetaMask/core/pull/8457))
|
|
15
34
|
|
|
16
35
|
## [28.0.2]
|
package/dist/controllers/authentication/AuthenticationController-method-action-types.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthenticationController-method-action-types.cjs","sourceRoot":"","sources":["../../../src/controllers/authentication/AuthenticationController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { AuthenticationController } from './AuthenticationController';\n\nexport type AuthenticationControllerPerformSignInAction = {\n type: `AuthenticationController:performSignIn`;\n handler: AuthenticationController['performSignIn'];\n};\n\nexport type AuthenticationControllerPerformSignOutAction = {\n type: `AuthenticationController:performSignOut`;\n handler: AuthenticationController['performSignOut'];\n};\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"AuthenticationController-method-action-types.cjs","sourceRoot":"","sources":["../../../src/controllers/authentication/AuthenticationController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { AuthenticationController } from './AuthenticationController';\n\nexport type AuthenticationControllerPerformSignInAction = {\n type: `AuthenticationController:performSignIn`;\n handler: AuthenticationController['performSignIn'];\n};\n\n/**\n * Marks profile pairing as needed. Clients call this when the SRP set\n * changes (e.g. a new keyring was added) so the next auto-sign-in cycle\n * re-runs `performSignIn` and re-pairs.\n */\nexport type AuthenticationControllerRequestProfilePairingAction = {\n type: `AuthenticationController:requestProfilePairing`;\n handler: AuthenticationController['requestProfilePairing'];\n};\n\nexport type AuthenticationControllerPerformSignOutAction = {\n type: `AuthenticationController:performSignOut`;\n handler: AuthenticationController['performSignOut'];\n};\n\n/**\n * Returns a bearer token for the specified SRP, logging in if needed.\n *\n * When called without `entropySourceId`, returns the primary (first) SRP's\n * access token, which is effectively the canonical\n * profile's token that can be used by alias-aware consumers for cross-SRP\n * operations.\n *\n * @param entropySourceId - The entropy source ID. Omit for the primary SRP.\n * @returns The OIDC access token.\n */\nexport type AuthenticationControllerGetBearerTokenAction = {\n type: `AuthenticationController:getBearerToken`;\n handler: AuthenticationController['getBearerToken'];\n};\n\n/**\n * Returns the cached session profile, logging in if no session exists.\n *\n * The returned `canonicalProfileId` reflects the value from the most recent\n * login or pairing. In the rare event where a canonical changed because of\n * a pairing that happened on another device, the cached value may be stale\n * until the next login. For guaranteed freshness, call\n * `refreshCanonicalProfileId()` before reading `canonicalProfileId`.\n *\n * @param entropySourceId - The entropy source ID used to derive the key,\n * when multiple sources are available (Multi-SRP).\n * @returns profile for the session.\n */\nexport type AuthenticationControllerGetSessionProfileAction = {\n type: `AuthenticationController:getSessionProfile`;\n handler: AuthenticationController['getSessionProfile'];\n};\n\n/**\n * Forces a fresh retrieval of the canonical profile ID from the server\n * and propagates it to all cached SRP sessions.\n *\n * This method invalidates the primary SRP's cached session and forces a\n * re-login. Use it before operations that require a guaranteed-fresh\n * canonical (e.g. storage key derivation for Accounts ADR 0005). For\n * best-effort reads, use\n * `getSessionProfile().canonicalProfileId` instead.\n *\n * Only the primary SRP is re-logged-in regardless of how many SRPs exist —\n * the server returns the current canonical for the entire pairing group\n * from any single SRP login.\n *\n * @returns The refreshed canonical profile ID.\n */\nexport type AuthenticationControllerRefreshCanonicalProfileIdAction = {\n type: `AuthenticationController:refreshCanonicalProfileId`;\n handler: AuthenticationController['refreshCanonicalProfileId'];\n};\n\nexport type AuthenticationControllerGetUserProfileLineageAction = {\n type: `AuthenticationController:getUserProfileLineage`;\n handler: AuthenticationController['getUserProfileLineage'];\n};\n\nexport type AuthenticationControllerIsSignedInAction = {\n type: `AuthenticationController:isSignedIn`;\n handler: AuthenticationController['isSignedIn'];\n};\n\n/**\n * Union of all AuthenticationController action types.\n */\nexport type AuthenticationControllerMethodActions =\n | AuthenticationControllerPerformSignInAction\n | AuthenticationControllerRequestProfilePairingAction\n | AuthenticationControllerPerformSignOutAction\n | AuthenticationControllerGetBearerTokenAction\n | AuthenticationControllerGetSessionProfileAction\n | AuthenticationControllerRefreshCanonicalProfileIdAction\n | AuthenticationControllerGetUserProfileLineageAction\n | AuthenticationControllerIsSignedInAction;\n"]}
|
|
@@ -7,23 +7,42 @@ export type AuthenticationControllerPerformSignInAction = {
|
|
|
7
7
|
type: `AuthenticationController:performSignIn`;
|
|
8
8
|
handler: AuthenticationController['performSignIn'];
|
|
9
9
|
};
|
|
10
|
+
/**
|
|
11
|
+
* Marks profile pairing as needed. Clients call this when the SRP set
|
|
12
|
+
* changes (e.g. a new keyring was added) so the next auto-sign-in cycle
|
|
13
|
+
* re-runs `performSignIn` and re-pairs.
|
|
14
|
+
*/
|
|
15
|
+
export type AuthenticationControllerRequestProfilePairingAction = {
|
|
16
|
+
type: `AuthenticationController:requestProfilePairing`;
|
|
17
|
+
handler: AuthenticationController['requestProfilePairing'];
|
|
18
|
+
};
|
|
10
19
|
export type AuthenticationControllerPerformSignOutAction = {
|
|
11
20
|
type: `AuthenticationController:performSignOut`;
|
|
12
21
|
handler: AuthenticationController['performSignOut'];
|
|
13
22
|
};
|
|
14
23
|
/**
|
|
15
|
-
*
|
|
16
|
-
* Logs a user in if a user is not logged in.
|
|
24
|
+
* Returns a bearer token for the specified SRP, logging in if needed.
|
|
17
25
|
*
|
|
18
|
-
*
|
|
26
|
+
* When called without `entropySourceId`, returns the primary (first) SRP's
|
|
27
|
+
* access token, which is effectively the canonical
|
|
28
|
+
* profile's token that can be used by alias-aware consumers for cross-SRP
|
|
29
|
+
* operations.
|
|
30
|
+
*
|
|
31
|
+
* @param entropySourceId - The entropy source ID. Omit for the primary SRP.
|
|
32
|
+
* @returns The OIDC access token.
|
|
19
33
|
*/
|
|
20
34
|
export type AuthenticationControllerGetBearerTokenAction = {
|
|
21
35
|
type: `AuthenticationController:getBearerToken`;
|
|
22
36
|
handler: AuthenticationController['getBearerToken'];
|
|
23
37
|
};
|
|
24
38
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
39
|
+
* Returns the cached session profile, logging in if no session exists.
|
|
40
|
+
*
|
|
41
|
+
* The returned `canonicalProfileId` reflects the value from the most recent
|
|
42
|
+
* login or pairing. In the rare event where a canonical changed because of
|
|
43
|
+
* a pairing that happened on another device, the cached value may be stale
|
|
44
|
+
* until the next login. For guaranteed freshness, call
|
|
45
|
+
* `refreshCanonicalProfileId()` before reading `canonicalProfileId`.
|
|
27
46
|
*
|
|
28
47
|
* @param entropySourceId - The entropy source ID used to derive the key,
|
|
29
48
|
* when multiple sources are available (Multi-SRP).
|
|
@@ -33,6 +52,26 @@ export type AuthenticationControllerGetSessionProfileAction = {
|
|
|
33
52
|
type: `AuthenticationController:getSessionProfile`;
|
|
34
53
|
handler: AuthenticationController['getSessionProfile'];
|
|
35
54
|
};
|
|
55
|
+
/**
|
|
56
|
+
* Forces a fresh retrieval of the canonical profile ID from the server
|
|
57
|
+
* and propagates it to all cached SRP sessions.
|
|
58
|
+
*
|
|
59
|
+
* This method invalidates the primary SRP's cached session and forces a
|
|
60
|
+
* re-login. Use it before operations that require a guaranteed-fresh
|
|
61
|
+
* canonical (e.g. storage key derivation for Accounts ADR 0005). For
|
|
62
|
+
* best-effort reads, use
|
|
63
|
+
* `getSessionProfile().canonicalProfileId` instead.
|
|
64
|
+
*
|
|
65
|
+
* Only the primary SRP is re-logged-in regardless of how many SRPs exist —
|
|
66
|
+
* the server returns the current canonical for the entire pairing group
|
|
67
|
+
* from any single SRP login.
|
|
68
|
+
*
|
|
69
|
+
* @returns The refreshed canonical profile ID.
|
|
70
|
+
*/
|
|
71
|
+
export type AuthenticationControllerRefreshCanonicalProfileIdAction = {
|
|
72
|
+
type: `AuthenticationController:refreshCanonicalProfileId`;
|
|
73
|
+
handler: AuthenticationController['refreshCanonicalProfileId'];
|
|
74
|
+
};
|
|
36
75
|
export type AuthenticationControllerGetUserProfileLineageAction = {
|
|
37
76
|
type: `AuthenticationController:getUserProfileLineage`;
|
|
38
77
|
handler: AuthenticationController['getUserProfileLineage'];
|
|
@@ -44,5 +83,5 @@ export type AuthenticationControllerIsSignedInAction = {
|
|
|
44
83
|
/**
|
|
45
84
|
* Union of all AuthenticationController action types.
|
|
46
85
|
*/
|
|
47
|
-
export type AuthenticationControllerMethodActions = AuthenticationControllerPerformSignInAction | AuthenticationControllerPerformSignOutAction | AuthenticationControllerGetBearerTokenAction | AuthenticationControllerGetSessionProfileAction | AuthenticationControllerGetUserProfileLineageAction | AuthenticationControllerIsSignedInAction;
|
|
86
|
+
export type AuthenticationControllerMethodActions = AuthenticationControllerPerformSignInAction | AuthenticationControllerRequestProfilePairingAction | AuthenticationControllerPerformSignOutAction | AuthenticationControllerGetBearerTokenAction | AuthenticationControllerGetSessionProfileAction | AuthenticationControllerRefreshCanonicalProfileIdAction | AuthenticationControllerGetUserProfileLineageAction | AuthenticationControllerIsSignedInAction;
|
|
48
87
|
//# sourceMappingURL=AuthenticationController-method-action-types.d.cts.map
|
package/dist/controllers/authentication/AuthenticationController-method-action-types.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthenticationController-method-action-types.d.cts","sourceRoot":"","sources":["../../../src/controllers/authentication/AuthenticationController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,uCAAmC;AAE3E,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,wBAAwB,CAAC,eAAe,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,yCAAyC,CAAC;IAChD,OAAO,EAAE,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;CACrD,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"AuthenticationController-method-action-types.d.cts","sourceRoot":"","sources":["../../../src/controllers/authentication/AuthenticationController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,uCAAmC;AAE3E,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,wBAAwB,CAAC,eAAe,CAAC,CAAC;CACpD,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,mDAAmD,GAAG;IAChE,IAAI,EAAE,gDAAgD,CAAC;IACvD,OAAO,EAAE,wBAAwB,CAAC,uBAAuB,CAAC,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,yCAAyC,CAAC;IAChD,OAAO,EAAE,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,yCAAyC,CAAC;IAChD,OAAO,EAAE,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,+CAA+C,GAAG;IAC5D,IAAI,EAAE,4CAA4C,CAAC;IACnD,OAAO,EAAE,wBAAwB,CAAC,mBAAmB,CAAC,CAAC;CACxD,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,uDAAuD,GAAG;IACpE,IAAI,EAAE,oDAAoD,CAAC;IAC3D,OAAO,EAAE,wBAAwB,CAAC,2BAA2B,CAAC,CAAC;CAChE,CAAC;AAEF,MAAM,MAAM,mDAAmD,GAAG;IAChE,IAAI,EAAE,gDAAgD,CAAC;IACvD,OAAO,EAAE,wBAAwB,CAAC,uBAAuB,CAAC,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,wCAAwC,GAAG;IACrD,IAAI,EAAE,qCAAqC,CAAC;IAC5C,OAAO,EAAE,wBAAwB,CAAC,YAAY,CAAC,CAAC;CACjD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qCAAqC,GAC7C,2CAA2C,GAC3C,mDAAmD,GACnD,4CAA4C,GAC5C,4CAA4C,GAC5C,+CAA+C,GAC/C,uDAAuD,GACvD,mDAAmD,GACnD,wCAAwC,CAAC"}
|
|
@@ -7,23 +7,42 @@ export type AuthenticationControllerPerformSignInAction = {
|
|
|
7
7
|
type: `AuthenticationController:performSignIn`;
|
|
8
8
|
handler: AuthenticationController['performSignIn'];
|
|
9
9
|
};
|
|
10
|
+
/**
|
|
11
|
+
* Marks profile pairing as needed. Clients call this when the SRP set
|
|
12
|
+
* changes (e.g. a new keyring was added) so the next auto-sign-in cycle
|
|
13
|
+
* re-runs `performSignIn` and re-pairs.
|
|
14
|
+
*/
|
|
15
|
+
export type AuthenticationControllerRequestProfilePairingAction = {
|
|
16
|
+
type: `AuthenticationController:requestProfilePairing`;
|
|
17
|
+
handler: AuthenticationController['requestProfilePairing'];
|
|
18
|
+
};
|
|
10
19
|
export type AuthenticationControllerPerformSignOutAction = {
|
|
11
20
|
type: `AuthenticationController:performSignOut`;
|
|
12
21
|
handler: AuthenticationController['performSignOut'];
|
|
13
22
|
};
|
|
14
23
|
/**
|
|
15
|
-
*
|
|
16
|
-
* Logs a user in if a user is not logged in.
|
|
24
|
+
* Returns a bearer token for the specified SRP, logging in if needed.
|
|
17
25
|
*
|
|
18
|
-
*
|
|
26
|
+
* When called without `entropySourceId`, returns the primary (first) SRP's
|
|
27
|
+
* access token, which is effectively the canonical
|
|
28
|
+
* profile's token that can be used by alias-aware consumers for cross-SRP
|
|
29
|
+
* operations.
|
|
30
|
+
*
|
|
31
|
+
* @param entropySourceId - The entropy source ID. Omit for the primary SRP.
|
|
32
|
+
* @returns The OIDC access token.
|
|
19
33
|
*/
|
|
20
34
|
export type AuthenticationControllerGetBearerTokenAction = {
|
|
21
35
|
type: `AuthenticationController:getBearerToken`;
|
|
22
36
|
handler: AuthenticationController['getBearerToken'];
|
|
23
37
|
};
|
|
24
38
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
39
|
+
* Returns the cached session profile, logging in if no session exists.
|
|
40
|
+
*
|
|
41
|
+
* The returned `canonicalProfileId` reflects the value from the most recent
|
|
42
|
+
* login or pairing. In the rare event where a canonical changed because of
|
|
43
|
+
* a pairing that happened on another device, the cached value may be stale
|
|
44
|
+
* until the next login. For guaranteed freshness, call
|
|
45
|
+
* `refreshCanonicalProfileId()` before reading `canonicalProfileId`.
|
|
27
46
|
*
|
|
28
47
|
* @param entropySourceId - The entropy source ID used to derive the key,
|
|
29
48
|
* when multiple sources are available (Multi-SRP).
|
|
@@ -33,6 +52,26 @@ export type AuthenticationControllerGetSessionProfileAction = {
|
|
|
33
52
|
type: `AuthenticationController:getSessionProfile`;
|
|
34
53
|
handler: AuthenticationController['getSessionProfile'];
|
|
35
54
|
};
|
|
55
|
+
/**
|
|
56
|
+
* Forces a fresh retrieval of the canonical profile ID from the server
|
|
57
|
+
* and propagates it to all cached SRP sessions.
|
|
58
|
+
*
|
|
59
|
+
* This method invalidates the primary SRP's cached session and forces a
|
|
60
|
+
* re-login. Use it before operations that require a guaranteed-fresh
|
|
61
|
+
* canonical (e.g. storage key derivation for Accounts ADR 0005). For
|
|
62
|
+
* best-effort reads, use
|
|
63
|
+
* `getSessionProfile().canonicalProfileId` instead.
|
|
64
|
+
*
|
|
65
|
+
* Only the primary SRP is re-logged-in regardless of how many SRPs exist —
|
|
66
|
+
* the server returns the current canonical for the entire pairing group
|
|
67
|
+
* from any single SRP login.
|
|
68
|
+
*
|
|
69
|
+
* @returns The refreshed canonical profile ID.
|
|
70
|
+
*/
|
|
71
|
+
export type AuthenticationControllerRefreshCanonicalProfileIdAction = {
|
|
72
|
+
type: `AuthenticationController:refreshCanonicalProfileId`;
|
|
73
|
+
handler: AuthenticationController['refreshCanonicalProfileId'];
|
|
74
|
+
};
|
|
36
75
|
export type AuthenticationControllerGetUserProfileLineageAction = {
|
|
37
76
|
type: `AuthenticationController:getUserProfileLineage`;
|
|
38
77
|
handler: AuthenticationController['getUserProfileLineage'];
|
|
@@ -44,5 +83,5 @@ export type AuthenticationControllerIsSignedInAction = {
|
|
|
44
83
|
/**
|
|
45
84
|
* Union of all AuthenticationController action types.
|
|
46
85
|
*/
|
|
47
|
-
export type AuthenticationControllerMethodActions = AuthenticationControllerPerformSignInAction | AuthenticationControllerPerformSignOutAction | AuthenticationControllerGetBearerTokenAction | AuthenticationControllerGetSessionProfileAction | AuthenticationControllerGetUserProfileLineageAction | AuthenticationControllerIsSignedInAction;
|
|
86
|
+
export type AuthenticationControllerMethodActions = AuthenticationControllerPerformSignInAction | AuthenticationControllerRequestProfilePairingAction | AuthenticationControllerPerformSignOutAction | AuthenticationControllerGetBearerTokenAction | AuthenticationControllerGetSessionProfileAction | AuthenticationControllerRefreshCanonicalProfileIdAction | AuthenticationControllerGetUserProfileLineageAction | AuthenticationControllerIsSignedInAction;
|
|
48
87
|
//# sourceMappingURL=AuthenticationController-method-action-types.d.mts.map
|
package/dist/controllers/authentication/AuthenticationController-method-action-types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthenticationController-method-action-types.d.mts","sourceRoot":"","sources":["../../../src/controllers/authentication/AuthenticationController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,uCAAmC;AAE3E,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,wBAAwB,CAAC,eAAe,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,yCAAyC,CAAC;IAChD,OAAO,EAAE,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;CACrD,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"AuthenticationController-method-action-types.d.mts","sourceRoot":"","sources":["../../../src/controllers/authentication/AuthenticationController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,uCAAmC;AAE3E,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,wBAAwB,CAAC,eAAe,CAAC,CAAC;CACpD,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,mDAAmD,GAAG;IAChE,IAAI,EAAE,gDAAgD,CAAC;IACvD,OAAO,EAAE,wBAAwB,CAAC,uBAAuB,CAAC,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,yCAAyC,CAAC;IAChD,OAAO,EAAE,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,yCAAyC,CAAC;IAChD,OAAO,EAAE,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,+CAA+C,GAAG;IAC5D,IAAI,EAAE,4CAA4C,CAAC;IACnD,OAAO,EAAE,wBAAwB,CAAC,mBAAmB,CAAC,CAAC;CACxD,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,uDAAuD,GAAG;IACpE,IAAI,EAAE,oDAAoD,CAAC;IAC3D,OAAO,EAAE,wBAAwB,CAAC,2BAA2B,CAAC,CAAC;CAChE,CAAC;AAEF,MAAM,MAAM,mDAAmD,GAAG;IAChE,IAAI,EAAE,gDAAgD,CAAC;IACvD,OAAO,EAAE,wBAAwB,CAAC,uBAAuB,CAAC,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,wCAAwC,GAAG;IACrD,IAAI,EAAE,qCAAqC,CAAC;IAC5C,OAAO,EAAE,wBAAwB,CAAC,YAAY,CAAC,CAAC;CACjD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qCAAqC,GAC7C,2CAA2C,GAC3C,mDAAmD,GACnD,4CAA4C,GAC5C,4CAA4C,GAC5C,+CAA+C,GAC/C,uDAAuD,GACvD,mDAAmD,GACnD,wCAAwC,CAAC"}
|
package/dist/controllers/authentication/AuthenticationController-method-action-types.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthenticationController-method-action-types.mjs","sourceRoot":"","sources":["../../../src/controllers/authentication/AuthenticationController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { AuthenticationController } from './AuthenticationController';\n\nexport type AuthenticationControllerPerformSignInAction = {\n type: `AuthenticationController:performSignIn`;\n handler: AuthenticationController['performSignIn'];\n};\n\nexport type AuthenticationControllerPerformSignOutAction = {\n type: `AuthenticationController:performSignOut`;\n handler: AuthenticationController['performSignOut'];\n};\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"AuthenticationController-method-action-types.mjs","sourceRoot":"","sources":["../../../src/controllers/authentication/AuthenticationController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { AuthenticationController } from './AuthenticationController';\n\nexport type AuthenticationControllerPerformSignInAction = {\n type: `AuthenticationController:performSignIn`;\n handler: AuthenticationController['performSignIn'];\n};\n\n/**\n * Marks profile pairing as needed. Clients call this when the SRP set\n * changes (e.g. a new keyring was added) so the next auto-sign-in cycle\n * re-runs `performSignIn` and re-pairs.\n */\nexport type AuthenticationControllerRequestProfilePairingAction = {\n type: `AuthenticationController:requestProfilePairing`;\n handler: AuthenticationController['requestProfilePairing'];\n};\n\nexport type AuthenticationControllerPerformSignOutAction = {\n type: `AuthenticationController:performSignOut`;\n handler: AuthenticationController['performSignOut'];\n};\n\n/**\n * Returns a bearer token for the specified SRP, logging in if needed.\n *\n * When called without `entropySourceId`, returns the primary (first) SRP's\n * access token, which is effectively the canonical\n * profile's token that can be used by alias-aware consumers for cross-SRP\n * operations.\n *\n * @param entropySourceId - The entropy source ID. Omit for the primary SRP.\n * @returns The OIDC access token.\n */\nexport type AuthenticationControllerGetBearerTokenAction = {\n type: `AuthenticationController:getBearerToken`;\n handler: AuthenticationController['getBearerToken'];\n};\n\n/**\n * Returns the cached session profile, logging in if no session exists.\n *\n * The returned `canonicalProfileId` reflects the value from the most recent\n * login or pairing. In the rare event where a canonical changed because of\n * a pairing that happened on another device, the cached value may be stale\n * until the next login. For guaranteed freshness, call\n * `refreshCanonicalProfileId()` before reading `canonicalProfileId`.\n *\n * @param entropySourceId - The entropy source ID used to derive the key,\n * when multiple sources are available (Multi-SRP).\n * @returns profile for the session.\n */\nexport type AuthenticationControllerGetSessionProfileAction = {\n type: `AuthenticationController:getSessionProfile`;\n handler: AuthenticationController['getSessionProfile'];\n};\n\n/**\n * Forces a fresh retrieval of the canonical profile ID from the server\n * and propagates it to all cached SRP sessions.\n *\n * This method invalidates the primary SRP's cached session and forces a\n * re-login. Use it before operations that require a guaranteed-fresh\n * canonical (e.g. storage key derivation for Accounts ADR 0005). For\n * best-effort reads, use\n * `getSessionProfile().canonicalProfileId` instead.\n *\n * Only the primary SRP is re-logged-in regardless of how many SRPs exist —\n * the server returns the current canonical for the entire pairing group\n * from any single SRP login.\n *\n * @returns The refreshed canonical profile ID.\n */\nexport type AuthenticationControllerRefreshCanonicalProfileIdAction = {\n type: `AuthenticationController:refreshCanonicalProfileId`;\n handler: AuthenticationController['refreshCanonicalProfileId'];\n};\n\nexport type AuthenticationControllerGetUserProfileLineageAction = {\n type: `AuthenticationController:getUserProfileLineage`;\n handler: AuthenticationController['getUserProfileLineage'];\n};\n\nexport type AuthenticationControllerIsSignedInAction = {\n type: `AuthenticationController:isSignedIn`;\n handler: AuthenticationController['isSignedIn'];\n};\n\n/**\n * Union of all AuthenticationController action types.\n */\nexport type AuthenticationControllerMethodActions =\n | AuthenticationControllerPerformSignInAction\n | AuthenticationControllerRequestProfilePairingAction\n | AuthenticationControllerPerformSignOutAction\n | AuthenticationControllerGetBearerTokenAction\n | AuthenticationControllerGetSessionProfileAction\n | AuthenticationControllerRefreshCanonicalProfileIdAction\n | AuthenticationControllerGetUserProfileLineageAction\n | AuthenticationControllerIsSignedInAction;\n"]}
|
|
@@ -10,7 +10,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
11
11
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
12
12
|
};
|
|
13
|
-
var _AuthenticationController_instances, _AuthenticationController_metametrics, _AuthenticationController_auth, _AuthenticationController_config, _AuthenticationController_isUnlocked, _AuthenticationController_cachedPrimaryEntropySourceId, _AuthenticationController_keyringController, _AuthenticationController_getLoginResponseFromState, _AuthenticationController_setLoginResponseToState, _AuthenticationController_assertIsUnlocked, _AuthenticationController_getPrimaryEntropySourceId, _AuthenticationController_snapGetPublicKey, _AuthenticationController_snapGetAllPublicKeys, _AuthenticationController__snapSignMessageCache, _AuthenticationController_snapSignMessage;
|
|
13
|
+
var _AuthenticationController_instances, _AuthenticationController_metametrics, _AuthenticationController_auth, _AuthenticationController_config, _AuthenticationController_isUnlocked, _AuthenticationController_cachedPrimaryEntropySourceId, _AuthenticationController_profilePairingRequestEpoch, _AuthenticationController_keyringController, _AuthenticationController_getLoginResponseFromState, _AuthenticationController_setLoginResponseToState, _AuthenticationController_assertIsUnlocked, _AuthenticationController_getPrimaryEntropySourceId, _AuthenticationController_tryClearNeedsProfilePairing, _AuthenticationController_doPair, _AuthenticationController_pairSrpProfiles, _AuthenticationController_propagateCanonical, _AuthenticationController_getCanonicalProfileId, _AuthenticationController_invalidateSrpSession, _AuthenticationController_snapGetPublicKey, _AuthenticationController_snapGetAllPublicKeys, _AuthenticationController__snapSignMessageCache, _AuthenticationController_snapSignMessage;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.AuthenticationController = exports.defaultState = void 0;
|
|
16
16
|
const base_controller_1 = require("@metamask/base-controller");
|
|
@@ -19,6 +19,7 @@ const auth_snap_requests_1 = require("./auth-snap-requests.cjs");
|
|
|
19
19
|
const controllerName = 'AuthenticationController';
|
|
20
20
|
exports.defaultState = {
|
|
21
21
|
isSignedIn: false,
|
|
22
|
+
needsProfilePairing: true,
|
|
22
23
|
};
|
|
23
24
|
const metadata = {
|
|
24
25
|
isSignedIn: {
|
|
@@ -27,6 +28,12 @@ const metadata = {
|
|
|
27
28
|
includeInDebugSnapshot: true,
|
|
28
29
|
usedInUi: true,
|
|
29
30
|
},
|
|
31
|
+
needsProfilePairing: {
|
|
32
|
+
includeInStateLogs: true,
|
|
33
|
+
persist: true,
|
|
34
|
+
includeInDebugSnapshot: true,
|
|
35
|
+
usedInUi: true,
|
|
36
|
+
},
|
|
30
37
|
srpSessionData: {
|
|
31
38
|
// Remove access token from state logs
|
|
32
39
|
includeInStateLogs: (srpSessionData) => {
|
|
@@ -57,8 +64,10 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
57
64
|
'performSignOut',
|
|
58
65
|
'getBearerToken',
|
|
59
66
|
'getSessionProfile',
|
|
67
|
+
'refreshCanonicalProfileId',
|
|
60
68
|
'getUserProfileLineage',
|
|
61
69
|
'isSignedIn',
|
|
70
|
+
'requestProfilePairing',
|
|
62
71
|
];
|
|
63
72
|
/**
|
|
64
73
|
* Controller that enables authentication for restricted endpoints.
|
|
@@ -80,6 +89,10 @@ class AuthenticationController extends base_controller_1.BaseController {
|
|
|
80
89
|
});
|
|
81
90
|
_AuthenticationController_isUnlocked.set(this, false);
|
|
82
91
|
_AuthenticationController_cachedPrimaryEntropySourceId.set(this, void 0);
|
|
92
|
+
// Bumped by `requestProfilePairing`. `performSignIn` snapshots this
|
|
93
|
+
// before its first await; if it changes mid-flight we must NOT clear
|
|
94
|
+
// `needsProfilePairing` (the rearm signal wins).
|
|
95
|
+
_AuthenticationController_profilePairingRequestEpoch.set(this, 0);
|
|
83
96
|
_AuthenticationController_keyringController.set(this, {
|
|
84
97
|
setupLockedStateSubscriptions: () => {
|
|
85
98
|
const { isUnlocked } = this.messenger.call('KeyringController:getState');
|
|
@@ -121,6 +134,7 @@ class AuthenticationController extends base_controller_1.BaseController {
|
|
|
121
134
|
}
|
|
122
135
|
async performSignIn() {
|
|
123
136
|
__classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_assertIsUnlocked).call(this, 'performSignIn');
|
|
137
|
+
const epochAtStart = __classPrivateFieldGet(this, _AuthenticationController_profilePairingRequestEpoch, "f");
|
|
124
138
|
const allPublicKeys = await __classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_snapGetAllPublicKeys).call(this);
|
|
125
139
|
const accessTokens = [];
|
|
126
140
|
// We iterate sequentially in order to be sure that the first entry
|
|
@@ -129,8 +143,34 @@ class AuthenticationController extends base_controller_1.BaseController {
|
|
|
129
143
|
const accessToken = await __classPrivateFieldGet(this, _AuthenticationController_auth, "f").getAccessToken(entropySourceId);
|
|
130
144
|
accessTokens.push(accessToken);
|
|
131
145
|
}
|
|
146
|
+
if (allPublicKeys.length < 2) {
|
|
147
|
+
// Single-SRP wallet: nothing to pair.
|
|
148
|
+
__classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_tryClearNeedsProfilePairing).call(this, epochAtStart);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// Pair failures must not break sign-in; the gate stays `true` for retry.
|
|
152
|
+
try {
|
|
153
|
+
await __classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_doPair).call(this, accessTokens, epochAtStart);
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// noop
|
|
157
|
+
}
|
|
158
|
+
}
|
|
132
159
|
return accessTokens;
|
|
133
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Marks profile pairing as needed. Clients call this when the SRP set
|
|
163
|
+
* changes (e.g. a new keyring was added) so the next auto-sign-in cycle
|
|
164
|
+
* re-runs `performSignIn` and re-pairs.
|
|
165
|
+
*/
|
|
166
|
+
requestProfilePairing() {
|
|
167
|
+
__classPrivateFieldSet(this, _AuthenticationController_profilePairingRequestEpoch, __classPrivateFieldGet(this, _AuthenticationController_profilePairingRequestEpoch, "f") + 1, "f");
|
|
168
|
+
if (!this.state.needsProfilePairing) {
|
|
169
|
+
this.update((state) => {
|
|
170
|
+
state.needsProfilePairing = true;
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
134
174
|
performSignOut() {
|
|
135
175
|
__classPrivateFieldSet(this, _AuthenticationController_cachedPrimaryEntropySourceId, undefined, "f");
|
|
136
176
|
this.update((state) => {
|
|
@@ -139,10 +179,15 @@ class AuthenticationController extends base_controller_1.BaseController {
|
|
|
139
179
|
});
|
|
140
180
|
}
|
|
141
181
|
/**
|
|
142
|
-
*
|
|
143
|
-
* Logs a user in if a user is not logged in.
|
|
182
|
+
* Returns a bearer token for the specified SRP, logging in if needed.
|
|
144
183
|
*
|
|
145
|
-
*
|
|
184
|
+
* When called without `entropySourceId`, returns the primary (first) SRP's
|
|
185
|
+
* access token, which is effectively the canonical
|
|
186
|
+
* profile's token that can be used by alias-aware consumers for cross-SRP
|
|
187
|
+
* operations.
|
|
188
|
+
*
|
|
189
|
+
* @param entropySourceId - The entropy source ID. Omit for the primary SRP.
|
|
190
|
+
* @returns The OIDC access token.
|
|
146
191
|
*/
|
|
147
192
|
async getBearerToken(entropySourceId) {
|
|
148
193
|
__classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_assertIsUnlocked).call(this, 'getBearerToken');
|
|
@@ -150,8 +195,13 @@ class AuthenticationController extends base_controller_1.BaseController {
|
|
|
150
195
|
return await __classPrivateFieldGet(this, _AuthenticationController_auth, "f").getAccessToken(resolvedId);
|
|
151
196
|
}
|
|
152
197
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
198
|
+
* Returns the cached session profile, logging in if no session exists.
|
|
199
|
+
*
|
|
200
|
+
* The returned `canonicalProfileId` reflects the value from the most recent
|
|
201
|
+
* login or pairing. In the rare event where a canonical changed because of
|
|
202
|
+
* a pairing that happened on another device, the cached value may be stale
|
|
203
|
+
* until the next login. For guaranteed freshness, call
|
|
204
|
+
* `refreshCanonicalProfileId()` before reading `canonicalProfileId`.
|
|
155
205
|
*
|
|
156
206
|
* @param entropySourceId - The entropy source ID used to derive the key,
|
|
157
207
|
* when multiple sources are available (Multi-SRP).
|
|
@@ -162,6 +212,34 @@ class AuthenticationController extends base_controller_1.BaseController {
|
|
|
162
212
|
const resolvedId = entropySourceId ?? (await __classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_getPrimaryEntropySourceId).call(this));
|
|
163
213
|
return await __classPrivateFieldGet(this, _AuthenticationController_auth, "f").getUserProfile(resolvedId);
|
|
164
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Forces a fresh retrieval of the canonical profile ID from the server
|
|
217
|
+
* and propagates it to all cached SRP sessions.
|
|
218
|
+
*
|
|
219
|
+
* This method invalidates the primary SRP's cached session and forces a
|
|
220
|
+
* re-login. Use it before operations that require a guaranteed-fresh
|
|
221
|
+
* canonical (e.g. storage key derivation for Accounts ADR 0005). For
|
|
222
|
+
* best-effort reads, use
|
|
223
|
+
* `getSessionProfile().canonicalProfileId` instead.
|
|
224
|
+
*
|
|
225
|
+
* Only the primary SRP is re-logged-in regardless of how many SRPs exist —
|
|
226
|
+
* the server returns the current canonical for the entire pairing group
|
|
227
|
+
* from any single SRP login.
|
|
228
|
+
*
|
|
229
|
+
* @returns The refreshed canonical profile ID.
|
|
230
|
+
*/
|
|
231
|
+
async refreshCanonicalProfileId() {
|
|
232
|
+
__classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_assertIsUnlocked).call(this, 'refreshCanonicalProfileId');
|
|
233
|
+
const primaryEntropySourceId = await __classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_getPrimaryEntropySourceId).call(this);
|
|
234
|
+
__classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_invalidateSrpSession).call(this, primaryEntropySourceId);
|
|
235
|
+
await __classPrivateFieldGet(this, _AuthenticationController_auth, "f").getAccessToken(primaryEntropySourceId);
|
|
236
|
+
const canonical = await __classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_getCanonicalProfileId).call(this);
|
|
237
|
+
if (!canonical) {
|
|
238
|
+
throw new Error('refreshCanonicalProfileId - Unable to resolve canonical profile ID');
|
|
239
|
+
}
|
|
240
|
+
__classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_propagateCanonical).call(this, canonical);
|
|
241
|
+
return canonical;
|
|
242
|
+
}
|
|
165
243
|
async getUserProfileLineage(entropySourceId) {
|
|
166
244
|
__classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_assertIsUnlocked).call(this, 'getUserProfileLineage');
|
|
167
245
|
const resolvedId = entropySourceId ?? (await __classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_getPrimaryEntropySourceId).call(this));
|
|
@@ -172,7 +250,7 @@ class AuthenticationController extends base_controller_1.BaseController {
|
|
|
172
250
|
}
|
|
173
251
|
}
|
|
174
252
|
exports.AuthenticationController = AuthenticationController;
|
|
175
|
-
_AuthenticationController_metametrics = new WeakMap(), _AuthenticationController_auth = new WeakMap(), _AuthenticationController_config = new WeakMap(), _AuthenticationController_isUnlocked = new WeakMap(), _AuthenticationController_cachedPrimaryEntropySourceId = new WeakMap(), _AuthenticationController_keyringController = new WeakMap(), _AuthenticationController__snapSignMessageCache = new WeakMap(), _AuthenticationController_instances = new WeakSet(), _AuthenticationController_getLoginResponseFromState = async function _AuthenticationController_getLoginResponseFromState(entropySourceId) {
|
|
253
|
+
_AuthenticationController_metametrics = new WeakMap(), _AuthenticationController_auth = new WeakMap(), _AuthenticationController_config = new WeakMap(), _AuthenticationController_isUnlocked = new WeakMap(), _AuthenticationController_cachedPrimaryEntropySourceId = new WeakMap(), _AuthenticationController_profilePairingRequestEpoch = new WeakMap(), _AuthenticationController_keyringController = new WeakMap(), _AuthenticationController__snapSignMessageCache = new WeakMap(), _AuthenticationController_instances = new WeakSet(), _AuthenticationController_getLoginResponseFromState = async function _AuthenticationController_getLoginResponseFromState(entropySourceId) {
|
|
176
254
|
const resolvedId = entropySourceId ?? (await __classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_getPrimaryEntropySourceId).call(this));
|
|
177
255
|
if (!this.state.srpSessionData?.[resolvedId]) {
|
|
178
256
|
return null;
|
|
@@ -212,6 +290,90 @@ _AuthenticationController_metametrics = new WeakMap(), _AuthenticationController
|
|
|
212
290
|
}
|
|
213
291
|
__classPrivateFieldSet(this, _AuthenticationController_cachedPrimaryEntropySourceId, primaryId, "f");
|
|
214
292
|
return __classPrivateFieldGet(this, _AuthenticationController_cachedPrimaryEntropySourceId, "f");
|
|
293
|
+
}, _AuthenticationController_tryClearNeedsProfilePairing = function _AuthenticationController_tryClearNeedsProfilePairing(epochAtStart) {
|
|
294
|
+
if (__classPrivateFieldGet(this, _AuthenticationController_profilePairingRequestEpoch, "f") !== epochAtStart) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
if (this.state.needsProfilePairing) {
|
|
298
|
+
this.update((state) => {
|
|
299
|
+
state.needsProfilePairing = false;
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}, _AuthenticationController_doPair =
|
|
303
|
+
/**
|
|
304
|
+
* Pairs all SRPs via `POST /profile/pair`, propagates the canonical
|
|
305
|
+
* profile ID, clears `needsProfilePairing`, and emits
|
|
306
|
+
* `AuthenticationController:profileSignIn` when the canonical changes or
|
|
307
|
+
* new aliases are returned. Throws on failure.
|
|
308
|
+
*
|
|
309
|
+
* @param accessTokens - Per-SRP access tokens, primary first.
|
|
310
|
+
* @param epochAtStart - Pairing-request epoch captured by the caller.
|
|
311
|
+
* Used to skip the gate clear if `requestProfilePairing` ran while the
|
|
312
|
+
* pair API call was in-flight.
|
|
313
|
+
*/
|
|
314
|
+
async function _AuthenticationController_doPair(accessTokens, epochAtStart) {
|
|
315
|
+
const previousCanonical = await __classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_getCanonicalProfileId).call(this);
|
|
316
|
+
const profileAliases = await __classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_pairSrpProfiles).call(this, accessTokens);
|
|
317
|
+
const newCanonical = await __classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_getCanonicalProfileId).call(this);
|
|
318
|
+
// If somehow we cannot compute the new canonical profile ID after pairing,
|
|
319
|
+
// we just return now and do not update the `needsProfilePairing` flag.
|
|
320
|
+
if (!newCanonical) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
__classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_tryClearNeedsProfilePairing).call(this, epochAtStart);
|
|
324
|
+
const profileIdChanged = previousCanonical !== newCanonical;
|
|
325
|
+
const shouldEmitProfileSignInEvent = profileIdChanged || profileAliases.length > 0;
|
|
326
|
+
if (shouldEmitProfileSignInEvent) {
|
|
327
|
+
this.messenger.publish('AuthenticationController:profileSignIn', {
|
|
328
|
+
profileId: newCanonical,
|
|
329
|
+
profileAliases,
|
|
330
|
+
profileIdChanged,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
}, _AuthenticationController_pairSrpProfiles = async function _AuthenticationController_pairSrpProfiles(accessTokens) {
|
|
334
|
+
if (accessTokens.length < 2) {
|
|
335
|
+
return [];
|
|
336
|
+
}
|
|
337
|
+
const primaryAccessToken = accessTokens[0]; // Associated with primary SRP.
|
|
338
|
+
const { profileAliases, profile: { canonicalProfileId }, } = await __classPrivateFieldGet(this, _AuthenticationController_auth, "f").pairSrpProfiles(accessTokens, primaryAccessToken);
|
|
339
|
+
__classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_propagateCanonical).call(this, canonicalProfileId);
|
|
340
|
+
return profileAliases;
|
|
341
|
+
}, _AuthenticationController_propagateCanonical = function _AuthenticationController_propagateCanonical(canonicalProfileId) {
|
|
342
|
+
const { srpSessionData } = this.state;
|
|
343
|
+
if (!srpSessionData) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
this.update((state) => {
|
|
347
|
+
for (const entry of Object.values(state.srpSessionData ?? {})) {
|
|
348
|
+
if (entry?.profile) {
|
|
349
|
+
entry.profile.canonicalProfileId = canonicalProfileId;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
}, _AuthenticationController_getCanonicalProfileId =
|
|
354
|
+
/**
|
|
355
|
+
* Returns the canonical profile id from the primary SRP's cached session.
|
|
356
|
+
* Returns `null` when no session exists yet for the primary SRP.
|
|
357
|
+
*
|
|
358
|
+
* Always reads from the primary SRP because the canonical is shared across
|
|
359
|
+
* all paired SRPs after `#propagateCanonical`.
|
|
360
|
+
*
|
|
361
|
+
* @returns The canonical profile id, or `null` if unavailable.
|
|
362
|
+
*/
|
|
363
|
+
async function _AuthenticationController_getCanonicalProfileId() {
|
|
364
|
+
const primaryEntropySourceId = await __classPrivateFieldGet(this, _AuthenticationController_instances, "m", _AuthenticationController_getPrimaryEntropySourceId).call(this);
|
|
365
|
+
return (this.state.srpSessionData?.[primaryEntropySourceId]?.profile
|
|
366
|
+
?.canonicalProfileId ?? null);
|
|
367
|
+
}, _AuthenticationController_invalidateSrpSession = function _AuthenticationController_invalidateSrpSession(entropySourceId) {
|
|
368
|
+
this.update((state) => {
|
|
369
|
+
const entry = state.srpSessionData?.[entropySourceId];
|
|
370
|
+
if (entry?.profile) {
|
|
371
|
+
// Setting canonicalProfileId to '' forces a re-fetch on the next
|
|
372
|
+
// #getAuthSession call. The falsy check (!auth.profile.canonicalProfileId)
|
|
373
|
+
// treats '' the same as undefined/null — all signal an invalid session.
|
|
374
|
+
entry.profile.canonicalProfileId = '';
|
|
375
|
+
}
|
|
376
|
+
});
|
|
215
377
|
}, _AuthenticationController_snapGetPublicKey =
|
|
216
378
|
/**
|
|
217
379
|
* Returns the auth snap public key.
|