UNPKG

@aws-amplify/auth

Version:
143 lines (129 loc) 4.2 kB
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { AuthConfig, AuthTokens, AuthUserPoolConfig, CognitoUserPoolConfig, } from '@aws-amplify/core'; import { AuthError } from '../../../errors/AuthError'; import { CognitoAuthTokens, DeviceMetadata } from '../tokenProvider/types'; import { DEVICE_METADATA_NOT_FOUND_EXCEPTION, TOKEN_REFRESH_EXCEPTION, USER_UNAUTHENTICATED_EXCEPTION, } from '../../../errors/constants'; export function isTypeUserPoolConfig( authConfig?: AuthConfig, ): authConfig is AuthUserPoolConfig { if ( authConfig && authConfig.Cognito.userPoolId && authConfig.Cognito.userPoolClientId ) { return true; } return false; } export function assertAuthTokens( tokens?: AuthTokens | null, ): asserts tokens is AuthTokens { if (!tokens || !tokens.accessToken) { throw new AuthError({ name: USER_UNAUTHENTICATED_EXCEPTION, message: 'User needs to be authenticated to call this API.', recoverySuggestion: 'Sign in before calling this API again.', }); } } export function assertIdTokenInAuthTokens( tokens?: AuthTokens, ): asserts tokens is AuthTokens { if (!tokens || !tokens.idToken) { throw new AuthError({ name: USER_UNAUTHENTICATED_EXCEPTION, message: 'User needs to be authenticated to call this API.', recoverySuggestion: 'Sign in before calling this API again.', }); } } export const oAuthTokenRefreshException = new AuthError({ name: TOKEN_REFRESH_EXCEPTION, message: `Token refresh is not supported when authenticated with the 'implicit grant' (token) oauth flow. Please change your oauth configuration to use 'code grant' flow.`, recoverySuggestion: `Please logout and change your Amplify configuration to use "code grant" flow. E.g { responseType: 'code' }`, }); export const tokenRefreshException = new AuthError({ name: USER_UNAUTHENTICATED_EXCEPTION, message: 'User needs to be authenticated to call this API.', recoverySuggestion: 'Sign in before calling this API again.', }); export function assertAuthTokensWithRefreshToken( tokens?: CognitoAuthTokens | null, ): asserts tokens is CognitoAuthTokens & { refreshToken: string } { if (isAuthenticatedWithImplicitOauthFlow(tokens)) { throw oAuthTokenRefreshException; } if (!isAuthenticatedWithRefreshToken(tokens)) { throw tokenRefreshException; } } type NonNullableDeviceMetadata = DeviceMetadata & { deviceKey: string; deviceGroupKey: string; }; export function assertDeviceMetadata( deviceMetadata?: DeviceMetadata | null, ): asserts deviceMetadata is NonNullableDeviceMetadata { if ( !deviceMetadata || !deviceMetadata.deviceKey || !deviceMetadata.deviceGroupKey || !deviceMetadata.randomPassword ) { throw new AuthError({ name: DEVICE_METADATA_NOT_FOUND_EXCEPTION, message: 'Either deviceKey, deviceGroupKey or secretPassword were not found during the sign-in process.', recoverySuggestion: 'Make sure to not clear storage after calling the signIn API.', }); } } export const OAuthStorageKeys = { inflightOAuth: 'inflightOAuth', oauthSignIn: 'oauthSignIn', oauthPKCE: 'oauthPKCE', oauthState: 'oauthState', }; export interface OAuthStore { setAuthConfig(authConfigParam: CognitoUserPoolConfig): void; loadOAuthInFlight(): Promise<boolean>; storeOAuthInFlight(inflight: boolean): Promise<void>; loadOAuthSignIn(): Promise<{ isOAuthSignIn: boolean; preferPrivateSession: boolean; }>; storeOAuthSignIn( oauthSignIn: boolean, preferPrivateSession: boolean, ): Promise<void>; loadOAuthState(): Promise<string | null>; storeOAuthState(state: string): Promise<void>; loadPKCE(): Promise<string | null>; storePKCE(pkce: string): Promise<void>; clearOAuthInflightData(): Promise<void>; clearOAuthData(): Promise<void>; } function isAuthenticated(tokens?: CognitoAuthTokens | null) { return tokens?.accessToken || tokens?.idToken; } function isAuthenticatedWithRefreshToken(tokens?: CognitoAuthTokens | null) { return isAuthenticated(tokens) && tokens?.refreshToken; } function isAuthenticatedWithImplicitOauthFlow( tokens?: CognitoAuthTokens | null, ) { return isAuthenticated(tokens) && !tokens?.refreshToken; }