Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import {
DEFAULT_AUTH_SESSION_VALIDITY_MS,
getAuthSessionValidity,
} from '../../../../src/providers/cognito/utils/getAuthSessionValidity';

jest.mock(
'@aws-amplify/core',
() => ({
Amplify: {
getConfig: jest.fn(),
},
}),
{ virtual: true },
);

describe('getAuthSessionValidity()', () => {
const mockGetConfig = (
jest.requireMock('@aws-amplify/core') as {
Amplify: { getConfig: jest.Mock };
}
).Amplify.getConfig;

afterEach(() => {
mockGetConfig.mockReset();
});

it('returns the default Cognito auth session validity when not configured', () => {
mockGetConfig.mockReturnValue({} as any);

expect(getAuthSessionValidity()).toBe(DEFAULT_AUTH_SESSION_VALIDITY_MS);
});

it('returns configured Cognito auth session validity in milliseconds', () => {
mockGetConfig.mockReturnValue({
Auth: {
Cognito: {
userPoolId: 'us-west-2_test',
userPoolClientId: 'clientId',
authSessionValidity: 15,
},
},
});

expect(getAuthSessionValidity()).toBe(15 * 60 * 1000);
});

it('bounds configured Cognito auth session validity to the Cognito range', () => {
mockGetConfig.mockReturnValueOnce({
Auth: {
Cognito: {
userPoolId: 'us-west-2_test',
userPoolClientId: 'clientId',
authSessionValidity: 2,
},
},
});
expect(getAuthSessionValidity()).toBe(3 * 60 * 1000);

mockGetConfig.mockReturnValueOnce({
Auth: {
Cognito: {
userPoolId: 'us-west-2_test',
userPoolClientId: 'clientId',
authSessionValidity: 16,
},
},
});
expect(getAuthSessionValidity()).toBe(15 * 60 * 1000);
});
});
6 changes: 2 additions & 4 deletions packages/auth/src/client/utils/store/signInStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { syncSessionStorage } from '@aws-amplify/core';

import { CognitoAuthSignInDetails } from '../../../providers/cognito/types';
import { ChallengeName } from '../../../foundation/factories/serviceClients/cognitoIdentityProvider/types';
import { getAuthSessionValidity } from '../../../providers/cognito/utils/getAuthSessionValidity';

import { Reducer, Store } from './types';

Expand All @@ -24,9 +25,6 @@ type SignInAction =
| { type: 'SET_SIGN_IN_SESSION'; value?: string }
| { type: 'RESET_STATE' };

