Loading package-lock.json +27 −0 Original line number Diff line number Diff line Loading @@ -9379,6 +9379,20 @@ "node": ">= 0.10.0" } }, "node_modules/express-rate-limit": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.3.1.tgz", "integrity": "sha512-BbaryvkY4wEgDqLgD18/NSy2lDO2jTuT9Y8c1Mpx0X63Yz0sYd5zN6KPe7UvpuSVvV33T6RaE1o1IVZQjHMYgw==", "engines": { "node": ">= 16" }, "funding": { "url": "https://github.com/sponsors/express-rate-limit" }, "peerDependencies": { "express": "4 || 5 || ^5.0.0-beta.1" } }, "node_modules/express-session": { "version": "1.17.3", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", Loading Loading @@ -12519,6 +12533,17 @@ "node": ">= 0.6" } }, "node_modules/rate-limit-redis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/rate-limit-redis/-/rate-limit-redis-4.2.0.tgz", "integrity": "sha512-wV450NQyKC24NmPosJb2131RoczLdfIJdKCReNwtVpm5998U8SgKrAZrIHaN/NfQgqOHaan8Uq++B4sa5REwjA==", "engines": { "node": ">= 16" }, "peerDependencies": { "express-rate-limit": ">= 6" } }, "node_modules/raw-body": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", Loading Loading @@ -16269,9 +16294,11 @@ "connect-redis": "^7.1.1", "cors": "^2.8.5", "express": "^4.18.2", "express-rate-limit": "^7.3.1", "express-session": "^1.17.3", "openid-client": "^5.6.5", "prisma-dbml-generator": "^0.12.0", "rate-limit-redis": "^4.2.0", "redis": "^4.6.12", "socket.io": "^4.7.2", "winston": "^3.11.0" packages/server/package.json +2 −0 Original line number Diff line number Diff line Loading @@ -35,9 +35,11 @@ "connect-redis": "^7.1.1", "cors": "^2.8.5", "express": "^4.18.2", "express-rate-limit": "^7.3.1", "express-session": "^1.17.3", "openid-client": "^5.6.5", "prisma-dbml-generator": "^0.12.0", "rate-limit-redis": "^4.2.0", "redis": "^4.6.12", "socket.io": "^4.7.2", "winston": "^3.11.0" Loading packages/server/src/api/admin.ts +3 −0 Original line number Diff line number Diff line Loading @@ -2,9 +2,12 @@ import { Router } from "express"; import { User } from "../models/User"; import Canvas from "../lib/Canvas"; import { Logger } from "../lib/Logger"; import { RateLimiter } from "../lib/RateLimiter"; const app = Router(); app.use(RateLimiter.ADMIN); app.use(async (req, res, next) => { if (!req.session.user) { res.status(401).json({ Loading packages/server/src/api/client.ts +23 −7 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import { OpenID } from "../lib/oidc"; import { TokenSet, errors as OIDC_Errors } from "openid-client"; import { Logger } from "../lib/Logger"; import Canvas from "../lib/Canvas"; import { RateLimiter } from "../lib/RateLimiter"; const ClientParams = { TYPE: "auth_type", Loading @@ -23,6 +24,9 @@ const buildQuery = (obj: { [k in keyof typeof ClientParams]?: string }) => { const app = Router(); /** * Redirect to actual authorization page */ app.get("/login", (req, res) => { res.redirect( OpenID.client.authorizationUrl({ Loading @@ -34,10 +38,12 @@ app.get("/login", (req, res) => { // TODO: logout endpoint app.get("/callback", async (req, res) => { // TODO: return proper UIs for errors intead of raw JSON (#35) // const { code } = req.query; /** * Process token exchange from openid server * * This executes multiple database queries and should be ratelimited */ app.get("/callback", RateLimiter.HIGH, async (req, res) => { let exchange: TokenSet; try { Loading Loading @@ -190,8 +196,7 @@ app.get("/callback", async (req, res) => { res.redirect("/"); }); // TODO: Ratelimiting #40 app.get("/canvas/pixel/:x/:y", async (req, res) => { app.get("/canvas/pixel/:x/:y", RateLimiter.HIGH, async (req, res) => { const x = parseInt(req.params.x); const y = parseInt(req.params.y); Loading Loading @@ -234,6 +239,12 @@ app.get("/canvas/pixel/:x/:y", async (req, res) => { }); }); /** * Get the heatmap * * This is cached, so no need to ratelimit this * Even if the heatmap isn't ready, this doesn't cause the heatmap to get generated */ app.get("/heatmap", async (req, res) => { const heatmap = await Canvas.getCachedHeatmap(); Loading @@ -244,7 +255,12 @@ app.get("/heatmap", async (req, res) => { res.json({ success: true, heatmap }); }); app.get("/user/:sub", async (req, res) => { /** * Get user information from the sub (grant@toast.ooo) * * This causes a database query, so ratelimit it */ app.get("/user/:sub", RateLimiter.HIGH, async (req, res) => { const user = await prisma.user.findFirst({ where: { sub: req.params.sub } }); if (!user) { return res.status(404).json({ success: false, error: "unknown_user" }); Loading packages/server/src/index.ts +7 −1 Original line number Diff line number Diff line Loading @@ -39,6 +39,12 @@ if (!process.env.REDIS_SESSION_PREFIX) { ); } if (!process.env.REDIS_RATELIMIT_PREFIX) { Logger.info( "REDIS_RATELIMIT_PREFIX was not defined, defaulting to canvas_ratelimit:" ); } if (!process.env.AUTH_ENDPOINT) { Logger.error("AUTH_ENDPOINT is not defined"); process.exit(1); Loading @@ -61,7 +67,7 @@ if (!process.env.OIDC_CALLBACK_HOST) { // run startup tasks, all of these need to be completed to serve Promise.all([ Redis.connect(), Redis.getClient(), OpenID.setup().then(() => { Logger.info("Setup OpenID"); }), Loading Loading
package-lock.json +27 −0 Original line number Diff line number Diff line Loading @@ -9379,6 +9379,20 @@ "node": ">= 0.10.0" } }, "node_modules/express-rate-limit": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.3.1.tgz", "integrity": "sha512-BbaryvkY4wEgDqLgD18/NSy2lDO2jTuT9Y8c1Mpx0X63Yz0sYd5zN6KPe7UvpuSVvV33T6RaE1o1IVZQjHMYgw==", "engines": { "node": ">= 16" }, "funding": { "url": "https://github.com/sponsors/express-rate-limit" }, "peerDependencies": { "express": "4 || 5 || ^5.0.0-beta.1" } }, "node_modules/express-session": { "version": "1.17.3", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", Loading Loading @@ -12519,6 +12533,17 @@ "node": ">= 0.6" } }, "node_modules/rate-limit-redis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/rate-limit-redis/-/rate-limit-redis-4.2.0.tgz", "integrity": "sha512-wV450NQyKC24NmPosJb2131RoczLdfIJdKCReNwtVpm5998U8SgKrAZrIHaN/NfQgqOHaan8Uq++B4sa5REwjA==", "engines": { "node": ">= 16" }, "peerDependencies": { "express-rate-limit": ">= 6" } }, "node_modules/raw-body": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", Loading Loading @@ -16269,9 +16294,11 @@ "connect-redis": "^7.1.1", "cors": "^2.8.5", "express": "^4.18.2", "express-rate-limit": "^7.3.1", "express-session": "^1.17.3", "openid-client": "^5.6.5", "prisma-dbml-generator": "^0.12.0", "rate-limit-redis": "^4.2.0", "redis": "^4.6.12", "socket.io": "^4.7.2", "winston": "^3.11.0"
packages/server/package.json +2 −0 Original line number Diff line number Diff line Loading @@ -35,9 +35,11 @@ "connect-redis": "^7.1.1", "cors": "^2.8.5", "express": "^4.18.2", "express-rate-limit": "^7.3.1", "express-session": "^1.17.3", "openid-client": "^5.6.5", "prisma-dbml-generator": "^0.12.0", "rate-limit-redis": "^4.2.0", "redis": "^4.6.12", "socket.io": "^4.7.2", "winston": "^3.11.0" Loading
packages/server/src/api/admin.ts +3 −0 Original line number Diff line number Diff line Loading @@ -2,9 +2,12 @@ import { Router } from "express"; import { User } from "../models/User"; import Canvas from "../lib/Canvas"; import { Logger } from "../lib/Logger"; import { RateLimiter } from "../lib/RateLimiter"; const app = Router(); app.use(RateLimiter.ADMIN); app.use(async (req, res, next) => { if (!req.session.user) { res.status(401).json({ Loading
packages/server/src/api/client.ts +23 −7 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ import { OpenID } from "../lib/oidc"; import { TokenSet, errors as OIDC_Errors } from "openid-client"; import { Logger } from "../lib/Logger"; import Canvas from "../lib/Canvas"; import { RateLimiter } from "../lib/RateLimiter"; const ClientParams = { TYPE: "auth_type", Loading @@ -23,6 +24,9 @@ const buildQuery = (obj: { [k in keyof typeof ClientParams]?: string }) => { const app = Router(); /** * Redirect to actual authorization page */ app.get("/login", (req, res) => { res.redirect( OpenID.client.authorizationUrl({ Loading @@ -34,10 +38,12 @@ app.get("/login", (req, res) => { // TODO: logout endpoint app.get("/callback", async (req, res) => { // TODO: return proper UIs for errors intead of raw JSON (#35) // const { code } = req.query; /** * Process token exchange from openid server * * This executes multiple database queries and should be ratelimited */ app.get("/callback", RateLimiter.HIGH, async (req, res) => { let exchange: TokenSet; try { Loading Loading @@ -190,8 +196,7 @@ app.get("/callback", async (req, res) => { res.redirect("/"); }); // TODO: Ratelimiting #40 app.get("/canvas/pixel/:x/:y", async (req, res) => { app.get("/canvas/pixel/:x/:y", RateLimiter.HIGH, async (req, res) => { const x = parseInt(req.params.x); const y = parseInt(req.params.y); Loading Loading @@ -234,6 +239,12 @@ app.get("/canvas/pixel/:x/:y", async (req, res) => { }); }); /** * Get the heatmap * * This is cached, so no need to ratelimit this * Even if the heatmap isn't ready, this doesn't cause the heatmap to get generated */ app.get("/heatmap", async (req, res) => { const heatmap = await Canvas.getCachedHeatmap(); Loading @@ -244,7 +255,12 @@ app.get("/heatmap", async (req, res) => { res.json({ success: true, heatmap }); }); app.get("/user/:sub", async (req, res) => { /** * Get user information from the sub (grant@toast.ooo) * * This causes a database query, so ratelimit it */ app.get("/user/:sub", RateLimiter.HIGH, async (req, res) => { const user = await prisma.user.findFirst({ where: { sub: req.params.sub } }); if (!user) { return res.status(404).json({ success: false, error: "unknown_user" }); Loading
packages/server/src/index.ts +7 −1 Original line number Diff line number Diff line Loading @@ -39,6 +39,12 @@ if (!process.env.REDIS_SESSION_PREFIX) { ); } if (!process.env.REDIS_RATELIMIT_PREFIX) { Logger.info( "REDIS_RATELIMIT_PREFIX was not defined, defaulting to canvas_ratelimit:" ); } if (!process.env.AUTH_ENDPOINT) { Logger.error("AUTH_ENDPOINT is not defined"); process.exit(1); Loading @@ -61,7 +67,7 @@ if (!process.env.OIDC_CALLBACK_HOST) { // run startup tasks, all of these need to be completed to serve Promise.all([ Redis.connect(), Redis.getClient(), OpenID.setup().then(() => { Logger.info("Setup OpenID"); }), Loading