From f204376c20bdbb16e282b463740ecbafa0d94e77 Mon Sep 17 00:00:00 2001 From: CSantosM <4a.santos@gmail.com> Date: Mon, 23 Feb 2026 17:15:10 +0100 Subject: [PATCH] Updates to Express v5 Updates the Express dependency to version 5.2.1 and its corresponding types. This change also adapts the request validator middleware to extract validated query parameters and store them in `res.locals` instead of modifying `req.query` to align with Express v5's intended usage and prevent potential conflicts. Includes a fix for a server startup error, logging the error and exiting the process, and adds a type definition file for Express locals. --- meet-ce/backend/package.json | 4 +- .../src/controllers/recording.controller.ts | 17 ++-- .../src/controllers/room-member.controller.ts | 4 +- .../src/controllers/room.controller.ts | 12 +-- .../src/controllers/user.controller.ts | 6 +- .../recording-validator.middleware.ts | 32 ++++---- .../room-member-validator.middleware.ts | 4 +- .../room-validator.middleware.ts | 35 ++++---- .../user-validator.middleware.ts | 4 +- meet-ce/backend/src/server.ts | 7 +- meet-ce/backend/src/types/express-locals.d.ts | 9 ++ .../api/recordings/get-recordings.test.ts | 5 -- .../integration/api/rooms/get-rooms.test.ts | 5 -- pnpm-lock.yaml | 82 ++++--------------- 14 files changed, 93 insertions(+), 133 deletions(-) create mode 100644 meet-ce/backend/src/types/express-locals.d.ts diff --git a/meet-ce/backend/package.json b/meet-ce/backend/package.json index dc424657..3cc674f3 100644 --- a/meet-ce/backend/package.json +++ b/meet-ce/backend/package.json @@ -68,7 +68,7 @@ "cors": "2.8.6", "cron": "4.4.0", "dotenv": "16.6.1", - "express": "4.22.1", + "express": "5.2.1", "express-rate-limit": "7.5.1", "inversify": "6.2.2", "ioredis": "5.6.1", @@ -87,7 +87,7 @@ "@types/bcrypt": "5.0.2", "@types/cookie-parser": "1.4.9", "@types/cors": "2.8.19", - "@types/express": "4.17.25", + "@types/express": "5.0.6", "@types/jest": "29.5.14", "@types/lodash.merge": "4.6.9", "@types/ms": "2.1.0", diff --git a/meet-ce/backend/src/controllers/recording.controller.ts b/meet-ce/backend/src/controllers/recording.controller.ts index b506dc43..547ae4ac 100644 --- a/meet-ce/backend/src/controllers/recording.controller.ts +++ b/meet-ce/backend/src/controllers/recording.controller.ts @@ -19,7 +19,7 @@ export const startRecording = async (req: Request, res: Response) => { const logger = container.get(LoggerService); const recordingService = container.get(RecordingService); const { roomId, config } = req.body; - const { fields } = req.query as { fields?: MeetRecordingField[] }; + const { fields } = res.locals.validatedQuery as { fields?: MeetRecordingField[] }; logger.info(`Starting recording in room '${roomId}'`); try { @@ -39,7 +39,7 @@ export const startRecording = async (req: Request, res: Response) => { export const stopRecording = async (req: Request, res: Response) => { const logger = container.get(LoggerService); const recordingId = req.params.recordingId; - const { fields } = req.query as { fields?: MeetRecordingField[] }; + const { fields } = res.locals.validatedQuery as { fields?: MeetRecordingField[] }; try { logger.info(`Stopping recording '${recordingId}'`); @@ -58,7 +58,7 @@ export const stopRecording = async (req: Request, res: Response) => { export const getRecordings = async (req: Request, res: Response) => { const logger = container.get(LoggerService); const recordingService = container.get(RecordingService); - const queryParams = req.query; + const queryParams = res.locals.validatedQuery ?? {}; logger.info('Getting all recordings'); @@ -82,7 +82,7 @@ export const getRecordings = async (req: Request, res: Response) => { export const bulkDeleteRecordings = async (req: Request, res: Response) => { const logger = container.get(LoggerService); const recordingService = container.get(RecordingService); - const { recordingIds } = req.query as { recordingIds: string[] }; + const { recordingIds } = res.locals.validatedQuery as { recordingIds: string[] }; logger.info(`Deleting recordings: ${recordingIds}`); @@ -105,7 +105,7 @@ export const getRecording = async (req: Request, res: Response) => { const logger = container.get(LoggerService); const recordingService = container.get(RecordingService); const recordingId = req.params.recordingId; - const { fields } = req.query as { fields?: MeetRecordingField[] }; + const { fields } = res.locals.validatedQuery as { fields?: MeetRecordingField[] }; logger.info(`Getting recording '${recordingId}'`); @@ -220,13 +220,14 @@ export const getRecordingUrl = async (req: Request, res: Response) => { const logger = container.get(LoggerService); const recordingService = container.get(RecordingService); const recordingId = req.params.recordingId; - const privateAccess = req.query.privateAccess === 'true'; + const { privateAccess } = res.locals.validatedQuery as { privateAccess: string }; + const isPrivateAccess = privateAccess === 'true'; logger.info(`Getting URL for recording '${recordingId}'`); try { const recordingSecrets = await recordingService.getRecordingAccessSecrets(recordingId); - const secret = privateAccess ? recordingSecrets.privateAccessSecret : recordingSecrets.publicAccessSecret; + const secret = isPrivateAccess ? recordingSecrets.privateAccessSecret : recordingSecrets.publicAccessSecret; const recordingUrl = `${getBaseUrl()}/recording/${recordingId}?secret=${secret}`; return res.status(200).json({ url: recordingUrl }); @@ -239,7 +240,7 @@ export const downloadRecordingsZip = async (req: Request, res: Response) => { const logger = container.get(LoggerService); const recordingService = container.get(RecordingService); - const { recordingIds } = req.query as { recordingIds: string[] }; + const { recordingIds } = res.locals.validatedQuery as { recordingIds: string[] }; const validRecordings: MeetRecordingInfo[] = []; logger.info(`Preparing ZIP download for recordings: ${recordingIds}`); diff --git a/meet-ce/backend/src/controllers/room-member.controller.ts b/meet-ce/backend/src/controllers/room-member.controller.ts index 754526e1..0f74e291 100644 --- a/meet-ce/backend/src/controllers/room-member.controller.ts +++ b/meet-ce/backend/src/controllers/room-member.controller.ts @@ -32,7 +32,7 @@ export const getRoomMembers = async (req: Request, res: Response) => { const roomMemberService = container.get(RoomMemberService); const { roomId } = req.params; - const filters = req.query as MeetRoomMemberFilters; + const filters = res.locals.validatedQuery as MeetRoomMemberFilters; try { logger.verbose(`Getting members for room '${roomId}'`); @@ -100,7 +100,7 @@ export const bulkDeleteRoomMembers = async (req: Request, res: Response) => { const roomMemberService = container.get(RoomMemberService); const { roomId } = req.params; - const { memberIds } = req.query as { memberIds: string[] }; + const { memberIds } = res.locals.validatedQuery as { memberIds: string[] }; try { logger.verbose(`Deleting members from room '${roomId}' with IDs: ${memberIds}`); diff --git a/meet-ce/backend/src/controllers/room.controller.ts b/meet-ce/backend/src/controllers/room.controller.ts index 3901fa80..bccc213c 100644 --- a/meet-ce/backend/src/controllers/room.controller.ts +++ b/meet-ce/backend/src/controllers/room.controller.ts @@ -22,7 +22,7 @@ export const createRoom = async (req: Request, res: Response) => { const roomService = container.get(RoomService); const options: MeetRoomOptions = req.body; // Fields are merged from headers into req.query by the middleware - const { fields, extraFields } = req.query as { + const { fields, extraFields } = res.locals.validatedQuery as { fields?: MeetRoomField[]; extraFields?: MeetRoomExtraField[]; }; @@ -46,7 +46,7 @@ export const createRoom = async (req: Request, res: Response) => { export const getRooms = async (req: Request, res: Response) => { const logger = container.get(LoggerService); const roomService = container.get(RoomService); - const queryParams = req.query as MeetRoomFilters; + const queryParams = res.locals.validatedQuery as MeetRoomFilters; logger.verbose(`Getting all rooms with filters: ${JSON.stringify(queryParams)}`); @@ -71,7 +71,7 @@ export const getRoom = async (req: Request, res: Response) => { const { roomId } = req.params; // Zod already validated and transformed to typed arrays - const { fields, extraFields } = req.query as { + const { fields, extraFields } = res.locals.validatedQuery as { fields?: MeetRoomField[]; extraFields?: MeetRoomExtraField[]; }; @@ -101,7 +101,7 @@ export const deleteRoom = async (req: Request, res: Response) => { const roomService = container.get(RoomService); const { roomId } = req.params; - const { fields, extraFields, withMeeting, withRecordings } = req.query as { + const { fields, extraFields, withMeeting, withRecordings } = res.locals.validatedQuery as { fields?: MeetRoomField[]; extraFields?: MeetRoomExtraField[]; withMeeting: MeetRoomDeletionPolicyWithMeeting; @@ -141,7 +141,7 @@ export const bulkDeleteRooms = async (req: Request, res: Response) => { const logger = container.get(LoggerService); const roomService = container.get(RoomService); - const { roomIds, fields, extraFields, withMeeting, withRecordings } = req.query as { + const { roomIds, fields, extraFields, withMeeting, withRecordings } = res.locals.validatedQuery as { roomIds: string[]; fields?: MeetRoomField[]; extraFields?: MeetRoomExtraField[]; @@ -150,7 +150,7 @@ export const bulkDeleteRooms = async (req: Request, res: Response) => { }; try { - logger.verbose(`Deleting rooms: ${roomIds} with options: ${JSON.stringify(req.query)}`); + logger.verbose(`Deleting rooms: ${roomIds} with options: ${JSON.stringify(res.locals.validatedQuery)}`); const deleteOpts: MeetRoomDeletionOptions = { withMeeting, diff --git a/meet-ce/backend/src/controllers/user.controller.ts b/meet-ce/backend/src/controllers/user.controller.ts index 5670d6f4..efb39673 100644 --- a/meet-ce/backend/src/controllers/user.controller.ts +++ b/meet-ce/backend/src/controllers/user.controller.ts @@ -10,9 +10,9 @@ import { } from '../models/error.model.js'; import { LoggerService } from '../services/logger.service.js'; import { RequestSessionService } from '../services/request-session.service.js'; +import { TokenService } from '../services/token.service.js'; import { UserService } from '../services/user.service.js'; import { getBaseUrl } from '../utils/url.utils.js'; -import { TokenService } from '../services/token.service.js'; export const createUser = async (req: Request, res: Response) => { const userOptions = req.body as MeetUserOptions; @@ -31,7 +31,7 @@ export const createUser = async (req: Request, res: Response) => { }; export const getUsers = async (req: Request, res: Response) => { - const queryParams = req.query as MeetUserFilters; + const queryParams = res.locals.validatedQuery as MeetUserFilters; const logger = container.get(LoggerService); logger.verbose(`Getting all users`); @@ -186,7 +186,7 @@ export const deleteUser = async (req: Request, res: Response) => { }; export const bulkDeleteUsers = async (req: Request, res: Response) => { - const { userIds } = req.query as { userIds: string[] }; + const { userIds } = res.locals.validatedQuery as { userIds: string[] }; const logger = container.get(LoggerService); logger.verbose(`Deleting users: ${userIds}`); diff --git a/meet-ce/backend/src/middlewares/request-validators/recording-validator.middleware.ts b/meet-ce/backend/src/middlewares/request-validators/recording-validator.middleware.ts index d789ee23..89da001e 100644 --- a/meet-ce/backend/src/middlewares/request-validators/recording-validator.middleware.ts +++ b/meet-ce/backend/src/middlewares/request-validators/recording-validator.middleware.ts @@ -15,7 +15,8 @@ import { export const validateStartRecordingReq = (req: Request, res: Response, next: NextFunction) => { // Merge X-Fields header into query params before validation - mergeRecordingHeaderFieldsIntoQuery(req.headers, req.query); + const query = req.query; + mergeRecordingHeaderFieldsIntoQuery(req.headers, query); const bodyResult = StartRecordingReqSchema.safeParse(req.body); @@ -25,27 +26,28 @@ export const validateStartRecordingReq = (req: Request, res: Response, next: Nex req.body = bodyResult.data; - const queryResult = RecordingQueryFieldsSchema.safeParse(req.query); + const queryResult = RecordingQueryFieldsSchema.safeParse(query); if (!queryResult.success) { return rejectUnprocessableRequest(res, queryResult.error); } - req.query = queryResult.data; + res.locals.validatedQuery = queryResult.data; next(); }; export const validateGetRecordingsReq = (req: Request, res: Response, next: NextFunction) => { // Merge X-Fields header into query params before validation - mergeRecordingHeaderFieldsIntoQuery(req.headers, req.query); + const query = req.query; + mergeRecordingHeaderFieldsIntoQuery(req.headers, query); - const { success, error, data } = RecordingFiltersSchema.safeParse(req.query); + const { success, error, data } = RecordingFiltersSchema.safeParse(query); if (!success) { return rejectUnprocessableRequest(res, error); } - req.query = { + res.locals.validatedQuery = { ...data, maxItems: data.maxItems?.toString() }; @@ -59,7 +61,7 @@ export const validateBulkDeleteRecordingsReq = (req: Request, res: Response, nex return rejectUnprocessableRequest(res, error); } - req.query = data; + res.locals.validatedQuery = data; next(); }; @@ -77,11 +79,12 @@ export const withValidRecordingId = (req: Request, res: Response, next: NextFunc export const validateGetRecordingReq = (req: Request, res: Response, next: NextFunction) => { // Merge X-Fields header into query params before validation - mergeRecordingHeaderFieldsIntoQuery(req.headers, req.query); + const query = req.query; + mergeRecordingHeaderFieldsIntoQuery(req.headers, query); const { success, error, data } = GetRecordingReqSchema.safeParse({ params: req.params, - query: req.query + query }); if (!success) { @@ -89,17 +92,18 @@ export const validateGetRecordingReq = (req: Request, res: Response, next: NextF } req.params.recordingId = data.params.recordingId; - req.query = data.query; + res.locals.validatedQuery = data.query; next(); }; export const validateStopRecordingReq = (req: Request, res: Response, next: NextFunction) => { // Merge X-Fields header into query params before validation - mergeRecordingHeaderFieldsIntoQuery(req.headers, req.query); + const query = req.query; + mergeRecordingHeaderFieldsIntoQuery(req.headers, query); const { success, error, data } = StopRecordingReqSchema.safeParse({ params: req.params, - query: req.query + query }); if (!success) { @@ -107,7 +111,7 @@ export const validateStopRecordingReq = (req: Request, res: Response, next: Next } req.params.recordingId = data.params.recordingId; - req.query = data.query; + res.locals.validatedQuery = data.query; next(); }; @@ -139,6 +143,6 @@ export const validateGetRecordingUrlReq = (req: Request, res: Response, next: Ne } req.params.recordingId = data.params.recordingId; - req.query.privateAccess = data.query.privateAccess ? 'true' : 'false'; + res.locals.validatedQuery = { privateAccess: data.query.privateAccess ? 'true' : 'false' }; next(); }; diff --git a/meet-ce/backend/src/middlewares/request-validators/room-member-validator.middleware.ts b/meet-ce/backend/src/middlewares/request-validators/room-member-validator.middleware.ts index 764bead6..be1140d6 100644 --- a/meet-ce/backend/src/middlewares/request-validators/room-member-validator.middleware.ts +++ b/meet-ce/backend/src/middlewares/request-validators/room-member-validator.middleware.ts @@ -28,7 +28,7 @@ export const validateGetRoomMembersReq = (req: Request, res: Response, next: Nex return rejectUnprocessableRequest(res, error); } - req.query = { + res.locals.validatedQuery = { ...data, maxItems: data.maxItems?.toString() }; @@ -42,7 +42,7 @@ export const validateBulkDeleteRoomMembersReq = (req: Request, res: Response, ne return rejectUnprocessableRequest(res, error); } - req.query = data; + res.locals.validatedQuery = data; next(); }; diff --git a/meet-ce/backend/src/middlewares/request-validators/room-validator.middleware.ts b/meet-ce/backend/src/middlewares/request-validators/room-validator.middleware.ts index 84122857..c6837434 100644 --- a/meet-ce/backend/src/middlewares/request-validators/room-validator.middleware.ts +++ b/meet-ce/backend/src/middlewares/request-validators/room-validator.middleware.ts @@ -15,7 +15,8 @@ import { } from '../../models/zod-schemas/room.schema.js'; export const validateCreateRoomReq = (req: Request, res: Response, next: NextFunction) => { - mergeHeaderFieldsIntoQuery(req.headers, req.query); + const query = req.query; + mergeHeaderFieldsIntoQuery(req.headers, query); const bodyResult = RoomOptionsSchema.safeParse(req.body); @@ -25,27 +26,28 @@ export const validateCreateRoomReq = (req: Request, res: Response, next: NextFun req.body = bodyResult.data; - const { success, error, data } = RoomQueryFieldsSchema.safeParse(req.query); + const { success, error, data } = RoomQueryFieldsSchema.safeParse(query); if (!success) { return rejectUnprocessableRequest(res, error); } - req.query = data; + res.locals.validatedQuery = data; next(); }; export const validateGetRoomsReq = (req: Request, res: Response, next: NextFunction) => { // Merge X-Fields and X-ExtraFields headers into query params before validation - mergeHeaderFieldsIntoQuery(req.headers, req.query); + const query = req.query; + mergeHeaderFieldsIntoQuery(req.headers, query); - const { success, error, data } = RoomFiltersSchema.safeParse(req.query); + const { success, error, data } = RoomFiltersSchema.safeParse(query); if (!success) { return rejectUnprocessableRequest(res, error); } - req.query = { + res.locals.validatedQuery = { ...data, maxItems: data.maxItems?.toString() }; @@ -54,15 +56,16 @@ export const validateGetRoomsReq = (req: Request, res: Response, next: NextFunct export const validateBulkDeleteRoomsReq = (req: Request, res: Response, next: NextFunction) => { // Merge X-Fields and X-ExtraFields headers into query params before validation - mergeHeaderFieldsIntoQuery(req.headers, req.query); + const query = req.query; + mergeHeaderFieldsIntoQuery(req.headers, query); - const { success, error, data } = BulkDeleteRoomsReqSchema.safeParse(req.query); + const { success, error, data } = BulkDeleteRoomsReqSchema.safeParse(query); if (!success) { return rejectUnprocessableRequest(res, error); } - req.query = data; + res.locals.validatedQuery = data; next(); }; @@ -80,15 +83,16 @@ export const withValidRoomId = (req: Request, res: Response, next: NextFunction) export const validateGetRoomReq = (req: Request, res: Response, next: NextFunction) => { // Merge X-Fields and X-ExtraFields headers into query params before validation - mergeHeaderFieldsIntoQuery(req.headers, req.query); + const query = req.query; + mergeHeaderFieldsIntoQuery(req.headers, query); - const { success, error, data } = RoomQueryFieldsSchema.safeParse(req.query); + const { success, error, data } = RoomQueryFieldsSchema.safeParse(query); if (!success) { return rejectUnprocessableRequest(res, error); } - req.query = data; + res.locals.validatedQuery = data; next(); }; @@ -102,15 +106,16 @@ export const validateDeleteRoomReq = (req: Request, res: Response, next: NextFun req.params.roomId = roomIdResult.data; // Merge X-Fields and X-ExtraFields headers into query params before validation - mergeHeaderFieldsIntoQuery(req.headers, req.query); + const query = req.query; + mergeHeaderFieldsIntoQuery(req.headers, query); - const queryParamsResult = DeleteRoomReqSchema.safeParse(req.query); + const queryParamsResult = DeleteRoomReqSchema.safeParse(query); if (!queryParamsResult.success) { return rejectUnprocessableRequest(res, queryParamsResult.error); } - req.query = queryParamsResult.data; + res.locals.validatedQuery = queryParamsResult.data; next(); }; diff --git a/meet-ce/backend/src/middlewares/request-validators/user-validator.middleware.ts b/meet-ce/backend/src/middlewares/request-validators/user-validator.middleware.ts index 0134fad4..1799306f 100644 --- a/meet-ce/backend/src/middlewares/request-validators/user-validator.middleware.ts +++ b/meet-ce/backend/src/middlewares/request-validators/user-validator.middleware.ts @@ -27,7 +27,7 @@ export const validateGetUsersReq = (req: Request, res: Response, next: NextFunct return rejectUnprocessableRequest(res, error); } - req.query = { + res.locals.validatedQuery = { ...data, maxItems: data.maxItems?.toString() }; @@ -41,7 +41,7 @@ export const validateBulkDeleteUsersReq = (req: Request, res: Response, next: Ne return rejectUnprocessableRequest(res, error); } - req.query = data; + res.locals.validatedQuery = data; next(); }; diff --git a/meet-ce/backend/src/server.ts b/meet-ce/backend/src/server.ts index 1fefb73b..eb1e1c3e 100644 --- a/meet-ce/backend/src/server.ts +++ b/meet-ce/backend/src/server.ts @@ -127,7 +127,7 @@ const startServer = (app: express.Application) => { const basePath = getBasePath(); const basePathDisplay = basePath === '/' ? '' : basePath.slice(0, -1); - app.listen(MEET_ENV.SERVER_PORT, async () => { + const server = app.listen(MEET_ENV.SERVER_PORT, () => { console.log(' '); console.log('---------------------------------------------------------'); console.log(' '); @@ -145,6 +145,11 @@ const startServer = (app: express.Application) => { ); logEnvVars(); }); + + server.on('error', (error: Error) => { + console.error('Server failed to start:', error.message); + process.exit(1); + }); }; /** diff --git a/meet-ce/backend/src/types/express-locals.d.ts b/meet-ce/backend/src/types/express-locals.d.ts new file mode 100644 index 00000000..7e602279 --- /dev/null +++ b/meet-ce/backend/src/types/express-locals.d.ts @@ -0,0 +1,9 @@ +declare global { + namespace Express { + interface Locals { + validatedQuery?: Record; + } + } +} + +export {}; diff --git a/meet-ce/backend/tests/integration/api/recordings/get-recordings.test.ts b/meet-ce/backend/tests/integration/api/recordings/get-recordings.test.ts index d5c5fe75..bd695ae1 100644 --- a/meet-ce/backend/tests/integration/api/recordings/get-recordings.test.ts +++ b/meet-ce/backend/tests/integration/api/recordings/get-recordings.test.ts @@ -380,11 +380,6 @@ describe('Recordings API Tests', () => { expectValidationError(response, 'maxItems', 'must be a positive number'); }); - it('should fail when fields is not a string', async () => { - const response = await getAllRecordings({ fields: { invalid: 'object' } }); - expectValidationError(response, 'fields', 'Expected string'); - }); - it('should fail when sortField is invalid', async () => { const response = await getAllRecordings({ sortField: 'invalidField' }); expectValidationError(response, 'sortField', 'Invalid enum value'); diff --git a/meet-ce/backend/tests/integration/api/rooms/get-rooms.test.ts b/meet-ce/backend/tests/integration/api/rooms/get-rooms.test.ts index ffb7a289..3cb3af79 100644 --- a/meet-ce/backend/tests/integration/api/rooms/get-rooms.test.ts +++ b/meet-ce/backend/tests/integration/api/rooms/get-rooms.test.ts @@ -229,11 +229,6 @@ describe('Room API Tests', () => { expectValidationError(response, 'maxItems', 'must be a positive number'); }); - it('should fail when fields is not a string', async () => { - const response = await getRooms({ fields: { invalid: 'data' } }); - expectValidationError(response, 'fields', 'Expected string'); - }); - it('should fail when sortField is invalid', async () => { const response = await getRooms({ sortField: 'invalidField' }); expectValidationError(response, 'sortField', 'Invalid enum value'); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 66eca497..d08d1d3b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -105,11 +105,11 @@ importers: specifier: 16.6.1 version: 16.6.1 express: - specifier: 4.22.1 - version: 4.22.1 + specifier: 5.2.1 + version: 5.2.1 express-rate-limit: specifier: 7.5.1 - version: 7.5.1(express@4.22.1) + version: 7.5.1(express@5.2.1) inversify: specifier: 6.2.2 version: 6.2.2(reflect-metadata@0.2.2) @@ -152,13 +152,13 @@ importers: version: 5.0.2 '@types/cookie-parser': specifier: 1.4.9 - version: 1.4.9(@types/express@4.17.25) + version: 1.4.9(@types/express@5.0.6) '@types/cors': specifier: 2.8.19 version: 2.8.19 '@types/express': - specifier: 4.17.25 - version: 4.17.25 + specifier: 5.0.6 + version: 5.0.6 '@types/jest': specifier: 29.5.14 version: 29.5.14 @@ -4133,9 +4133,6 @@ packages: '@types/express@4.17.23': resolution: {integrity: sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==} - '@types/express@4.17.25': - resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} - '@types/express@5.0.6': resolution: {integrity: sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==} @@ -6080,10 +6077,6 @@ packages: resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} engines: {node: '>= 0.10.0'} - express@4.22.1: - resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} - engines: {node: '>= 0.10.0'} - express@5.2.1: resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} engines: {node: '>= 18'} @@ -14834,9 +14827,9 @@ snapshots: dependencies: '@types/express': 4.17.23 - '@types/cookie-parser@1.4.9(@types/express@4.17.25)': + '@types/cookie-parser@1.4.9(@types/express@5.0.6)': dependencies: - '@types/express': 4.17.25 + '@types/express': 5.0.6 '@types/cookiejar@2.1.5': {} @@ -14887,13 +14880,6 @@ snapshots: '@types/qs': 6.14.0 '@types/serve-static': 2.2.0 - '@types/express@4.17.25': - dependencies: - '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 4.19.7 - '@types/qs': 6.14.0 - '@types/serve-static': 1.15.10 - '@types/express@5.0.6': dependencies: '@types/body-parser': 1.19.6 @@ -17375,10 +17361,6 @@ snapshots: dependencies: express: 4.21.2 - express-rate-limit@7.5.1(express@4.22.1): - dependencies: - express: 4.22.1 - express-rate-limit@7.5.1(express@5.2.1): dependencies: express: 5.2.1 @@ -17419,42 +17401,6 @@ snapshots: transitivePeerDependencies: - supports-color - express@4.22.1: - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.4 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.7.2 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.3.1 - fresh: 0.5.2 - http-errors: 2.0.1 - merge-descriptors: 1.0.3 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.12 - proxy-addr: 2.0.7 - qs: 6.14.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.19.2 - serve-static: 1.16.3 - setprototypeof: 1.2.0 - statuses: 2.0.2 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - express@5.2.1: dependencies: accepts: 2.0.0 @@ -17477,7 +17423,7 @@ snapshots: once: 1.4.0 parseurl: 1.3.3 proxy-addr: 2.0.7 - qs: 6.14.0 + qs: 6.15.0 range-parser: 1.2.1 router: 2.2.0 send: 1.2.1 @@ -18028,7 +17974,7 @@ snapshots: transitivePeerDependencies: - supports-color - http-proxy-middleware@2.0.9(@types/express@4.17.25): + http-proxy-middleware@2.0.9(@types/express@4.17.23): dependencies: '@types/http-proxy': 1.17.17 http-proxy: 1.18.1(debug@4.4.3) @@ -18036,7 +17982,7 @@ snapshots: is-plain-obj: 3.0.0 micromatch: 4.0.8 optionalDependencies: - '@types/express': 4.17.25 + '@types/express': 4.17.23 transitivePeerDependencies: - debug @@ -22109,7 +22055,7 @@ snapshots: dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 - '@types/express': 4.17.25 + '@types/express': 4.17.23 '@types/express-serve-static-core': 4.19.7 '@types/serve-index': 1.9.4 '@types/serve-static': 1.15.10 @@ -22121,9 +22067,9 @@ snapshots: colorette: 2.0.20 compression: 1.8.1 connect-history-api-fallback: 2.0.0 - express: 4.22.1 + express: 4.21.2 graceful-fs: 4.2.11 - http-proxy-middleware: 2.0.9(@types/express@4.17.25) + http-proxy-middleware: 2.0.9(@types/express@4.17.23) ipaddr.js: 2.3.0 launch-editor: 2.12.0 open: 10.2.0