// Minutes until stored session invalidates is defaulted to 3 minutes
// to maintain parity with Amazon Cognito user pools API behavior
const MS_TO_EXPIRY = 3 * 60 * 1000;
const TGT_STATE = 'CognitoSignInState';
const SIGN_IN_STATE_KEYS = {
username: `${TGT_STATE}.username`,
Expand Down Expand Up @@ -166,7 +164,7 @@ export const persistSignInState = ({
// Updates expiry when session is passed
syncSessionStorage.setItem(
SIGN_IN_STATE_KEYS.expiry,
String(Date.now() + MS_TO_EXPIRY),
String(Date.now() + getAuthSessionValidity()),
);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { Amplify } from '@aws-amplify/core';

export const DEFAULT_AUTH_SESSION_VALIDITY_MS = 3 * 60 * 1000;
const MIN_AUTH_SESSION_VALIDITY_MS = 3 * 60 * 1000;
const MAX_AUTH_SESSION_VALIDITY_MS = 15 * 60 * 1000;

export const getAuthSessionValidity = (): number => {
const authSessionValidity =
Amplify.getConfig().Auth?.Cognito.authSessionValidity;

if (
typeof authSessionValidity !== 'number' ||
!Number.isFinite(authSessionValidity)
) {
return DEFAULT_AUTH_SESSION_VALIDITY_MS;
}

const authSessionValidityMs = authSessionValidity * 60 * 1000;
const boundedAuthSessionValidity = Math.min(
Math.max(authSessionValidityMs, MIN_AUTH_SESSION_VALIDITY_MS),
MAX_AUTH_SESSION_VALIDITY_MS,
);

return boundedAuthSessionValidity;
};
6 changes: 3 additions & 3 deletions packages/auth/src/providers/cognito/utils/signUpHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { resetAutoSignIn, setAutoSignIn } from '../apis/autoSignIn';
import { AUTO_SIGN_IN_EXCEPTION } from '../../../errors/constants';
import { signInWithUserAuth } from '../apis/signInWithUserAuth';

const MAX_AUTOSIGNIN_POLLING_MS = 3 * 60 * 1000;
import { getAuthSessionValidity } from './getAuthSessionValidity';

export function handleCodeAutoSignIn(signInInput: SignInInput) {
const stopHubListener = HubInternal.listen<AutoSignInEventData>(
Expand All @@ -38,7 +38,7 @@ export function handleCodeAutoSignIn(signInInput: SignInInput) {
stopHubListener();
clearTimeout(timeOutId);
resetAutoSignIn();
}, MAX_AUTOSIGNIN_POLLING_MS);
}, getAuthSessionValidity());
}

// Debounces the auto sign-in flow with link
Expand Down Expand Up @@ -70,7 +70,7 @@ function handleAutoSignInWithLink(
const start = Date.now();
const autoSignInPollingIntervalId = setInterval(async () => {
const elapsedTime = Date.now() - start;
const maxTime = MAX_AUTOSIGNIN_POLLING_MS;
const maxTime = getAuthSessionValidity();
if (elapsedTime > maxTime) {
clearInterval(autoSignInPollingIntervalId);
reject(
Expand Down
2 changes: 2 additions & 0 deletions packages/core/__tests__/parseAWSExports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ describe('parseAWSExports', () => {
Cognito: {
identityPoolId,
allowGuestAccess: false,
authSessionValidity: 15,
loginWith: {
email: false,
oauth: {
Expand Down Expand Up @@ -157,6 +158,7 @@ describe('parseAWSExports', () => {
parseAWSExports({
aws_project_region: 'us-west-2',
aws_cognito_identity_pool_id: identityPoolId,
aws_cognito_auth_session_validity: 15,
aws_cognito_sign_up_verification_method: signUpVerificationMethod,
aws_cognito_username_attributes: ['PHONE_NUMBER'],
aws_cognito_signup_attributes: ['PHONE_NUMBER'],
Expand Down
2 changes: 2 additions & 0 deletions packages/core/__tests__/parseAmplifyOutputs.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable camelcase */
import { AmplifyOutputs, parseAmplifyOutputs } from '../src/libraryUtils';

Check warning on line 2 in packages/core/__tests__/parseAmplifyOutputs.test.ts

View workflow job for this annotation

GitHub Actions / unit-tests / Unit Test - @aws-amplify/core

Deprecated: This type is deprecated and will be removed in future versions
import mockAmplifyOutputs from '../__mocks__/configMocks/amplify_outputs.json';

describe('parseAmplifyOutputs tests', () => {
Expand Down Expand Up @@ -110,6 +110,7 @@
auth: {
user_pool_id: 'us-east-1:',
user_pool_client_id: 'xxxx',
auth_session_validity: 15,
aws_region: 'us-east-1',
identity_pool_id: 'test',
oauth: {
Expand Down Expand Up @@ -162,6 +163,7 @@
},
userPoolClientId: 'xxxx',
userPoolId: 'us-east-1:',
authSessionValidity: 15,
loginWith: {
email: true,
phone: false,
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/parseAWSExports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export const parseAWSExports = (
aws_appsync_region,
aws_bots_config,
aws_cognito_identity_pool_id,
aws_cognito_auth_session_validity,
aws_cognito_sign_up_verification_method,
aws_cognito_mfa_configuration,
aws_cognito_mfa_types,
Expand Down Expand Up @@ -178,6 +179,7 @@ export const parseAWSExports = (
) ?? false,
}
: undefined;
const authSessionValidityConfig = aws_cognito_auth_session_validity;
const mergedUserAttributes: LegacyUserAttributeKey[] = Array.from(
new Set([
...(aws_cognito_verification_mechanisms ?? []),
Expand Down Expand Up @@ -216,6 +218,11 @@ export const parseAWSExports = (
},
},
};

if (authSessionValidityConfig !== undefined) {
amplifyConfig.Auth.Cognito.authSessionValidity =
authSessionValidityConfig;
}
}

const hasOAuthConfig = oauth ? Object.keys(oauth).length > 0 : false;
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/parseAmplifyOutputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ function parseAuth(
const {
user_pool_id,
user_pool_client_id,
auth_session_validity,
identity_pool_id,
password_policy,
mfa_configuration,
Expand All @@ -101,6 +102,10 @@ function parseAuth(
},
} as AuthConfig;

if (auth_session_validity !== undefined) {
authConfig.Cognito.authSessionValidity = auth_session_validity;
}

if (identity_pool_id) {
authConfig.Cognito = {
...authConfig.Cognito,
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/singleton/AmplifyOutputs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface AmplifyOutputsAuthProperties {
authentication_flow_type?: string;
user_pool_id: string;
user_pool_client_id: string;
auth_session_validity?: number;
identity_pool_id?: string;
password_policy?: {
min_length: number;
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/singleton/Auth/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export interface AuthIdentityPoolConfig {
userPoolClientId?: never;
userPoolId?: never;
userPoolEndpoint?: never;
authSessionValidity?: never;
loginWith?: never;
signUpVerificationMethod?: never;
userAttributes?: never;
Expand Down Expand Up @@ -179,6 +180,12 @@ export interface CognitoUserPoolConfig {
* Use this field to specify a custom endpoint for the Amazon Cognito user pool. Ensure this endpoint is correct and valid.
*/
userPoolEndpoint?: string;
/**
* Auth session duration in minutes for Cognito API challenge flows.
* This should match the user pool app client's AuthSessionValidity setting.
* Valid values are from 3 to 15 minutes.
*/
authSessionValidity?: number;
signUpVerificationMethod?: 'code' | 'link';
loginWith?: {
oauth?: OAuthConfig;
Expand Down
Loading