@metamask-previews/profile-sync-controller 28.0.2-preview-4845f8918 → 28.0.2-preview-8a15a8aa8
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 +0 -12
- package/dist/controllers/authentication/AuthenticationController-method-action-types.cjs.map +1 -1
- package/dist/controllers/authentication/AuthenticationController-method-action-types.d.cts +3 -8
- package/dist/controllers/authentication/AuthenticationController-method-action-types.d.cts.map +1 -1
- package/dist/controllers/authentication/AuthenticationController-method-action-types.d.mts +3 -8
- 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 +4 -58
- package/dist/controllers/authentication/AuthenticationController.cjs.map +1 -1
- package/dist/controllers/authentication/AuthenticationController.d.cts +5 -19
- package/dist/controllers/authentication/AuthenticationController.d.cts.map +1 -1
- package/dist/controllers/authentication/AuthenticationController.d.mts +5 -19
- package/dist/controllers/authentication/AuthenticationController.d.mts.map +1 -1
- package/dist/controllers/authentication/AuthenticationController.mjs +4 -58
- package/dist/controllers/authentication/AuthenticationController.mjs.map +1 -1
- package/dist/controllers/authentication/mocks/mockResponses.d.cts +0 -18
- package/dist/controllers/authentication/mocks/mockResponses.d.cts.map +1 -1
- package/dist/controllers/authentication/mocks/mockResponses.d.mts +0 -18
- package/dist/controllers/authentication/mocks/mockResponses.d.mts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.cjs +1 -18
- package/dist/sdk/authentication-jwt-bearer/flow-srp.cjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.d.cts +0 -2
- package/dist/sdk/authentication-jwt-bearer/flow-srp.d.cts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.d.mts +0 -2
- package/dist/sdk/authentication-jwt-bearer/flow-srp.d.mts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/flow-srp.mjs +2 -19
- package/dist/sdk/authentication-jwt-bearer/flow-srp.mjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/services.cjs +1 -56
- package/dist/sdk/authentication-jwt-bearer/services.cjs.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/services.d.cts +1 -17
- package/dist/sdk/authentication-jwt-bearer/services.d.cts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/services.d.mts +1 -17
- package/dist/sdk/authentication-jwt-bearer/services.d.mts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/services.mjs +0 -53
- 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 +1 -20
- package/dist/sdk/authentication-jwt-bearer/types.d.cts.map +1 -1
- package/dist/sdk/authentication-jwt-bearer/types.d.mts +1 -20
- 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.cjs +0 -4
- package/dist/sdk/authentication.cjs.map +1 -1
- package/dist/sdk/authentication.d.cts +0 -2
- package/dist/sdk/authentication.d.cts.map +1 -1
- package/dist/sdk/authentication.d.mts +0 -2
- package/dist/sdk/authentication.d.mts.map +1 -1
- package/dist/sdk/authentication.mjs +0 -4
- package/dist/sdk/authentication.mjs.map +1 -1
- package/dist/sdk/mocks/auth.cjs +1 -11
- package/dist/sdk/mocks/auth.cjs.map +1 -1
- package/dist/sdk/mocks/auth.d.cts +0 -10
- package/dist/sdk/mocks/auth.d.cts.map +1 -1
- package/dist/sdk/mocks/auth.d.mts +0 -10
- package/dist/sdk/mocks/auth.d.mts.map +1 -1
- package/dist/sdk/mocks/auth.mjs +1 -11
- package/dist/sdk/mocks/auth.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.cjs +0 -27
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.cjs.map +0 -1
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.d.cts +0 -13
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.d.cts.map +0 -1
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.d.mts +0 -13
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.d.mts.map +0 -1
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.mjs +0 -23
- package/dist/sdk/authentication-jwt-bearer/utils/identifier.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthenticationController.mjs","sourceRoot":"","sources":["../../../src/controllers/authentication/AuthenticationController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { SnapControllerHandleRequestAction } from '@metamask/snaps-controllers';\nimport type { Json } from '@metamask/utils';\n\nimport type {\n LoginResponse,\n ProfileAlias,\n SRPInterface,\n UserProfile,\n UserProfileLineage,\n} from '../../sdk';\nimport {\n assertMessageStartsWithMetamask,\n AuthType,\n Env,\n JwtBearerAuth,\n} from '../../sdk';\nimport type { MetaMetricsAuth } from '../../shared/types/services';\nimport {\n createSnapPublicKeyRequest,\n createSnapAllPublicKeysRequest,\n createSnapSignMessageRequest,\n} from './auth-snap-requests';\nimport { AuthenticationControllerMethodActions } from './AuthenticationController-method-action-types';\n\nconst controllerName = 'AuthenticationController';\n\n// State\nexport type AuthenticationControllerState = {\n isSignedIn: boolean;\n srpSessionData?: Record<string, LoginResponse>;\n};\nexport const defaultState: AuthenticationControllerState = {\n isSignedIn: false,\n};\nconst metadata: StateMetadata<AuthenticationControllerState> = {\n isSignedIn: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n srpSessionData: {\n // Remove access token from state logs\n includeInStateLogs: (srpSessionData) => {\n // Unreachable branch, included just to fix a type error for the case where this property is\n // unset. The type gets collapsed to include `| undefined` even though `undefined` is never\n // set here, because we don't yet use `exactOptionalPropertyTypes`.\n // TODO: Remove branch after enabling `exactOptionalPropertyTypes`\n // ref: https://github.com/MetaMask/core/issues/6565\n if (srpSessionData === null || srpSessionData === undefined) {\n return null;\n }\n return Object.entries(srpSessionData).reduce<Record<string, Json>>(\n (sanitizedSrpSessionData, [key, value]) => {\n const { accessToken: _unused, ...tokenWithoutAccessToken } =\n value.token;\n sanitizedSrpSessionData[key] = {\n ...value,\n token: tokenWithoutAccessToken,\n };\n return sanitizedSrpSessionData;\n },\n {},\n );\n },\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\ntype ControllerConfig = {\n env: Env;\n};\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'performSignIn',\n 'performSignOut',\n 'getBearerToken',\n 'getSessionProfile',\n 'getUserProfileLineage',\n 'isSignedIn',\n] as const;\n\nexport type Actions =\n | AuthenticationControllerGetStateAction\n | AuthenticationControllerMethodActions;\n\nexport type AuthenticationControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AuthenticationControllerState\n>;\n\nexport type AuthenticationControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n AuthenticationControllerState\n >;\n\nexport type ProfileSignInInfo = {\n profileId: string;\n profileAliases: ProfileAlias[];\n profileIdChanged: boolean;\n};\n\nexport type AuthenticationControllerProfileSignInEvent = {\n type: `${typeof controllerName}:profileSignIn`;\n payload: [ProfileSignInInfo];\n};\n\nexport type Events =\n | AuthenticationControllerStateChangeEvent\n | AuthenticationControllerProfileSignInEvent;\n\n// Allowed Actions\ntype AllowedActions =\n | KeyringControllerGetStateAction\n | SnapControllerHandleRequestAction;\n\ntype AllowedEvents = KeyringControllerLockEvent | KeyringControllerUnlockEvent;\n\n// Messenger\nexport type AuthenticationControllerMessenger = Messenger<\n typeof controllerName,\n Actions | AllowedActions,\n Events | AllowedEvents\n>;\n\n/**\n * Controller that enables authentication for restricted endpoints.\n * Used for Backup & Sync, Notifications, and other services.\n */\nexport class AuthenticationController extends BaseController<\n typeof controllerName,\n AuthenticationControllerState,\n AuthenticationControllerMessenger\n> {\n readonly #metametrics: MetaMetricsAuth;\n\n readonly #auth: SRPInterface;\n\n readonly #config: ControllerConfig = {\n env: Env.PRD,\n };\n\n #isUnlocked = false;\n\n #cachedPrimaryEntropySourceId?: string;\n\n readonly #keyringController = {\n setupLockedStateSubscriptions: () => {\n const { isUnlocked } = this.messenger.call('KeyringController:getState');\n this.#isUnlocked = isUnlocked;\n\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n });\n\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n });\n },\n };\n\n constructor({\n messenger,\n state,\n config,\n metametrics,\n }: {\n messenger: AuthenticationControllerMessenger;\n state?: AuthenticationControllerState;\n config?: Partial<ControllerConfig>;\n /**\n * Not using the Messaging System as we\n * do not want to tie this strictly to extension\n */\n metametrics: MetaMetricsAuth;\n }) {\n super({\n messenger,\n metadata,\n name: controllerName,\n state: { ...defaultState, ...state },\n });\n\n if (!metametrics) {\n throw new Error('`metametrics` field is required');\n }\n\n this.#config = {\n ...this.#config,\n ...config,\n };\n\n this.#metametrics = metametrics;\n\n this.#auth = new JwtBearerAuth(\n {\n env: this.#config.env,\n platform: metametrics.agent,\n type: AuthType.SRP,\n },\n {\n storage: {\n getLoginResponse: this.#getLoginResponseFromState.bind(this),\n setLoginResponse: this.#setLoginResponseToState.bind(this),\n },\n signing: {\n getIdentifier: this.#snapGetPublicKey.bind(this),\n signMessage: this.#snapSignMessage.bind(this),\n },\n metametrics: this.#metametrics,\n },\n );\n\n this.#keyringController.setupLockedStateSubscriptions();\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n async #getLoginResponseFromState(\n entropySourceId?: string,\n ): Promise<LoginResponse | null> {\n const resolvedId =\n entropySourceId ?? (await this.#getPrimaryEntropySourceId());\n if (!this.state.srpSessionData?.[resolvedId]) {\n return null;\n }\n return this.state.srpSessionData[resolvedId];\n }\n\n async #setLoginResponseToState(\n loginResponse: LoginResponse,\n entropySourceId?: string,\n ) {\n const resolvedId =\n entropySourceId ?? (await this.#getPrimaryEntropySourceId());\n const metaMetricsId = await this.#metametrics.getMetaMetricsId();\n this.update((state) => {\n state.isSignedIn = true;\n if (!state.srpSessionData) {\n state.srpSessionData = {};\n }\n state.srpSessionData[resolvedId] = {\n ...loginResponse,\n profile: {\n ...loginResponse.profile,\n metaMetricsId,\n },\n };\n });\n }\n\n #assertIsUnlocked(methodName: string): void {\n if (!this.#isUnlocked) {\n throw new Error(`${methodName} - unable to proceed, wallet is locked`);\n }\n }\n\n async #getPrimaryEntropySourceId(): Promise<string> {\n if (this.#cachedPrimaryEntropySourceId) {\n return this.#cachedPrimaryEntropySourceId;\n }\n const allPublicKeys = await this.#snapGetAllPublicKeys();\n\n if (allPublicKeys.length === 0) {\n throw new Error(\n '#getPrimaryEntropySourceId - No entropy sources found from snap',\n );\n }\n\n const primaryId = allPublicKeys[0][0];\n if (!primaryId) {\n throw new Error(\n '#getPrimaryEntropySourceId - Primary entropy source ID is undefined',\n );\n }\n\n this.#cachedPrimaryEntropySourceId = primaryId;\n return this.#cachedPrimaryEntropySourceId;\n }\n\n public async performSignIn(): Promise<string[]> {\n this.#assertIsUnlocked('performSignIn');\n\n const allPublicKeys = await this.#snapGetAllPublicKeys();\n const accessTokens: string[] = [];\n\n // We iterate sequentially in order to be sure that the first entry\n // is the primary SRP LoginResponse.\n for (const [entropySourceId] of allPublicKeys) {\n const accessToken = await this.#auth.getAccessToken(entropySourceId);\n accessTokens.push(accessToken);\n }\n\n // Pair SRP profiles (idempotent — no-op if already paired)\n if (accessTokens.length >= 2) {\n const previousCanonical = this.#getCanonicalProfileId();\n\n try {\n const profileAliases = await this.#pairSrpProfiles(accessTokens);\n\n const newCanonical = this.#getCanonicalProfileId();\n const profileIdChanged = previousCanonical !== newCanonical;\n const shouldEmitProfileSignInEvent =\n profileIdChanged || profileAliases.length > 0;\n\n if (shouldEmitProfileSignInEvent) {\n this.messenger.publish('AuthenticationController:profileSignIn', {\n profileId: newCanonical ?? '',\n profileAliases,\n profileIdChanged,\n });\n }\n } catch {\n // Pairing failure is non-fatal — retry on next performSignIn\n }\n }\n\n return accessTokens;\n }\n\n async #pairSrpProfiles(accessTokens: string[]): Promise<ProfileAlias[]> {\n if (accessTokens.length < 2) {\n return [];\n }\n const {\n profileAliases,\n profile: { canonicalProfileId },\n } = await this.#auth.pairSrpProfiles(accessTokens, accessTokens[0]);\n this.#propagateCanonical(canonicalProfileId);\n return profileAliases;\n }\n\n #propagateCanonical(canonicalProfileId: string): void {\n const { srpSessionData } = this.state;\n if (!srpSessionData) {\n return;\n }\n\n this.update((state) => {\n for (const key of Object.keys(state.srpSessionData ?? {})) {\n const entry = state.srpSessionData?.[key];\n if (entry?.profile) {\n entry.profile.canonicalProfileId = canonicalProfileId;\n }\n }\n });\n }\n\n #getCanonicalProfileId(): string | null {\n const { srpSessionData } = this.state;\n if (!srpSessionData) {\n return null;\n }\n const firstKey = Object.keys(srpSessionData)[0];\n return firstKey\n ? (srpSessionData[firstKey]?.profile?.canonicalProfileId ?? null)\n : null;\n }\n\n public performSignOut(): void {\n this.#cachedPrimaryEntropySourceId = undefined;\n this.update((state) => {\n state.isSignedIn = false;\n state.srpSessionData = undefined;\n });\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 */\n public async getBearerToken(entropySourceId?: string): Promise<string> {\n this.#assertIsUnlocked('getBearerToken');\n const resolvedId =\n entropySourceId ?? (await this.#getPrimaryEntropySourceId());\n return await this.#auth.getAccessToken(resolvedId);\n }\n\n /**\n * Will return a session profile.\n * Logs a user in if a user is not logged in.\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 */\n public async getSessionProfile(\n entropySourceId?: string,\n ): Promise<UserProfile> {\n this.#assertIsUnlocked('getSessionProfile');\n const resolvedId =\n entropySourceId ?? (await this.#getPrimaryEntropySourceId());\n return await this.#auth.getUserProfile(resolvedId);\n }\n\n public async getUserProfileLineage(\n entropySourceId?: string,\n ): Promise<UserProfileLineage> {\n this.#assertIsUnlocked('getUserProfileLineage');\n const resolvedId =\n entropySourceId ?? (await this.#getPrimaryEntropySourceId());\n return await this.#auth.getUserProfileLineage(resolvedId);\n }\n\n public isSignedIn(): boolean {\n return this.state.isSignedIn;\n }\n\n /**\n * Returns the auth snap public key.\n *\n * @param entropySourceId - The entropy source ID used to derive the key,\n * when multiple sources are available (Multi-SRP).\n * @returns The snap public key.\n */\n async #snapGetPublicKey(entropySourceId?: string): Promise<string> {\n this.#assertIsUnlocked('#snapGetPublicKey');\n\n const result = (await this.messenger.call(\n 'SnapController:handleRequest',\n createSnapPublicKeyRequest(entropySourceId),\n )) as string;\n\n return result;\n }\n\n /**\n * Returns a mapping of entropy source IDs to auth snap public keys.\n *\n * @returns A mapping of entropy source IDs to public keys.\n */\n async #snapGetAllPublicKeys(): Promise<[string, string][]> {\n this.#assertIsUnlocked('#snapGetAllPublicKeys');\n\n const result = (await this.messenger.call(\n 'SnapController:handleRequest',\n createSnapAllPublicKeysRequest(),\n )) as [string, string][];\n\n return result;\n }\n\n #_snapSignMessageCache: Record<`metamask:${string}`, string> = {};\n\n /**\n * Signs a specific message using an underlying auth snap.\n *\n * @param message - A specific tagged message to sign.\n * @param entropySourceId - The entropy source ID used to derive the key,\n * when multiple sources are available (Multi-SRP).\n * @returns A Signature created by the snap.\n */\n async #snapSignMessage(\n message: string,\n entropySourceId?: string,\n ): Promise<string> {\n assertMessageStartsWithMetamask(message);\n\n if (this.#_snapSignMessageCache[message]) {\n return this.#_snapSignMessageCache[message];\n }\n\n this.#assertIsUnlocked('#snapSignMessage');\n\n const result = (await this.messenger.call(\n 'SnapController:handleRequest',\n createSnapSignMessageRequest(message, entropySourceId),\n )) as string;\n\n this.#_snapSignMessageCache[message] = result;\n\n return result;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AuthenticationController.mjs","sourceRoot":"","sources":["../../../src/controllers/authentication/AuthenticationController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { SnapControllerHandleRequestAction } from '@metamask/snaps-controllers';\nimport type { Json } from '@metamask/utils';\n\nimport type {\n LoginResponse,\n SRPInterface,\n UserProfile,\n UserProfileLineage,\n} from '../../sdk';\nimport {\n assertMessageStartsWithMetamask,\n AuthType,\n Env,\n JwtBearerAuth,\n} from '../../sdk';\nimport type { MetaMetricsAuth } from '../../shared/types/services';\nimport {\n createSnapPublicKeyRequest,\n createSnapAllPublicKeysRequest,\n createSnapSignMessageRequest,\n} from './auth-snap-requests';\nimport { AuthenticationControllerMethodActions } from './AuthenticationController-method-action-types';\n\nconst controllerName = 'AuthenticationController';\n\n// State\nexport type AuthenticationControllerState = {\n isSignedIn: boolean;\n srpSessionData?: Record<string, LoginResponse>;\n};\nexport const defaultState: AuthenticationControllerState = {\n isSignedIn: false,\n};\nconst metadata: StateMetadata<AuthenticationControllerState> = {\n isSignedIn: {\n includeInStateLogs: true,\n persist: true,\n includeInDebugSnapshot: true,\n usedInUi: true,\n },\n srpSessionData: {\n // Remove access token from state logs\n includeInStateLogs: (srpSessionData) => {\n // Unreachable branch, included just to fix a type error for the case where this property is\n // unset. The type gets collapsed to include `| undefined` even though `undefined` is never\n // set here, because we don't yet use `exactOptionalPropertyTypes`.\n // TODO: Remove branch after enabling `exactOptionalPropertyTypes`\n // ref: https://github.com/MetaMask/core/issues/6565\n if (srpSessionData === null || srpSessionData === undefined) {\n return null;\n }\n return Object.entries(srpSessionData).reduce<Record<string, Json>>(\n (sanitizedSrpSessionData, [key, value]) => {\n const { accessToken: _unused, ...tokenWithoutAccessToken } =\n value.token;\n sanitizedSrpSessionData[key] = {\n ...value,\n token: tokenWithoutAccessToken,\n };\n return sanitizedSrpSessionData;\n },\n {},\n );\n },\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\ntype ControllerConfig = {\n env: Env;\n};\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'performSignIn',\n 'performSignOut',\n 'getBearerToken',\n 'getSessionProfile',\n 'getUserProfileLineage',\n 'isSignedIn',\n] as const;\n\nexport type Actions =\n | AuthenticationControllerGetStateAction\n | AuthenticationControllerMethodActions;\n\nexport type AuthenticationControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n AuthenticationControllerState\n>;\n\nexport type AuthenticationControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n AuthenticationControllerState\n >;\n\nexport type Events = AuthenticationControllerStateChangeEvent;\n\n// Allowed Actions\ntype AllowedActions =\n | KeyringControllerGetStateAction\n | SnapControllerHandleRequestAction;\n\ntype AllowedEvents = KeyringControllerLockEvent | KeyringControllerUnlockEvent;\n\n// Messenger\nexport type AuthenticationControllerMessenger = Messenger<\n typeof controllerName,\n Actions | AllowedActions,\n Events | AllowedEvents\n>;\n\n/**\n * Controller that enables authentication for restricted endpoints.\n * Used for Backup & Sync, Notifications, and other services.\n */\nexport class AuthenticationController extends BaseController<\n typeof controllerName,\n AuthenticationControllerState,\n AuthenticationControllerMessenger\n> {\n readonly #metametrics: MetaMetricsAuth;\n\n readonly #auth: SRPInterface;\n\n readonly #config: ControllerConfig = {\n env: Env.PRD,\n };\n\n #isUnlocked = false;\n\n #cachedPrimaryEntropySourceId?: string;\n\n readonly #keyringController = {\n setupLockedStateSubscriptions: () => {\n const { isUnlocked } = this.messenger.call('KeyringController:getState');\n this.#isUnlocked = isUnlocked;\n\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n });\n\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n });\n },\n };\n\n constructor({\n messenger,\n state,\n config,\n metametrics,\n }: {\n messenger: AuthenticationControllerMessenger;\n state?: AuthenticationControllerState;\n config?: Partial<ControllerConfig>;\n /**\n * Not using the Messaging System as we\n * do not want to tie this strictly to extension\n */\n metametrics: MetaMetricsAuth;\n }) {\n super({\n messenger,\n metadata,\n name: controllerName,\n state: { ...defaultState, ...state },\n });\n\n if (!metametrics) {\n throw new Error('`metametrics` field is required');\n }\n\n this.#config = {\n ...this.#config,\n ...config,\n };\n\n this.#metametrics = metametrics;\n\n this.#auth = new JwtBearerAuth(\n {\n env: this.#config.env,\n platform: metametrics.agent,\n type: AuthType.SRP,\n },\n {\n storage: {\n getLoginResponse: this.#getLoginResponseFromState.bind(this),\n setLoginResponse: this.#setLoginResponseToState.bind(this),\n },\n signing: {\n getIdentifier: this.#snapGetPublicKey.bind(this),\n signMessage: this.#snapSignMessage.bind(this),\n },\n metametrics: this.#metametrics,\n },\n );\n\n this.#keyringController.setupLockedStateSubscriptions();\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n async #getLoginResponseFromState(\n entropySourceId?: string,\n ): Promise<LoginResponse | null> {\n const resolvedId =\n entropySourceId ?? (await this.#getPrimaryEntropySourceId());\n if (!this.state.srpSessionData?.[resolvedId]) {\n return null;\n }\n return this.state.srpSessionData[resolvedId];\n }\n\n async #setLoginResponseToState(\n loginResponse: LoginResponse,\n entropySourceId?: string,\n ) {\n const resolvedId =\n entropySourceId ?? (await this.#getPrimaryEntropySourceId());\n const metaMetricsId = await this.#metametrics.getMetaMetricsId();\n this.update((state) => {\n state.isSignedIn = true;\n if (!state.srpSessionData) {\n state.srpSessionData = {};\n }\n state.srpSessionData[resolvedId] = {\n ...loginResponse,\n profile: {\n ...loginResponse.profile,\n metaMetricsId,\n },\n };\n });\n }\n\n #assertIsUnlocked(methodName: string): void {\n if (!this.#isUnlocked) {\n throw new Error(`${methodName} - unable to proceed, wallet is locked`);\n }\n }\n\n async #getPrimaryEntropySourceId(): Promise<string> {\n if (this.#cachedPrimaryEntropySourceId) {\n return this.#cachedPrimaryEntropySourceId;\n }\n const allPublicKeys = await this.#snapGetAllPublicKeys();\n\n if (allPublicKeys.length === 0) {\n throw new Error(\n '#getPrimaryEntropySourceId - No entropy sources found from snap',\n );\n }\n\n const primaryId = allPublicKeys[0][0];\n if (!primaryId) {\n throw new Error(\n '#getPrimaryEntropySourceId - Primary entropy source ID is undefined',\n );\n }\n\n this.#cachedPrimaryEntropySourceId = primaryId;\n return this.#cachedPrimaryEntropySourceId;\n }\n\n public async performSignIn(): Promise<string[]> {\n this.#assertIsUnlocked('performSignIn');\n\n const allPublicKeys = await this.#snapGetAllPublicKeys();\n const accessTokens = [];\n\n // We iterate sequentially in order to be sure that the first entry\n // is the primary SRP LoginResponse.\n for (const [entropySourceId] of allPublicKeys) {\n const accessToken = await this.#auth.getAccessToken(entropySourceId);\n accessTokens.push(accessToken);\n }\n\n return accessTokens;\n }\n\n public performSignOut(): void {\n this.#cachedPrimaryEntropySourceId = undefined;\n this.update((state) => {\n state.isSignedIn = false;\n state.srpSessionData = undefined;\n });\n }\n\n /**\n * Will return a bearer token.\n * Logs a user in if a user is not logged in.\n *\n * @returns profile for the session.\n */\n\n public async getBearerToken(entropySourceId?: string): Promise<string> {\n this.#assertIsUnlocked('getBearerToken');\n const resolvedId =\n entropySourceId ?? (await this.#getPrimaryEntropySourceId());\n return await this.#auth.getAccessToken(resolvedId);\n }\n\n /**\n * Will return a session profile.\n * Logs a user in if a user is not logged in.\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 */\n public async getSessionProfile(\n entropySourceId?: string,\n ): Promise<UserProfile> {\n this.#assertIsUnlocked('getSessionProfile');\n const resolvedId =\n entropySourceId ?? (await this.#getPrimaryEntropySourceId());\n return await this.#auth.getUserProfile(resolvedId);\n }\n\n public async getUserProfileLineage(\n entropySourceId?: string,\n ): Promise<UserProfileLineage> {\n this.#assertIsUnlocked('getUserProfileLineage');\n const resolvedId =\n entropySourceId ?? (await this.#getPrimaryEntropySourceId());\n return await this.#auth.getUserProfileLineage(resolvedId);\n }\n\n public isSignedIn(): boolean {\n return this.state.isSignedIn;\n }\n\n /**\n * Returns the auth snap public key.\n *\n * @param entropySourceId - The entropy source ID used to derive the key,\n * when multiple sources are available (Multi-SRP).\n * @returns The snap public key.\n */\n async #snapGetPublicKey(entropySourceId?: string): Promise<string> {\n this.#assertIsUnlocked('#snapGetPublicKey');\n\n const result = (await this.messenger.call(\n 'SnapController:handleRequest',\n createSnapPublicKeyRequest(entropySourceId),\n )) as string;\n\n return result;\n }\n\n /**\n * Returns a mapping of entropy source IDs to auth snap public keys.\n *\n * @returns A mapping of entropy source IDs to public keys.\n */\n async #snapGetAllPublicKeys(): Promise<[string, string][]> {\n this.#assertIsUnlocked('#snapGetAllPublicKeys');\n\n const result = (await this.messenger.call(\n 'SnapController:handleRequest',\n createSnapAllPublicKeysRequest(),\n )) as [string, string][];\n\n return result;\n }\n\n #_snapSignMessageCache: Record<`metamask:${string}`, string> = {};\n\n /**\n * Signs a specific message using an underlying auth snap.\n *\n * @param message - A specific tagged message to sign.\n * @param entropySourceId - The entropy source ID used to derive the key,\n * when multiple sources are available (Multi-SRP).\n * @returns A Signature created by the snap.\n */\n async #snapSignMessage(\n message: string,\n entropySourceId?: string,\n ): Promise<string> {\n assertMessageStartsWithMetamask(message);\n\n if (this.#_snapSignMessageCache[message]) {\n return this.#_snapSignMessageCache[message];\n }\n\n this.#assertIsUnlocked('#snapSignMessage');\n\n const result = (await this.messenger.call(\n 'SnapController:handleRequest',\n createSnapSignMessageRequest(message, entropySourceId),\n )) as string;\n\n this.#_snapSignMessageCache[message] = result;\n\n return result;\n }\n}\n"]}
|
|
@@ -21,18 +21,9 @@ export declare const MOCK_LOGIN_RESPONSE: {
|
|
|
21
21
|
profile_id: string;
|
|
22
22
|
metametrics_id: string;
|
|
23
23
|
identifier_id: string;
|
|
24
|
-
/**
|
|
25
|
-
* Wraps a plain-text identifier in a minimal JWT so that client-side
|
|
26
|
-
* JWT validation (exp check) passes in E2E tests. The identifier is
|
|
27
|
-
* stored in the `sub` claim and can be extracted via {@link getE2EIdentifierFromJwt}.
|
|
28
|
-
*
|
|
29
|
-
* @param identifier - The plain-text E2E identifier to wrap.
|
|
30
|
-
* @returns A JWT-shaped string containing the identifier.
|
|
31
|
-
*/
|
|
32
24
|
identifier_type: string;
|
|
33
25
|
encrypted_storage_key: string;
|
|
34
26
|
};
|
|
35
|
-
profile_aliases: never[];
|
|
36
27
|
};
|
|
37
28
|
export declare const getMockAuthLoginResponse: () => {
|
|
38
29
|
url: string;
|
|
@@ -45,19 +36,10 @@ export declare const getMockAuthLoginResponse: () => {
|
|
|
45
36
|
profile_id: string;
|
|
46
37
|
identifier_id: string;
|
|
47
38
|
metametrics_id: string;
|
|
48
|
-
/**
|
|
49
|
-
* Wraps a plain-text identifier in a minimal JWT so that client-side
|
|
50
|
-
* JWT validation (exp check) passes in E2E tests. The identifier is
|
|
51
|
-
* stored in the `sub` claim and can be extracted via {@link getE2EIdentifierFromJwt}.
|
|
52
|
-
*
|
|
53
|
-
* @param identifier - The plain-text E2E identifier to wrap.
|
|
54
|
-
* @returns A JWT-shaped string containing the identifier.
|
|
55
|
-
*/
|
|
56
39
|
identifier_type: string;
|
|
57
40
|
encrypted_storage_key: string;
|
|
58
41
|
};
|
|
59
42
|
expires_in: number;
|
|
60
|
-
profile_aliases: never[];
|
|
61
43
|
};
|
|
62
44
|
};
|
|
63
45
|
export declare const MOCK_OATH_TOKEN_RESPONSE: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockResponses.d.cts","sourceRoot":"","sources":["../../../../src/controllers/authentication/mocks/mockResponses.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,mBAAmB;;;;CAA0B,CAAC;AAC3D,eAAO,MAAM,UAAU,QAA4B,CAAC;AACpD,eAAO,MAAM,QAAQ,upBAAe,CAAC;AAErC,eAAO,MAAM,wBAAwB;;;mBAK3B,OAAO,SACJ,MAAM,iDACiC,MAAM,KAAK,MAAM;;;;;CAcpE,CAAC;AAEF,eAAO,MAAM,mBAAmB
|
|
1
|
+
{"version":3,"file":"mockResponses.d.cts","sourceRoot":"","sources":["../../../../src/controllers/authentication/mocks/mockResponses.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,mBAAmB;;;;CAA0B,CAAC;AAC3D,eAAO,MAAM,UAAU,QAA4B,CAAC;AACpD,eAAO,MAAM,QAAQ,upBAAe,CAAC;AAErC,eAAO,MAAM,wBAAwB;;;mBAK3B,OAAO,SACJ,MAAM,iDACiC,MAAM,KAAK,MAAM;;;;;CAcpE,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;CAA8B,CAAC;AAE/D,eAAO,MAAM,wBAAwB;;;iCAMJ;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;CAgBvD,CAAC;AAEF,eAAO,MAAM,wBAAwB;;;CAA+B,CAAC;AAoBrE;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,UAAW,MAAM,KAAG,MAavD,CAAC;AAEF,eAAO,MAAM,8BAA8B;;;iCAIV,MAAM;;;;CAetC,CAAC"}
|
|
@@ -21,18 +21,9 @@ export declare const MOCK_LOGIN_RESPONSE: {
|
|
|
21
21
|
profile_id: string;
|
|
22
22
|
metametrics_id: string;
|
|
23
23
|
identifier_id: string;
|
|
24
|
-
/**
|
|
25
|
-
* Wraps a plain-text identifier in a minimal JWT so that client-side
|
|
26
|
-
* JWT validation (exp check) passes in E2E tests. The identifier is
|
|
27
|
-
* stored in the `sub` claim and can be extracted via {@link getE2EIdentifierFromJwt}.
|
|
28
|
-
*
|
|
29
|
-
* @param identifier - The plain-text E2E identifier to wrap.
|
|
30
|
-
* @returns A JWT-shaped string containing the identifier.
|
|
31
|
-
*/
|
|
32
24
|
identifier_type: string;
|
|
33
25
|
encrypted_storage_key: string;
|
|
34
26
|
};
|
|
35
|
-
profile_aliases: never[];
|
|
36
27
|
};
|
|
37
28
|
export declare const getMockAuthLoginResponse: () => {
|
|
38
29
|
url: string;
|
|
@@ -45,19 +36,10 @@ export declare const getMockAuthLoginResponse: () => {
|
|
|
45
36
|
profile_id: string;
|
|
46
37
|
identifier_id: string;
|
|
47
38
|
metametrics_id: string;
|
|
48
|
-
/**
|
|
49
|
-
* Wraps a plain-text identifier in a minimal JWT so that client-side
|
|
50
|
-
* JWT validation (exp check) passes in E2E tests. The identifier is
|
|
51
|
-
* stored in the `sub` claim and can be extracted via {@link getE2EIdentifierFromJwt}.
|
|
52
|
-
*
|
|
53
|
-
* @param identifier - The plain-text E2E identifier to wrap.
|
|
54
|
-
* @returns A JWT-shaped string containing the identifier.
|
|
55
|
-
*/
|
|
56
39
|
identifier_type: string;
|
|
57
40
|
encrypted_storage_key: string;
|
|
58
41
|
};
|
|
59
42
|
expires_in: number;
|
|
60
|
-
profile_aliases: never[];
|
|
61
43
|
};
|
|
62
44
|
};
|
|
63
45
|
export declare const MOCK_OATH_TOKEN_RESPONSE: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockResponses.d.mts","sourceRoot":"","sources":["../../../../src/controllers/authentication/mocks/mockResponses.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,mBAAmB;;;;CAA0B,CAAC;AAC3D,eAAO,MAAM,UAAU,QAA4B,CAAC;AACpD,eAAO,MAAM,QAAQ,upBAAe,CAAC;AAErC,eAAO,MAAM,wBAAwB;;;mBAK3B,OAAO,SACJ,MAAM,iDACiC,MAAM,KAAK,MAAM;;;;;CAcpE,CAAC;AAEF,eAAO,MAAM,mBAAmB
|
|
1
|
+
{"version":3,"file":"mockResponses.d.mts","sourceRoot":"","sources":["../../../../src/controllers/authentication/mocks/mockResponses.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,mBAAmB;;;;CAA0B,CAAC;AAC3D,eAAO,MAAM,UAAU,QAA4B,CAAC;AACpD,eAAO,MAAM,QAAQ,upBAAe,CAAC;AAErC,eAAO,MAAM,wBAAwB;;;mBAK3B,OAAO,SACJ,MAAM,iDACiC,MAAM,KAAK,MAAM;;;;;CAcpE,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;CAA8B,CAAC;AAE/D,eAAO,MAAM,wBAAwB;;;iCAMJ;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;CAgBvD,CAAC;AAEF,eAAO,MAAM,wBAAwB;;;CAA+B,CAAC;AAoBrE;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,UAAW,MAAM,KAAG,MAavD,CAAC;AAEF,eAAO,MAAM,8BAA8B;;;iCAIV,MAAM;;;;CAetC,CAAC"}
|
|
@@ -41,7 +41,6 @@ const eip_6963_metamask_provider_1 = require("../utils/eip-6963-metamask-provide
|
|
|
41
41
|
const messaging_signing_snap_requests_1 = require("../utils/messaging-signing-snap-requests.cjs");
|
|
42
42
|
const validate_login_response_1 = require("../utils/validate-login-response.cjs");
|
|
43
43
|
const services_1 = require("./services.cjs");
|
|
44
|
-
const identifier_1 = require("./utils/identifier.cjs");
|
|
45
44
|
const timeUtils = __importStar(require("./utils/time.cjs"));
|
|
46
45
|
const getDefaultEIP6963Provider = async () => {
|
|
47
46
|
const provider = await (0, eip_6963_metamask_provider_1.getMetaMaskProviderEIP6963)();
|
|
@@ -114,9 +113,6 @@ class SRPJwtBearerAuth {
|
|
|
114
113
|
const accessToken = await this.getAccessToken(entropySourceId);
|
|
115
114
|
return await (0, services_1.getUserProfileLineage)(__classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").env, accessToken);
|
|
116
115
|
}
|
|
117
|
-
async pairSrpProfiles(accessTokens, authAccessToken) {
|
|
118
|
-
return await (0, services_1.pairProfiles)(accessTokens, authAccessToken, __classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").env);
|
|
119
|
-
}
|
|
120
116
|
async signMessage(message, entropySourceId) {
|
|
121
117
|
return await __classPrivateFieldGet(this, _SRPJwtBearerAuth_options, "f").signing.signMessage(message, entropySourceId);
|
|
122
118
|
}
|
|
@@ -160,24 +156,11 @@ async function _SRPJwtBearerAuth_getAuthSession(entropySourceId) {
|
|
|
160
156
|
const signature = await this.signMessage(rawMessage, entropySourceId);
|
|
161
157
|
// Authenticate
|
|
162
158
|
const authResponse = await (0, services_1.authenticate)(rawMessage, signature, __classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").type, __classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").env, __classPrivateFieldGet(this, _SRPJwtBearerAuth_metametrics, "f"));
|
|
163
|
-
// Resolve original profileId from aliases.
|
|
164
|
-
// This is done mainly to preserve the original profileId for storage key derivation
|
|
165
|
-
// until we migrate to the canonical profileId storage system.
|
|
166
|
-
const canonicalProfileId = authResponse.profile.profileId;
|
|
167
|
-
const profile = { ...authResponse.profile };
|
|
168
|
-
if (authResponse.profileAliases?.length > 0) {
|
|
169
|
-
const targetIdentifierId = (0, identifier_1.computeIdentifierId)(publicKey, __classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").env);
|
|
170
|
-
const targetAlias = authResponse.profileAliases.find((alias) => alias.identifierIds.some((id) => id.id === targetIdentifierId));
|
|
171
|
-
if (targetAlias) {
|
|
172
|
-
profile.profileId = targetAlias.aliasProfileId;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
profile.canonicalProfileId = canonicalProfileId;
|
|
176
159
|
// Authorize
|
|
177
160
|
const tokenResponse = await (0, services_1.authorizeOIDC)(authResponse.token, __classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").env, __classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").platform);
|
|
178
161
|
// Save
|
|
179
162
|
const result = {
|
|
180
|
-
profile,
|
|
163
|
+
profile: authResponse.profile,
|
|
181
164
|
token: tokenResponse,
|
|
182
165
|
};
|
|
183
166
|
await __classPrivateFieldGet(this, _SRPJwtBearerAuth_options, "f").storage.setLoginResponse(result, entropySourceId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow-srp.cjs","sourceRoot":"","sources":["../../../src/sdk/authentication-jwt-bearer/flow-srp.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Eip1193Provider } from 'ethers';\n\nimport type { MetaMetricsAuth } from '../../shared/types/services';\nimport { ValidationError, RateLimitedError } from '../errors';\nimport { getMetaMaskProviderEIP6963 } from '../utils/eip-6963-metamask-provider';\nimport {\n MESSAGE_SIGNING_SNAP,\n assertMessageStartsWithMetamask,\n connectSnap,\n isSnapConnected,\n} from '../utils/messaging-signing-snap-requests';\nimport { validateLoginResponse } from '../utils/validate-login-response';\nimport {\n authenticate,\n authorizeOIDC,\n getNonce,\n getUserProfileLineage,\n pairProfiles,\n} from './services';\nimport type { PairProfilesResponse } from './services';\nimport type {\n AuthConfig,\n AuthSigningOptions,\n AuthStorageOptions,\n AuthType,\n IBaseAuth,\n LoginResponse,\n UserProfile,\n UserProfileLineage,\n} from './types';\nimport { computeIdentifierId } from './utils/identifier';\nimport * as timeUtils from './utils/time';\n\ntype JwtBearerAuth_SRP_Options = {\n storage: AuthStorageOptions;\n signing?: AuthSigningOptions;\n rateLimitRetry?: {\n cooldownDefaultMs?: number; // default cooldown when 429 has no Retry-After\n maxLoginRetries?: number; // maximum number of login retries on rate limit\n };\n};\n\nconst getDefaultEIP6963Provider = async () => {\n const provider = await getMetaMaskProviderEIP6963();\n if (!provider) {\n throw new ValidationError('No MetaMask wallet connected');\n }\n return provider;\n};\n\nconst getDefaultEIP6963SigningOptions = (\n customProvider?: Eip1193Provider,\n): AuthSigningOptions => ({\n getIdentifier: async (entropySourceId?: string): Promise<string> => {\n const provider = customProvider ?? (await getDefaultEIP6963Provider());\n return await MESSAGE_SIGNING_SNAP.getPublicKey(provider, entropySourceId);\n },\n signMessage: async (\n message: string,\n entropySourceId?: string,\n ): Promise<string> => {\n const provider = customProvider ?? (await getDefaultEIP6963Provider());\n assertMessageStartsWithMetamask(message);\n return await MESSAGE_SIGNING_SNAP.signMessage(\n provider,\n message,\n entropySourceId,\n );\n },\n});\n\nexport class SRPJwtBearerAuth implements IBaseAuth {\n readonly #config: AuthConfig;\n\n readonly #options: {\n storage: AuthStorageOptions;\n signing: AuthSigningOptions;\n };\n\n readonly #metametrics?: MetaMetricsAuth;\n\n // Map to store ongoing login promises by entropySourceId\n readonly #ongoingLogins = new Map<\n string | undefined,\n Promise<LoginResponse>\n >();\n\n // Default cooldown when 429 has no Retry-After header\n readonly #cooldownDefaultMs: number;\n\n // Maximum number of login retries on rate limit errors\n readonly #maxLoginRetries: number;\n\n #customProvider?: Eip1193Provider;\n\n constructor(\n config: AuthConfig & { type: AuthType.SRP },\n options: JwtBearerAuth_SRP_Options & {\n customProvider?: Eip1193Provider;\n metametrics?: MetaMetricsAuth;\n },\n ) {\n this.#config = config;\n this.#customProvider = options.customProvider;\n this.#options = {\n storage: options.storage,\n signing:\n options.signing ??\n getDefaultEIP6963SigningOptions(this.#customProvider),\n };\n this.#metametrics = options.metametrics;\n\n // Apply rate limit retry config if provided\n this.#cooldownDefaultMs =\n options.rateLimitRetry?.cooldownDefaultMs ?? 10000;\n this.#maxLoginRetries = options.rateLimitRetry?.maxLoginRetries ?? 1;\n }\n\n setCustomProvider(provider: Eip1193Provider) {\n this.#customProvider = provider;\n this.#options.signing = getDefaultEIP6963SigningOptions(provider);\n }\n\n // TODO: might be easier to keep entropySourceId as a class param and use multiple SRPJwtBearerAuth instances where needed\n async getAccessToken(entropySourceId?: string): Promise<string> {\n const session = await this.#getAuthSession(entropySourceId);\n if (session) {\n return session.token.accessToken;\n }\n\n const loginResponse = await this.#login(entropySourceId);\n return loginResponse.token.accessToken;\n }\n\n async getUserProfile(entropySourceId?: string): Promise<UserProfile> {\n const session = await this.#getAuthSession(entropySourceId);\n if (session) {\n return session.profile;\n }\n\n const loginResponse = await this.#login(entropySourceId);\n return loginResponse.profile;\n }\n\n async getIdentifier(entropySourceId?: string): Promise<string> {\n return await this.#options.signing.getIdentifier(entropySourceId);\n }\n\n async getUserProfileLineage(\n entropySourceId?: string,\n ): Promise<UserProfileLineage> {\n const accessToken = await this.getAccessToken(entropySourceId);\n return await getUserProfileLineage(this.#config.env, accessToken);\n }\n\n async pairSrpProfiles(\n accessTokens: string[],\n authAccessToken: string,\n ): Promise<PairProfilesResponse> {\n return await pairProfiles(accessTokens, authAccessToken, this.#config.env);\n }\n\n async signMessage(\n message: string,\n entropySourceId?: string,\n ): Promise<string> {\n return await this.#options.signing.signMessage(message, entropySourceId);\n }\n\n async isSnapConnected(): Promise<boolean> {\n const provider =\n this.#customProvider ?? (await getDefaultEIP6963Provider());\n if (!provider) {\n return false;\n }\n\n const isConnected = await isSnapConnected(provider);\n return isConnected;\n }\n\n async connectSnap(): Promise<string> {\n const provider =\n this.#customProvider ?? (await getDefaultEIP6963Provider());\n\n const res = await connectSnap(provider);\n return res;\n }\n\n // convert expiresIn from seconds to milliseconds and use 90% of expiresIn\n async #getAuthSession(\n entropySourceId?: string,\n ): Promise<LoginResponse | null> {\n const auth = await this.#options.storage.getLoginResponse(entropySourceId);\n if (!validateLoginResponse(auth)) {\n return null;\n }\n\n const currentTime = Date.now();\n const sessionAge = currentTime - auth.token.obtainedAt;\n const refreshThreshold = auth.token.expiresIn * 1000 * 0.9;\n\n if (sessionAge < refreshThreshold) {\n return auth;\n }\n return null;\n }\n\n async #login(entropySourceId?: string): Promise<LoginResponse> {\n // Use a deferred login to avoid race conditions\n return await this.#deferredLogin(entropySourceId);\n }\n\n async #performLogin(entropySourceId?: string): Promise<LoginResponse> {\n // Nonce\n const publicKey = await this.getIdentifier(entropySourceId);\n const nonceRes = await getNonce(publicKey, this.#config.env);\n\n const rawMessage = this.#createSrpLoginRawMessage(\n nonceRes.nonce,\n publicKey,\n );\n const signature = await this.signMessage(rawMessage, entropySourceId);\n\n // Authenticate\n const authResponse = await authenticate(\n rawMessage,\n signature,\n this.#config.type,\n this.#config.env,\n this.#metametrics,\n );\n\n // Resolve original profileId from aliases.\n // This is done mainly to preserve the original profileId for storage key derivation\n // until we migrate to the canonical profileId storage system.\n const canonicalProfileId = authResponse.profile.profileId;\n const profile = { ...authResponse.profile };\n\n if (authResponse.profileAliases?.length > 0) {\n const targetIdentifierId = computeIdentifierId(\n publicKey,\n this.#config.env,\n );\n\n const targetAlias = authResponse.profileAliases.find((alias) =>\n alias.identifierIds.some((id) => id.id === targetIdentifierId),\n );\n\n if (targetAlias) {\n profile.profileId = targetAlias.aliasProfileId;\n }\n }\n\n profile.canonicalProfileId = canonicalProfileId;\n\n // Authorize\n const tokenResponse = await authorizeOIDC(\n authResponse.token,\n this.#config.env,\n this.#config.platform,\n );\n\n // Save\n const result: LoginResponse = {\n profile,\n token: tokenResponse,\n };\n\n await this.#options.storage.setLoginResponse(result, entropySourceId);\n\n return result;\n }\n\n async #deferredLogin(entropySourceId?: string): Promise<LoginResponse> {\n // Check if there's already an ongoing login for this entropySourceId\n const existingLogin = this.#ongoingLogins.get(entropySourceId);\n if (existingLogin) {\n return existingLogin;\n }\n\n // Create a new login promise\n const loginPromise = this.#loginWithRetry(entropySourceId);\n\n // Store the promise in the map\n this.#ongoingLogins.set(entropySourceId, loginPromise);\n\n try {\n // Wait for the login to complete\n return await loginPromise;\n } finally {\n // Always clean up the ongoing login promise when done\n this.#ongoingLogins.delete(entropySourceId);\n }\n }\n\n async #loginWithRetry(entropySourceId?: string): Promise<LoginResponse> {\n // Allow max attempts: initial + maxLoginRetries on 429\n for (let attempt = 0; attempt < 1 + this.#maxLoginRetries; attempt += 1) {\n try {\n return await this.#performLogin(entropySourceId);\n } catch (e) {\n // Only retry on rate-limit (429) errors\n if (!RateLimitedError.isRateLimitError(e)) {\n throw e;\n }\n\n // If we've exhausted attempts, rethrow\n if (attempt >= this.#maxLoginRetries) {\n throw e;\n }\n\n // Wait for Retry-After or default cooldown\n const waitMs = e.retryAfterMs ?? this.#cooldownDefaultMs;\n await timeUtils.delay(waitMs);\n\n // Loop continues to retry\n }\n }\n\n // Should never reach here due to loop logic, but TypeScript needs a return\n throw new Error('Unexpected: login loop exhausted without result');\n }\n\n #createSrpLoginRawMessage(\n nonce: string,\n publicKey: string,\n ): `metamask:${string}:${string}` {\n return `metamask:${nonce}:${publicKey}` as const;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"flow-srp.cjs","sourceRoot":"","sources":["../../../src/sdk/authentication-jwt-bearer/flow-srp.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Eip1193Provider } from 'ethers';\n\nimport type { MetaMetricsAuth } from '../../shared/types/services';\nimport { ValidationError, RateLimitedError } from '../errors';\nimport { getMetaMaskProviderEIP6963 } from '../utils/eip-6963-metamask-provider';\nimport {\n MESSAGE_SIGNING_SNAP,\n assertMessageStartsWithMetamask,\n connectSnap,\n isSnapConnected,\n} from '../utils/messaging-signing-snap-requests';\nimport { validateLoginResponse } from '../utils/validate-login-response';\nimport {\n authenticate,\n authorizeOIDC,\n getNonce,\n getUserProfileLineage,\n} from './services';\nimport type {\n AuthConfig,\n AuthSigningOptions,\n AuthStorageOptions,\n AuthType,\n IBaseAuth,\n LoginResponse,\n UserProfile,\n UserProfileLineage,\n} from './types';\nimport * as timeUtils from './utils/time';\n\ntype JwtBearerAuth_SRP_Options = {\n storage: AuthStorageOptions;\n signing?: AuthSigningOptions;\n rateLimitRetry?: {\n cooldownDefaultMs?: number; // default cooldown when 429 has no Retry-After\n maxLoginRetries?: number; // maximum number of login retries on rate limit\n };\n};\n\nconst getDefaultEIP6963Provider = async () => {\n const provider = await getMetaMaskProviderEIP6963();\n if (!provider) {\n throw new ValidationError('No MetaMask wallet connected');\n }\n return provider;\n};\n\nconst getDefaultEIP6963SigningOptions = (\n customProvider?: Eip1193Provider,\n): AuthSigningOptions => ({\n getIdentifier: async (entropySourceId?: string): Promise<string> => {\n const provider = customProvider ?? (await getDefaultEIP6963Provider());\n return await MESSAGE_SIGNING_SNAP.getPublicKey(provider, entropySourceId);\n },\n signMessage: async (\n message: string,\n entropySourceId?: string,\n ): Promise<string> => {\n const provider = customProvider ?? (await getDefaultEIP6963Provider());\n assertMessageStartsWithMetamask(message);\n return await MESSAGE_SIGNING_SNAP.signMessage(\n provider,\n message,\n entropySourceId,\n );\n },\n});\n\nexport class SRPJwtBearerAuth implements IBaseAuth {\n readonly #config: AuthConfig;\n\n readonly #options: {\n storage: AuthStorageOptions;\n signing: AuthSigningOptions;\n };\n\n readonly #metametrics?: MetaMetricsAuth;\n\n // Map to store ongoing login promises by entropySourceId\n readonly #ongoingLogins = new Map<\n string | undefined,\n Promise<LoginResponse>\n >();\n\n // Default cooldown when 429 has no Retry-After header\n readonly #cooldownDefaultMs: number;\n\n // Maximum number of login retries on rate limit errors\n readonly #maxLoginRetries: number;\n\n #customProvider?: Eip1193Provider;\n\n constructor(\n config: AuthConfig & { type: AuthType.SRP },\n options: JwtBearerAuth_SRP_Options & {\n customProvider?: Eip1193Provider;\n metametrics?: MetaMetricsAuth;\n },\n ) {\n this.#config = config;\n this.#customProvider = options.customProvider;\n this.#options = {\n storage: options.storage,\n signing:\n options.signing ??\n getDefaultEIP6963SigningOptions(this.#customProvider),\n };\n this.#metametrics = options.metametrics;\n\n // Apply rate limit retry config if provided\n this.#cooldownDefaultMs =\n options.rateLimitRetry?.cooldownDefaultMs ?? 10000;\n this.#maxLoginRetries = options.rateLimitRetry?.maxLoginRetries ?? 1;\n }\n\n setCustomProvider(provider: Eip1193Provider) {\n this.#customProvider = provider;\n this.#options.signing = getDefaultEIP6963SigningOptions(provider);\n }\n\n // TODO: might be easier to keep entropySourceId as a class param and use multiple SRPJwtBearerAuth instances where needed\n async getAccessToken(entropySourceId?: string): Promise<string> {\n const session = await this.#getAuthSession(entropySourceId);\n if (session) {\n return session.token.accessToken;\n }\n\n const loginResponse = await this.#login(entropySourceId);\n return loginResponse.token.accessToken;\n }\n\n async getUserProfile(entropySourceId?: string): Promise<UserProfile> {\n const session = await this.#getAuthSession(entropySourceId);\n if (session) {\n return session.profile;\n }\n\n const loginResponse = await this.#login(entropySourceId);\n return loginResponse.profile;\n }\n\n async getIdentifier(entropySourceId?: string): Promise<string> {\n return await this.#options.signing.getIdentifier(entropySourceId);\n }\n\n async getUserProfileLineage(\n entropySourceId?: string,\n ): Promise<UserProfileLineage> {\n const accessToken = await this.getAccessToken(entropySourceId);\n return await getUserProfileLineage(this.#config.env, accessToken);\n }\n\n async signMessage(\n message: string,\n entropySourceId?: string,\n ): Promise<string> {\n return await this.#options.signing.signMessage(message, entropySourceId);\n }\n\n async isSnapConnected(): Promise<boolean> {\n const provider =\n this.#customProvider ?? (await getDefaultEIP6963Provider());\n if (!provider) {\n return false;\n }\n\n const isConnected = await isSnapConnected(provider);\n return isConnected;\n }\n\n async connectSnap(): Promise<string> {\n const provider =\n this.#customProvider ?? (await getDefaultEIP6963Provider());\n\n const res = await connectSnap(provider);\n return res;\n }\n\n // convert expiresIn from seconds to milliseconds and use 90% of expiresIn\n async #getAuthSession(\n entropySourceId?: string,\n ): Promise<LoginResponse | null> {\n const auth = await this.#options.storage.getLoginResponse(entropySourceId);\n if (!validateLoginResponse(auth)) {\n return null;\n }\n\n const currentTime = Date.now();\n const sessionAge = currentTime - auth.token.obtainedAt;\n const refreshThreshold = auth.token.expiresIn * 1000 * 0.9;\n\n if (sessionAge < refreshThreshold) {\n return auth;\n }\n return null;\n }\n\n async #login(entropySourceId?: string): Promise<LoginResponse> {\n // Use a deferred login to avoid race conditions\n return await this.#deferredLogin(entropySourceId);\n }\n\n async #performLogin(entropySourceId?: string): Promise<LoginResponse> {\n // Nonce\n const publicKey = await this.getIdentifier(entropySourceId);\n const nonceRes = await getNonce(publicKey, this.#config.env);\n\n const rawMessage = this.#createSrpLoginRawMessage(\n nonceRes.nonce,\n publicKey,\n );\n const signature = await this.signMessage(rawMessage, entropySourceId);\n\n // Authenticate\n const authResponse = await authenticate(\n rawMessage,\n signature,\n this.#config.type,\n this.#config.env,\n this.#metametrics,\n );\n\n // Authorize\n const tokenResponse = await authorizeOIDC(\n authResponse.token,\n this.#config.env,\n this.#config.platform,\n );\n\n // Save\n const result: LoginResponse = {\n profile: authResponse.profile,\n token: tokenResponse,\n };\n\n await this.#options.storage.setLoginResponse(result, entropySourceId);\n\n return result;\n }\n\n async #deferredLogin(entropySourceId?: string): Promise<LoginResponse> {\n // Check if there's already an ongoing login for this entropySourceId\n const existingLogin = this.#ongoingLogins.get(entropySourceId);\n if (existingLogin) {\n return existingLogin;\n }\n\n // Create a new login promise\n const loginPromise = this.#loginWithRetry(entropySourceId);\n\n // Store the promise in the map\n this.#ongoingLogins.set(entropySourceId, loginPromise);\n\n try {\n // Wait for the login to complete\n return await loginPromise;\n } finally {\n // Always clean up the ongoing login promise when done\n this.#ongoingLogins.delete(entropySourceId);\n }\n }\n\n async #loginWithRetry(entropySourceId?: string): Promise<LoginResponse> {\n // Allow max attempts: initial + maxLoginRetries on 429\n for (let attempt = 0; attempt < 1 + this.#maxLoginRetries; attempt += 1) {\n try {\n return await this.#performLogin(entropySourceId);\n } catch (e) {\n // Only retry on rate-limit (429) errors\n if (!RateLimitedError.isRateLimitError(e)) {\n throw e;\n }\n\n // If we've exhausted attempts, rethrow\n if (attempt >= this.#maxLoginRetries) {\n throw e;\n }\n\n // Wait for Retry-After or default cooldown\n const waitMs = e.retryAfterMs ?? this.#cooldownDefaultMs;\n await timeUtils.delay(waitMs);\n\n // Loop continues to retry\n }\n }\n\n // Should never reach here due to loop logic, but TypeScript needs a return\n throw new Error('Unexpected: login loop exhausted without result');\n }\n\n #createSrpLoginRawMessage(\n nonce: string,\n publicKey: string,\n ): `metamask:${string}:${string}` {\n return `metamask:${nonce}:${publicKey}` as const;\n }\n}\n"]}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Eip1193Provider } from "ethers";
|
|
2
2
|
import type { MetaMetricsAuth } from "../../shared/types/services.cjs";
|
|
3
|
-
import type { PairProfilesResponse } from "./services.cjs";
|
|
4
3
|
import type { AuthConfig, AuthSigningOptions, AuthStorageOptions, AuthType, IBaseAuth, UserProfile, UserProfileLineage } from "./types.cjs";
|
|
5
4
|
type JwtBearerAuth_SRP_Options = {
|
|
6
5
|
storage: AuthStorageOptions;
|
|
@@ -23,7 +22,6 @@ export declare class SRPJwtBearerAuth implements IBaseAuth {
|
|
|
23
22
|
getUserProfile(entropySourceId?: string): Promise<UserProfile>;
|
|
24
23
|
getIdentifier(entropySourceId?: string): Promise<string>;
|
|
25
24
|
getUserProfileLineage(entropySourceId?: string): Promise<UserProfileLineage>;
|
|
26
|
-
pairSrpProfiles(accessTokens: string[], authAccessToken: string): Promise<PairProfilesResponse>;
|
|
27
25
|
signMessage(message: string, entropySourceId?: string): Promise<string>;
|
|
28
26
|
isSnapConnected(): Promise<boolean>;
|
|
29
27
|
connectSnap(): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow-srp.d.cts","sourceRoot":"","sources":["../../../src/sdk/authentication-jwt-bearer/flow-srp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe;AAE9C,OAAO,KAAK,EAAE,eAAe,EAAE,wCAAoC;
|
|
1
|
+
{"version":3,"file":"flow-srp.d.cts","sourceRoot":"","sources":["../../../src/sdk/authentication-jwt-bearer/flow-srp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe;AAE9C,OAAO,KAAK,EAAE,eAAe,EAAE,wCAAoC;AAgBnE,OAAO,KAAK,EACV,UAAU,EACV,kBAAkB,EAClB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EAET,WAAW,EACX,kBAAkB,EACnB,oBAAgB;AAGjB,KAAK,yBAAyB,GAAG;IAC/B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,cAAc,CAAC,EAAE;QACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH,CAAC;AA+BF,qBAAa,gBAAiB,YAAW,SAAS;;gBAyB9C,MAAM,EAAE,UAAU,GAAG;QAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAA;KAAE,EAC3C,OAAO,EAAE,yBAAyB,GAAG;QACnC,cAAc,CAAC,EAAE,eAAe,CAAC;QACjC,WAAW,CAAC,EAAE,eAAe,CAAC;KAC/B;IAkBH,iBAAiB,CAAC,QAAQ,EAAE,eAAe;IAMrC,cAAc,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUzD,cAAc,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAU9D,aAAa,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIxD,qBAAqB,CACzB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,kBAAkB,CAAC;IAKxB,WAAW,CACf,OAAO,EAAE,MAAM,EACf,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,CAAC;IAIZ,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAWnC,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;CA8HrC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Eip1193Provider } from "ethers";
|
|
2
2
|
import type { MetaMetricsAuth } from "../../shared/types/services.mjs";
|
|
3
|
-
import type { PairProfilesResponse } from "./services.mjs";
|
|
4
3
|
import type { AuthConfig, AuthSigningOptions, AuthStorageOptions, AuthType, IBaseAuth, UserProfile, UserProfileLineage } from "./types.mjs";
|
|
5
4
|
type JwtBearerAuth_SRP_Options = {
|
|
6
5
|
storage: AuthStorageOptions;
|
|
@@ -23,7 +22,6 @@ export declare class SRPJwtBearerAuth implements IBaseAuth {
|
|
|
23
22
|
getUserProfile(entropySourceId?: string): Promise<UserProfile>;
|
|
24
23
|
getIdentifier(entropySourceId?: string): Promise<string>;
|
|
25
24
|
getUserProfileLineage(entropySourceId?: string): Promise<UserProfileLineage>;
|
|
26
|
-
pairSrpProfiles(accessTokens: string[], authAccessToken: string): Promise<PairProfilesResponse>;
|
|
27
25
|
signMessage(message: string, entropySourceId?: string): Promise<string>;
|
|
28
26
|
isSnapConnected(): Promise<boolean>;
|
|
29
27
|
connectSnap(): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow-srp.d.mts","sourceRoot":"","sources":["../../../src/sdk/authentication-jwt-bearer/flow-srp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe;AAE9C,OAAO,KAAK,EAAE,eAAe,EAAE,wCAAoC;
|
|
1
|
+
{"version":3,"file":"flow-srp.d.mts","sourceRoot":"","sources":["../../../src/sdk/authentication-jwt-bearer/flow-srp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe;AAE9C,OAAO,KAAK,EAAE,eAAe,EAAE,wCAAoC;AAgBnE,OAAO,KAAK,EACV,UAAU,EACV,kBAAkB,EAClB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EAET,WAAW,EACX,kBAAkB,EACnB,oBAAgB;AAGjB,KAAK,yBAAyB,GAAG;IAC/B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,cAAc,CAAC,EAAE;QACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH,CAAC;AA+BF,qBAAa,gBAAiB,YAAW,SAAS;;gBAyB9C,MAAM,EAAE,UAAU,GAAG;QAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAA;KAAE,EAC3C,OAAO,EAAE,yBAAyB,GAAG;QACnC,cAAc,CAAC,EAAE,eAAe,CAAC;QACjC,WAAW,CAAC,EAAE,eAAe,CAAC;KAC/B;IAkBH,iBAAiB,CAAC,QAAQ,EAAE,eAAe;IAMrC,cAAc,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUzD,cAAc,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAU9D,aAAa,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIxD,qBAAqB,CACzB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,kBAAkB,CAAC;IAKxB,WAAW,CACf,OAAO,EAAE,MAAM,EACf,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,CAAC;IAIZ,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAWnC,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;CA8HrC"}
|
|
@@ -14,8 +14,7 @@ import { ValidationError, RateLimitedError } from "../errors.mjs";
|
|
|
14
14
|
import { getMetaMaskProviderEIP6963 } from "../utils/eip-6963-metamask-provider.mjs";
|
|
15
15
|
import { MESSAGE_SIGNING_SNAP, assertMessageStartsWithMetamask, connectSnap, isSnapConnected } from "../utils/messaging-signing-snap-requests.mjs";
|
|
16
16
|
import { validateLoginResponse } from "../utils/validate-login-response.mjs";
|
|
17
|
-
import { authenticate, authorizeOIDC, getNonce, getUserProfileLineage
|
|
18
|
-
import { computeIdentifierId } from "./utils/identifier.mjs";
|
|
17
|
+
import { authenticate, authorizeOIDC, getNonce, getUserProfileLineage } from "./services.mjs";
|
|
19
18
|
import * as timeUtils from "./utils/time.mjs";
|
|
20
19
|
const getDefaultEIP6963Provider = async () => {
|
|
21
20
|
const provider = await getMetaMaskProviderEIP6963();
|
|
@@ -88,9 +87,6 @@ export class SRPJwtBearerAuth {
|
|
|
88
87
|
const accessToken = await this.getAccessToken(entropySourceId);
|
|
89
88
|
return await getUserProfileLineage(__classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").env, accessToken);
|
|
90
89
|
}
|
|
91
|
-
async pairSrpProfiles(accessTokens, authAccessToken) {
|
|
92
|
-
return await pairProfiles(accessTokens, authAccessToken, __classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").env);
|
|
93
|
-
}
|
|
94
90
|
async signMessage(message, entropySourceId) {
|
|
95
91
|
return await __classPrivateFieldGet(this, _SRPJwtBearerAuth_options, "f").signing.signMessage(message, entropySourceId);
|
|
96
92
|
}
|
|
@@ -133,24 +129,11 @@ async function _SRPJwtBearerAuth_getAuthSession(entropySourceId) {
|
|
|
133
129
|
const signature = await this.signMessage(rawMessage, entropySourceId);
|
|
134
130
|
// Authenticate
|
|
135
131
|
const authResponse = await authenticate(rawMessage, signature, __classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").type, __classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").env, __classPrivateFieldGet(this, _SRPJwtBearerAuth_metametrics, "f"));
|
|
136
|
-
// Resolve original profileId from aliases.
|
|
137
|
-
// This is done mainly to preserve the original profileId for storage key derivation
|
|
138
|
-
// until we migrate to the canonical profileId storage system.
|
|
139
|
-
const canonicalProfileId = authResponse.profile.profileId;
|
|
140
|
-
const profile = { ...authResponse.profile };
|
|
141
|
-
if (authResponse.profileAliases?.length > 0) {
|
|
142
|
-
const targetIdentifierId = computeIdentifierId(publicKey, __classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").env);
|
|
143
|
-
const targetAlias = authResponse.profileAliases.find((alias) => alias.identifierIds.some((id) => id.id === targetIdentifierId));
|
|
144
|
-
if (targetAlias) {
|
|
145
|
-
profile.profileId = targetAlias.aliasProfileId;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
profile.canonicalProfileId = canonicalProfileId;
|
|
149
132
|
// Authorize
|
|
150
133
|
const tokenResponse = await authorizeOIDC(authResponse.token, __classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").env, __classPrivateFieldGet(this, _SRPJwtBearerAuth_config, "f").platform);
|
|
151
134
|
// Save
|
|
152
135
|
const result = {
|
|
153
|
-
profile,
|
|
136
|
+
profile: authResponse.profile,
|
|
154
137
|
token: tokenResponse,
|
|
155
138
|
};
|
|
156
139
|
await __classPrivateFieldGet(this, _SRPJwtBearerAuth_options, "f").storage.setLoginResponse(result, entropySourceId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow-srp.mjs","sourceRoot":"","sources":["../../../src/sdk/authentication-jwt-bearer/flow-srp.ts"],"names":[],"mappings":";;;;;;;;;;;;AAGA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,sBAAkB;AAC9D,OAAO,EAAE,0BAA0B,EAAE,gDAA4C;AACjF,OAAO,EACL,oBAAoB,EACpB,+BAA+B,EAC/B,WAAW,EACX,eAAe,EAChB,qDAAiD;AAClD,OAAO,EAAE,qBAAqB,EAAE,6CAAyC;AACzE,OAAO,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,qBAAqB,EACrB,YAAY,EACb,uBAAmB;AAYpB,OAAO,EAAE,mBAAmB,EAAE,+BAA2B;AACzD,OAAO,KAAK,SAAS,yBAAqB;AAW1C,MAAM,yBAAyB,GAAG,KAAK,IAAI,EAAE;IAC3C,MAAM,QAAQ,GAAG,MAAM,0BAA0B,EAAE,CAAC;IACpD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,eAAe,CAAC,8BAA8B,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,+BAA+B,GAAG,CACtC,cAAgC,EACZ,EAAE,CAAC,CAAC;IACxB,aAAa,EAAE,KAAK,EAAE,eAAwB,EAAmB,EAAE;QACjE,MAAM,QAAQ,GAAG,cAAc,IAAI,CAAC,MAAM,yBAAyB,EAAE,CAAC,CAAC;QACvE,OAAO,MAAM,oBAAoB,CAAC,YAAY,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAC5E,CAAC;IACD,WAAW,EAAE,KAAK,EAChB,OAAe,EACf,eAAwB,EACP,EAAE;QACnB,MAAM,QAAQ,GAAG,cAAc,IAAI,CAAC,MAAM,yBAAyB,EAAE,CAAC,CAAC;QACvE,+BAA+B,CAAC,OAAO,CAAC,CAAC;QACzC,OAAO,MAAM,oBAAoB,CAAC,WAAW,CAC3C,QAAQ,EACR,OAAO,EACP,eAAe,CAChB,CAAC;IACJ,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,OAAO,gBAAgB;IAwB3B,YACE,MAA2C,EAC3C,OAGC;;QA5BM,2CAAoB;QAEpB,4CAGP;QAEO,gDAA+B;QAExC,yDAAyD;QAChD,0CAAiB,IAAI,GAAG,EAG9B,EAAC;QAEJ,sDAAsD;QAC7C,sDAA2B;QAEpC,uDAAuD;QAC9C,oDAAyB;QAElC,mDAAkC;QAShC,uBAAA,IAAI,4BAAW,MAAM,MAAA,CAAC;QACtB,uBAAA,IAAI,oCAAmB,OAAO,CAAC,cAAc,MAAA,CAAC;QAC9C,uBAAA,IAAI,6BAAY;YACd,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EACL,OAAO,CAAC,OAAO;gBACf,+BAA+B,CAAC,uBAAA,IAAI,wCAAgB,CAAC;SACxD,MAAA,CAAC;QACF,uBAAA,IAAI,iCAAgB,OAAO,CAAC,WAAW,MAAA,CAAC;QAExC,4CAA4C;QAC5C,uBAAA,IAAI,uCACF,OAAO,CAAC,cAAc,EAAE,iBAAiB,IAAI,KAAK,MAAA,CAAC;QACrD,uBAAA,IAAI,qCAAoB,OAAO,CAAC,cAAc,EAAE,eAAe,IAAI,CAAC,MAAA,CAAC;IACvE,CAAC;IAED,iBAAiB,CAAC,QAAyB;QACzC,uBAAA,IAAI,oCAAmB,QAAQ,MAAA,CAAC;QAChC,uBAAA,IAAI,iCAAS,CAAC,OAAO,GAAG,+BAA+B,CAAC,QAAQ,CAAC,CAAC;IACpE,CAAC;IAED,0HAA0H;IAC1H,KAAK,CAAC,cAAc,CAAC,eAAwB;QAC3C,MAAM,OAAO,GAAG,MAAM,uBAAA,IAAI,qEAAgB,MAApB,IAAI,EAAiB,eAAe,CAAC,CAAC;QAC5D,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC;QACnC,CAAC;QAED,MAAM,aAAa,GAAG,MAAM,uBAAA,IAAI,4DAAO,MAAX,IAAI,EAAQ,eAAe,CAAC,CAAC;QACzD,OAAO,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,eAAwB;QAC3C,MAAM,OAAO,GAAG,MAAM,uBAAA,IAAI,qEAAgB,MAApB,IAAI,EAAiB,eAAe,CAAC,CAAC;QAC5D,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,OAAO,CAAC,OAAO,CAAC;QACzB,CAAC;QAED,MAAM,aAAa,GAAG,MAAM,uBAAA,IAAI,4DAAO,MAAX,IAAI,EAAQ,eAAe,CAAC,CAAC;QACzD,OAAO,aAAa,CAAC,OAAO,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,eAAwB;QAC1C,OAAO,MAAM,uBAAA,IAAI,iCAAS,CAAC,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,qBAAqB,CACzB,eAAwB;QAExB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;QAC/D,OAAO,MAAM,qBAAqB,CAAC,uBAAA,IAAI,gCAAQ,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,eAAe,CACnB,YAAsB,EACtB,eAAuB;QAEvB,OAAO,MAAM,YAAY,CAAC,YAAY,EAAE,eAAe,EAAE,uBAAA,IAAI,gCAAQ,CAAC,GAAG,CAAC,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,WAAW,CACf,OAAe,EACf,eAAwB;QAExB,OAAO,MAAM,uBAAA,IAAI,iCAAS,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,MAAM,QAAQ,GACZ,uBAAA,IAAI,wCAAgB,IAAI,CAAC,MAAM,yBAAyB,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAC;QACpD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,QAAQ,GACZ,uBAAA,IAAI,wCAAgB,IAAI,CAAC,MAAM,yBAAyB,EAAE,CAAC,CAAC;QAE9D,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC;QACxC,OAAO,GAAG,CAAC;IACb,CAAC;CA+IF;;AA7IC,0EAA0E;AAC1E,KAAK,2CACH,eAAwB;IAExB,MAAM,IAAI,GAAG,MAAM,uBAAA,IAAI,iCAAS,CAAC,OAAO,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;IAC3E,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAG,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;IACvD,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,GAAG,GAAG,CAAC;IAE3D,IAAI,UAAU,GAAG,gBAAgB,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,4BAED,KAAK,kCAAQ,eAAwB;IACnC,gDAAgD;IAChD,OAAO,MAAM,uBAAA,IAAI,oEAAe,MAAnB,IAAI,EAAgB,eAAe,CAAC,CAAC;AACpD,CAAC,mCAED,KAAK,yCAAe,eAAwB;IAC1C,QAAQ;IACR,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,uBAAA,IAAI,gCAAQ,CAAC,GAAG,CAAC,CAAC;IAE7D,MAAM,UAAU,GAAG,uBAAA,IAAI,+EAA0B,MAA9B,IAAI,EACrB,QAAQ,CAAC,KAAK,EACd,SAAS,CACV,CAAC;IACF,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IAEtE,eAAe;IACf,MAAM,YAAY,GAAG,MAAM,YAAY,CACrC,UAAU,EACV,SAAS,EACT,uBAAA,IAAI,gCAAQ,CAAC,IAAI,EACjB,uBAAA,IAAI,gCAAQ,CAAC,GAAG,EAChB,uBAAA,IAAI,qCAAa,CAClB,CAAC;IAEF,2CAA2C;IAC3C,oFAAoF;IACpF,8DAA8D;IAC9D,MAAM,kBAAkB,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC;IAC1D,MAAM,OAAO,GAAG,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC;IAE5C,IAAI,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,MAAM,kBAAkB,GAAG,mBAAmB,CAC5C,SAAS,EACT,uBAAA,IAAI,gCAAQ,CAAC,GAAG,CACjB,CAAC;QAEF,MAAM,WAAW,GAAG,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAC7D,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,kBAAkB,CAAC,CAC/D,CAAC;QAEF,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,CAAC,SAAS,GAAG,WAAW,CAAC,cAAc,CAAC;QACjD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IAEhD,YAAY;IACZ,MAAM,aAAa,GAAG,MAAM,aAAa,CACvC,YAAY,CAAC,KAAK,EAClB,uBAAA,IAAI,gCAAQ,CAAC,GAAG,EAChB,uBAAA,IAAI,gCAAQ,CAAC,QAAQ,CACtB,CAAC;IAEF,OAAO;IACP,MAAM,MAAM,GAAkB;QAC5B,OAAO;QACP,KAAK,EAAE,aAAa;KACrB,CAAC;IAEF,MAAM,uBAAA,IAAI,iCAAS,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAEtE,OAAO,MAAM,CAAC;AAChB,CAAC,oCAED,KAAK,0CAAgB,eAAwB;IAC3C,qEAAqE;IACrE,MAAM,aAAa,GAAG,uBAAA,IAAI,uCAAe,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC/D,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,6BAA6B;IAC7B,MAAM,YAAY,GAAG,uBAAA,IAAI,qEAAgB,MAApB,IAAI,EAAiB,eAAe,CAAC,CAAC;IAE3D,+BAA+B;IAC/B,uBAAA,IAAI,uCAAe,CAAC,GAAG,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;IAEvD,IAAI,CAAC;QACH,iCAAiC;QACjC,OAAO,MAAM,YAAY,CAAC;IAC5B,CAAC;YAAS,CAAC;QACT,sDAAsD;QACtD,uBAAA,IAAI,uCAAe,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC,qCAED,KAAK,2CAAiB,eAAwB;IAC5C,uDAAuD;IACvD,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,GAAG,uBAAA,IAAI,yCAAiB,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QACxE,IAAI,CAAC;YACH,OAAO,MAAM,uBAAA,IAAI,mEAAc,MAAlB,IAAI,EAAe,eAAe,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,wCAAwC;YACxC,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1C,MAAM,CAAC,CAAC;YACV,CAAC;YAED,uCAAuC;YACvC,IAAI,OAAO,IAAI,uBAAA,IAAI,yCAAiB,EAAE,CAAC;gBACrC,MAAM,CAAC,CAAC;YACV,CAAC;YAED,2CAA2C;YAC3C,MAAM,MAAM,GAAG,CAAC,CAAC,YAAY,IAAI,uBAAA,IAAI,2CAAmB,CAAC;YACzD,MAAM,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAE9B,0BAA0B;QAC5B,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;AACrE,CAAC,mGAGC,KAAa,EACb,SAAiB;IAEjB,OAAO,YAAY,KAAK,IAAI,SAAS,EAAW,CAAC;AACnD,CAAC","sourcesContent":["import type { Eip1193Provider } from 'ethers';\n\nimport type { MetaMetricsAuth } from '../../shared/types/services';\nimport { ValidationError, RateLimitedError } from '../errors';\nimport { getMetaMaskProviderEIP6963 } from '../utils/eip-6963-metamask-provider';\nimport {\n MESSAGE_SIGNING_SNAP,\n assertMessageStartsWithMetamask,\n connectSnap,\n isSnapConnected,\n} from '../utils/messaging-signing-snap-requests';\nimport { validateLoginResponse } from '../utils/validate-login-response';\nimport {\n authenticate,\n authorizeOIDC,\n getNonce,\n getUserProfileLineage,\n pairProfiles,\n} from './services';\nimport type { PairProfilesResponse } from './services';\nimport type {\n AuthConfig,\n AuthSigningOptions,\n AuthStorageOptions,\n AuthType,\n IBaseAuth,\n LoginResponse,\n UserProfile,\n UserProfileLineage,\n} from './types';\nimport { computeIdentifierId } from './utils/identifier';\nimport * as timeUtils from './utils/time';\n\ntype JwtBearerAuth_SRP_Options = {\n storage: AuthStorageOptions;\n signing?: AuthSigningOptions;\n rateLimitRetry?: {\n cooldownDefaultMs?: number; // default cooldown when 429 has no Retry-After\n maxLoginRetries?: number; // maximum number of login retries on rate limit\n };\n};\n\nconst getDefaultEIP6963Provider = async () => {\n const provider = await getMetaMaskProviderEIP6963();\n if (!provider) {\n throw new ValidationError('No MetaMask wallet connected');\n }\n return provider;\n};\n\nconst getDefaultEIP6963SigningOptions = (\n customProvider?: Eip1193Provider,\n): AuthSigningOptions => ({\n getIdentifier: async (entropySourceId?: string): Promise<string> => {\n const provider = customProvider ?? (await getDefaultEIP6963Provider());\n return await MESSAGE_SIGNING_SNAP.getPublicKey(provider, entropySourceId);\n },\n signMessage: async (\n message: string,\n entropySourceId?: string,\n ): Promise<string> => {\n const provider = customProvider ?? (await getDefaultEIP6963Provider());\n assertMessageStartsWithMetamask(message);\n return await MESSAGE_SIGNING_SNAP.signMessage(\n provider,\n message,\n entropySourceId,\n );\n },\n});\n\nexport class SRPJwtBearerAuth implements IBaseAuth {\n readonly #config: AuthConfig;\n\n readonly #options: {\n storage: AuthStorageOptions;\n signing: AuthSigningOptions;\n };\n\n readonly #metametrics?: MetaMetricsAuth;\n\n // Map to store ongoing login promises by entropySourceId\n readonly #ongoingLogins = new Map<\n string | undefined,\n Promise<LoginResponse>\n >();\n\n // Default cooldown when 429 has no Retry-After header\n readonly #cooldownDefaultMs: number;\n\n // Maximum number of login retries on rate limit errors\n readonly #maxLoginRetries: number;\n\n #customProvider?: Eip1193Provider;\n\n constructor(\n config: AuthConfig & { type: AuthType.SRP },\n options: JwtBearerAuth_SRP_Options & {\n customProvider?: Eip1193Provider;\n metametrics?: MetaMetricsAuth;\n },\n ) {\n this.#config = config;\n this.#customProvider = options.customProvider;\n this.#options = {\n storage: options.storage,\n signing:\n options.signing ??\n getDefaultEIP6963SigningOptions(this.#customProvider),\n };\n this.#metametrics = options.metametrics;\n\n // Apply rate limit retry config if provided\n this.#cooldownDefaultMs =\n options.rateLimitRetry?.cooldownDefaultMs ?? 10000;\n this.#maxLoginRetries = options.rateLimitRetry?.maxLoginRetries ?? 1;\n }\n\n setCustomProvider(provider: Eip1193Provider) {\n this.#customProvider = provider;\n this.#options.signing = getDefaultEIP6963SigningOptions(provider);\n }\n\n // TODO: might be easier to keep entropySourceId as a class param and use multiple SRPJwtBearerAuth instances where needed\n async getAccessToken(entropySourceId?: string): Promise<string> {\n const session = await this.#getAuthSession(entropySourceId);\n if (session) {\n return session.token.accessToken;\n }\n\n const loginResponse = await this.#login(entropySourceId);\n return loginResponse.token.accessToken;\n }\n\n async getUserProfile(entropySourceId?: string): Promise<UserProfile> {\n const session = await this.#getAuthSession(entropySourceId);\n if (session) {\n return session.profile;\n }\n\n const loginResponse = await this.#login(entropySourceId);\n return loginResponse.profile;\n }\n\n async getIdentifier(entropySourceId?: string): Promise<string> {\n return await this.#options.signing.getIdentifier(entropySourceId);\n }\n\n async getUserProfileLineage(\n entropySourceId?: string,\n ): Promise<UserProfileLineage> {\n const accessToken = await this.getAccessToken(entropySourceId);\n return await getUserProfileLineage(this.#config.env, accessToken);\n }\n\n async pairSrpProfiles(\n accessTokens: string[],\n authAccessToken: string,\n ): Promise<PairProfilesResponse> {\n return await pairProfiles(accessTokens, authAccessToken, this.#config.env);\n }\n\n async signMessage(\n message: string,\n entropySourceId?: string,\n ): Promise<string> {\n return await this.#options.signing.signMessage(message, entropySourceId);\n }\n\n async isSnapConnected(): Promise<boolean> {\n const provider =\n this.#customProvider ?? (await getDefaultEIP6963Provider());\n if (!provider) {\n return false;\n }\n\n const isConnected = await isSnapConnected(provider);\n return isConnected;\n }\n\n async connectSnap(): Promise<string> {\n const provider =\n this.#customProvider ?? (await getDefaultEIP6963Provider());\n\n const res = await connectSnap(provider);\n return res;\n }\n\n // convert expiresIn from seconds to milliseconds and use 90% of expiresIn\n async #getAuthSession(\n entropySourceId?: string,\n ): Promise<LoginResponse | null> {\n const auth = await this.#options.storage.getLoginResponse(entropySourceId);\n if (!validateLoginResponse(auth)) {\n return null;\n }\n\n const currentTime = Date.now();\n const sessionAge = currentTime - auth.token.obtainedAt;\n const refreshThreshold = auth.token.expiresIn * 1000 * 0.9;\n\n if (sessionAge < refreshThreshold) {\n return auth;\n }\n return null;\n }\n\n async #login(entropySourceId?: string): Promise<LoginResponse> {\n // Use a deferred login to avoid race conditions\n return await this.#deferredLogin(entropySourceId);\n }\n\n async #performLogin(entropySourceId?: string): Promise<LoginResponse> {\n // Nonce\n const publicKey = await this.getIdentifier(entropySourceId);\n const nonceRes = await getNonce(publicKey, this.#config.env);\n\n const rawMessage = this.#createSrpLoginRawMessage(\n nonceRes.nonce,\n publicKey,\n );\n const signature = await this.signMessage(rawMessage, entropySourceId);\n\n // Authenticate\n const authResponse = await authenticate(\n rawMessage,\n signature,\n this.#config.type,\n this.#config.env,\n this.#metametrics,\n );\n\n // Resolve original profileId from aliases.\n // This is done mainly to preserve the original profileId for storage key derivation\n // until we migrate to the canonical profileId storage system.\n const canonicalProfileId = authResponse.profile.profileId;\n const profile = { ...authResponse.profile };\n\n if (authResponse.profileAliases?.length > 0) {\n const targetIdentifierId = computeIdentifierId(\n publicKey,\n this.#config.env,\n );\n\n const targetAlias = authResponse.profileAliases.find((alias) =>\n alias.identifierIds.some((id) => id.id === targetIdentifierId),\n );\n\n if (targetAlias) {\n profile.profileId = targetAlias.aliasProfileId;\n }\n }\n\n profile.canonicalProfileId = canonicalProfileId;\n\n // Authorize\n const tokenResponse = await authorizeOIDC(\n authResponse.token,\n this.#config.env,\n this.#config.platform,\n );\n\n // Save\n const result: LoginResponse = {\n profile,\n token: tokenResponse,\n };\n\n await this.#options.storage.setLoginResponse(result, entropySourceId);\n\n return result;\n }\n\n async #deferredLogin(entropySourceId?: string): Promise<LoginResponse> {\n // Check if there's already an ongoing login for this entropySourceId\n const existingLogin = this.#ongoingLogins.get(entropySourceId);\n if (existingLogin) {\n return existingLogin;\n }\n\n // Create a new login promise\n const loginPromise = this.#loginWithRetry(entropySourceId);\n\n // Store the promise in the map\n this.#ongoingLogins.set(entropySourceId, loginPromise);\n\n try {\n // Wait for the login to complete\n return await loginPromise;\n } finally {\n // Always clean up the ongoing login promise when done\n this.#ongoingLogins.delete(entropySourceId);\n }\n }\n\n async #loginWithRetry(entropySourceId?: string): Promise<LoginResponse> {\n // Allow max attempts: initial + maxLoginRetries on 429\n for (let attempt = 0; attempt < 1 + this.#maxLoginRetries; attempt += 1) {\n try {\n return await this.#performLogin(entropySourceId);\n } catch (e) {\n // Only retry on rate-limit (429) errors\n if (!RateLimitedError.isRateLimitError(e)) {\n throw e;\n }\n\n // If we've exhausted attempts, rethrow\n if (attempt >= this.#maxLoginRetries) {\n throw e;\n }\n\n // Wait for Retry-After or default cooldown\n const waitMs = e.retryAfterMs ?? this.#cooldownDefaultMs;\n await timeUtils.delay(waitMs);\n\n // Loop continues to retry\n }\n }\n\n // Should never reach here due to loop logic, but TypeScript needs a return\n throw new Error('Unexpected: login loop exhausted without result');\n }\n\n #createSrpLoginRawMessage(\n nonce: string,\n publicKey: string,\n ): `metamask:${string}:${string}` {\n return `metamask:${nonce}:${publicKey}` as const;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"flow-srp.mjs","sourceRoot":"","sources":["../../../src/sdk/authentication-jwt-bearer/flow-srp.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Eip1193Provider } from 'ethers';\n\nimport type { MetaMetricsAuth } from '../../shared/types/services';\nimport { ValidationError, RateLimitedError } from '../errors';\nimport { getMetaMaskProviderEIP6963 } from '../utils/eip-6963-metamask-provider';\nimport {\n MESSAGE_SIGNING_SNAP,\n assertMessageStartsWithMetamask,\n connectSnap,\n isSnapConnected,\n} from '../utils/messaging-signing-snap-requests';\nimport { validateLoginResponse } from '../utils/validate-login-response';\nimport {\n authenticate,\n authorizeOIDC,\n getNonce,\n getUserProfileLineage,\n} from './services';\nimport type {\n AuthConfig,\n AuthSigningOptions,\n AuthStorageOptions,\n AuthType,\n IBaseAuth,\n LoginResponse,\n UserProfile,\n UserProfileLineage,\n} from './types';\nimport * as timeUtils from './utils/time';\n\ntype JwtBearerAuth_SRP_Options = {\n storage: AuthStorageOptions;\n signing?: AuthSigningOptions;\n rateLimitRetry?: {\n cooldownDefaultMs?: number; // default cooldown when 429 has no Retry-After\n maxLoginRetries?: number; // maximum number of login retries on rate limit\n };\n};\n\nconst getDefaultEIP6963Provider = async () => {\n const provider = await getMetaMaskProviderEIP6963();\n if (!provider) {\n throw new ValidationError('No MetaMask wallet connected');\n }\n return provider;\n};\n\nconst getDefaultEIP6963SigningOptions = (\n customProvider?: Eip1193Provider,\n): AuthSigningOptions => ({\n getIdentifier: async (entropySourceId?: string): Promise<string> => {\n const provider = customProvider ?? (await getDefaultEIP6963Provider());\n return await MESSAGE_SIGNING_SNAP.getPublicKey(provider, entropySourceId);\n },\n signMessage: async (\n message: string,\n entropySourceId?: string,\n ): Promise<string> => {\n const provider = customProvider ?? (await getDefaultEIP6963Provider());\n assertMessageStartsWithMetamask(message);\n return await MESSAGE_SIGNING_SNAP.signMessage(\n provider,\n message,\n entropySourceId,\n );\n },\n});\n\nexport class SRPJwtBearerAuth implements IBaseAuth {\n readonly #config: AuthConfig;\n\n readonly #options: {\n storage: AuthStorageOptions;\n signing: AuthSigningOptions;\n };\n\n readonly #metametrics?: MetaMetricsAuth;\n\n // Map to store ongoing login promises by entropySourceId\n readonly #ongoingLogins = new Map<\n string | undefined,\n Promise<LoginResponse>\n >();\n\n // Default cooldown when 429 has no Retry-After header\n readonly #cooldownDefaultMs: number;\n\n // Maximum number of login retries on rate limit errors\n readonly #maxLoginRetries: number;\n\n #customProvider?: Eip1193Provider;\n\n constructor(\n config: AuthConfig & { type: AuthType.SRP },\n options: JwtBearerAuth_SRP_Options & {\n customProvider?: Eip1193Provider;\n metametrics?: MetaMetricsAuth;\n },\n ) {\n this.#config = config;\n this.#customProvider = options.customProvider;\n this.#options = {\n storage: options.storage,\n signing:\n options.signing ??\n getDefaultEIP6963SigningOptions(this.#customProvider),\n };\n this.#metametrics = options.metametrics;\n\n // Apply rate limit retry config if provided\n this.#cooldownDefaultMs =\n options.rateLimitRetry?.cooldownDefaultMs ?? 10000;\n this.#maxLoginRetries = options.rateLimitRetry?.maxLoginRetries ?? 1;\n }\n\n setCustomProvider(provider: Eip1193Provider) {\n this.#customProvider = provider;\n this.#options.signing = getDefaultEIP6963SigningOptions(provider);\n }\n\n // TODO: might be easier to keep entropySourceId as a class param and use multiple SRPJwtBearerAuth instances where needed\n async getAccessToken(entropySourceId?: string): Promise<string> {\n const session = await this.#getAuthSession(entropySourceId);\n if (session) {\n return session.token.accessToken;\n }\n\n const loginResponse = await this.#login(entropySourceId);\n return loginResponse.token.accessToken;\n }\n\n async getUserProfile(entropySourceId?: string): Promise<UserProfile> {\n const session = await this.#getAuthSession(entropySourceId);\n if (session) {\n return session.profile;\n }\n\n const loginResponse = await this.#login(entropySourceId);\n return loginResponse.profile;\n }\n\n async getIdentifier(entropySourceId?: string): Promise<string> {\n return await this.#options.signing.getIdentifier(entropySourceId);\n }\n\n async getUserProfileLineage(\n entropySourceId?: string,\n ): Promise<UserProfileLineage> {\n const accessToken = await this.getAccessToken(entropySourceId);\n return await getUserProfileLineage(this.#config.env, accessToken);\n }\n\n async signMessage(\n message: string,\n entropySourceId?: string,\n ): Promise<string> {\n return await this.#options.signing.signMessage(message, entropySourceId);\n }\n\n async isSnapConnected(): Promise<boolean> {\n const provider =\n this.#customProvider ?? (await getDefaultEIP6963Provider());\n if (!provider) {\n return false;\n }\n\n const isConnected = await isSnapConnected(provider);\n return isConnected;\n }\n\n async connectSnap(): Promise<string> {\n const provider =\n this.#customProvider ?? (await getDefaultEIP6963Provider());\n\n const res = await connectSnap(provider);\n return res;\n }\n\n // convert expiresIn from seconds to milliseconds and use 90% of expiresIn\n async #getAuthSession(\n entropySourceId?: string,\n ): Promise<LoginResponse | null> {\n const auth = await this.#options.storage.getLoginResponse(entropySourceId);\n if (!validateLoginResponse(auth)) {\n return null;\n }\n\n const currentTime = Date.now();\n const sessionAge = currentTime - auth.token.obtainedAt;\n const refreshThreshold = auth.token.expiresIn * 1000 * 0.9;\n\n if (sessionAge < refreshThreshold) {\n return auth;\n }\n return null;\n }\n\n async #login(entropySourceId?: string): Promise<LoginResponse> {\n // Use a deferred login to avoid race conditions\n return await this.#deferredLogin(entropySourceId);\n }\n\n async #performLogin(entropySourceId?: string): Promise<LoginResponse> {\n // Nonce\n const publicKey = await this.getIdentifier(entropySourceId);\n const nonceRes = await getNonce(publicKey, this.#config.env);\n\n const rawMessage = this.#createSrpLoginRawMessage(\n nonceRes.nonce,\n publicKey,\n );\n const signature = await this.signMessage(rawMessage, entropySourceId);\n\n // Authenticate\n const authResponse = await authenticate(\n rawMessage,\n signature,\n this.#config.type,\n this.#config.env,\n this.#metametrics,\n );\n\n // Authorize\n const tokenResponse = await authorizeOIDC(\n authResponse.token,\n this.#config.env,\n this.#config.platform,\n );\n\n // Save\n const result: LoginResponse = {\n profile: authResponse.profile,\n token: tokenResponse,\n };\n\n await this.#options.storage.setLoginResponse(result, entropySourceId);\n\n return result;\n }\n\n async #deferredLogin(entropySourceId?: string): Promise<LoginResponse> {\n // Check if there's already an ongoing login for this entropySourceId\n const existingLogin = this.#ongoingLogins.get(entropySourceId);\n if (existingLogin) {\n return existingLogin;\n }\n\n // Create a new login promise\n const loginPromise = this.#loginWithRetry(entropySourceId);\n\n // Store the promise in the map\n this.#ongoingLogins.set(entropySourceId, loginPromise);\n\n try {\n // Wait for the login to complete\n return await loginPromise;\n } finally {\n // Always clean up the ongoing login promise when done\n this.#ongoingLogins.delete(entropySourceId);\n }\n }\n\n async #loginWithRetry(entropySourceId?: string): Promise<LoginResponse> {\n // Allow max attempts: initial + maxLoginRetries on 429\n for (let attempt = 0; attempt < 1 + this.#maxLoginRetries; attempt += 1) {\n try {\n return await this.#performLogin(entropySourceId);\n } catch (e) {\n // Only retry on rate-limit (429) errors\n if (!RateLimitedError.isRateLimitError(e)) {\n throw e;\n }\n\n // If we've exhausted attempts, rethrow\n if (attempt >= this.#maxLoginRetries) {\n throw e;\n }\n\n // Wait for Retry-After or default cooldown\n const waitMs = e.retryAfterMs ?? this.#cooldownDefaultMs;\n await timeUtils.delay(waitMs);\n\n // Loop continues to retry\n }\n }\n\n // Should never reach here due to loop logic, but TypeScript needs a return\n throw new Error('Unexpected: login loop exhausted without result');\n }\n\n #createSrpLoginRawMessage(\n nonce: string,\n publicKey: string,\n ): `metamask:${string}:${string}` {\n return `metamask:${nonce}:${publicKey}` as const;\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getUserProfileLineage = exports.authenticate = exports.authorizeOIDC = exports.getNonce = exports.
|
|
3
|
+
exports.getUserProfileLineage = exports.authenticate = exports.authorizeOIDC = exports.getNonce = exports.pairIdentifiers = exports.PROFILE_LINEAGE_URL = exports.SIWE_LOGIN_URL = exports.SRP_LOGIN_URL = exports.OIDC_TOKEN_URL = exports.PAIR_IDENTIFIERS = exports.NONCE_URL = void 0;
|
|
4
4
|
const env_1 = require("../../shared/env.cjs");
|
|
5
5
|
const constants_1 = require("../constants.cjs");
|
|
6
6
|
const errors_1 = require("../errors.cjs");
|
|
@@ -112,8 +112,6 @@ const SRP_LOGIN_URL = (env) => `${(0, env_1.getEnvUrls)(env).authApiUrl}/api/v2/
|
|
|
112
112
|
exports.SRP_LOGIN_URL = SRP_LOGIN_URL;
|
|
113
113
|
const SIWE_LOGIN_URL = (env) => `${(0, env_1.getEnvUrls)(env).authApiUrl}/api/v2/siwe/login`;
|
|
114
114
|
exports.SIWE_LOGIN_URL = SIWE_LOGIN_URL;
|
|
115
|
-
const PAIR_PROFILES_URL = (env) => `${(0, env_1.getEnvUrls)(env).authApiUrl}/api/v2/profile/pair`;
|
|
116
|
-
exports.PAIR_PROFILES_URL = PAIR_PROFILES_URL;
|
|
117
115
|
const PROFILE_LINEAGE_URL = (env) => `${(0, env_1.getEnvUrls)(env).authApiUrl}/api/v2/profile/lineage`;
|
|
118
116
|
exports.PROFILE_LINEAGE_URL = PROFILE_LINEAGE_URL;
|
|
119
117
|
const getAuthenticationUrl = (authType, env) => {
|
|
@@ -127,13 +125,6 @@ const getAuthenticationUrl = (authType, env) => {
|
|
|
127
125
|
throw new errors_1.ValidationError(`Invalid AuthType: ${authType} - unable to create Auth URL`);
|
|
128
126
|
}
|
|
129
127
|
};
|
|
130
|
-
const parseProfileAliases = (raw) => {
|
|
131
|
-
return raw.map((alias) => ({
|
|
132
|
-
aliasProfileId: alias.alias_profile_id,
|
|
133
|
-
canonicalProfileId: alias.canonical_profile_id,
|
|
134
|
-
identifierIds: alias.identifier_ids ?? [],
|
|
135
|
-
}));
|
|
136
|
-
};
|
|
137
128
|
/**
|
|
138
129
|
* Pair multiple identifiers under a single profile
|
|
139
130
|
*
|
|
@@ -167,47 +158,6 @@ async function pairIdentifiers(nonce, logins, accessToken, env) {
|
|
|
167
158
|
}
|
|
168
159
|
}
|
|
169
160
|
exports.pairIdentifiers = pairIdentifiers;
|
|
170
|
-
/**
|
|
171
|
-
* Pair multiple profiles using their OIDC access tokens.
|
|
172
|
-
* Idempotent — calling with already-paired tokens is a no-op.
|
|
173
|
-
*
|
|
174
|
-
* @param accessTokens - Two or more OIDC access tokens to pair
|
|
175
|
-
* @param authAccessToken - A valid access token for the Authorization header
|
|
176
|
-
* @param env - server environment
|
|
177
|
-
* @returns The pair response containing the canonical profile and aliases
|
|
178
|
-
*/
|
|
179
|
-
async function pairProfiles(accessTokens, authAccessToken, env) {
|
|
180
|
-
const pairUrl = new URL((0, exports.PAIR_PROFILES_URL)(env));
|
|
181
|
-
try {
|
|
182
|
-
const response = await fetch(pairUrl, {
|
|
183
|
-
method: 'POST',
|
|
184
|
-
headers: {
|
|
185
|
-
'Content-Type': 'application/json',
|
|
186
|
-
Authorization: `Bearer ${authAccessToken}`,
|
|
187
|
-
},
|
|
188
|
-
body: JSON.stringify({
|
|
189
|
-
jwts: accessTokens,
|
|
190
|
-
}),
|
|
191
|
-
});
|
|
192
|
-
if (!response.ok) {
|
|
193
|
-
return await throwServiceError(response, 'Failed to pair profiles', errors_1.PairError);
|
|
194
|
-
}
|
|
195
|
-
const pairResponse = await response.json();
|
|
196
|
-
return {
|
|
197
|
-
profile: {
|
|
198
|
-
identifierId: pairResponse.profile.identifier_id,
|
|
199
|
-
metaMetricsId: pairResponse.profile.metametrics_id ?? '',
|
|
200
|
-
profileId: pairResponse.profile.profile_id,
|
|
201
|
-
canonicalProfileId: pairResponse.profile.profile_id,
|
|
202
|
-
},
|
|
203
|
-
profileAliases: parseProfileAliases(pairResponse.profile_aliases ?? []),
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
catch (error) {
|
|
207
|
-
return await throwServiceError(error, 'Failed to pair profiles', errors_1.PairError);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
exports.pairProfiles = pairProfiles;
|
|
211
161
|
/**
|
|
212
162
|
* Service to Get Nonce for JWT Bearer Flow
|
|
213
163
|
*
|
|
@@ -290,9 +240,6 @@ async function authenticate(rawMessage, signature, authType, env, metametrics) {
|
|
|
290
240
|
method: 'POST',
|
|
291
241
|
headers: {
|
|
292
242
|
'Content-Type': 'application/json',
|
|
293
|
-
...(authType === types_1.AuthType.SRP
|
|
294
|
-
? { 'X-MetaMask-Profile-Pairing': 'enabled' }
|
|
295
|
-
: {}),
|
|
296
243
|
},
|
|
297
244
|
body: JSON.stringify({
|
|
298
245
|
signature,
|
|
@@ -318,9 +265,7 @@ async function authenticate(rawMessage, signature, authType, env, metametrics) {
|
|
|
318
265
|
identifierId: loginResponse.profile.identifier_id,
|
|
319
266
|
metaMetricsId: loginResponse.profile.metametrics_id,
|
|
320
267
|
profileId: loginResponse.profile.profile_id,
|
|
321
|
-
canonicalProfileId: loginResponse.profile.profile_id,
|
|
322
268
|
},
|
|
323
|
-
profileAliases: parseProfileAliases(loginResponse.profile_aliases ?? []),
|
|
324
269
|
};
|
|
325
270
|
}
|
|
326
271
|
catch (error) {
|