Skip to content

Commit

Permalink
Merge branch 'next/main' into chore/sync-console-preview-10-10-2
Browse files Browse the repository at this point in the history
  • Loading branch information
jimblanc committed Oct 10, 2023
2 parents 5f040a2 + db28490 commit 3c98807
Show file tree
Hide file tree
Showing 37 changed files with 1,143 additions and 190 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
name: Unit and Bundle tests have passed
needs:
- unit-tests
- bundle-size-tests
# - bundle-size-tests
- license-test
- github-actions-test
- tsc-compliance-test
Expand Down
87 changes: 87 additions & 0 deletions packages/auth/__tests__/providers/cognito/autoSignIn.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import {
CognitoUserPoolsTokenProvider,
signUp,
} from '../../../src/providers/cognito';
import { autoSignIn } from '../../../src/providers/cognito/apis/autoSignIn';
import * as signUpClient from '../../../src/providers/cognito/utils/clients/CognitoIdentityProvider';
import { authAPITestParams } from './testUtils/authApiTestParams';
import { RespondToAuthChallengeCommandOutput } from '../../../src/providers/cognito/utils/clients/CognitoIdentityProvider/types';
import { Amplify } from 'aws-amplify';
import * as initiateAuthHelpers from '../../../src/providers/cognito/utils/signInHelpers';
import { AuthError } from '../../../src/errors/AuthError';
jest.mock('@aws-amplify/core/lib/clients/handlers/fetch');

const authConfig = {
Cognito: {
userPoolClientId: '111111-aaaaa-42d8-891d-ee81a1549398',
userPoolId: 'us-west-2_zzzzz',
},
};
CognitoUserPoolsTokenProvider.setAuthConfig(authConfig);
Amplify.configure({
Auth: authConfig,
});
describe('Auto sign-in API Happy Path Cases:', () => {
let signUpSpy;
let handleUserSRPAuthflowSpy;
const { user1 } = authAPITestParams;
beforeEach(async () => {
signUpSpy = jest
.spyOn(signUpClient, 'signUp')
.mockImplementationOnce(async () => {
return {
UserConfirmed: true,
};
});

handleUserSRPAuthflowSpy = jest
.spyOn(initiateAuthHelpers, 'handleUserSRPAuthFlow')
.mockImplementationOnce(
async (): Promise<RespondToAuthChallengeCommandOutput> =>
authAPITestParams.RespondToAuthChallengeCommandOutput
);
});
afterEach(() => {
signUpSpy.mockClear();
handleUserSRPAuthflowSpy.mockClear();
});
test('signUp should enable autoSignIn and return COMPLETE_AUTO_SIGN_IN step', async () => {
const resp = await signUp({
username: user1.username,
password: user1.password,
options: {
userAttributes: { email: user1.email },
serviceOptions: {
autoSignIn: true,
},
},
});
expect(resp).toEqual({
isSignUpComplete: true,
nextStep: {
signUpStep: 'COMPLETE_AUTO_SIGN_IN',
},
});
expect(signUpSpy).toBeCalledTimes(1);
});

test('Auto sign-in should resolve to a signIn output', async () => {
const signInOutput = await autoSignIn();
expect(signInOutput).toEqual(authAPITestParams.signInResult());
expect(handleUserSRPAuthflowSpy).toBeCalledTimes(1);
});
});

describe('Auto sign-in API Error Path Cases:', () => {
test('autoSignIn should throw an error when autoSignIn is not enabled', async () => {
try {
await autoSignIn();
} catch (error) {
expect(error).toBeInstanceOf(AuthError);
expect(error.name).toBe('AutoSignInException');
}
});
});
11 changes: 6 additions & 5 deletions packages/auth/__tests__/providers/cognito/deleteUser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,13 @@ describe('deleteUser API happy path cases', () => {
})
);
expect(deleteUserClientSpy).toBeCalledTimes(1);
expect(tokenOrchestratorSpy).toHaveBeenCalledTimes(1);
expect(signOutApiSpy).toHaveBeenCalledTimes(1);

// signout
expect(signOutApiSpy).toBeCalledTimes(1);

// clear device tokens
expect(tokenOrchestratorSpy).toBeCalled();
// make sure we clearDeviceToken -> signout, in that order
expect(tokenOrchestratorSpy.mock.invocationCallOrder[0]).toBeLessThan(
signOutApiSpy.mock.invocationCallOrder[0]
);
});
});

