Skip to content

Commit

Permalink
Feat/user agent enhancements/auth (#11442)
Browse files Browse the repository at this point in the history
* feat: add action and category to cognito calls based on Client request operation

* fix: add exports to index.d.ts

* fix: fix silly mistakes in user agent work

* test: fix spacing issue in index.test.js

* test: fix failing tests and update getAmplifyUserAgentString signature based on changes

* test: adds user agent test to CognitoUserPool

* fix: update name missmatch

* fix: update name missmatch

* chore: add revokeToken for non global sign outs

* test: fix name mismatch

* test: fix test side effects:

* test: add tests for InitiateAuth user agent headers

* test: fix plain username password test

* chore: set category/framework on UserAgent instead of UserAgent.prototype

* test: user agent test for authaction confirmdevice

* test: remove unnecessary spies

* test: fix test name

* test: add getDeviceResponse test for user agent header

* chore: move new function exports to internals
  • Loading branch information
erinleigh90 committed Jun 5, 2023
1 parent d295bd1 commit e5115ef
Show file tree
Hide file tree
Showing 14 changed files with 342 additions and 64 deletions.
225 changes: 204 additions & 21 deletions packages/amazon-cognito-identity-js/__tests__/CognitoUser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import Client from '../src/Client';
import CognitoIdToken from '../src/CognitoIdToken';
import CognitoAccessToken from '../src/CognitoAccessToken';
import CognitoRefreshToken from '../src/CognitoRefreshToken';
import { getUserAgent } from '../src/Platform';
import { AuthAction } from '../src/Platform/constants';
import { addAuthCategoryToCognitoUserAgent } from '../src/UserAgent';

import {
callback,
Expand Down Expand Up @@ -184,10 +187,38 @@ describe('initiateAuth()', () => {
expect(cacheTokensSpy).toBeCalled();
expect(callback.onSuccess.mock.calls.length).toBe(1);
});

test('global fetch called with expected user agent header InitiateAuth', () => {
const fetchMock = jest
.spyOn(global, 'fetch')
.mockImplementation(() =>
Promise.resolve({ json: () => Promise.resolve([]) })
);

addAuthCategoryToCognitoUserAgent();

const authDetails = new AuthenticationDetails(authDetailData);
user.initiateAuth(authDetails, callback);

expect(global.fetch.mock.calls.length).toBe(1);
expect(fetchMock).toBeCalledWith(
expect.anything(),
expect.objectContaining({
headers: expect.objectContaining({
'X-Amz-User-Agent': `${getUserAgent()} auth/${
AuthAction.InitiateAuth
}`,
}),
})
);
});
});

