Skip to content

Commit 7a61061

Browse files
committed
merged upstream PR thedevs-network#728
2 parents 6d4acf0 + 27bc266 commit 7a61061

File tree

13 files changed

+142
-9
lines changed

13 files changed

+142
-9
lines changed

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
12

package-lock.json

Lines changed: 46 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
"passport-localapikey-update": "^0.6.0",
6969
"pg": "^8.8.0",
7070
"pg-query-stream": "^4.2.4",
71+
"prom-client": "14.2.0",
7172
"qrcode.react": "^3.1.0",
7273
"query-string": "^7.1.1",
7374
"re2": "^1.17.8",

server/handlers/auth.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { Handler } from "express";
33
import passport from "passport";
44
import bcrypt from "bcryptjs";
55
import nanoid from "nanoid";
6-
import { v4 as uuid } from "uuid";
76
import axios from "axios";
7+
import { randomUUID } from "crypto";
88

99
import { CustomError } from "../utils";
1010
import * as utils from "../utils";
@@ -193,7 +193,7 @@ export const resetPasswordRequest: Handler = async (req, res) => {
193193
const [user] = await query.user.update(
194194
{ email: req.body.email },
195195
{
196-
reset_password_token: uuid(),
196+
reset_password_token: randomUUID(),
197197
reset_password_expires: addMinutes(new Date(), 30).toISOString()
198198
}
199199
);
@@ -251,7 +251,7 @@ export const changeEmailRequest: Handler = async (req, res) => {
251251
{ id: req.user.id },
252252
{
253253
change_email_address: email,
254-
change_email_token: uuid(),
254+
change_email_token: randomUUID(),
255255
change_email_expires: addMinutes(new Date(), 30).toISOString()
256256
}
257257
);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Handler, NextFunction, Request, Response } from "express";
2+
import { Counter } from "prom-client";
3+
import { register } from "../routes/metrics";
4+
5+
const linkCounter = new Counter({
6+
name: 'link_counter',
7+
help: 'Number of links created',
8+
registers: [register]
9+
})
10+
11+
export const linkCounterMiddleware: Handler = (
12+
_req: Request, res: Response, next: NextFunction,
13+
) => {
14+
res.on("close", () => {
15+
if ([200, 201].includes(res.statusCode)) {
16+
linkCounter.inc(1);
17+
}
18+
})
19+
next();
20+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Handler, Request, Response } from "express";
2+
import { Histogram, } from "prom-client";
3+
import { register } from "../routes/metrics";
4+
5+
const responseDurationHistogram: Histogram = new Histogram({
6+
name: 'response_duration',
7+
help: 'response_duration',
8+
labelNames: ["method", "path", "status"],
9+
registers: [register]
10+
});
11+
12+
export const responseDurationMiddleware: Handler = (
13+
req: Request, res: Response, next
14+
) => {
15+
const { method, originalUrl } = req;
16+
17+
const endTimer = responseDurationHistogram.startTimer({
18+
method,
19+
path: originalUrl
20+
})
21+
22+
res.on("close", () => {
23+
const { statusCode } = res;
24+
endTimer({ status: statusCode });
25+
});
26+
27+
next();
28+
};

server/queries/user.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { v4 as uuid } from "uuid";
21
import { addMinutes } from "date-fns";
32

43
import redisCLient, * as redis from "../redis";
54
import knex from "../knex";
5+
import { randomUUID } from "crypto";
66

77
export const find = async (match: Partial<User>) => {
88
if (match.email || match.apikey) {
@@ -35,7 +35,7 @@ export const add = async (params: Add, user?: User) => {
3535
const data = {
3636
email: params.email,
3737
password: params.password,
38-
verification_token: uuid(),
38+
verification_token: randomUUID(),
3939
verification_expires: addMinutes(new Date(), 60).toISOString(),
4040
verified: process.env.MAIL_HOST ? false : true
4141
};

server/redis.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const client = new Redis({
1010
});
1111

1212
export default client;
13+
export const redisHealthStatus = [ "connect", "ready" ];
1314

1415
export const key = {
1516
link: (address: string, domain_id?: number, user_id?: number) =>

server/routes/health.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
import { Router } from "express";
2+
import client, { redisHealthStatus } from "../redis";
23

34
const router = Router();
4-
5-
router.get("/", (_, res) => res.send("OK"));
5+
router.get("/", (_, res) => {
6+
const redisStatus = client.status;
7+
const status = redisHealthStatus.includes(redisStatus) ? 200 : 500;
8+
res
9+
.status(status)
10+
.json({
11+
api: "OK",
12+
redis: client.status,
13+
});
14+
});
615

716
export default router;

server/routes/links.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as helpers from "../handlers/helpers";
77
import * as link from "../handlers/links";
88
import * as auth from "../handlers/auth";
99
import env from "../env";
10+
import { linkCounterMiddleware } from "../metrics/link-counter.middleware";
1011

1112
const router = Router();
1213

@@ -27,6 +28,7 @@ router.post(
2728
asyncHandler(auth.cooldown),
2829
validators.createLink,
2930
asyncHandler(helpers.verify),
31+
asyncHandler(linkCounterMiddleware),
3032
asyncHandler(link.create)
3133
);
3234

server/routes/metrics.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import asyncHandler from "express-async-handler";
2+
import client from 'prom-client'
3+
import { Router } from "express";
4+
5+
const router = Router();
6+
7+
export const register = new client.Registry();
8+
9+
client.collectDefaultMetrics({
10+
register,
11+
});
12+
13+
router.get(
14+
"/",
15+
asyncHandler(async (_, res) => {
16+
res.set("Content-Type", register.contentType);
17+
return res.send(await register.metrics());
18+
})
19+
);
20+
21+
export default router;

server/routes/routes.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import { Router } from "express";
22

3+
import auth from "./auth";
34
import domains from "./domains";
45
import health from "./health";
56
import links from "./links";
7+
import metrics from "./metrics";
68
import user from "./users";
7-
import auth from "./auth";
89

910
const router = Router();
1011

12+
router.use("/auth", auth);
1113
router.use("/domains", domains);
1214
router.use("/health", health);
1315
router.use("/links", links);
16+
router.use("/metrics", metrics);
1417
router.use("/users", user);
15-
router.use("/auth", auth);
1618

1719
export default router;

server/server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { stream } from "./config/winston";
1616

1717
import "./cron";
1818
import "./passport";
19+
import { responseDurationMiddleware } from "./metrics/response-duration.middleware";
1920

2021
const port = env.PORT;
2122
const app = nextApp({ dir: "./client", dev: env.isDev });
@@ -37,6 +38,7 @@ app.prepare().then(async () => {
3738
server.use(passport.initialize());
3839
server.use(express.static("static"));
3940
server.use(helpers.ip);
41+
server.use(responseDurationMiddleware)
4042

4143
server.use(asyncHandler(links.redirectCustomDomain));
4244

0 commit comments

Comments
 (0)