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; - } }