diff --git a/.eslintignore b/.eslintignore
index 6a24a87b..bc613e26 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1 +1,3 @@
-src/events/*
\ No newline at end of file
+src/events/*
+**/src/loader-npm-rum.ts
+**/src/loader-npm-rum-2.ts
\ No newline at end of file
diff --git a/.github/scripts/update_smoke_test.sh b/.github/scripts/update_smoke_test.sh
old mode 100644
new mode 100755
index d9d8dc61..8d93fac2
--- a/.github/scripts/update_smoke_test.sh
+++ b/.github/scripts/update_smoke_test.sh
@@ -5,6 +5,9 @@ GUEST_ARN=$3
IDENTITY_POOL=$4
ENDPOINT=$5
CDN=$6
+MONITOR_ID_2=$7
+GUEST_ARN_2=$8
+IDENTITY_POOL_2=$9
VERSION=$(npm pkg get version | sed 's/"//g')/cwr.js
CDN+=${VERSION}
@@ -16,6 +19,12 @@ awk '{sub(/\$MONITOR_ID/,MONITOR_ID);sub(/\$REGION/,REGION);sub(/\$CDN/,CDN);sub
awk '{sub(/\$MONITOR_ID/,MONITOR_ID);sub(/\$REGION/,REGION);sub(/\$CDN/,CDN);sub(/\$GUEST_ARN/,GUEST_ARN);sub(/\$IDENTITY_POOL/,IDENTITY_POOL);sub(/\$ENDPOINT/,ENDPOINT);}1' \
MONITOR_ID="'$MONITOR_ID'" REGION="'$REGION'" CDN="'$CDN'" GUEST_ARN="'$GUEST_ARN'" IDENTITY_POOL="'$IDENTITY_POOL'" ENDPOINT="'$ENDPOINT'" smoke/smoke-test-application-NPM-ES/src/loader-npm-rum.ts > smoke/smoke-test-application-NPM-ES/src/loader-npm-rum-tmp.ts
+awk '{sub(/\$MONITOR_ID_2/,MONITOR_ID_2);sub(/\$REGION/,REGION);sub(/\$CDN/,CDN);sub(/\$GUEST_ARN_2/,GUEST_ARN_2);sub(/\$IDENTITY_POOL_2/,IDENTITY_POOL_2);sub(/\$ENDPOINT/,ENDPOINT);}1' \
+ MONITOR_ID_2="'$MONITOR_ID_2'" REGION="'$REGION'" CDN="'$CDN'" GUEST_ARN_2="'$GUEST_ARN_2'" IDENTITY_POOL_2="'$IDENTITY_POOL_2'" ENDPOINT="'$ENDPOINT'" smoke/smoke-test-application-NPM-ES/src/loader-npm-rum-2.ts > smoke/smoke-test-application-NPM-ES/src/loader-npm-rum-tmp-2.ts
+
# Module CJS
awk '{sub(/\$MONITOR_ID/,MONITOR_ID);sub(/\$REGION/,REGION);sub(/\$CDN/,CDN);sub(/\$GUEST_ARN/,GUEST_ARN);sub(/\$IDENTITY_POOL/,IDENTITY_POOL);sub(/\$ENDPOINT/,ENDPOINT);}1' \
MONITOR_ID="'$MONITOR_ID'" REGION="'$REGION'" CDN="'$CDN'" GUEST_ARN="'$GUEST_ARN'" IDENTITY_POOL="'$IDENTITY_POOL'" ENDPOINT="'$ENDPOINT'" smoke/smoke-test-application-NPM-CJS/src/loader-npm-rum.ts > smoke/smoke-test-application-NPM-CJS/src/loader-npm-rum-tmp.ts
+
+awk '{sub(/\$MONITOR_ID_2/,MONITOR_ID_2);sub(/\$REGION/,REGION);sub(/\$CDN/,CDN);sub(/\$GUEST_ARN_2/,GUEST_ARN_2);sub(/\$IDENTITY_POOL_2/,IDENTITY_POOL_2);sub(/\$ENDPOINT/,ENDPOINT);}1' \
+ MONITOR_ID_2="'$MONITOR_ID_2'" REGION="'$REGION'" CDN="'$CDN'" GUEST_ARN_2="'$GUEST_ARN_2'" IDENTITY_POOL_2="'$IDENTITY_POOL_2'" ENDPOINT="'$ENDPOINT'" smoke/smoke-test-application-NPM-CJS/src/loader-npm-rum-2.ts > smoke/smoke-test-application-NPM-CJS/src/loader-npm-rum-tmp-2.ts
diff --git a/.github/scripts/upload_smoke_test.sh b/.github/scripts/upload_smoke_test.sh
index ea3b6a5c..9eedd1ac 100644
--- a/.github/scripts/upload_smoke_test.sh
+++ b/.github/scripts/upload_smoke_test.sh
@@ -7,7 +7,9 @@ aws s3api put-object --bucket $bucket --key "smoke-$version.html" --body process
# NPM ES
aws s3api put-object --bucket $bucket --key "npm/es/$version/smoke.html" --body smoke/smoke-test-application-NPM-ES/app/smoke.html --content-type "text/html"
aws s3api put-object --bucket $bucket --key "npm/es/$version/loader_npm_rum_tmp.js" --body smoke/smoke-test-application-NPM-ES/build/dev/loader_npm_rum_tmp.js --content-type application/x-javascript
+aws s3api put-object --bucket $bucket --key "npm/es/$version/loader_npm_rum_tmp_2.js" --body smoke/smoke-test-application-NPM-ES/build/dev/loader_npm_rum_tmp_2.js --content-type application/x-javascript
# NPM CJS
aws s3api put-object --bucket $bucket --key "npm/cjs/$version/smoke.html" --body smoke/smoke-test-application-NPM-CJS/app/smoke.html --content-type "text/html"
aws s3api put-object --bucket $bucket --key "npm/cjs/$version/loader_npm_rum_tmp.js" --body smoke/smoke-test-application-NPM-CJS/build/dev/loader_npm_rum_tmp.js --content-type application/x-javascript
+aws s3api put-object --bucket $bucket --key "npm/cjs/$version/loader_npm_rum_tmp_2.js" --body smoke/smoke-test-application-NPM-CJS/build/dev/loader_npm_rum_tmp_2.js --content-type application/x-javascript
diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml
index c60f72e4..273af64d 100644
--- a/.github/workflows/cd.yaml
+++ b/.github/workflows/cd.yaml
@@ -74,7 +74,7 @@ jobs:
id: update-smoke-test-gamma-cdn
run: |
chmod u+x .github/scripts/update_smoke_test.sh
- .github/scripts/update_smoke_test.sh ${{ secrets.SMOKE_MONITOR }} ${{ secrets.SMOKE_REGION }} ${{ secrets.SMOKE_ARN }} ${{ secrets.SMOKE_IDENTITY }} ${{ secrets.CONFIG_ENDPOINT }} ${{ secrets.CDN_GAMMA }}
+ .github/scripts/update_smoke_test.sh ${{ secrets.SMOKE_MONITOR }} ${{ secrets.SMOKE_REGION }} ${{ secrets.SMOKE_ARN }} ${{ secrets.SMOKE_IDENTITY }} ${{ secrets.CONFIG_ENDPOINT }} ${{ secrets.CDN_GAMMA }} ${{ secrets.SMOKE_MONITOR_2 }} ${{ secrets.SMOKE_ARN_2 }} ${{ secrets.SMOKE_IDENTITY_2 }}
- name: Build Smoke Test Application - NPM/ES
id: build-npm-es-application-pre-release
@@ -98,6 +98,7 @@ jobs:
env:
URL: ${{ secrets.SMOKE_URL }}
MONITOR: ${{ secrets.SMOKE_MONITOR }}
+ MONITOR2: ${{ secrets.SMOKE_MONITOR_2 }}
ENDPOINT: ${{ secrets.SMOKE_ENDPOINT }}
NAME: ${{ secrets.SMOKE_MONITOR_NAME }}
INSTALL_METHOD: 'NPM-ES'
@@ -110,6 +111,7 @@ jobs:
env:
URL: ${{ secrets.SMOKE_URL }}
MONITOR: ${{ secrets.SMOKE_MONITOR }}
+ MONITOR_2: ${{ secrets.SMOKE_MONITOR_2 }}
ENDPOINT: ${{ secrets.SMOKE_ENDPOINT }}
NAME: ${{ secrets.SMOKE_MONITOR_NAME }}
INSTALL_METHOD: 'NPM-CJS'
@@ -168,7 +170,7 @@ jobs:
id: update-smoke-test-prod-cdn
run: |
chmod u+x .github/scripts/update_smoke_test.sh
- .github/scripts/update_smoke_test.sh ${{ secrets.SMOKE_MONITOR }} ${{ secrets.SMOKE_REGION }} ${{ secrets.SMOKE_ARN }} ${{ secrets.SMOKE_IDENTITY }} ${{ secrets.CONFIG_ENDPOINT }} ${{ secrets.CDN }}
+ .github/scripts/update_smoke_test.sh ${{ secrets.SMOKE_MONITOR }} ${{ secrets.SMOKE_REGION }} ${{ secrets.SMOKE_ARN }} ${{ secrets.SMOKE_IDENTITY }} ${{ secrets.CONFIG_ENDPOINT }} ${{ secrets.CDN }} ${{ secrets.SMOKE_MONITOR_2 }} ${{ secrets.SMOKE_ARN_2 }} ${{ secrets.SMOKE_IDENTITY_2 }}
- name: Upload Prod Smoke Tests to CloudFront
id: upload-smoke-test-prod
@@ -180,6 +182,7 @@ jobs:
env:
URL: ${{ secrets.SMOKE_URL }}
MONITOR: ${{ secrets.SMOKE_MONITOR }}
+ MONITOR_2: ${{ secrets.SMOKE_MONITOR_2 }}
ENDPOINT: ${{ secrets.SMOKE_ENDPOINT }}
NAME: ${{ secrets.SMOKE_MONITOR_NAME }}
INSTALL_METHOD: 'CDN'
diff --git a/.github/workflows/cdn_rollback.yaml b/.github/workflows/cdn_rollback.yaml
index 0cea1ec0..1a6c9322 100644
--- a/.github/workflows/cdn_rollback.yaml
+++ b/.github/workflows/cdn_rollback.yaml
@@ -66,7 +66,7 @@ jobs:
id: update-smoke-test
run: |
chmod u+x .github/scripts/update_smoke_test.sh
- .github/scripts/update_smoke_test.sh ${{ secrets.SMOKE_MONITOR }} ${{ secrets.SMOKE_REGION }} ${{ secrets.SMOKE_ARN }} ${{ secrets.SMOKE_IDENTITY }} ${{ secrets.CONFIG_ENDPOINT }} ${{ secrets.CDN }} >> processed_smoke.html
+ .github/scripts/update_smoke_test.sh ${{ secrets.SMOKE_MONITOR }} ${{ secrets.SMOKE_REGION }} ${{ secrets.SMOKE_ARN }} ${{ secrets.SMOKE_IDENTITY }} ${{ secrets.CONFIG_ENDPOINT }} ${{ secrets.CDN }} ${{ secrets.SMOKE_MONITOR_2 }} ${{ secrets.SMOKE_ARN_2 }} ${{ secrets.SMOKE_IDENTITY_2 }} >> processed_smoke.html
- name: Upload Smoke Test to CloudFront
id: upload-smoke-test
@@ -81,6 +81,7 @@ jobs:
env:
URL: ${{ secrets.SMOKE_URL }}
MONITOR: ${{ secrets.SMOKE_MONITOR }}
+ MONITOR_2: ${{ secrets.SMOKE_MONITOR_2 }}
ENDPOINT: ${{ secrets.SMOKE_ENDPOINT }}
NAME: ${{ secrets.SMOKE_MONITOR_NAME }}
run: npm run smoke:headless
diff --git a/docs/configuration.md b/docs/configuration.md
index 24952226..35d5be1f 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -51,7 +51,7 @@ For example, the config object may look similar to the following:
| path | String | `/` | See https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_where_cookies_are_sent |
| sameSite | Boolean | `true` | See https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_where_cookies_are_sent |
| secure | Boolean | `true` | See https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_where_cookies_are_sent |
-| unique | Boolean | `false` | When this field is `false`, the session cookie name is `cwr_s`. When this field is `true`, the session cookie name is `cwr_s_[AppMonitor Id]`. Set this field to `true` when multiple AppMonitors will monitor the same page. For example, this might be the case if one AppMonitor is used for logged-in users, and a second AppMonitor is used for guest users. |
+| unique | Boolean | `false` | When this field is `false`, the session cookie name is `cwr_s` and the credential cookie name is `cwr_c`. When this field is `true`, the session cookie name is `cwr_s_[AppMonitor Id]` and the credential cookie name is `cwr_c_[AppMonitor Id]`. Set this field to `true` when multiple AppMonitors will monitor the same page. For example, this might be the case if one AppMonitor is used for logged-in users, and a second AppMonitor is used for guest users. |
## MetadataAttributes
diff --git a/package.json b/package.json
index 3952d85b..1f6393b8 100644
--- a/package.json
+++ b/package.json
@@ -54,9 +54,9 @@
"preinteg:local:nightwatch:firefox": "http-server ./build/dev -s &",
"integ:local:nightwatch:firefox": "nightwatch -e firefox",
"postinteg:local:nightwatch:firefox": "kill $(lsof -t -i:8080)",
- "smoke:local:headless": "cross-env URL=$URL MONITOR_ID=$MONITOR ENDPOINT=$ENDPOINT NAME=$NAME VERSION=$npm_package_version npx playwright test --config=playwright.local.config.ts",
- "smoke:local": "cross-env URL=$URL MONITOR_ID=$MONITOR ENDPOINT=$ENDPOINT NAME=$NAME VERSION=$npm_package_version npx playwright test --config=playwright.local.config.ts --headed",
- "smoke:headless": "cross-env URL=$URL MONITOR_ID=$MONITOR ENDPOINT=$ENDPOINT NAME=$NAME VERSION=$npm_package_version INSTALL_METHOD=$INSTALL_METHOD npx playwright test --config=playwright.config.ts",
+ "smoke:local:headless": "cross-env URL=$URL MONITOR_ID=$MONITOR ENDPOINT=$ENDPOINT NAME=$NAME VERSION=$npm_package_version MONITOR_ID_2=$MONITOR_ID_2 npx playwright test --config=playwright.local.config.ts",
+ "smoke:local": "cross-env URL=$URL MONITOR_ID=$MONITOR ENDPOINT=$ENDPOINT NAME=$NAME VERSION=$npm_package_version MONITOR_ID_2=$MONITOR_ID_2 npx playwright test --config=playwright.local.config.ts --headed",
+ "smoke:headless": "cross-env URL=$URL MONITOR_ID=$MONITOR ENDPOINT=$ENDPOINT NAME=$NAME VERSION=$npm_package_version INSTALL_METHOD=$INSTALL_METHOD MONITOR_ID_2=$MONITOR_ID_2 npx playwright test --config=playwright.config.ts",
"prepare": "husky install"
},
"devDependencies": {
diff --git a/smoke/smoke-test-application-NPM-CJS/app/smoke.html b/smoke/smoke-test-application-NPM-CJS/app/smoke.html
index 4d99a58a..22addf68 100644
--- a/smoke/smoke-test-application-NPM-CJS/app/smoke.html
+++ b/smoke/smoke-test-application-NPM-CJS/app/smoke.html
@@ -8,6 +8,19 @@
RUM Smoke Test
+
RUM Smoke Test
+
{
+ // Open page
+ await page.goto(TEST_URL);
+
+ // Test will timeout if no successful dataplane request is found
+ await page.waitForResponse(async (response) =>
+ isDataPlaneRequest(response, TARGET_URL_2)
+ );
+});
+
test('when web client calls PutRumEvents then the payload contains all events', async ({
page
}) => {
diff --git a/src/dispatch/Authentication.ts b/src/dispatch/Authentication.ts
index 856b0da0..c960bd2d 100644
--- a/src/dispatch/Authentication.ts
+++ b/src/dispatch/Authentication.ts
@@ -8,14 +8,20 @@ export abstract class Authentication {
protected cognitoIdentityClient: CognitoIdentityClient;
protected config: Config;
protected credentials: AwsCredentialIdentity | undefined;
+ protected credentialStorageKey: string;
- constructor(config: Config) {
+ constructor(config: Config, applicationId: string) {
const region: string = config.identityPoolId!.split(':')[0];
this.config = config;
this.cognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region
+ region,
+ clientConfig: config,
+ applicationId
});
+ this.credentialStorageKey = this.config.cookieAttributes.unique
+ ? `${CRED_KEY}_${applicationId}`
+ : CRED_KEY;
}
/**
@@ -80,7 +86,9 @@ export abstract class Authentication {
return new Promise((resolve, reject) => {
let credentials: AwsCredentialIdentity;
try {
- credentials = JSON.parse(localStorage.getItem(CRED_KEY)!);
+ credentials = JSON.parse(
+ localStorage.getItem(this.credentialStorageKey)!
+ );
} catch (e) {
// Error retrieving, decoding or parsing the cred string -- abort
return reject();
diff --git a/src/dispatch/BasicAuthentication.ts b/src/dispatch/BasicAuthentication.ts
index 908cdff9..39bea76c 100644
--- a/src/dispatch/BasicAuthentication.ts
+++ b/src/dispatch/BasicAuthentication.ts
@@ -2,14 +2,13 @@ import { Config } from '../orchestration/Orchestration';
import { AwsCredentialIdentity } from '@aws-sdk/types';
import { FetchHttpHandler } from '@aws-sdk/fetch-http-handler';
import { StsClient } from './StsClient';
-import { CRED_KEY } from '../utils/constants';
import { Authentication } from './Authentication';
export class BasicAuthentication extends Authentication {
private stsClient: StsClient;
- constructor(config: Config) {
- super(config);
+ constructor(config: Config, applicationId: string) {
+ super(config, applicationId);
const region: string = config.identityPoolId!.split(':')[0];
this.stsClient = new StsClient({
fetchRequestHandler: new FetchHttpHandler(),
@@ -51,7 +50,7 @@ export class BasicAuthentication extends Authentication {
this.credentials = credentials;
try {
localStorage.setItem(
- CRED_KEY,
+ this.credentialStorageKey,
JSON.stringify(credentials)
);
} catch (e) {
diff --git a/src/dispatch/CognitoIdentityClient.ts b/src/dispatch/CognitoIdentityClient.ts
index 59397666..5a040aee 100644
--- a/src/dispatch/CognitoIdentityClient.ts
+++ b/src/dispatch/CognitoIdentityClient.ts
@@ -3,6 +3,7 @@ import { HttpHandler, HttpRequest } from '@aws-sdk/protocol-http';
import { AwsCredentialIdentity } from '@aws-sdk/types';
import { responseToJson } from './utils';
import { IDENTITY_KEY } from '../utils/constants';
+import { Config } from '../orchestration/Orchestration';
const METHOD = 'POST';
const CONTENT_TYPE = 'application/x-amz-json-1.1';
@@ -39,15 +40,21 @@ interface GetIdResponse {
export declare type CognitoIdentityClientConfig = {
fetchRequestHandler: HttpHandler;
region?: string;
+ clientConfig?: Config;
+ applicationId?: string;
};
export class CognitoIdentityClient {
private fetchRequestHandler: HttpHandler;
private hostname: string;
+ private identityStorageKey: string;
constructor(config: CognitoIdentityClientConfig) {
this.hostname = `cognito-identity.${config.region}.amazonaws.com`;
this.fetchRequestHandler = config.fetchRequestHandler;
+ this.identityStorageKey = config.clientConfig?.cookieAttributes.unique
+ ? `${IDENTITY_KEY}_${config.applicationId}`
+ : IDENTITY_KEY;
}
public getId = async (request: { IdentityPoolId: string }) => {
@@ -55,7 +62,7 @@ export class CognitoIdentityClient {
try {
getIdResponse = JSON.parse(
- localStorage.getItem(IDENTITY_KEY)!
+ localStorage.getItem(this.identityStorageKey)!
) as GetIdResponse | null;
} catch (e) {
// Ignore -- we will get a new identity Id from Cognito
@@ -78,7 +85,7 @@ export class CognitoIdentityClient {
)) as GetIdResponse;
try {
localStorage.setItem(
- IDENTITY_KEY,
+ this.identityStorageKey,
JSON.stringify({ IdentityId: getIdResponse.IdentityId })
);
} catch (e) {
@@ -104,7 +111,7 @@ export class CognitoIdentityClient {
await responseToJson(response)
);
} catch (e) {
- localStorage.removeItem(IDENTITY_KEY);
+ localStorage.removeItem(this.identityStorageKey);
throw new Error(
`CWR: Failed to retrieve Cognito OpenId token: ${e}`
);
@@ -134,7 +141,7 @@ export class CognitoIdentityClient {
expiration: new Date(Expiration * 1000)
};
} catch (e) {
- localStorage.removeItem(IDENTITY_KEY);
+ localStorage.removeItem(this.identityStorageKey);
throw new Error(
`CWR: Failed to retrieve credentials for Cognito identity: ${e}`
);
diff --git a/src/dispatch/EnhancedAuthentication.ts b/src/dispatch/EnhancedAuthentication.ts
index adc3ac5f..bc284800 100644
--- a/src/dispatch/EnhancedAuthentication.ts
+++ b/src/dispatch/EnhancedAuthentication.ts
@@ -1,11 +1,10 @@
import { Config } from '../orchestration/Orchestration';
import { AwsCredentialIdentity } from '@aws-sdk/types';
-import { CRED_KEY } from '../utils/constants';
import { Authentication } from './Authentication';
export class EnhancedAuthentication extends Authentication {
- constructor(config: Config) {
- super(config);
+ constructor(config: Config, applicationId: string) {
+ super(config, applicationId);
}
/**
* Provides credentials for an anonymous (guest) user. These credentials are retrieved from Cognito's enhanced
@@ -34,7 +33,7 @@ export class EnhancedAuthentication extends Authentication {
this.credentials = credentials;
try {
localStorage.setItem(
- CRED_KEY,
+ this.credentialStorageKey,
JSON.stringify(credentials)
);
} catch (e) {
diff --git a/src/dispatch/__tests__/BasicAuthentication.test.ts b/src/dispatch/__tests__/BasicAuthentication.test.ts
index 36ae038e..1fdec27e 100644
--- a/src/dispatch/__tests__/BasicAuthentication.test.ts
+++ b/src/dispatch/__tests__/BasicAuthentication.test.ts
@@ -1,6 +1,6 @@
import { BasicAuthentication } from '../BasicAuthentication';
import { CRED_KEY } from '../../utils/constants';
-import { DEFAULT_CONFIG } from '../../test-utils/test-utils';
+import { APPLICATION_ID, DEFAULT_CONFIG } from '../../test-utils/test-utils';
const assumeRole = jest.fn();
const mockGetId = jest.fn();
@@ -42,6 +42,7 @@ describe('BasicAuthentication tests', () => {
expiration: new Date(new Date().getTime() + 60 * 60 * 1000)
});
localStorage.removeItem(CRED_KEY);
+ localStorage.removeItem(`${CRED_KEY}_${APPLICATION_ID}`);
});
test('when credential is in localStorage then authentication chain retrieves credential from localStorage', async () => {
@@ -54,7 +55,7 @@ describe('BasicAuthentication tests', () => {
guestRoleArn: GUEST_ROLE_ARN
}
};
- const auth = new BasicAuthentication(config);
+ const auth = new BasicAuthentication(config, APPLICATION_ID);
localStorage.setItem(
CRED_KEY,
@@ -88,7 +89,7 @@ describe('BasicAuthentication tests', () => {
guestRoleArn: GUEST_ROLE_ARN
}
};
- const auth = new BasicAuthentication(config);
+ const auth = new BasicAuthentication(config, APPLICATION_ID);
localStorage.setItem(CRED_KEY, 'corrupt');
@@ -107,13 +108,16 @@ describe('BasicAuthentication tests', () => {
test('when credential is not in localStorage then authentication chain retrieves credential from basic authflow', async () => {
// Init
- const auth = new BasicAuthentication({
- ...DEFAULT_CONFIG,
- ...{
- identityPoolId: IDENTITY_POOL_ID,
- guestRoleArn: GUEST_ROLE_ARN
- }
- });
+ const auth = new BasicAuthentication(
+ {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID,
+ guestRoleArn: GUEST_ROLE_ARN
+ }
+ },
+ APPLICATION_ID
+ );
// Run
const credentials = await auth.ChainAnonymousCredentialsProvider();
@@ -139,7 +143,7 @@ describe('BasicAuthentication tests', () => {
}
};
- const auth = new BasicAuthentication(config);
+ const auth = new BasicAuthentication(config, APPLICATION_ID);
localStorage.setItem(
CRED_KEY,
@@ -181,13 +185,16 @@ describe('BasicAuthentication tests', () => {
sessionToken: 'z'
});
- const auth = new BasicAuthentication({
- ...DEFAULT_CONFIG,
- ...{
- identityPoolId: IDENTITY_POOL_ID,
- guestRoleArn: GUEST_ROLE_ARN
- }
- });
+ const auth = new BasicAuthentication(
+ {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID,
+ guestRoleArn: GUEST_ROLE_ARN
+ }
+ },
+ APPLICATION_ID
+ );
// Run
await auth.ChainAnonymousCredentialsProvider();
@@ -210,13 +217,16 @@ describe('BasicAuthentication tests', () => {
throw e;
});
// Init
- const auth = new BasicAuthentication({
- ...DEFAULT_CONFIG,
- ...{
- identityPoolId: IDENTITY_POOL_ID,
- guestRoleArn: GUEST_ROLE_ARN
- }
- });
+ const auth = new BasicAuthentication(
+ {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID,
+ guestRoleArn: GUEST_ROLE_ARN
+ }
+ },
+ APPLICATION_ID
+ );
// Assert
return expect(auth.ChainAnonymousCredentialsProvider()).rejects.toEqual(
@@ -230,13 +240,16 @@ describe('BasicAuthentication tests', () => {
throw e;
});
// Init
- const auth = new BasicAuthentication({
- ...DEFAULT_CONFIG,
- ...{
- identityPoolId: IDENTITY_POOL_ID,
- guestRoleArn: GUEST_ROLE_ARN
- }
- });
+ const auth = new BasicAuthentication(
+ {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID,
+ guestRoleArn: GUEST_ROLE_ARN
+ }
+ },
+ APPLICATION_ID
+ );
// Assert
return expect(auth.ChainAnonymousCredentialsProvider()).rejects.toEqual(
@@ -250,13 +263,16 @@ describe('BasicAuthentication tests', () => {
throw e;
});
// Init
- const auth = new BasicAuthentication({
- ...DEFAULT_CONFIG,
- ...{
- identityPoolId: IDENTITY_POOL_ID,
- guestRoleArn: GUEST_ROLE_ARN
- }
- });
+ const auth = new BasicAuthentication(
+ {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID,
+ guestRoleArn: GUEST_ROLE_ARN
+ }
+ },
+ APPLICATION_ID
+ );
// Assert
expect(auth.ChainAnonymousCredentialsProvider()).rejects.toEqual(e);
@@ -272,7 +288,7 @@ describe('BasicAuthentication tests', () => {
guestRoleArn: GUEST_ROLE_ARN
}
};
- const auth = new BasicAuthentication(config);
+ const auth = new BasicAuthentication(config, APPLICATION_ID);
// Run
await auth.ChainAnonymousCredentialsProvider();
@@ -321,7 +337,7 @@ describe('BasicAuthentication tests', () => {
guestRoleArn: GUEST_ROLE_ARN
}
};
- const auth = new BasicAuthentication(config);
+ const auth = new BasicAuthentication(config, APPLICATION_ID);
// Run
await auth.ChainAnonymousCredentialsProvider();
@@ -358,7 +374,7 @@ describe('BasicAuthentication tests', () => {
guestRoleArn: GUEST_ROLE_ARN
}
};
- const auth = new BasicAuthentication(config);
+ const auth = new BasicAuthentication(config, APPLICATION_ID);
// Run
const credentials = await auth.ChainAnonymousCredentialsProvider();
@@ -396,7 +412,7 @@ describe('BasicAuthentication tests', () => {
guestRoleArn: GUEST_ROLE_ARN
}
};
- const auth = new BasicAuthentication(config);
+ const auth = new BasicAuthentication(config, APPLICATION_ID);
// Run
await auth.ChainAnonymousCredentialsProvider();
@@ -414,13 +430,77 @@ describe('BasicAuthentication tests', () => {
throw e;
});
// Init
- const auth = new BasicAuthentication({
+ const auth = new BasicAuthentication(
+ {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID,
+ guestRoleArn: GUEST_ROLE_ARN
+ }
+ },
+ APPLICATION_ID
+ );
+
+ // Run
+ const credentials = await auth.ChainAnonymousCredentialsProvider();
+
+ // Assert
+ expect(credentials).toEqual(
+ expect.objectContaining({
+ accessKeyId: 'x',
+ secretAccessKey: 'y',
+ sessionToken: 'z'
+ })
+ );
+ });
+
+ test('when unique cookie names are used then cookie name with application id appended is stored', async () => {
+ // Init
+ const config = {
...DEFAULT_CONFIG,
...{
identityPoolId: IDENTITY_POOL_ID,
- guestRoleArn: GUEST_ROLE_ARN
+ guestRoleArn: GUEST_ROLE_ARN,
+ allowCookies: true,
+ cookieAttributes: {
+ ...DEFAULT_CONFIG.cookieAttributes,
+ ...{ unique: true }
+ }
}
- });
+ };
+ const auth = new BasicAuthentication(config, APPLICATION_ID);
+
+ // Run
+ await auth.ChainAnonymousCredentialsProvider();
+ const credentials = JSON.parse(
+ localStorage.getItem(`${CRED_KEY}_${APPLICATION_ID}`)!
+ );
+
+ // Assert
+ expect(credentials).toEqual(
+ expect.objectContaining({
+ accessKeyId: 'x',
+ secretAccessKey: 'y',
+ sessionToken: 'z'
+ })
+ );
+ });
+
+ test('when unique cookie names are used then cookie name with application id appended is retrieved', async () => {
+ // Init
+ const config = {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID,
+ guestRoleArn: GUEST_ROLE_ARN,
+ allowCookies: true,
+ cookieAttributes: {
+ ...DEFAULT_CONFIG.cookieAttributes,
+ ...{ unique: true }
+ }
+ }
+ };
+ const auth = new BasicAuthentication(config, APPLICATION_ID);
// Run
const credentials = await auth.ChainAnonymousCredentialsProvider();
diff --git a/src/dispatch/__tests__/CognitoIdentityClient.test.ts b/src/dispatch/__tests__/CognitoIdentityClient.test.ts
index 13ae46e4..e7639e5c 100644
--- a/src/dispatch/__tests__/CognitoIdentityClient.test.ts
+++ b/src/dispatch/__tests__/CognitoIdentityClient.test.ts
@@ -3,7 +3,11 @@ import { FetchHttpHandler } from '@aws-sdk/fetch-http-handler';
import { advanceTo } from 'jest-date-mock';
import { CognitoIdentityClient } from '../CognitoIdentityClient';
import { AwsCredentialIdentity } from '@aws-sdk/types';
-import { getReadableStream } from '../../test-utils/test-utils';
+import {
+ APPLICATION_ID,
+ getReadableStream,
+ DEFAULT_CONFIG
+} from '../../test-utils/test-utils';
import { IDENTITY_KEY } from '../../utils/constants';
const mockCredentials =
@@ -11,6 +15,8 @@ const mockCredentials =
const mockToken = '{"IdentityId": "mockId", "Token": "mockToken"}';
const mockIdCommand = '{"IdentityId": "mockId"}';
+const uniqueIdentityCookie = `${IDENTITY_KEY}_${APPLICATION_ID}`;
+
const fetchHandler = jest.fn();
jest.mock('@aws-sdk/fetch-http-handler', () => ({
@@ -43,7 +49,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Run
@@ -71,7 +84,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Assert
@@ -90,7 +110,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Run
@@ -118,7 +145,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Assert
@@ -139,7 +173,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Run
@@ -166,7 +207,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Assert
@@ -187,7 +235,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Run
@@ -218,7 +273,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Assert
@@ -242,7 +304,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Assert
@@ -264,7 +333,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Assert
@@ -285,7 +361,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Run
@@ -314,7 +397,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Assert
@@ -336,7 +426,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Assert
@@ -357,7 +454,14 @@ describe('CognitoIdentityClient tests', () => {
// Init
const client: CognitoIdentityClient = new CognitoIdentityClient({
fetchRequestHandler: new FetchHttpHandler(),
- region: Utils.AWS_RUM_REGION
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: false
+ }
+ },
+ applicationId: APPLICATION_ID
});
// Run
@@ -370,4 +474,155 @@ describe('CognitoIdentityClient tests', () => {
// Assert
expect(localStorage.getItem(IDENTITY_KEY)).toBe(null);
});
+
+ test('when unique cookie names are used then cookie name with application id appended is stored', async () => {
+ fetchHandler.mockResolvedValueOnce({
+ response: {
+ body: getReadableStream(mockIdCommand)
+ }
+ });
+
+ // Init
+ const client: CognitoIdentityClient = new CognitoIdentityClient({
+ fetchRequestHandler: new FetchHttpHandler(),
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: true,
+ cookieAttributes: {
+ ...DEFAULT_CONFIG.cookieAttributes,
+ ...{ unique: true }
+ }
+ }
+ },
+ applicationId: APPLICATION_ID
+ });
+
+ // Run
+ await client.getId({
+ IdentityPoolId: 'my-fake-identity-pool-id'
+ });
+
+ // Assert
+ const credentials = JSON.parse(
+ localStorage.getItem(uniqueIdentityCookie)!
+ );
+
+ expect(credentials).toEqual(
+ expect.objectContaining({
+ IdentityId: 'mockId'
+ })
+ );
+ });
+
+ test('when unique cookie names are used then cookie name with application id appended is retrieved', async () => {
+ fetchHandler.mockResolvedValueOnce({
+ response: {
+ body: getReadableStream(mockIdCommand)
+ }
+ });
+
+ // Init
+ const client: CognitoIdentityClient = new CognitoIdentityClient({
+ fetchRequestHandler: new FetchHttpHandler(),
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: true,
+ cookieAttributes: {
+ ...DEFAULT_CONFIG.cookieAttributes,
+ ...{ unique: true }
+ }
+ }
+ },
+ applicationId: APPLICATION_ID
+ });
+
+ // Run
+ const idCommand = await client.getId({
+ IdentityPoolId: 'my-fake-identity-pool-id'
+ });
+
+ // Assert
+ expect(fetchHandler).toHaveBeenCalledTimes(1);
+ expect(idCommand).toMatchObject({
+ IdentityId: 'mockId'
+ });
+ });
+
+ test('when unique cookie names and getOpenIdToken returns a bad response then identity id is removed from localStorage', async () => {
+ localStorage.setItem(uniqueIdentityCookie, 'my-fake-identity-id');
+
+ fetchHandler.mockResolvedValueOnce({
+ response: {
+ body: getReadableStream('not-json')
+ }
+ });
+
+ // Init
+ const client: CognitoIdentityClient = new CognitoIdentityClient({
+ fetchRequestHandler: new FetchHttpHandler(),
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: true,
+ cookieAttributes: {
+ ...DEFAULT_CONFIG.cookieAttributes,
+ ...{ unique: true }
+ }
+ }
+ },
+ applicationId: APPLICATION_ID
+ });
+
+ // Run
+ try {
+ await client.getOpenIdToken({ IdentityId: 'my-fake-identity-id' });
+ } catch (e) {
+ // Ignore
+ }
+
+ // Assert
+ expect(localStorage.getItem(uniqueIdentityCookie)).toBe(null);
+ });
+
+ test('when unique cookie names and getCredentialsForIdentity returns bad response then identity id is removed from localStorage ', async () => {
+ localStorage.setItem(uniqueIdentityCookie, 'my-fake-identity-id');
+
+ fetchHandler.mockResolvedValueOnce({
+ response: {
+ body: getReadableStream('not-json')
+ }
+ });
+
+ // Init
+ const client: CognitoIdentityClient = new CognitoIdentityClient({
+ fetchRequestHandler: new FetchHttpHandler(),
+ region: Utils.AWS_RUM_REGION,
+ clientConfig: {
+ ...DEFAULT_CONFIG,
+ ...{
+ allowCookies: true,
+ cookieAttributes: {
+ ...DEFAULT_CONFIG.cookieAttributes,
+ ...{ unique: true }
+ }
+ }
+ },
+ applicationId: APPLICATION_ID
+ });
+
+ // Run
+ try {
+ await client.getCredentialsForIdentity('my-fake-identity-id');
+ } catch (e) {
+ // Ignore
+ }
+
+ // Assert
+ expect(localStorage.getItem(uniqueIdentityCookie)).toBe(null);
+ });
});
diff --git a/src/dispatch/__tests__/EnhancedAuthentication.test.ts b/src/dispatch/__tests__/EnhancedAuthentication.test.ts
index fd330d54..0a91625b 100644
--- a/src/dispatch/__tests__/EnhancedAuthentication.test.ts
+++ b/src/dispatch/__tests__/EnhancedAuthentication.test.ts
@@ -1,6 +1,6 @@
import { CRED_KEY } from '../../utils/constants';
import { EnhancedAuthentication } from '../EnhancedAuthentication';
-import { DEFAULT_CONFIG } from '../../test-utils/test-utils';
+import { APPLICATION_ID, DEFAULT_CONFIG } from '../../test-utils/test-utils';
const mockGetId = jest.fn();
const getCredentials = jest.fn();
@@ -29,6 +29,7 @@ describe('EnhancedAuthentication tests', () => {
expiration: new Date(Date.now() + 3600 * 1000)
});
localStorage.removeItem(CRED_KEY);
+ localStorage.removeItem(`${CRED_KEY}_${APPLICATION_ID}`);
});
test('when credential is in localStorage then authentication chain retrieves credential from localStorage', async () => {
@@ -41,7 +42,7 @@ describe('EnhancedAuthentication tests', () => {
}
};
- const auth = new EnhancedAuthentication(config);
+ const auth = new EnhancedAuthentication(config, APPLICATION_ID);
localStorage.setItem(
CRED_KEY,
@@ -76,7 +77,7 @@ describe('EnhancedAuthentication tests', () => {
}
};
- const auth = new EnhancedAuthentication(config);
+ const auth = new EnhancedAuthentication(config, APPLICATION_ID);
localStorage.setItem(CRED_KEY, 'corrupt');
@@ -95,12 +96,15 @@ describe('EnhancedAuthentication tests', () => {
test('when credential is not in the store authentication chain retrieves credential from basic authflow', async () => {
// Init
- const auth = new EnhancedAuthentication({
- ...DEFAULT_CONFIG,
- ...{
- identityPoolId: IDENTITY_POOL_ID
- }
- });
+ const auth = new EnhancedAuthentication(
+ {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID
+ }
+ },
+ APPLICATION_ID
+ );
// Run
const credentials = await auth.ChainAnonymousCredentialsProvider();
@@ -126,7 +130,7 @@ describe('EnhancedAuthentication tests', () => {
}
};
- const auth = new EnhancedAuthentication(config);
+ const auth = new EnhancedAuthentication(config, APPLICATION_ID);
localStorage.setItem(
CRED_KEY,
@@ -168,13 +172,16 @@ describe('EnhancedAuthentication tests', () => {
sessionToken: 'z'
});
- const auth = new EnhancedAuthentication({
- ...DEFAULT_CONFIG,
- ...{
- identityPoolId: IDENTITY_POOL_ID,
- guestRoleArn: GUEST_ROLE_ARN
- }
- });
+ const auth = new EnhancedAuthentication(
+ {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID,
+ guestRoleArn: GUEST_ROLE_ARN
+ }
+ },
+ APPLICATION_ID
+ );
// Run
await auth.ChainAnonymousCredentialsProvider();
@@ -197,13 +204,16 @@ describe('EnhancedAuthentication tests', () => {
throw new Error('mockGetId error');
});
- const auth = new EnhancedAuthentication({
- ...DEFAULT_CONFIG,
- ...{
- identityPoolId: IDENTITY_POOL_ID,
- guestRoleArn: GUEST_ROLE_ARN
- }
- });
+ const auth = new EnhancedAuthentication(
+ {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID,
+ guestRoleArn: GUEST_ROLE_ARN
+ }
+ },
+ APPLICATION_ID
+ );
// Assert
expect((auth: EnhancedAuthentication) => {
@@ -217,13 +227,16 @@ describe('EnhancedAuthentication tests', () => {
throw new Error('mockGetId error');
});
- const auth = new EnhancedAuthentication({
- ...DEFAULT_CONFIG,
- ...{
- identityPoolId: IDENTITY_POOL_ID,
- guestRoleArn: GUEST_ROLE_ARN
- }
- });
+ const auth = new EnhancedAuthentication(
+ {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID,
+ guestRoleArn: GUEST_ROLE_ARN
+ }
+ },
+ APPLICATION_ID
+ );
// Assert
expect((auth: EnhancedAuthentication) => {
@@ -241,7 +254,7 @@ describe('EnhancedAuthentication tests', () => {
guestRoleArn: GUEST_ROLE_ARN
}
};
- const auth = new EnhancedAuthentication(config);
+ const auth = new EnhancedAuthentication(config, APPLICATION_ID);
// Run
await auth.ChainAnonymousCredentialsProvider();
@@ -290,7 +303,7 @@ describe('EnhancedAuthentication tests', () => {
guestRoleArn: GUEST_ROLE_ARN
}
};
- const auth = new EnhancedAuthentication(config);
+ const auth = new EnhancedAuthentication(config, APPLICATION_ID);
// Run
await auth.ChainAnonymousCredentialsProvider();
@@ -327,12 +340,15 @@ describe('EnhancedAuthentication tests', () => {
})
);
- const auth = new EnhancedAuthentication({
- ...DEFAULT_CONFIG,
- ...{
- identityPoolId: IDENTITY_POOL_ID
- }
- });
+ const auth = new EnhancedAuthentication(
+ {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID
+ }
+ },
+ APPLICATION_ID
+ );
// Run
const credentials = await auth.ChainAnonymousCredentialsProvider();
@@ -364,12 +380,15 @@ describe('EnhancedAuthentication tests', () => {
})
);
- const auth = new EnhancedAuthentication({
- ...DEFAULT_CONFIG,
- ...{
- identityPoolId: IDENTITY_POOL_ID
- }
- });
+ const auth = new EnhancedAuthentication(
+ {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID
+ }
+ },
+ APPLICATION_ID
+ );
// Run
await auth.ChainAnonymousCredentialsProvider();
@@ -387,13 +406,76 @@ describe('EnhancedAuthentication tests', () => {
throw new Error('mockGetId error');
});
- const auth = new EnhancedAuthentication({
+ const auth = new EnhancedAuthentication(
+ {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID,
+ guestRoleArn: GUEST_ROLE_ARN
+ }
+ },
+ APPLICATION_ID
+ );
+
+ // Run
+ const credentials = await auth.ChainAnonymousCredentialsProvider();
+
+ // Assert
+ expect(credentials).toEqual(
+ expect.objectContaining({
+ accessKeyId: 'x',
+ secretAccessKey: 'y',
+ sessionToken: 'z'
+ })
+ );
+ });
+
+ test('when unique cookie names are used then cookie name with application id appended is stored', async () => {
+ // Init
+ const config = {
...DEFAULT_CONFIG,
...{
identityPoolId: IDENTITY_POOL_ID,
- guestRoleArn: GUEST_ROLE_ARN
+ allowCookies: true,
+ cookieAttributes: {
+ ...DEFAULT_CONFIG.cookieAttributes,
+ ...{ unique: true }
+ }
}
- });
+ };
+
+ const auth = new EnhancedAuthentication(config, APPLICATION_ID);
+
+ // Run
+ await auth.ChainAnonymousCredentialsProvider();
+ const credentials = JSON.parse(
+ localStorage.getItem(`${CRED_KEY}_${APPLICATION_ID}`)!
+ );
+
+ // Assert
+ expect(credentials).toEqual(
+ expect.objectContaining({
+ accessKeyId: 'x',
+ secretAccessKey: 'y',
+ sessionToken: 'z'
+ })
+ );
+ });
+ test('when unique cookie names are used then cookie name with application id appended is retrieved', async () => {
+ // Init
+ const config = {
+ ...DEFAULT_CONFIG,
+ ...{
+ identityPoolId: IDENTITY_POOL_ID,
+ allowCookies: true,
+ cookieAttributes: {
+ ...DEFAULT_CONFIG.cookieAttributes,
+ ...{ unique: true }
+ }
+ }
+ };
+
+ const auth = new EnhancedAuthentication(config, APPLICATION_ID);
// Run
const credentials = await auth.ChainAnonymousCredentialsProvider();
diff --git a/src/orchestration/Orchestration.ts b/src/orchestration/Orchestration.ts
index 4155bbd7..a94a4c15 100644
--- a/src/orchestration/Orchestration.ts
+++ b/src/orchestration/Orchestration.ts
@@ -238,7 +238,7 @@ export class Orchestration {
applicationVersion
);
- this.dispatchManager = this.initDispatch(region);
+ this.dispatchManager = this.initDispatch(region, applicationId);
this.pluginManager = this.initPluginManager(
applicationId,
applicationVersion
@@ -378,7 +378,7 @@ export class Orchestration {
);
}
- private initDispatch(region: string) {
+ private initDispatch(region: string, applicationId: string) {
const dispatch: Dispatch = new Dispatch(
region,
this.config.endpointUrl,
@@ -395,12 +395,12 @@ export class Orchestration {
if (this.config.identityPoolId && this.config.guestRoleArn) {
dispatch.setAwsCredentials(
- new BasicAuthentication(this.config)
+ new BasicAuthentication(this.config, applicationId)
.ChainAnonymousCredentialsProvider
);
} else if (this.config.identityPoolId) {
dispatch.setAwsCredentials(
- new EnhancedAuthentication(this.config)
+ new EnhancedAuthentication(this.config, applicationId)
.ChainAnonymousCredentialsProvider
);
}
diff --git a/src/sessions/SessionManager.ts b/src/sessions/SessionManager.ts
index ac33d712..c8a1afd2 100644
--- a/src/sessions/SessionManager.ts
+++ b/src/sessions/SessionManager.ts
@@ -69,6 +69,7 @@ export class SessionManager {
private config: Config;
private record: RecordSessionInitEvent;
private attributes!: Attributes;
+ private sessionCookieName: string;
constructor(
appMonitorDetails: AppMonitorDetails,
@@ -81,6 +82,10 @@ export class SessionManager {
this.record = record;
this.pageManager = pageManager;
+ this.sessionCookieName = this.config.cookieAttributes.unique
+ ? `${SESSION_COOKIE_NAME}_${this.appMonitorDetails.id}`
+ : SESSION_COOKIE_NAME;
+
// Initialize the session to the nil session
this.session = {
sessionId: NIL_UUID,
@@ -176,7 +181,7 @@ export class SessionManager {
private createOrRenewSessionCookie(session: Session, expires: Date) {
if (btoa) {
storeCookie(
- this.sessionCookieName(),
+ this.sessionCookieName,
btoa(JSON.stringify(session)),
this.config.cookieAttributes,
undefined,
@@ -201,8 +206,7 @@ export class SessionManager {
private getSessionFromCookie() {
if (this.useCookies()) {
- const cookie: string = getCookie(this.sessionCookieName());
-
+ const cookie: string = getCookie(this.sessionCookieName);
if (cookie && atob) {
try {
this.session = JSON.parse(atob(cookie)) as Session;
@@ -286,11 +290,4 @@ export class SessionManager {
private sample(): boolean {
return Math.random() < this.config.sessionSampleRate;
}
-
- private sessionCookieName(): string {
- if (this.config.cookieAttributes.unique) {
- return `${SESSION_COOKIE_NAME}_${this.appMonitorDetails.id}`;
- }
- return SESSION_COOKIE_NAME;
- }
}