Skip to content

Commit

Permalink
feat: user agent enhancements - part1 cognito (#11324)
Browse files Browse the repository at this point in the history
* feat: implement new custom user agent details in amazon-cognito-identity-js

* chore: update variable name for clearer semantics

Co-authored-by: Chris F <5827964+cshfang@users.noreply.github.com>

* chore: incorporate PR feedback, fix inconsistent renaming of frameworkHasBeenRerun

---------

Co-authored-by: Chris F <5827964+cshfang@users.noreply.github.com>
  • Loading branch information
erinleigh90 and cshfang committed May 17, 2023
1 parent 65bf314 commit 4f541d2
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 25 deletions.
17 changes: 15 additions & 2 deletions packages/amazon-cognito-identity-js/__tests__/UserAgent.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import UserAgent, { appendToCognitoUserAgent } from '../src/UserAgent';
import { AuthAction, Framework } from '../src/Platform/constants';
import UserAgent, {
appendToCognitoUserAgent,
getAmplifyUserAgentString,
} from '../src/UserAgent';

const DEFAULT_USER_AGENT = 'aws-amplify/0.1.x js';
const DEFAULT_USER_AGENT = 'aws-amplify/0.1.x';
const AMPLIFY_USER_AGENT_NONE = `auth/${AuthAction.None} framework/${Framework.None}`;

describe('UserAgent test', () => {
beforeEach(() => {
Expand All @@ -18,6 +23,10 @@ describe('UserAgent test', () => {
test('appendToCognitoUserAgent appends content to userAgent', () => {
appendToCognitoUserAgent('test');
expect(UserAgent.prototype.userAgent).toBe(`${DEFAULT_USER_AGENT} test`);

expect(getAmplifyUserAgentString({ action: AuthAction.None })).toBe(
`${DEFAULT_USER_AGENT} test ${AMPLIFY_USER_AGENT_NONE}`
);
});

test('appendToCognitoUserAgent does not append duplicate content', () => {
Expand All @@ -28,6 +37,10 @@ describe('UserAgent test', () => {
);

expect(UserAgent.prototype.userAgent).toBe(`${DEFAULT_USER_AGENT} test`);

expect(getAmplifyUserAgentString({ action: AuthAction.None })).toBe(
`${DEFAULT_USER_AGENT} test ${AMPLIFY_USER_AGENT_NONE}`
);
});

test('appendToCognitoUserAgent sets userAgent if userAgent has no content', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import { version } from '../src/Platform/version';
describe('User agent version', () => {
test('getUserAgent version match', () => {
const userAgent = new UserAgent();
expect(userAgent.userAgent).toEqual(`aws-amplify/${version} js`);
expect(userAgent.userAgent).toEqual(`aws-amplify/${version}`);
});
})
});
7 changes: 5 additions & 2 deletions packages/amazon-cognito-identity-js/src/Client.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'isomorphic-unfetch';

import UserAgent from './UserAgent';
import { getAmplifyUserAgentString } from './UserAgent';
import { AuthAction } from './Platform/constants';

class CognitoError extends Error {
constructor(message, code, name, statusCode) {
Expand Down Expand Up @@ -79,7 +80,9 @@ export default class Client {
const headers = {
'Content-Type': 'application/x-amz-json-1.1',
'X-Amz-Target': `AWSCognitoIdentityProviderService.${operation}`,
'X-Amz-User-Agent': UserAgent.prototype.userAgent,
'X-Amz-User-Agent': getAmplifyUserAgentString({
action: AuthAction.None,
}),
'Cache-Control': 'no-store',
};

Expand Down
12 changes: 12 additions & 0 deletions packages/amazon-cognito-identity-js/src/Platform/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const Framework = {
None: '0',
ReactNative: '1',
};

export const category = 'auth';

// Actions
/* TODO: Replace 'None' with all expected Actions */
export const AuthAction = {
None: '0',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { Framework } from './constants';

export const detectFramework = () => {
if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
return Framework.ReactNative;
}
return Framework.None;
};
38 changes: 21 additions & 17 deletions packages/amazon-cognito-identity-js/src/Platform/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,34 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { version } from './version';
import { Framework } from './constants';
import { detectFramework } from './detectFramework';

const BASE_USER_AGENT = `aws-amplify/${version}`;

let framework = detectFramework();
let frameworkDetectionHasBeenRerun = false;
export const Platform = {
userAgent: `${BASE_USER_AGENT} js`,
product: '',
navigator: null,
isReactNative: false,
userAgent: BASE_USER_AGENT,
framework,
isReactNative: framework === Framework.ReactNative,
};

if (typeof navigator !== 'undefined' && navigator.product) {
Platform.product = navigator.product || '';
Platform.navigator = navigator || null;
switch (navigator.product) {
case 'ReactNative':
Platform.userAgent = `${BASE_USER_AGENT} react-native`;
Platform.isReactNative = true;
break;
default:
Platform.userAgent = `${BASE_USER_AGENT} js`;
Platform.isReactNative = false;
break;
/**
* Rerun framework detection once when getAmplifyUserAgent is called if framework is None.
* ReactNative framework must be detected initially, however other frameworks may not be
* detected in cases where DOM is not yet loaded.
*/
export const rerunFrameworkDetection = () => {
if (
Platform.framework === Framework.None &&
!frameworkDetectionHasBeenRerun
) {
framework = detectFramework();
frameworkDetectionHasBeenRerun = true;
Platform.framework = framework;
}
}
};

export const getUserAgent = () => {
return Platform.userAgent;
Expand Down
15 changes: 13 additions & 2 deletions packages/amazon-cognito-identity-js/src/UserAgent.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getUserAgent } from "./Platform";
import { Platform, getUserAgent, rerunFrameworkDetection } from './Platform';
import { category } from './Platform/constants';
// constructor
function UserAgent() { }
function UserAgent() {}
// public
UserAgent.prototype.userAgent = getUserAgent();

Expand All @@ -24,3 +25,13 @@ export const appendToCognitoUserAgent = content => {

// class for defining the amzn user-agent
export default UserAgent;

export const getAmplifyUserAgentString = ({ action, framework } = {}) => {
rerunFrameworkDetection();
const uaAction = action ?? AuthAction.None;
const uaFramework = framework ?? Platform.framework;

const userAgent = `${UserAgent.prototype.userAgent} ${category}/${uaAction} framework/${uaFramework}`;

return userAgent;
};

0 comments on commit 4f541d2

Please sign in to comment.