From 733cbd57abc63dcd279526b3666020754bace765 Mon Sep 17 00:00:00 2001 From: Sam Chung Date: Fri, 27 May 2022 10:22:38 +1000 Subject: [PATCH] fix(RequestLogging.createContextStorage): Shallow copy context store for the `mixin` function (#155) --- src/requestLogging/requestLogging.test.ts | 33 +++++++++++++++++++++++ src/requestLogging/requestLogging.ts | 4 +-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/requestLogging/requestLogging.test.ts b/src/requestLogging/requestLogging.test.ts index 80d352d..ed71775 100644 --- a/src/requestLogging/requestLogging.test.ts +++ b/src/requestLogging/requestLogging.test.ts @@ -341,5 +341,38 @@ describe('RequestLogging', () => { 'x-session-id': '8f859d2a-46a7-4b2d-992b-3da4a18b7ab5', }); }); + + it('should not mutate the current context if surface level fields are changed', async () => { + const { createContextMiddleware, mixin } = createContextStorage(); + + const contextMiddleware = createContextMiddleware(); + + // We need to grab the result from within the run() chain + let result: Fields = {}; + const setResultMiddleware = jest.fn(async (_ctx: Context, next: Next) => { + const tempResult = mixin(); + tempResult.abcd = 'extra'; + result = mixin(); + await next(); + }); + + const handler = jest.fn((ctx: Context) => { + ctx.status = 201; + }); + + await createAgent(contextMiddleware, setResultMiddleware, handler) + .post('/my/test/service') + .set('Authenticated-User', 'somesercret') + .set('user-agent', 'Safari') + .set('x-session-id', '8f859d2a-46a7-4b2d-992b-3da4a18b7ab5') + .expect(201); + + expect(result).toStrictEqual({ + method: 'POST', + url: '/my/test/service', + 'x-request-id': expect.any(String), + 'x-session-id': '8f859d2a-46a7-4b2d-992b-3da4a18b7ab5', + }); + }); }); }); diff --git a/src/requestLogging/requestLogging.ts b/src/requestLogging/requestLogging.ts index 8618cc7..ec432e6 100644 --- a/src/requestLogging/requestLogging.ts +++ b/src/requestLogging/requestLogging.ts @@ -193,8 +193,8 @@ export const createContextStorage = () => { await loggerContext.run(getFieldsFn(ctx, contextFields(ctx)), next); }, /** - * Returns fields from the logger context store + * Returns a shallow copy of fields from the logger context store. For performance reason we only copy the surface level fields. */ - mixin: () => loggerContext.getStore() ?? {}, + mixin: () => ({ ...loggerContext.getStore() }), }; };