diff --git a/.github/workflows/deploy-npm.yml b/.github/workflows/deploy-npm.yml index fbe84bdf0..04249dae9 100644 --- a/.github/workflows/deploy-npm.yml +++ b/.github/workflows/deploy-npm.yml @@ -46,9 +46,11 @@ jobs: run: | current_version_v1=$(jq -r .version packages/analytics-v1.1/package.json) current_version_sw=$(jq -r .version packages/analytics-js-service-worker/package.json) + current_version_cookie_utils=$(jq -r .version packages/analytics-js-cookies/package.json) current_version=$(jq -r .version packages/analytics-js/package.json) echo "CURRENT_VERSION_V1_VALUE=$current_version_v1" >> $GITHUB_ENV echo "CURRENT_VERSION_SW_VALUE=$current_version_sw" >> $GITHUB_ENV + echo "CURRENT_VERSION_COOKIE_UTILS_VALUE=$current_version_cookie_utils" >> $GITHUB_ENV echo "CURRENT_VERSION_VALUE=$current_version" >> $GITHUB_ENV - name: Get versions in NPM @@ -59,6 +61,9 @@ jobs: current_npm_version_sw=$(npm show @rudderstack/analytics-js-service-worker version 2>/dev/null || echo "not found") echo "CURRENT_NPM_VERSION_SW=$current_npm_version_sw" >> $GITHUB_ENV + current_npm_version_cookie_utils=$(npm show @rudderstack/analytics-js-cookies version 2>/dev/null || echo "not found") + echo "CURRENT_NPM_VERSION_COOKIE_UTILS=$current_npm_version_cookie_utils" >> $GITHUB_ENV + - name: Setup Node uses: actions/setup-node@v4 with: @@ -92,20 +97,28 @@ jobs: - name: Get versions in NPM after publish run: | + npm cache clean --force new_npm_version=$(npm show @rudderstack/analytics-js version 2>/dev/null || echo "not found") echo "NEW_NPM_VERSION=$new_npm_version" >> $GITHUB_ENV new_npm_version_sw=$(npm show @rudderstack/analytics-js-service-worker version 2>/dev/null || echo "not found") echo "NEW_NPM_VERSION_SW=$new_npm_version_sw" >> $GITHUB_ENV + new_npm_version_cookie_utils=$(npm show @rudderstack/analytics-js-cookies version 2>/dev/null || echo "not found") + echo "NEW_NPM_VERSION_COOKIE_UTILS=$new_npm_version_cookie_utils" >> $GITHUB_ENV + - name: Debug environment variables continue-on-error: true run: | echo "CURRENT_NPM_VERSION=${{ env.CURRENT_NPM_VERSION }}" echo "NEW_NPM_VERSION=${{ env.NEW_NPM_VERSION }}" + echo "CURRENT_NPM_VERSION_SW=${{ env.CURRENT_NPM_VERSION_SW }}" echo "NEW_NPM_VERSION_SW=${{ env.NEW_NPM_VERSION_SW }}" + echo "CURRENT_NPM_VERSION_COOKIE_UTILS=${{ env.CURRENT_NPM_VERSION_COOKIE_UTILS }}" + echo "NEW_NPM_VERSION_COOKIE_UTILS=${{ env.NEW_NPM_VERSION_COOKIE_UTILS }}" + - name: Send message to Slack channel if: env.CURRENT_NPM_VERSION != env.NEW_NPM_VERSION && env.NEW_NPM_VERSION != 'not found' id: slack @@ -205,3 +218,53 @@ jobs: } ] } + + - name: Send message to Slack channel for cookie utilities + if: env.CURRENT_NPM_VERSION_COOKIE_UTILS != env.CURRENT_NPM_VERSION_COOKIE_UTILS && env.CURRENT_NPM_VERSION_COOKIE_UTILS != 'not found' + id: slack-cookie-utils + continue-on-error: true + uses: slackapi/slack-github-action@v1.26.0 + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + PROJECT_NAME: 'JS SDK Cookies Utilities' + NPM_PACKAGE_URL: 'https://www.npmjs.com/package/@rudderstack/analytics-js-cookies' + RELEASES_URL: 'https://github.com/rudderlabs/rudder-sdk-js/releases/tag/@rudderstack/analytics-js-cookies@' + with: + channel-id: ${{ secrets.SLACK_RELEASE_CHANNEL_ID }} + payload: | + { + "text": "*New Release: ${{ env.PROJECT_NAME }} - <${{ env.NPM_PACKAGE_URL }}|${{ env.CURRENT_VERSION_COOKIE_UTILS_VALUE }}>*\n${{ env.DATE }}\nCC: ", + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "New Release: ${{ env.PROJECT_NAME }}" + } + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*<${{ env.NPM_PACKAGE_URL }}|v${{ env.CURRENT_VERSION_COOKIE_UTILS_VALUE }}>*\n${{ env.DATE }}\nCC: " + }, + "accessory": { + "type": "image", + "image_url": "https://img.icons8.com/color/452/npm.png", + "alt_text": "NPM Icon" + } + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "For more details, check the full release notes <${{ env.RELEASES_URL }}${{ env.CURRENT_VERSION_COOKIE_UTILS_VALUE }}|here>." + } + ] + } + ] + } diff --git a/packages/analytics-js-cookies/README.md b/packages/analytics-js-cookies/README.md index bec6566c3..8b02902ee 100644 --- a/packages/analytics-js-cookies/README.md +++ b/packages/analytics-js-cookies/README.md @@ -25,6 +25,23 @@ RudderStack JavaScript SDK utility for cookies. ## APIs +### `getDecryptedValue` + +This function decrypts the provided encrypted RudderStack JavaScript cookie value using the RudderStack JavaScript SDK encryption version "v3". + +> The encrypted value should be a string starting with `RS_ENC_v3_`. + +> If the provided value is not properly encrypted, the function will throw an exception. + +```javascript +import { decrypt } from '@rudderstack/analytics-js-cookies'; + +const encryptedCookieValue = 'RS_ENC_v3_InRlc3QtZGF0YSI='; +const decryptedCookieValue = decrypt(encryptedCookieValue); +console.log('Decrypted Cookie Value: ', decryptedCookieValue); +// Output: Decrypted Cookie Value: test-data +``` + ### `getDecryptedCookie` This function decrypts and returns the RudderStack JavaScript SDK cookie values. @@ -39,11 +56,10 @@ It returns `null` in either of the following scenarios: - If the decrypted cookie value is not a valid JSON string. - If the provided cookie name is not a valid RudderStack JavaScript SDK cookie name. -> If unencrypted, the cookie value will be returned as is. - > Any errors during decryption are swallowed by the function, returning `null`. The following are the available cookie key exports: + - `userIdKey`: The key for the user ID cookie. - `userTraitsKey`: The key for the user traits cookie. - `anonymousUserIdKey`: The key for the anonymous user ID cookie. @@ -54,7 +70,6 @@ The following are the available cookie key exports: - `sessionInfoKey`: The key for the session ID cookie. - `authTokenKey`: The key for the auth token cookie. - ```javascript import { getDecryptedCookie, diff --git a/packages/analytics-js-cookies/__tests__/cookieUtilities.test.ts b/packages/analytics-js-cookies/__tests__/cookieUtilities.test.ts index 0b9bd496f..f2e909cc7 100644 --- a/packages/analytics-js-cookies/__tests__/cookieUtilities.test.ts +++ b/packages/analytics-js-cookies/__tests__/cookieUtilities.test.ts @@ -9,7 +9,7 @@ import { userIdKey, userTraitsKey, } from '../src'; -import { encrypt, decrypt, getDecryptedCookie } from '../src/cookiesUtilities'; +import { encrypt, decrypt, getDecryptedCookie, getDecryptedValue } from '../src/cookiesUtilities'; describe('Cookie Utilities', () => { describe('encrypt', () => { @@ -119,4 +119,26 @@ describe('Cookie Utilities', () => { document.cookie = 'rl_auth_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC'; }); }); + + describe('getDecryptedValue', () => { + it('should return the decrypted value', () => { + expect(getDecryptedValue('RS_ENC_v3_InRlc3QtZGF0YSI=')).toBe('test-data'); + }); + + it('should return null if it is not encrypted', () => { + expect(getDecryptedValue('test-data')).toBeNull(); + }); + + it('should return null if the value is not properly encrypted', () => { + expect(getDecryptedValue('RS_ENC_v3_InRlc3QtZGF0YSI-some-random-data')).toBeNull(); + }); + + it('should return null if the input is null', () => { + expect(getDecryptedValue(null)).toBeNull(); + }); + + it('should return null if the input is undefined', () => { + expect(getDecryptedValue(undefined)).toBeNull(); + }); + }); }); diff --git a/packages/analytics-js-cookies/package.json b/packages/analytics-js-cookies/package.json index d9eb772db..d9ad1bbac 100644 --- a/packages/analytics-js-cookies/package.json +++ b/packages/analytics-js-cookies/package.json @@ -1,7 +1,7 @@ { "name": "@rudderstack/analytics-js-cookies", "version": "0.1.0", - "description": "RudderStack JavaScript SDK Cookies Module", + "description": "RudderStack JavaScript SDK Cookies Utilities", "main": "dist/npm/modern/cjs/index.js", "module": "dist/npm/modern/esm/index.js", "exports": { @@ -56,7 +56,7 @@ "build:browser": "exit 0", "build:npm": "rollup -c --environment VERSION:$npm_package_version,ENV:prod,MODULE_TYPE:npm", "build:npm:modern": "BROWSERSLIST_ENV=modern npm run build:npm", - "build:package": "npm run build:npm:modern", + "build:package": "npm run build:npm:modern && npm run build:npm", "test": "nx test --maxWorkers=50%", "test:ci": "nx test --parallel=false --configuration=ci --runInBand --maxWorkers=1 --forceExit", "check:lint": "nx lint", diff --git a/packages/analytics-js-cookies/src/cookiesUtilities.ts b/packages/analytics-js-cookies/src/cookiesUtilities.ts index 6a8785485..f383cc1d8 100644 --- a/packages/analytics-js-cookies/src/cookiesUtilities.ts +++ b/packages/analytics-js-cookies/src/cookiesUtilities.ts @@ -15,22 +15,26 @@ const decrypt = (value: string | undefined): string | undefined => { return value; }; -const getDecryptedCookie = (cookieKey: string): Nullable => { +const getDecryptedValue = (value: string): Nullable => { const fallbackValue = null; try { - if (Object.values(COOKIE_KEYS).includes(cookieKey)) { - const decryptedVal = decrypt(cookie(cookieKey)); - - if (isNullOrUndefined(decryptedVal)) { - return fallbackValue; - } + const decryptedVal = decrypt(value); - return JSON.parse(decryptedVal as string); + if (isNullOrUndefined(decryptedVal)) { + return fallbackValue; } - return fallbackValue; + + return JSON.parse(decryptedVal as string); } catch (err) { return fallbackValue; } }; -export { getDecryptedCookie, encrypt, decrypt }; +const getDecryptedCookie = (cookieKey: string): Nullable => { + if (Object.values(COOKIE_KEYS).includes(cookieKey)) { + return getDecryptedValue(cookie(cookieKey)); + } + return null; +}; + +export { getDecryptedCookie, encrypt, decrypt, getDecryptedValue }; diff --git a/packages/analytics-js-cookies/src/index.ts b/packages/analytics-js-cookies/src/index.ts index 0fce670e7..fbfa1e207 100644 --- a/packages/analytics-js-cookies/src/index.ts +++ b/packages/analytics-js-cookies/src/index.ts @@ -1,4 +1,4 @@ -export { getDecryptedCookie } from './cookiesUtilities'; +export { getDecryptedCookie, getDecryptedValue } from './cookiesUtilities'; export { userIdKey,