Skip to content

Commit

Permalink
feat(@aws-amplify/ui-components): User agent tracking for UI componen…
Browse files Browse the repository at this point in the history
…t packages (#4804)

* Update Cognito user agent inside of amplify-authenticator

* Move user agent set to configure, change append logic check

* UserAgent unit tests for cognito sdk
  • Loading branch information
jordanranz committed Feb 4, 2020
1 parent 6d1019f commit 15a0a2f
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 19 deletions.
42 changes: 42 additions & 0 deletions packages/amazon-cognito-identity-js/__tests__/UserAgent-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import UserAgent, { appendToCognitoUserAgent } from '../src/UserAgent';

const DEFAULT_USER_AGENT = 'amazon-cognito-identity-js';

describe('UserAgent test', () => {
beforeEach(() => {
UserAgent.prototype.userAgent = DEFAULT_USER_AGENT;
});
test('userAgent is set by default', () => {
expect(UserAgent.prototype.userAgent).toBe(DEFAULT_USER_AGENT);
});

test('appendToCognitoUserAgent does nothing to the userAgent if nothing is passed into it', () => {
appendToCognitoUserAgent();
expect(UserAgent.prototype.userAgent).toBe(DEFAULT_USER_AGENT);
});

test('appendToCognitoUserAgent appends content to userAgent', () => {
appendToCognitoUserAgent('test');
expect(UserAgent.prototype.userAgent).toBe(`${DEFAULT_USER_AGENT} test`);
});

test('appendToCognitoUserAgent does not append duplicate content', () => {
appendToCognitoUserAgent('test');
appendToCognitoUserAgent('test');
expect(UserAgent.prototype.userAgent).not.toBe(
`${DEFAULT_USER_AGENT} test test`
);

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

test('appendToCognitoUserAgent sets userAgent if userAgent has no content', () => {
UserAgent.prototype.userAgent = '';
appendToCognitoUserAgent('test');
expect(UserAgent.prototype.userAgent).toBe('test');

UserAgent.prototype.userAgent = undefined;
appendToCognitoUserAgent('test');
expect(UserAgent.prototype.userAgent).toBe('test');
});
});
6 changes: 6 additions & 0 deletions packages/amazon-cognito-identity-js/index.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 42 additions & 0 deletions packages/amazon-cognito-identity-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,47 @@
"react-native": "^0.44.0",
"rimraf": "^2.5.4",
"webpack": "^3.5.5"
},
"jest": {
"globals": {
"ts-jest": {
"diagnostics": false,
"tsConfig": {
"lib": [
"es5",
"es2015",
"dom",
"esnext.asynciterable",
"es2017.object"
],
"allowJs": true
}
}
},
"transform": {
"^.+\\.(js|jsx|ts|tsx)$": "ts-jest"
},
"preset": "ts-jest",
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(tsx?|jsx?)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"json",
"jsx"
],
"testEnvironment": "jsdom",
"testURL": "http://localhost/",
"coverageThreshold": {
"global": {
"branches": 0,
"functions": 0,
"lines": 0,
"statements": 0
}
},
"coveragePathIgnorePatterns": [
"/node_modules/"
]
}
}
3 changes: 1 addition & 2 deletions packages/amazon-cognito-identity-js/src/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export default class Client {
*/
constructor(region, endpoint) {
this.endpoint = endpoint || `https://cognito-idp.${region}.amazonaws.com/`;
this.userAgent = UserAgent.prototype.userAgent || 'aws-amplify/0.1.x js';
}

/**
Expand All @@ -23,7 +22,7 @@ export default class Client {
const headers = {
'Content-Type': 'application/x-amz-json-1.1',
'X-Amz-Target': `AWSCognitoIdentityProviderService.${operation}`,
'X-Amz-User-Agent': this.userAgent,
'X-Amz-User-Agent': UserAgent.prototype.userAgent,
};

const options = {
Expand Down
26 changes: 23 additions & 3 deletions packages/amazon-cognito-identity-js/src/UserAgent.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
// class for defining the amzn user-agent
export default UserAgent;
const DEFAULT_USER_AGENT = 'amazon-cognito-identity-js';
// constructor
function UserAgent() {}
// public
UserAgent.prototype.userAgent = 'aws-amplify/0.1.x js';
UserAgent.prototype.userAgent = DEFAULT_USER_AGENT;

export const appendToCognitoUserAgent = content => {
if (!content) {
return;
}
if (
UserAgent.prototype.userAgent &&
!UserAgent.prototype.userAgent.includes(content)
) {
UserAgent.prototype.userAgent = UserAgent.prototype.userAgent.concat(
' ',
content
);
}
if (!UserAgent.prototype.userAgent || UserAgent.prototype.userAgent === '') {
UserAgent.prototype.userAgent = content;
}
};

// class for defining the amzn user-agent
export default UserAgent;
1 change: 1 addition & 0 deletions packages/amazon-cognito-identity-js/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ export { default as CognitoUserPool } from './CognitoUserPool';
export { default as CognitoUserSession } from './CognitoUserSession';
export { default as CookieStorage } from './CookieStorage';
export { default as DateHelper } from './DateHelper';
export { appendToCognitoUserAgent } from './UserAgent';
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ Object {
"amplify-ui-components/p-c0fae6c3.js": "2 KB",
"amplify-ui-components/p-d1csj4vs.entry.js": "1 KB",
"amplify-ui-components/p-d447982c.js": "12 KB",
"amplify-ui-components/p-ddpnluaq.entry.js": "115 KB",
"amplify-ui-components/p-ea249ef6.system.js": "21 KB",
"amplify-ui-components/p-emwljr8n.entry.js": "115 KB",
"amplify-ui-components/p-f28d0f9c.js": "15 KB",
"amplify-ui-components/p-qa19ycsj.system.entry.js": "2 KB",
"amplify-ui-components/p-uxv5ujph.system.entry.js": "143 KB",
"amplify-ui-components/p-xpmjxplw.system.entry.js": "3 KB",
"amplify-ui-components/p-zpx5ky0w.system.entry.js": "143 KB",
"cjs/amplify-amazon-button_45.cjs.entry.js": "248 KB",
"cjs/amplify-checkbox.cjs.entry.js": "1 KB",
"cjs/amplify-federated-sign-in.cjs.entry.js": "2 KB",
Expand Down Expand Up @@ -75,7 +75,7 @@ Object {
"collection/components/amplify-examples/rock-paper-scissor/rock-paper-scissor.css": "69 Bytes",
"collection/components/amplify-examples/rock-paper-scissor/rock-paper-scissor.js": "2 KB",
"collection/components/amplify-examples/scene-example.js": "191 Bytes",
"collection/components/amplify-examples/src/aws-exports.js": "19 Bytes",
"collection/components/amplify-examples/src/aws-exports.js": "1 KB",
"collection/components/amplify-facebook-button/amplify-facebook-button.js": "5 KB",
"collection/components/amplify-federated-buttons/amplify-federated-buttons.js": "6 KB",
"collection/components/amplify-federated-sign-in/amplify-federated-sign-in.js": "4 KB",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component, State, Prop, h, Host } from '@stencil/core';
import { AuthState, CognitoUserInterface, FederatedConfig } from '../../common/types/auth-types';
import { NO_AUTH_MODULE_FOUND, SIGNING_IN_WITH_HOSTEDUI_KEY, AUTHENTICATOR_AUTHSTATE } from '../../common/constants';
import { Auth } from '@aws-amplify/auth';
import { Auth, appendToCognitoUserAgent } from '@aws-amplify/auth';

This comment has been minimized.

Copy link
@mdlavin

mdlavin Apr 5, 2020

Due to this addition, I believe that the @aws-amplify/auth dependency version in amplify-ui-components should be bumped to 3.x so that this method can be found. If. @aws-amplify/ui-components is paired with @aws-amplify/auth 2 an error is hit at runtime

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

const logger = new Logger('Authenticator');
Expand All @@ -21,6 +21,7 @@ export class AmplifyAuthenticator {
@Prop() federated: FederatedConfig;

async componentWillLoad() {
appendToCognitoUserAgent('amplify-ui');
const byHostedUI = localStorage.getItem(SIGNING_IN_WITH_HOSTEDUI_KEY);
localStorage.removeItem(SIGNING_IN_WITH_HOSTEDUI_KEY);
if (byHostedUI !== 'true') await this.checkUser();
Expand Down
2 changes: 1 addition & 1 deletion packages/amplify-ui-react/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './components';
export * from './components';
13 changes: 9 additions & 4 deletions packages/auth/src/Auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
ICredentials,
Parser,
JS,
Platform,
} from '@aws-amplify/core';
import {
CookieStorage,
Expand All @@ -58,6 +59,7 @@ import {
CognitoIdToken,
CognitoRefreshToken,
CognitoAccessToken,
appendToCognitoUserAgent,
} from 'amazon-cognito-identity-js';

import { parse } from 'url';
Expand All @@ -70,7 +72,7 @@ const logger = new Logger('AuthClass');
const USER_ADMIN_SCOPE = 'aws.cognito.signin.user.admin';

const AMPLIFY_SYMBOL = (typeof Symbol !== 'undefined' &&
typeof Symbol.for === 'function'
typeof Symbol.for === 'function'
? Symbol.for('amplify_default')
: '@@amplify_default') as Symbol;

Expand Down Expand Up @@ -223,6 +225,8 @@ export class AuthClass {
});
}

appendToCognitoUserAgent(Platform.userAgent);

dispatchAuthEvent(
'configured',
null,
Expand Down Expand Up @@ -416,6 +420,7 @@ export class AuthClass {
if (!this.userPool) {
return this.rejectNoUserPool();
}

let username = null;
let password = null;
let validationData = {};
Expand Down Expand Up @@ -1159,7 +1164,7 @@ export class AuthClass {
} else {
logger.debug(
`Unable to get the user data because the ${USER_ADMIN_SCOPE} ` +
`is not in the scopes of the access token`
`is not in the scopes of the access token`
);
return res(user);
}
Expand Down Expand Up @@ -1210,7 +1215,7 @@ export class AuthClass {
if (e === 'No userPool') {
logger.error(
'Cannot get the current user because the user pool is missing. ' +
'Please make sure the Auth module is configured with a valid Cognito User Pool ID'
'Please make sure the Auth module is configured with a valid Cognito User Pool ID'
);
}
logger.debug('The user is not authenticated by the error', e);
Expand Down Expand Up @@ -1759,7 +1764,7 @@ export class AuthClass {
logger.warn(`There is already a signed in user: ${loggedInUser} in your app.
You should not call Auth.federatedSignIn method again as it may cause unexpected behavior.`);
}
} catch (e) {}
} catch (e) { }

const { token, identity_id, expires_at } = response;
// Because Credentials.set would update the user info with identity id
Expand Down
5 changes: 3 additions & 2 deletions packages/auth/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
*/

import { AuthClass, CognitoHostedUIIdentityProvider } from './Auth';
import { CognitoUser, CookieStorage } from 'amazon-cognito-identity-js';
import { Amplify, ConsoleLogger as Logger } from '@aws-amplify/core';
import { CognitoUser, CookieStorage, appendToCognitoUserAgent } from 'amazon-cognito-identity-js';
import { ConsoleLogger as Logger } from '@aws-amplify/core';

const logger = new Logger('Auth');

Expand All @@ -36,4 +36,5 @@ export {
CognitoUser,
CookieStorage,
CognitoHostedUIIdentityProvider,
appendToCognitoUserAgent
};
9 changes: 6 additions & 3 deletions packages/core/src/Platform/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
*/
import { version } from './version';
import { appendToUserAgent } from '@aws-sdk/util-user-agent-browser';

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

export const Platform = {
userAgent: `aws-amplify/${version} js`,
userAgent: `${BASE_USER_AGENT} js`,
product: '',
navigator: null,
isReactNative: false,
Expand All @@ -23,11 +26,11 @@ if (typeof navigator !== 'undefined' && navigator.product) {
Platform.navigator = navigator || null;
switch (navigator.product) {
case 'ReactNative':
Platform.userAgent = `aws-amplify/${version} react-native`;
Platform.userAgent = `${BASE_USER_AGENT} react-native`;
Platform.isReactNative = true;
break;
default:
Platform.userAgent = `aws-amplify/${version} js`;
Platform.userAgent = `${BASE_USER_AGENT} js`;
Platform.isReactNative = false;
break;
}
Expand Down

0 comments on commit 15a0a2f

Please sign in to comment.