@aws-amplify/auth
Version:
Auth category of aws-amplify
143 lines (129 loc) • 4.2 kB
text/typescript
// 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;
}