UNPKG

@aws-amplify/auth

Version:
111 lines (97 loc) 3.3 kB
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { AuthTokens, ConsoleLogger, Identity, getId } from '@aws-amplify/core'; import { CognitoIdentityPoolConfig } from '@aws-amplify/core/internals/utils'; import { AuthError } from '../../../errors/AuthError'; import { getRegionFromIdentityPoolId } from '../../../foundation/parsers'; import { GetIdException } from '../types/errors'; import { IdentityIdStore } from './types'; import { formLoginsMap } from './utils'; const logger = new ConsoleLogger('CognitoIdentityIdProvider'); /** * Provides a Cognito identityId * * @param tokens - The AuthTokens received after SignIn * @returns string * @throws configuration exceptions: `InvalidIdentityPoolIdException` * - Auth errors that may arise from misconfiguration. * @throws service exceptions: {@link GetIdException } */ export async function cognitoIdentityIdProvider({ tokens, authConfig, identityIdStore, }: { tokens?: AuthTokens; authConfig: CognitoIdentityPoolConfig; identityIdStore: IdentityIdStore; }): Promise<string> { identityIdStore.setAuthConfig({ Cognito: authConfig }); // will return null only if there is no identityId cached or if there is an error retrieving it let identityId: Identity | null = await identityIdStore.loadIdentityId(); // Tokens are available so return primary identityId if (tokens) { // If there is existing primary identityId in-memory return that if (identityId && identityId.type === 'primary') { return identityId.id; } else { const logins = tokens.idToken ? formLoginsMap(tokens.idToken.toString()) : {}; const generatedIdentityId = await generateIdentityId(logins, authConfig); if (identityId && identityId.id === generatedIdentityId) { logger.debug( `The guest identity ${identityId.id} has become the primary identity.`, ); } identityId = { id: generatedIdentityId, type: 'primary', }; } } else { // If there is existing guest identityId cached return that if (identityId && identityId.type === 'guest') { return identityId.id; } else { identityId = { id: await generateIdentityId({}, authConfig), type: 'guest', }; } } // Store in-memory or local storage depending on guest or primary identityId identityIdStore.storeIdentityId(identityId); return identityId.id; } async function generateIdentityId( logins: Record<string, string>, authConfig: CognitoIdentityPoolConfig, ): Promise<string> { const identityPoolId = authConfig?.identityPoolId; const region = getRegionFromIdentityPoolId(identityPoolId); // IdentityId is absent so get it using IdentityPoolId with Cognito's GetId API const idResult = // for a first-time user, this will return a brand new identity // for a returning user, this will retrieve the previous identity assocaited with the logins ( await getId( { region, }, { IdentityPoolId: identityPoolId, Logins: logins, }, ) ).IdentityId; if (!idResult) { throw new AuthError({ name: 'GetIdResponseException', message: 'Received undefined response from getId operation', recoverySuggestion: 'Make sure to pass a valid identityPoolId in the configuration.', }); } return idResult; }