Skip to content

Commit

Permalink
fix(auth): impossibility to sign-in when RandomKeyPassword is missing (
Browse files Browse the repository at this point in the history
  • Loading branch information
israx committed Apr 25, 2024
2 parents 3f07b11 + 57c9aca commit 6d4366e
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 7 deletions.
84 changes: 80 additions & 4 deletions packages/auth/__tests__/providers/cognito/signInWithSRP.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,18 @@ import {
import { AuthError } from '../../../src';
import { createKeysForAuthStorage } from '../../../src/providers/cognito/tokenProvider/TokenStore';
import * as clients from '../../../src/providers/cognito/utils/clients/CognitoIdentityProvider';

jest.mock('../../../src/providers/cognito/utils/dispatchSignedInHubEvent');

jest.mock('../../../src/providers/cognito/utils/srp', () => {
return {
...jest.requireActual('../../../src/providers/cognito/utils/srp'),
getAuthenticationHelper: jest.fn(() => ({
A: { toString: jest.fn() },
getPasswordAuthenticationKey: jest.fn(),
})),
getSignatureString: jest.fn(),
}
})
jest.mock('@aws-amplify/core/internals/utils', () => ({
...jest.requireActual('@aws-amplify/core/internals/utils'),
isBrowser: jest.fn(() => false),
Expand Down Expand Up @@ -56,13 +66,27 @@ function setDeviceKeys() {
mockedDeviceMetadata.randomPasswordKey,
);
}
type DeviceKey = 'deviceKey' | 'deviceGroupKey' | 'randomPasswordKey';
function deleteDeviceKey(key: DeviceKey) {
switch (key) {
case 'deviceKey':
localStorage.removeItem(authKeys.deviceKey);
break
case 'deviceGroupKey':
localStorage.removeItem(authKeys.deviceGroupKey);
break
case 'randomPasswordKey':
localStorage.removeItem(authKeys.randomPasswordKey);
break
}
}

describe('signIn API happy path cases', () => {
let handleUserSRPAuthflowSpy;
let handleUserSRPAuthflowSpy = jest
.spyOn(initiateAuthHelpers, 'handleUserSRPAuthFlow')

beforeEach(() => {
handleUserSRPAuthflowSpy = jest
.spyOn(initiateAuthHelpers, 'handleUserSRPAuthFlow')
handleUserSRPAuthflowSpy
.mockImplementation(
async (): Promise<RespondToAuthChallengeCommandOutput> =>
authAPITestParams.RespondToAuthChallengeCommandOutput,
Expand Down Expand Up @@ -163,6 +187,58 @@ describe('signIn API happy path cases', () => {
tokenOrchestrator,
);
});

describe('sign in with device keys', () => {
const initiateAuthSpy = jest
.spyOn(clients, 'initiateAuth')
const respondToAuthChallengeAuthSpy = jest
.spyOn(clients, 'respondToAuthChallenge')
beforeEach(() => {
setDeviceKeys();
handleUserSRPAuthflowSpy.mockRestore();
initiateAuthSpy.mockResolvedValueOnce({
ChallengeName: 'SRP_AUTH',
Session: '1234234232',
$metadata: {},
ChallengeParameters: {
USER_ID_FOR_SRP: lastAuthUser,
}
});
respondToAuthChallengeAuthSpy.mockResolvedValueOnce(authAPITestParams.RespondToAuthChallengeCommandOutput);
})

afterEach(() => {
initiateAuthSpy.mockClear();
respondToAuthChallengeAuthSpy.mockClear();
})

test('respondToAuthChallenge should include device key in the request', async () => {

await signIn({
username: lastAuthUser,
password: 'XXXXXXXX',
});

expect(respondToAuthChallengeAuthSpy).toHaveBeenCalledTimes(1);
const deviceKeyFromRequest = respondToAuthChallengeAuthSpy.mock.calls[0][1].ChallengeResponses?.DEVICE_KEY
expect(deviceKeyFromRequest).toBe('mockedKey')

})
const deviceKeys: DeviceKey[] = ['deviceKey', 'deviceGroupKey', 'randomPasswordKey']
test.each(deviceKeys)('respondToAuthChallenge should not include device key in the request if any device key in storage is deleted', async deviceKey => {
deleteDeviceKey(deviceKey);
await signIn({
username: lastAuthUser,
password: 'XXXXXXXX',
});

expect(respondToAuthChallengeAuthSpy).toHaveBeenCalledTimes(1);
const deviceKeyFromRequest = respondToAuthChallengeAuthSpy.mock.calls[0][1].ChallengeResponses?.DEVICE_KEY
expect(deviceKeyFromRequest).toBe(undefined)

})
})

});

describe('Cognito ASF', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,10 @@ export class DefaultTokenStore implements AuthTokenStore {
authKeys.randomPasswordKey,
);

return randomPassword
return randomPassword && deviceGroupKey && deviceKey
? {
deviceKey: deviceKey ?? undefined,
deviceGroupKey: deviceGroupKey ?? undefined,
deviceKey,
deviceGroupKey,
randomPassword,
}
: null;
Expand Down

0 comments on commit 6d4366e

Please sign in to comment.