Expand Down
1 change: 1 addition & 0 deletions packages/auth/src/errors/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export const USER_ALREADY_AUTHENTICATED_EXCEPTION =
'UserAlreadyAuthenticatedException';
export const DEVICE_METADATA_NOT_FOUND_EXCEPTION =
'DeviceMetadataNotFoundException';
export const AUTO_SIGN_IN_EXCEPTION = 'AutoSignInException';
1 change: 1 addition & 0 deletions packages/auth/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export {
rememberDevice,
forgetDevice,
fetchDevices,
autoSignIn,
} from './providers/cognito';

export {
Expand Down
119 changes: 119 additions & 0 deletions packages/auth/src/providers/cognito/apis/autoSignIn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { AuthError } from '../../../errors/AuthError';
import { AUTO_SIGN_IN_EXCEPTION } from '../../../errors/constants';
import { AutoSignInCallback } from '../../../types/models';
import { SignInOutput } from '../types';

const initialAutoSignIn: AutoSignInCallback =
async (): Promise<SignInOutput> => {
throw new AuthError({
name: AUTO_SIGN_IN_EXCEPTION,
message:
'The autoSignIn flow has not started, or has been cancelled/completed.',
recoverySuggestion:
'Please try to use the signIn API or log out before starting a new autoSignIn flow.',
});
};

/**
* Signs a user in automatically after finishing the sign-up process.
*
* This API will automatically sign a user in if the autoSignIn flow has been completed in the following cases:
* - User confirmed their account with a verification code sent to their phone or email (default option).
* - User confirmed their account with a verification link sent to their phone or email. In order to
* enable this option you need to go to the Amazon Cognito [console](https://aws.amazon.com/pm/cognito),
* look for your userpool, then go to the `Messaging` tab and enable `link` mode inside the `Verification message` option.
* Finally you need to define the `signUpVerificationMethod` in your `Auth` config.
*
* @example
* ```typescript
* Amplify.configure({
* Auth: {
* Cognito: {
* ...cognitoConfig,
* signUpVerificationMethod: "link" // the default value is "code"
* }
* }});
* ```
*
* @throws AutoSignInException - Thrown when the autoSignIn flow has not started, or has been cancelled/completed.
* @returns The signInOutput.
*
* @example
* ```typescript
* // handleSignUp.ts
* async function handleSignUp(
* username:string,
* password:string
* ){
* try {
* const { nextStep } = await signUp({
* username,
* password,
* options: {
* userAttributes:{ email:'[email protected]'},
* serviceOptions: {
* autoSignIn: true // This enables the auto sign-in flow.
* },
* },
* });
*
* handleSignUpStep(nextStep);
*
* } catch (error) {
* console.log(error);
* }
* }
*
* // handleConfirmSignUp.ts
* async function handleConfirmSignUp(username:string, confirmationCode:string) {
* try {
* const { nextStep } = await confirmSignUp({
* username,
* confirmationCode,
* });
*
* handleSignUpStep(nextStep);
* } catch (error) {
* console.log(error);
* }
* }
*
* // signUpUtils.ts
* async function handleSignUpStep( step: SignUpOutput["nextStep"]) {
* switch (step.signUpStep) {
* case "CONFIRM_SIGN_UP":
*
* // Redirect end-user to confirm-sign up screen.
*
* case "COMPLETE_AUTO_SIGN_IN":
* const codeDeliveryDetails = step.codeDeliveryDetails;
* if (codeDeliveryDetails) {
* // Redirect user to confirm-sign-up with link screen.
* }
* const signInOutput = await autoSignIn();
* // handle sign-in steps
* }
*
* ```
*/
export let autoSignIn: AutoSignInCallback = initialAutoSignIn;

/**
* Sets the context of autoSignIn at run time.
* @internal
*/
export function setAutoSignIn(callback: AutoSignInCallback) {
autoSignIn = callback;
}

/**
* Resets the context
*
* @internal
*/
export function resetAutoSignIn() {
autoSignIn = initialAutoSignIn;
}
63 changes: 54 additions & 9 deletions packages/auth/src/providers/cognito/apis/confirmSignUp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@
// SPDX-License-Identifier: Apache-2.0

import { Amplify } from '@aws-amplify/core';
import { assertTokenProviderConfig, AuthAction } from '@aws-amplify/core/internals/utils';
import {
assertTokenProviderConfig,
AuthAction,
HubInternal,
} from '@aws-amplify/core/internals/utils';
import { ConfirmSignUpInput, ConfirmSignUpOutput } from '../types';
import { assertValidationError } from '../../../errors/utils/assertValidationError';
import { AuthValidationErrorCode } from '../../../errors/types/validation';
import { ConfirmSignUpException } from '../types/errors';
import { confirmSignUp as confirmSignUpClient } from '../utils/clients/CognitoIdentityProvider';
import { getRegion } from '../utils/clients/CognitoIdentityProvider/utils';
import { AutoSignInEventData } from '../types/models';
import {
isAutoSignInStarted,
isAutoSignInUserUsingConfirmSignUp,
setAutoSignInStarted,
} from '../utils/signUpHelpers';
import { getAuthUserAgentValue } from '../../../utils';

/**
Expand Down Expand Up @@ -40,9 +50,9 @@ export async function confirmSignUp(
);

await confirmSignUpClient(
{
{
region: getRegion(authConfig.userPoolId),
userAgentValue: getAuthUserAgentValue(AuthAction.ConfirmSignUp)
userAgentValue: getAuthUserAgentValue(AuthAction.ConfirmSignUp),
},
{
Username: username,
Expand All @@ -54,10 +64,45 @@ export async function confirmSignUp(
}
);

return {
isSignUpComplete: true,
nextStep: {
signUpStep: 'DONE',
},
};
return new Promise((resolve, reject) => {
try {
const signUpOut: ConfirmSignUpOutput = {
isSignUpComplete: true,
nextStep: {
signUpStep: 'DONE',
},
};

if (
!isAutoSignInStarted() ||
!isAutoSignInUserUsingConfirmSignUp(username)
) {
return resolve(signUpOut);
}

const stopListener = HubInternal.listen<AutoSignInEventData>(
'auth-internal',
({ payload }) => {
switch (payload.event) {
case 'autoSignIn':
resolve({
isSignUpComplete: true,
nextStep: {
signUpStep: 'COMPLETE_AUTO_SIGN_IN',
},
});
setAutoSignInStarted(false);
stopListener();
}
}
);

HubInternal.dispatch('auth-internal', {
event: 'confirmSignUp',
data: signUpOut,
});
} catch (error) {
reject(error);
}
});
}
11 changes: 7 additions & 4 deletions packages/auth/src/providers/cognito/apis/deleteUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
// SPDX-License-Identifier: Apache-2.0

import { Amplify } from '@aws-amplify/core';
import { assertTokenProviderConfig, AuthAction } from '@aws-amplify/core/internals/utils';
import {
assertTokenProviderConfig,
AuthAction,
} from '@aws-amplify/core/internals/utils';
import { fetchAuthSession } from '../../../';
import { getRegion } from '../utils/clients/CognitoIdentityProvider/utils';
import { assertAuthTokens } from '../utils/types';
Expand All @@ -26,14 +29,14 @@ export async function deleteUser(): Promise<void> {
assertAuthTokens(tokens);

await serviceDeleteUser(
{
{
region: getRegion(authConfig.userPoolId),
userAgentValue: getAuthUserAgentValue(AuthAction.DeleteUser)
userAgentValue: getAuthUserAgentValue(AuthAction.DeleteUser),
},
{
AccessToken: tokens.accessToken.toString(),
}
);
await signOut();
await tokenOrchestrator.clearDeviceMetadata();
await signOut();
}
4 changes: 2 additions & 2 deletions packages/auth/src/providers/cognito/apis/resendSignUpCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// SPDX-License-Identifier: Apache-2.0

import { Amplify } from '@aws-amplify/core';
import { assertTokenProviderConfig, AuthAction } from '@aws-amplify/core/internals/utils';
import { AuthStandardAttributeKey, AuthDeliveryMedium } from '../../../types';
import { assertTokenProviderConfig, AuthAction, AuthStandardAttributeKey } from '@aws-amplify/core/internals/utils';
import { AuthDeliveryMedium } from '../../../types';
import { assertValidationError } from '../../../errors/utils/assertValidationError';
import { AuthValidationErrorCode } from '../../../errors/types/validation';
import { ResendSignUpCodeInput, ResendSignUpCodeOutput } from '../types';
Expand Down
4 changes: 2 additions & 2 deletions packages/auth/src/providers/cognito/apis/resetPassword.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
// SPDX-License-Identifier: Apache-2.0

import { Amplify } from '@aws-amplify/core';
import { assertTokenProviderConfig, AuthAction } from '@aws-amplify/core/internals/utils';
import { assertTokenProviderConfig, AuthAction, AuthStandardAttributeKey } from '@aws-amplify/core/internals/utils';
import { AuthValidationErrorCode } from '../../../errors/types/validation';
import { assertValidationError } from '../../../errors/utils/assertValidationError';
import { AuthDeliveryMedium, AuthStandardAttributeKey } from '../../../types';
import { AuthDeliveryMedium } from '../../../types';
import { ResetPasswordInput, ResetPasswordOutput } from '../types';
import { forgotPassword } from '../utils/clients/CognitoIdentityProvider';
import { getRegion } from '../utils/clients/CognitoIdentityProvider/utils';
Expand Down
Loading

0 comments on commit 3c98807

Please sign in to comment.