describe('authenticateUser()', () => {
afterAll(() => {
afterEach(() => {
callback.onFailure.mockClear();
callback.onSuccess.mockClear();
callback.customChallenge.mockClear();
jest.restoreAllMocks();
});

Expand Down Expand Up @@ -222,6 +253,31 @@ describe('authenticateUser()', () => {
user.authenticateUser(authDetails, callback);
expect(callback.onFailure.mock.calls.length).toBe(1);
});

test('global fetch called with expected user agent header InitiateAuth', () => {
const fetchMock = jest
.spyOn(global, 'fetch')
.mockImplementation(() =>
Promise.resolve({ json: () => Promise.resolve([]) })
);

addAuthCategoryToCognitoUserAgent();

user.setAuthenticationFlowType('USER_PASSWORD_AUTH');
user.authenticateUser(authDetails, callback);

expect(global.fetch.mock.calls.length).toBe(1);
expect(fetchMock).toBeCalledWith(
expect.anything(),
expect.objectContaining({
headers: expect.objectContaining({
'X-Amz-User-Agent': `${getUserAgent()} auth/${
AuthAction.InitiateAuth
}`,
}),
})
);
});
});

describe('authenticateUserDefaultAuth()', () => {
Expand Down Expand Up @@ -259,6 +315,29 @@ describe('authenticateUserDefaultAuth()', () => {
user.authenticateUserDefaultAuth(authDetails, callback);
expect(callback.onFailure.mock.calls.length).toBe(1);
});

test('global fetch called with expected user agent header InitiateAuth', () => {
const fetchMock = jest
.spyOn(global, 'fetch')
.mockImplementation(() =>
Promise.resolve({ json: () => Promise.resolve([]) })
);

addAuthCategoryToCognitoUserAgent();
user.authenticateUserDefaultAuth(authDetails, callback);

expect(global.fetch.mock.calls.length).toBe(1);
expect(fetchMock).toBeCalledWith(
expect.anything(),
expect.objectContaining({
headers: expect.objectContaining({
'X-Amz-User-Agent': `${getUserAgent()} auth/${
AuthAction.InitiateAuth
}`,
}),
})
);
});
});

describe('authenticateUserPlainUsernamePassword()', () => {
Expand Down Expand Up @@ -311,6 +390,31 @@ describe('authenticateUserPlainUsernamePassword()', () => {
);
expect(userSpy3.mock.results[0].value).toBe('test return value');
});

test('global fetch called with expected user agent header InitiateAuth', () => {
const fetchMock = jest
.spyOn(global, 'fetch')
.mockImplementation(() =>
Promise.resolve({ json: () => Promise.resolve([]) })
);

addAuthCategoryToCognitoUserAgent();

const authDetails = new AuthenticationDetails(authDetailData);
user.authenticateUserPlainUsernamePassword(authDetails, callback);

expect(global.fetch.mock.calls.length).toBe(1);
expect(fetchMock).toBeCalledWith(
expect.anything(),
expect.objectContaining({
headers: expect.objectContaining({
'X-Amz-User-Agent': `${getUserAgent()} auth/${
AuthAction.InitiateAuth
}`,
}),
})
);
});
});

describe('authenticateUserInternal()', () => {
Expand Down Expand Up @@ -482,6 +586,30 @@ describe('authenticateUserInternal()', () => {
user.authenticateUserInternal(authData, authHelper, callback);
expect(callback.onSuccess).toBeCalledWith(user.signInUserSession, true);
});

test('global fetch called with expected user agent header ConfirmDevice', () => {
const fetchMock = jest
.spyOn(global, 'fetch')
.mockImplementation(() =>
Promise.resolve({ json: () => Promise.resolve([]) })
);

addAuthCategoryToCognitoUserAgent();

user.authenticateUserInternal(authData, authHelper, callback);

expect(global.fetch.mock.calls.length).toBe(1);
expect(fetchMock).toBeCalledWith(
expect.anything(),
expect.objectContaining({
headers: expect.objectContaining({
'X-Amz-User-Agent': `${getUserAgent()} auth/${
AuthAction.ConfirmDevice
}`,
}),
})
);
});
});

describe('completeNewPasswordChallenge()', () => {
Expand Down Expand Up @@ -560,6 +688,35 @@ describe('completeNewPasswordChallenge()', () => {
);
expect(spyon2).toBeCalledTimes(1);
});

test('global fetch called with expected user agent header RespondToAuthChallenge', () => {
const fetchMock = jest
.spyOn(global, 'fetch')
.mockImplementation(() =>
Promise.resolve({ json: () => Promise.resolve([]) })
);

addAuthCategoryToCognitoUserAgent();

user.completeNewPasswordChallenge(
'NEWp@ssw0rd',
requiredAttributeData,
callback,
clientMetadata
);

expect(global.fetch.mock.calls.length).toBe(1);
expect(fetchMock).toBeCalledWith(
expect.anything(),
expect.objectContaining({
headers: expect.objectContaining({
'X-Amz-User-Agent': `${getUserAgent()} auth/${
AuthAction.RespondToAuthChallenge
}`,
}),
})
);
});
});

