From 96b6165bd38032bf8201404ccdd30611455e6a11 Mon Sep 17 00:00:00 2001 From: Timon Date: Tue, 28 Apr 2026 19:07:39 +0200 Subject: [PATCH] refactor(server)!: move correlationId to X-Correlation-ID response header (#28139) --- e2e/src/responses.ts | 13 ------------- server/src/enum.ts | 1 - server/src/middleware/global-exception.filter.ts | 6 ++++-- server/src/repositories/config.repository.ts | 5 ++--- server/test/medium/responses.ts | 10 ---------- 5 files changed, 6 insertions(+), 29 deletions(-) diff --git a/e2e/src/responses.ts b/e2e/src/responses.ts index 3d7971d6f0..fcb300828e 100644 --- a/e2e/src/responses.ts +++ b/e2e/src/responses.ts @@ -5,79 +5,66 @@ export const errorDto = { error: 'Unauthorized', statusCode: 401, message: 'Authentication required', - correlationId: expect.any(String), }, unauthorizedWithMessage: (message: string) => ({ error: 'Unauthorized', statusCode: 401, message, - correlationId: expect.any(String), }), forbidden: { error: 'Forbidden', statusCode: 403, message: expect.any(String), - correlationId: expect.any(String), }, missingPermission: (permission: string) => ({ error: 'Forbidden', statusCode: 403, message: `Missing required permission: ${permission}`, - correlationId: expect.any(String), }), wrongPassword: { error: 'Bad Request', statusCode: 400, message: 'Wrong password', - correlationId: expect.any(String), }, invalidToken: { error: 'Unauthorized', statusCode: 401, message: 'Invalid user token', - correlationId: expect.any(String), }, invalidShareKey: { error: 'Unauthorized', statusCode: 401, message: 'Invalid share key', - correlationId: expect.any(String), }, passwordRequired: { error: 'Unauthorized', statusCode: 401, message: 'Password required', - correlationId: expect.any(String), }, badRequest: (message: any = null) => ({ error: 'Bad Request', statusCode: 400, message: message ?? expect.anything(), - correlationId: expect.any(String), }), noPermission: { error: 'Bad Request', statusCode: 400, message: expect.stringContaining('Not found or no'), - correlationId: expect.any(String), }, incorrectLogin: { error: 'Unauthorized', statusCode: 401, message: 'Incorrect email or password', - correlationId: expect.any(String), }, alreadyHasAdmin: { error: 'Bad Request', statusCode: 400, message: 'The server already has an admin', - correlationId: expect.any(String), }, invalidEmail: { error: 'Bad Request', statusCode: 400, message: ['email must be an email'], - correlationId: expect.any(String), }, }; diff --git a/server/src/enum.ts b/server/src/enum.ts index 8a1993b48f..fc43f54db1 100644 --- a/server/src/enum.ts +++ b/server/src/enum.ts @@ -22,7 +22,6 @@ export enum ImmichHeader { SharedLinkKey = 'x-immich-share-key', SharedLinkSlug = 'x-immich-share-slug', Checksum = 'x-immich-checksum', - Cid = 'x-immich-cid', } export enum ImmichQuery { diff --git a/server/src/middleware/global-exception.filter.ts b/server/src/middleware/global-exception.filter.ts index f91bb2b122..e83ee18fea 100644 --- a/server/src/middleware/global-exception.filter.ts +++ b/server/src/middleware/global-exception.filter.ts @@ -20,14 +20,16 @@ export class GlobalExceptionFilter implements ExceptionFilter { const response = ctx.getResponse(); const { status, body } = this.fromError(error); if (!response.headersSent) { - response.status(status).json({ ...body, statusCode: status, correlationId: this.cls.getId() }); + response.header('X-Correlation-ID', this.cls.getId()); + response.status(status).json({ ...body, statusCode: status }); } } handleError(res: Response, error: Error) { const { status, body } = this.fromError(error); if (!res.headersSent) { - res.status(status).json({ ...body, statusCode: status, correlationId: this.cls.getId() }); + res.header('X-Correlation-ID', this.cls.getId()); + res.status(status).json({ ...body, statusCode: status }); } } diff --git a/server/src/repositories/config.repository.ts b/server/src/repositories/config.repository.ts index 97ec3f1cdc..b77f9fc8c3 100644 --- a/server/src/repositories/config.repository.ts +++ b/server/src/repositories/config.repository.ts @@ -15,7 +15,6 @@ import { EnvSchema } from 'src/dtos/env.dto'; import { DatabaseExtension, ImmichEnvironment, - ImmichHeader, ImmichTelemetry, ImmichWorker, LogFormat, @@ -301,11 +300,11 @@ const getEnv = (): EnvData => { mount: true, generateId: true, setup: (cls, req: Request, res: Response) => { - const headerValues = req.headers[ImmichHeader.Cid]; + const headerValues = req.headers['x-correlation-id']; const headerValue = Array.isArray(headerValues) ? headerValues[0] : headerValues; const cid = headerValue || cls.get(CLS_ID); cls.set(CLS_ID, cid); - res.header(ImmichHeader.Cid, cid); + res.header('X-Correlation-ID', cid); }, }, }, diff --git a/server/test/medium/responses.ts b/server/test/medium/responses.ts index dcc4cdd177..adff5703c1 100644 --- a/server/test/medium/responses.ts +++ b/server/test/medium/responses.ts @@ -5,43 +5,36 @@ export const errorDto = { error: 'Unauthorized', statusCode: 401, message: 'Authentication required', - correlationId: expect.any(String), }, forbidden: { error: 'Forbidden', statusCode: 403, message: expect.any(String), - correlationId: expect.any(String), }, missingPermission: (permission: string) => ({ error: 'Forbidden', statusCode: 403, message: `Missing required permission: ${permission}`, - correlationId: expect.any(String), }), wrongPassword: { error: 'Bad Request', statusCode: 400, message: 'Wrong password', - correlationId: expect.any(String), }, invalidToken: { error: 'Unauthorized', statusCode: 401, message: 'Invalid user token', - correlationId: expect.any(String), }, invalidShareKey: { error: 'Unauthorized', statusCode: 401, message: 'Invalid share key', - correlationId: expect.any(String), }, invalidSharePassword: { error: 'Unauthorized', statusCode: 401, message: 'Invalid password', - correlationId: expect.any(String), }, badRequest: (message: any = null) => ({ error: 'Bad Request', @@ -52,18 +45,15 @@ export const errorDto = { error: 'Bad Request', statusCode: 400, message: expect.stringContaining('Not found or no'), - correlationId: expect.any(String), }, incorrectLogin: { error: 'Unauthorized', statusCode: 401, message: 'Incorrect email or password', - correlationId: expect.any(String), }, alreadyHasAdmin: { error: 'Bad Request', statusCode: 400, message: 'The server already has an admin', - correlationId: expect.any(String), }, };