mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
refactor(server)!: move correlationId to X-Correlation-ID response header (#28139)
This commit is contained in:
@@ -5,79 +5,66 @@ export const errorDto = {
|
|||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
message: 'Authentication required',
|
message: 'Authentication required',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
unauthorizedWithMessage: (message: string) => ({
|
unauthorizedWithMessage: (message: string) => ({
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
message,
|
message,
|
||||||
correlationId: expect.any(String),
|
|
||||||
}),
|
}),
|
||||||
forbidden: {
|
forbidden: {
|
||||||
error: 'Forbidden',
|
error: 'Forbidden',
|
||||||
statusCode: 403,
|
statusCode: 403,
|
||||||
message: expect.any(String),
|
message: expect.any(String),
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
missingPermission: (permission: string) => ({
|
missingPermission: (permission: string) => ({
|
||||||
error: 'Forbidden',
|
error: 'Forbidden',
|
||||||
statusCode: 403,
|
statusCode: 403,
|
||||||
message: `Missing required permission: ${permission}`,
|
message: `Missing required permission: ${permission}`,
|
||||||
correlationId: expect.any(String),
|
|
||||||
}),
|
}),
|
||||||
wrongPassword: {
|
wrongPassword: {
|
||||||
error: 'Bad Request',
|
error: 'Bad Request',
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
message: 'Wrong password',
|
message: 'Wrong password',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
invalidToken: {
|
invalidToken: {
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
message: 'Invalid user token',
|
message: 'Invalid user token',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
invalidShareKey: {
|
invalidShareKey: {
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
message: 'Invalid share key',
|
message: 'Invalid share key',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
passwordRequired: {
|
passwordRequired: {
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
message: 'Password required',
|
message: 'Password required',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
badRequest: (message: any = null) => ({
|
badRequest: (message: any = null) => ({
|
||||||
error: 'Bad Request',
|
error: 'Bad Request',
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
message: message ?? expect.anything(),
|
message: message ?? expect.anything(),
|
||||||
correlationId: expect.any(String),
|
|
||||||
}),
|
}),
|
||||||
noPermission: {
|
noPermission: {
|
||||||
error: 'Bad Request',
|
error: 'Bad Request',
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
message: expect.stringContaining('Not found or no'),
|
message: expect.stringContaining('Not found or no'),
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
incorrectLogin: {
|
incorrectLogin: {
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
message: 'Incorrect email or password',
|
message: 'Incorrect email or password',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
alreadyHasAdmin: {
|
alreadyHasAdmin: {
|
||||||
error: 'Bad Request',
|
error: 'Bad Request',
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
message: 'The server already has an admin',
|
message: 'The server already has an admin',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
invalidEmail: {
|
invalidEmail: {
|
||||||
error: 'Bad Request',
|
error: 'Bad Request',
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
message: ['email must be an email'],
|
message: ['email must be an email'],
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ export enum ImmichHeader {
|
|||||||
SharedLinkKey = 'x-immich-share-key',
|
SharedLinkKey = 'x-immich-share-key',
|
||||||
SharedLinkSlug = 'x-immich-share-slug',
|
SharedLinkSlug = 'x-immich-share-slug',
|
||||||
Checksum = 'x-immich-checksum',
|
Checksum = 'x-immich-checksum',
|
||||||
Cid = 'x-immich-cid',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ImmichQuery {
|
export enum ImmichQuery {
|
||||||
|
|||||||
@@ -20,14 +20,16 @@ export class GlobalExceptionFilter implements ExceptionFilter<Error> {
|
|||||||
const response = ctx.getResponse<Response>();
|
const response = ctx.getResponse<Response>();
|
||||||
const { status, body } = this.fromError(error);
|
const { status, body } = this.fromError(error);
|
||||||
if (!response.headersSent) {
|
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) {
|
handleError(res: Response, error: Error) {
|
||||||
const { status, body } = this.fromError(error);
|
const { status, body } = this.fromError(error);
|
||||||
if (!res.headersSent) {
|
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 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import { EnvSchema } from 'src/dtos/env.dto';
|
|||||||
import {
|
import {
|
||||||
DatabaseExtension,
|
DatabaseExtension,
|
||||||
ImmichEnvironment,
|
ImmichEnvironment,
|
||||||
ImmichHeader,
|
|
||||||
ImmichTelemetry,
|
ImmichTelemetry,
|
||||||
ImmichWorker,
|
ImmichWorker,
|
||||||
LogFormat,
|
LogFormat,
|
||||||
@@ -301,11 +300,11 @@ const getEnv = (): EnvData => {
|
|||||||
mount: true,
|
mount: true,
|
||||||
generateId: true,
|
generateId: true,
|
||||||
setup: (cls, req: Request, res: Response) => {
|
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 headerValue = Array.isArray(headerValues) ? headerValues[0] : headerValues;
|
||||||
const cid = headerValue || cls.get(CLS_ID);
|
const cid = headerValue || cls.get(CLS_ID);
|
||||||
cls.set(CLS_ID, cid);
|
cls.set(CLS_ID, cid);
|
||||||
res.header(ImmichHeader.Cid, cid);
|
res.header('X-Correlation-ID', cid);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,43 +5,36 @@ export const errorDto = {
|
|||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
message: 'Authentication required',
|
message: 'Authentication required',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
forbidden: {
|
forbidden: {
|
||||||
error: 'Forbidden',
|
error: 'Forbidden',
|
||||||
statusCode: 403,
|
statusCode: 403,
|
||||||
message: expect.any(String),
|
message: expect.any(String),
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
missingPermission: (permission: string) => ({
|
missingPermission: (permission: string) => ({
|
||||||
error: 'Forbidden',
|
error: 'Forbidden',
|
||||||
statusCode: 403,
|
statusCode: 403,
|
||||||
message: `Missing required permission: ${permission}`,
|
message: `Missing required permission: ${permission}`,
|
||||||
correlationId: expect.any(String),
|
|
||||||
}),
|
}),
|
||||||
wrongPassword: {
|
wrongPassword: {
|
||||||
error: 'Bad Request',
|
error: 'Bad Request',
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
message: 'Wrong password',
|
message: 'Wrong password',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
invalidToken: {
|
invalidToken: {
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
message: 'Invalid user token',
|
message: 'Invalid user token',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
invalidShareKey: {
|
invalidShareKey: {
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
message: 'Invalid share key',
|
message: 'Invalid share key',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
invalidSharePassword: {
|
invalidSharePassword: {
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
message: 'Invalid password',
|
message: 'Invalid password',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
badRequest: (message: any = null) => ({
|
badRequest: (message: any = null) => ({
|
||||||
error: 'Bad Request',
|
error: 'Bad Request',
|
||||||
@@ -52,18 +45,15 @@ export const errorDto = {
|
|||||||
error: 'Bad Request',
|
error: 'Bad Request',
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
message: expect.stringContaining('Not found or no'),
|
message: expect.stringContaining('Not found or no'),
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
incorrectLogin: {
|
incorrectLogin: {
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
statusCode: 401,
|
statusCode: 401,
|
||||||
message: 'Incorrect email or password',
|
message: 'Incorrect email or password',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
alreadyHasAdmin: {
|
alreadyHasAdmin: {
|
||||||
error: 'Bad Request',
|
error: 'Bad Request',
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
message: 'The server already has an admin',
|
message: 'The server already has an admin',
|
||||||
correlationId: expect.any(String),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user