describe('getDeviceResponse()', () => {
Expand Down Expand Up @@ -603,6 +760,34 @@ describe('getDeviceResponse()', () => {
expect(callback.onFailure).toBeCalledWith(networkError);
});

test('global fetch called with expected user agent header RespondToAuthChallenge', () => {
const fetchMock = jest
.spyOn(global, 'fetch')
.mockImplementation(() =>
Promise.resolve({ json: () => Promise.resolve([]) })
);

addAuthCategoryToCognitoUserAgent();

jest
.spyOn(AuthenticationHelper.prototype, 'getLargeAValue')
.mockImplementation(cb => cb(null, 12345));

user.getDeviceResponse(callback, {});

expect(global.fetch.mock.calls.length).toBe(1);
expect(fetchMock).toBeCalledWith(
expect.anything(),
expect.objectContaining({
headers: expect.objectContaining({
'X-Amz-User-Agent': `${getUserAgent()} auth/${
AuthAction.RespondToAuthChallenge
}`,
}),
})
);
});

/**TODO: Check this clientRequestSpy */
describe('RespondToAuthChallenge nested Client method suite', () => {
let clientRequestSpy;
Expand Down Expand Up @@ -1660,36 +1845,34 @@ describe('refreshSession()', () => {

test('update attributes usage of three out of three parameters in callback', () => {
const codeDeliverDetailsResult = {
'CodeDeliveryDetailsList': [
{
'AttributeName': 'email',
'DeliveryMedium': 'EMAIL',
'Destination': 'e***@e***'
}
]
CodeDeliveryDetailsList: [
{
AttributeName: 'email',
DeliveryMedium: 'EMAIL',
Destination: 'e***@e***',
},
],
};
const spyon = jest.spyOn(CognitoUser.prototype, 'updateAttributes')
const spyon = jest
.spyOn(CognitoUser.prototype, 'updateAttributes')
.mockImplementationOnce((attrs, callback) => {
callback(null, 'SUCCESS', codeDeliverDetailsResult);
});
});
const attrs = [
{
Name: 'email',
Value: 'email@email.com'
Value: 'email@email.com',
},
{
Name: 'family_name',
Value: 'familyName'
}
Value: 'familyName',
},
];
cognitoUser.updateAttributes(
attrs,
(err, result, details) => {
expect(err).toBe(null);
expect(result).toBe('SUCCESS');
expect(details).toBe(codeDeliverDetailsResult);
}
);
cognitoUser.updateAttributes(attrs, (err, result, details) => {
expect(err).toBe(null);
expect(result).toBe('SUCCESS');
expect(details).toBe(codeDeliverDetailsResult);
});
spyon.mockClear();
});
});
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import CognitoUserPool from '../src/CognitoUserPool';
import Client from '../src/Client';
import { getUserAgent } from '../src/Platform';
import { AuthAction } from '../src/Platform/constants';
import {
clientId,
userPoolId,
userPoolName,
userName,
password,
} from './constants';
import { addAuthCategoryToCognitoUserAgent } from '../src/UserAgent';

describe('Constructor and accessor methods', () => {
const minimalData = { UserPoolId: userPoolId, ClientId: clientId };
Expand Down Expand Up @@ -59,7 +62,7 @@ describe('Testing signUp of a user into a user pool', () => {
const minimalData = { UserPoolId: userPoolId, ClientId: clientId };
const cognitoUserPool = new CognitoUserPool(minimalData);

afterAll(() => {
afterEach(() => {
jest.restoreAllMocks();
});

Expand Down Expand Up @@ -89,4 +92,25 @@ describe('Testing signUp of a user into a user pool', () => {
cognitoUserPool.signUp(userName, password, [], [], callback, []);
expect(callback.mock.calls.length).toBe(1);
});

test('headers contain user agent with auth category and sign up action', () => {
const fetchMock = jest
.spyOn(global, 'fetch')
.mockImplementation(() =>
Promise.resolve({ json: () => Promise.resolve([]) })
);

addAuthCategoryToCognitoUserAgent();

const callback = jest.fn();
cognitoUserPool.signUp(userName, password, [], [], callback, []);
expect(fetchMock).toBeCalledWith(
expect.anything(),
expect.objectContaining({
headers: expect.objectContaining({
'X-Amz-User-Agent': `${getUserAgent()} auth/${AuthAction.SignUp}`,
}),
})
);
});
});
Loading

0 comments on commit e5115ef

Please sign in to comment.