Skip to content

Commit 1d1dfec

Browse files
committed
Upgrade Express to version 5
1 parent 389b795 commit 1d1dfec

File tree

11 files changed

+284
-182
lines changed

11 files changed

+284
-182
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"url": "https://juffalow.com"
1111
},
1212
"devDependencies": {
13-
"@types/express": "^4.17.21",
13+
"@types/express": "^5.0.0",
1414
"@types/jest": "^29.5.12",
1515
"@types/jsonwebtoken": "^9.0.6",
1616
"@types/multer": "^1.4.12",
@@ -39,7 +39,7 @@
3939
"aws-xray-sdk": "^3.10.2",
4040
"cls-hooked": "^4.2.2",
4141
"deepmerge": "^4.3.1",
42-
"express": "^4.19.2",
42+
"express": "^5.0.1",
4343
"fluent-ffmpeg": "^2.1.3",
4444
"image-size": "^1.1.1",
4545
"joi": "^17.13.3",

src/app.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ app.use(express.urlencoded({ extended: true }));
2121
app.use(cors);
2222
app.use(logRequest);
2323

24-
app.use(services.Trace.openSegment(config.serviceName) as any);
24+
app.use(services.Trace.openSegment(config.serviceName));
2525
app.use(`${config.routePrefix}`, routes);
26-
app.use(services.Trace.closeSegment() as any);
26+
app.use(services.Trace.closeSegment());
2727

2828
app.use(errorHandler);
2929

src/middlewares/logRequest.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@ import type { Request, Response, NextFunction } from 'express';
22
import logger from '../logger';
33

44
export default function logRequest(req: Request, res: Response, next: NextFunction): void {
5-
if (req.method === 'OPTIONS') {
6-
next();
7-
return;
5+
if (req.method !== 'OPTIONS') {
6+
logger.debug(`${req.method} ${req.path}`, { body: req.body, query: req.query });
87
}
98

10-
logger.debug(`${req.method} ${req.path}`, { body: req.body, query: req.query });
11-
129
next();
1310
}

src/middlewares/optionalAuth.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import type { Request, Response, NextFunction } from 'express';
22
import services from '../services';
33

4-
export default async function auth(req: Request, res: Response, next: NextFunction): Promise<unknown> {
5-
if (req.method === 'OPTIONS') {
6-
return next();
7-
}
8-
9-
if ('authorization' in req.headers) {
4+
export default async function auth(req: Request, res: Response, next: NextFunction): Promise<void> {
5+
if (req.method !== 'OPTIONS' && 'authorization' in req.headers) {
106
const token = req.headers.authorization.replace('Bearer ', '');
117

128
try {
@@ -16,7 +12,7 @@ export default async function auth(req: Request, res: Response, next: NextFuncti
1612

1713
req['user'] = services.Token.getUserData(data);
1814
} catch (err) {
19-
return res.status(401).json({ error: 'Unauthorized!' });
15+
res.status(401).json({ error: 'Unauthorized!' });
2016
}
2117
}
2218

src/middlewares/requireAdmin.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
import type { Request, Response, NextFunction } from 'express';
22
import tokenService from '../services/token';
33

4-
export default async function requireAdmin(req: Request, res: Response, next: NextFunction): Promise<unknown> {
4+
export default async function requireAdmin(req: Request, res: Response, next: NextFunction): Promise<void> {
55
if ('authorization' in req.headers === false) {
6-
return res.status(401).json({ error: 'Unauthorized!' });
7-
}
8-
9-
const token = req.headers.authorization.replace('Bearer ', '');
6+
res.status(401).json({ error: 'Unauthorized!' });
7+
} else {
8+
const token = req.headers.authorization.replace('Bearer ', '');
109

11-
try {
12-
const jwt = tokenService.JWT;
13-
const data = jwt.verify(token);
10+
try {
11+
const jwt = tokenService.JWT;
12+
const data = jwt.verify(token);
1413

15-
if ('role' in data === false || 'service' in data === false) {
16-
throw new Error('Token does not contain mandatory fields!');
14+
if ('role' in data === false || 'service' in data === false) {
15+
throw new Error('Token does not contain mandatory fields!');
16+
}
17+
} catch (err) {
18+
res.status(401).json({ error: 'Unauthorized!' });
1719
}
18-
} catch (err) {
19-
return res.status(401).json({ error: 'Unauthorized!' });
2020
}
2121

2222
next();

src/middlewares/requireAuth.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import type { Request, Response, NextFunction } from 'express';
22
import services from '../services';
33

4-
export default async function requireAuth(req: Request, res: Response, next: NextFunction): Promise<unknown> {
4+
export default async function requireAuth(req: Request, res: Response, next: NextFunction): Promise<void> {
55
if ('authorization' in req.headers === false) {
6-
return res.status(401).json({ error: 'Unauthorized!' });
7-
}
8-
9-
const token = req.headers.authorization.replace('Bearer ', '');
6+
res.status(401).json({ error: 'Unauthorized!' });
7+
} else {
8+
const token = req.headers.authorization.replace('Bearer ', '');
109

11-
try {
12-
const payload = services.Token.verify(token);
13-
14-
const data = payload instanceof Promise ? await payload : payload;
10+
try {
11+
const payload = services.Token.verify(token);
12+
13+
const data = payload instanceof Promise ? await payload : payload;
1514

16-
req['user'] = services.Token.getUserData(data);
17-
} catch (err) {
18-
return res.status(401).json({ error: 'Unauthorized!' });
15+
req['user'] = services.Token.getUserData(data);
16+
} catch (err) {
17+
res.status(401).json({ error: 'Unauthorized!' });
18+
}
1919
}
2020

2121
next();

src/routes/upload.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const router = express.Router();
2626
*/
2727
const multerPromise = (req: express.Request, res: express.Response) => {
2828
return new Promise<void>((resolve, reject) => {
29-
upload(req, res, (err) => {
29+
upload(req as any, res as any, (err) => {
3030
if(!err) {
3131
resolve();
3232
}
@@ -64,7 +64,7 @@ router.post('/', optionalAuth, uploadMiddleware, validateRequest(postSchema), as
6464
}
6565
});
6666

67-
next();
67+
next();
6868
} catch (err) {
6969
next(err);
7070
}

src/services/trace/AWSXRay.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
11
import XRay from 'aws-xray-sdk';
22
import http from 'http';
33
import https from 'https';
4-
import type { Request, Response, NextFunction } from 'express';
4+
import type {
5+
Request,
6+
Response,
7+
NextFunction,
8+
RequestHandler,
9+
ErrorRequestHandler,
10+
} from 'express';
511

612
class AWSXRay implements Services.Trace {
713
constructor (plugins: string) {
814
this.setPlugins(plugins);
915
}
1016

11-
public openSegment(defaultName: string) {
17+
public openSegment(defaultName: string): RequestHandler[] {
1218
const traceMiddleware = (req: Request, res: Response, next: NextFunction) => {
1319
const traceId = this.getTraceId();
1420

15-
res.setHeader('x-request-id', traceId);
21+
res.setHeader('X-Request-Id', traceId);
1622

1723
next();
1824
};
1925

2026
return [ XRay.express.openSegment(defaultName), traceMiddleware ];
2127
}
2228

23-
public closeSegment() {
29+
public closeSegment(): ErrorRequestHandler {
2430
return XRay.express.closeSegment();
2531
}
2632

src/services/trace/CLSHooked.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,34 @@
11
import cls from 'cls-hooked';
22
import { v7 as uuidv7 } from 'uuid';
3-
import type { Request, Response, NextFunction } from 'express';
3+
import type {
4+
Request,
5+
Response,
6+
NextFunction,
7+
RequestHandler,
8+
ErrorRequestHandler,
9+
} from 'express';
410

511
const NAMESPACE = 'aws-upload-service';
612

713
class CLSHooked implements Services.Trace {
8-
public openSegment() {
14+
public openSegment(): RequestHandler {
915
const namespace = this.getNamespace();
1016

1117
return (req: Request, res: Response, next: NextFunction) => {
1218
const traceId = req.headers['x-request-id'] as string || req.query.traceId as string || uuidv7();
1319

1420
namespace.run(() => {
1521
namespace.set('traceId', traceId);
16-
res.setHeader('x-request-id', traceId);
22+
res.setHeader('X-Request-Id', traceId);
1723

1824
next();
1925
});
2026
}
2127
}
2228

23-
public closeSegment() {
24-
return (req: Request, res: Response, next: NextFunction) => {
25-
next();
29+
public closeSegment(): ErrorRequestHandler {
30+
return (error: Error, req: Request, res: Response, next: NextFunction) => {
31+
next(error);
2632
}
2733
}
2834

src/types/services.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ declare namespace Services {
5252
}
5353

5454
interface Trace {
55-
openSegment(defaultName: string): unknown;
55+
openSegment(defaultName: string): import ('express').RequestHandler | import ('express').RequestHandler[];
5656

57-
closeSegment(): unknown;
57+
closeSegment(): import ('express').ErrorRequestHandler;
5858

5959
createSegment(name: string, rootId?: string | null, parentId?: string | null): unknown;
6060

0 commit comments

Comments
 (0)