diff --git a/src/commands/app/deploy.js b/src/commands/app/deploy.js index d868f36a..03fa59bb 100644 --- a/src/commands/app/deploy.js +++ b/src/commands/app/deploy.js @@ -26,7 +26,7 @@ const { const rtLib = require('@adobe/aio-lib-runtime') const LogForwarding = require('../../lib/log-forwarding') const { sendAppAssetsDeployedAuditLog, sendAppDeployAuditLog } = require('../../lib/audit-logger') -const { setRuntimeApiHostAndAuthHandler, getAccessToken, getTokenData } = require('../../lib/auth-helper') +const { setRuntimeApiHostAndAuthHandler, getAccessToken } = require('../../lib/auth-helper') const logActions = require('../../lib/log-actions') const PRE_DEPLOY_EVENT_REG = 'pre-deploy-event-reg' @@ -68,8 +68,6 @@ class Deploy extends BuildCommand { if (cliDetails?.accessToken) { try { - // store user id from token data for cdn deploy audit metadata - appInfo.auditUserId = getTokenData(cliDetails.accessToken)?.user_id // send audit log at start (don't wait for deployment to finish) await sendAppDeployAuditLog({ accessToken: cliDetails?.accessToken, @@ -132,10 +130,7 @@ class Deploy extends BuildCommand { // - break into smaller pieces deploy, allowing to first deploy all actions then all web assets for (let i = 0; i < keys.length; ++i) { const k = keys[i] - // auditUserId is only set if it is available in the token data - // falsy because "", 0, false, null, undefined, NaN, etc. are all invalid values const v = { - ...(appInfo.auditUserId && { auditUserId: appInfo.auditUserId }), ...setRuntimeApiHostAndAuthHandler(values[i]) } await this.deploySingleConfig({ name: k, config: v, originalConfig: values[i], flags, spinner }) diff --git a/src/lib/auth-helper.js b/src/lib/auth-helper.js index 033ba9be..84fc1fce 100644 --- a/src/lib/auth-helper.js +++ b/src/lib/auth-helper.js @@ -9,7 +9,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const { getToken, context, getTokenData: getImsTokenData } = require('@adobe/aio-lib-ims') +const { getToken, context } = require('@adobe/aio-lib-ims') const { CLI } = require('@adobe/aio-lib-ims/src/context') const { getCliEnv } = require('@adobe/aio-lib-env') const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app:auth-helper', { provider: 'debug' }) @@ -90,29 +90,8 @@ const setRuntimeApiHostAndAuthHandler = (_config) => { } } -/** - * Decodes a JWT token and returns its payload as a JavaScript object. - * - * @function getTokenData - * @param {string} token - The JWT token to decode - * @returns {object|null} The decoded payload of the JWT token or null if the token is invalid or cannot be decoded - */ -const getTokenData = (token) => { - if (typeof token !== 'string') { - aioLogger.error('Invalid token provided to getTokenData :: not a string') - return null - } - try { - return getImsTokenData(token) - } catch (e) { - aioLogger.error('Error decoding token payload in getTokenData ::', e) - return null - } -} - module.exports = { getAccessToken, - getTokenData, bearerAuthHandler, setRuntimeApiHostAndAuthHandler } diff --git a/test/commands/app/deploy.test.js b/test/commands/app/deploy.test.js index fe30a244..054b5836 100644 --- a/test/commands/app/deploy.test.js +++ b/test/commands/app/deploy.test.js @@ -198,9 +198,7 @@ beforeEach(() => { env: 'stage' } }) - authHelper.getTokenData.mockImplementation(() => { - return null // default to null, tests can override - }) + LogForwarding.init.mockResolvedValue(mockLogForwarding) command = new TheCommand([]) @@ -673,136 +671,6 @@ describe('run', () => { expect(open).toHaveBeenCalledWith('http://prefix?fake=https://example.com') }) - test('deploy should pass auditUserId to deployWeb config when user_id is present in token', async () => { - const mockUserId = 'test-user-123' - const mockToken = 'mock.token.value' - - authHelper.getAccessToken.mockResolvedValueOnce({ - accessToken: mockToken, - env: 'stage' - }) - authHelper.getTokenData.mockReturnValueOnce({ - user_id: mockUserId - }) - - command.getAppExtConfigs.mockResolvedValueOnce(createAppConfig(command.appConfig)) - mockWebLib.deployWeb.mockResolvedValue('https://example.com') - - command.argv = [] - await command.run() - - expect(command.error).toHaveBeenCalledTimes(0) - expect(authHelper.getTokenData).toHaveBeenCalledWith(mockToken) - expect(mockWebLib.deployWeb).toHaveBeenCalledWith( - expect.objectContaining({ - auditUserId: mockUserId - }), - expect.any(Function) - ) - }) - - test('deploy should NOT include auditUserId in config when user_id is undefined', async () => { - const mockToken = 'mock.token.value' - - authHelper.getAccessToken.mockResolvedValueOnce({ - accessToken: mockToken, - env: 'stage' - }) - authHelper.getTokenData.mockReturnValueOnce({ - // user_id is undefined - }) - - command.getAppExtConfigs.mockResolvedValueOnce(createAppConfig(command.appConfig)) - mockWebLib.deployWeb.mockResolvedValue('https://example.com') - - command.argv = [] - await command.run() - - expect(command.error).toHaveBeenCalledTimes(0) - expect(mockWebLib.deployWeb).toHaveBeenCalledWith( - expect.not.objectContaining({ - auditUserId: expect.anything() - }), - expect.any(Function) - ) - }) - - test('deploy should NOT include auditUserId in config when user_id is null', async () => { - const mockToken = 'mock.token.value' - - authHelper.getAccessToken.mockResolvedValueOnce({ - accessToken: mockToken, - env: 'stage' - }) - authHelper.getTokenData.mockReturnValueOnce({ - user_id: null - }) - - command.getAppExtConfigs.mockResolvedValueOnce(createAppConfig(command.appConfig)) - mockWebLib.deployWeb.mockResolvedValue('https://example.com') - - command.argv = [] - await command.run() - - expect(command.error).toHaveBeenCalledTimes(0) - expect(mockWebLib.deployWeb).toHaveBeenCalledWith( - expect.not.objectContaining({ - auditUserId: expect.anything() - }), - expect.any(Function) - ) - }) - - test('deploy should NOT include auditUserId in config when user_id is empty string', async () => { - const mockToken = 'mock.token.value' - - authHelper.getAccessToken.mockResolvedValueOnce({ - accessToken: mockToken, - env: 'stage' - }) - authHelper.getTokenData.mockReturnValueOnce({ - user_id: '' - }) - - command.getAppExtConfigs.mockResolvedValueOnce(createAppConfig(command.appConfig)) - mockWebLib.deployWeb.mockResolvedValue('https://example.com') - - command.argv = [] - await command.run() - - expect(command.error).toHaveBeenCalledTimes(0) - expect(mockWebLib.deployWeb).toHaveBeenCalledWith( - expect.not.objectContaining({ - auditUserId: expect.anything() - }), - expect.any(Function) - ) - }) - - test('deploy should NOT include auditUserId when getTokenData returns null', async () => { - const mockToken = 'mock.token.value' - - authHelper.getAccessToken.mockResolvedValueOnce({ - accessToken: mockToken, - env: 'stage' - }) - authHelper.getTokenData.mockReturnValueOnce(null) - - command.getAppExtConfigs.mockResolvedValueOnce(createAppConfig(command.appConfig)) - mockWebLib.deployWeb.mockResolvedValue('https://example.com') - - command.argv = [] - await command.run() - - expect(command.error).toHaveBeenCalledTimes(0) - expect(mockWebLib.deployWeb).toHaveBeenCalledWith( - expect.not.objectContaining({ - auditUserId: expect.anything() - }), - expect.any(Function) - ) - }) - test('deploy should show action urls (web-export: true)', async () => { command.getAppExtConfigs.mockResolvedValueOnce(createAppConfig(command.appConfig)) mockRuntimeLib.deployActions.mockResolvedValue({ diff --git a/test/commands/lib/auth-helper.test.js b/test/commands/lib/auth-helper.test.js index 693a9027..cf2d4081 100644 --- a/test/commands/lib/auth-helper.test.js +++ b/test/commands/lib/auth-helper.test.js @@ -1,5 +1,5 @@ -const { getAccessToken, bearerAuthHandler, setRuntimeApiHostAndAuthHandler, getTokenData } = require('../../../src/lib/auth-helper') -const { getToken, context, getTokenData: getImsTokenData } = require('@adobe/aio-lib-ims') +const { getAccessToken, bearerAuthHandler, setRuntimeApiHostAndAuthHandler } = require('../../../src/lib/auth-helper') +const { getToken, context } = require('@adobe/aio-lib-ims') const { CLI } = require('@adobe/aio-lib-ims/src/context') const { getCliEnv } = require('@adobe/aio-lib-env') @@ -57,37 +57,6 @@ describe('getAccessToken', () => { }) }) -describe('getTokenData', () => { - beforeEach(() => { - jest.clearAllMocks() - }) - - test('should call through to getImsTokenData to decode JWT token and return payload', () => { - getImsTokenData.mockReturnValue({ user_id: '12345', name: 'Test User' }) - // Example JWT token with payload: {"user_id":"12345","name":"Test User"} - const exampleToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMTIzNDUiLCJuYW1lIjoiVGVzdCBVc2VyIn0.sflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' - const result = getTokenData(exampleToken) - expect(result).toEqual({ user_id: '12345', name: 'Test User' }) - }) - test('should return null for invalid token', () => { - getImsTokenData.mockImplementation(() => { throw new Error('Invalid token') }) - const invalidToken = 'invalid.token.string' - const result = getTokenData(invalidToken) - expect(result).toBeNull() - }) - test('should return null for malformed token', () => { - getImsTokenData.mockImplementation(() => { throw new Error('Malformed token') }) - const malformedToken = 'malformedtoken' - const result = getTokenData(malformedToken) - expect(result).toBeNull() - }) - test('should return null for non-string token', () => { - const nonStringToken = 12345 - const result = getTokenData(nonStringToken) - expect(result).toBeNull() - }) -}) - describe('bearerAuthHandler', () => { beforeEach(() => { jest.clearAllMocks()