-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
369 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ | |
"terser": "^5.10.0" | ||
}, | ||
"engines": { | ||
"node": "^16", | ||
"yarn": "^1.22.0" | ||
"node": ">=16", | ||
"yarn": ">=1.22.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
get: | ||
summary: Get ED Contributions | ||
description: | | ||
Returns all contributions. | ||
The contributions aren't sorted, they're returned in the order they were returned by the database. | ||
responses: | ||
"200": | ||
description: OK | ||
content: | ||
application/json: | ||
schema: | ||
$ref: "#/components/schemas/edcontributions" | ||
examples: | ||
contributions: | ||
$ref: "#/components/examples/edcontributions" | ||
"500": | ||
$ref: "#/components/responses/internal_server_error" | ||
post: | ||
summary: Add ED Contribution | ||
description: | | ||
Adds ED contributions. | ||
This endpoint is rate-limited to 15 calls/min (0.25/sec) in order to prevent abuse. | ||
security: | ||
- token | ||
requestBody: | ||
required: true | ||
content: | ||
application/json: | ||
schema: | ||
$ref: "#/components/schemas/initial_edcontributions" | ||
responses: | ||
"201": | ||
description: Created | ||
content: | ||
application/json: | ||
schema: | ||
$ref: "#/components/schemas/edcontributions" | ||
examples: | ||
contributions: | ||
$ref: "#/components/examples/edcontributions" | ||
"400": | ||
$ref: "#/components/responses/zod_error" | ||
"403": | ||
$ref: "#/components/responses/forbidden" | ||
"419": | ||
$ref: "#/components/responses/too_many_requests" | ||
"500": | ||
$ref: "#/components/responses/internal_server_error" | ||
delete: | ||
summary: Delete ED Contribution | ||
security: | ||
- token | ||
parameters: | ||
- name: id | ||
in: path | ||
required: true | ||
schema: | ||
type: string | ||
description: The contribution's unique ID. | ||
responses: | ||
"204": | ||
description: No Content | ||
"400": | ||
$ref: "#/components/responses/zod_error" | ||
"401": | ||
$ref: "#/components/responses/unauthorized" | ||
"404": | ||
description: Not Found | ||
content: | ||
application/json: | ||
schema: | ||
$ref: "#/components/schemas/error" | ||
examples: | ||
contribution_not_found: | ||
summary: Contribution not found | ||
value: { "errors": ["Contribution not found"] } | ||
"419": | ||
$ref: "#/components/responses/too_many_requests" | ||
"500": | ||
$ref: "#/components/responses/internal_server_error" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// Copyright (c) 2022 Infernal Studios, All Rights Reserved unless otherwise explicitly stated. | ||
import express, { Router } from "express"; | ||
import { RateLimiterMemory } from "rate-limiter-flexible"; | ||
import { z } from "zod"; | ||
import { Database } from "../database/Database"; | ||
import { EDContribution } from "../database/EDContribution"; | ||
import { getAuthMiddleware, randomString } from "../util/Util"; | ||
|
||
export function getTempEDAPI(database: Database): Router { | ||
const api = Router(); | ||
|
||
api.get("/contributions", async (_req, res) => { | ||
res.status(200); | ||
res.json(await database.temp_ed.getAllClean()); | ||
return res.end(); | ||
}); | ||
|
||
const postContributionsSchema = z.record( | ||
z.string().refine(s => /^everydesc.[a-zA-Z0-9_-]+:[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)*$/.test(s)), | ||
z.array( | ||
z | ||
.object({ | ||
value: z.string().max(2047), | ||
user: z.string(), | ||
isDiscord: z.boolean(), | ||
}) | ||
.strict() | ||
) | ||
); | ||
|
||
const rateLimit = new RateLimiterMemory({ | ||
points: 15, | ||
duration: 60, | ||
}); | ||
|
||
api.post("/contributions", (req, res, next) => { | ||
rateLimit | ||
.consume(req.ip) | ||
.then(rateLimiterRes => { | ||
res.setHeader("X-RateLimit-Limit", rateLimit.points); | ||
res.setHeader("X-RateLimit-Remaining", rateLimiterRes.remainingPoints); | ||
res.setHeader("X-RateLimit-Reset", Math.ceil(rateLimiterRes.msBeforeNext / 1000)); | ||
next(); | ||
}) | ||
.catch(rateLimiterRes => { | ||
rateLimit.block(req.ip, Math.min(rateLimiterRes.msBeforeNext / 1000 + 12, 600)); | ||
res.setHeader("X-RateLimit-Limit", rateLimit.points); | ||
res.setHeader("X-RateLimit-Remaining", 0); | ||
res.setHeader("X-RateLimit-Reset", Math.ceil(rateLimiterRes.msBeforeNext / 1000)); | ||
res.status(429); | ||
res.json({ | ||
errors: ["Too many requests"], | ||
}); | ||
return res.end(); | ||
}); | ||
}); | ||
|
||
api.post("/contributions", express.json()); | ||
api.post("/contributions", getAuthMiddleware(database)); | ||
api.post("/contributions", async (req, res) => { | ||
res.status(200); | ||
const contributions = postContributionsSchema.parse(req.body); | ||
|
||
const createContributionsPromises: Promise<EDContribution>[] = []; | ||
for (const key in contributions) { | ||
if (Object.prototype.hasOwnProperty.call(contributions, key)) { | ||
const value = contributions[key]; | ||
for (const contribution of value) { | ||
const promise = database.temp_ed.create({ | ||
id: randomString(), | ||
key, | ||
value: contribution.value, | ||
user: contribution.user, | ||
isDiscord: contribution.isDiscord, | ||
}); | ||
createContributionsPromises.push(promise); | ||
} | ||
} | ||
} | ||
|
||
await Promise.all(createContributionsPromises); | ||
|
||
res.json(await database.temp_ed.getAllClean()); | ||
|
||
return res.end(); | ||
}); | ||
|
||
api.delete("/contributions", getAuthMiddleware(database)); | ||
api.delete("/contributions", async (req, res) => { | ||
if (typeof req.query.id !== "string") { | ||
res.status(400); | ||
res.json({ | ||
errors: [`Invalid id parameter`], | ||
}); | ||
return res.end(); | ||
} | ||
|
||
await database.temp_ed.delete(req.query.id); | ||
|
||
return res.end(); | ||
}); | ||
|
||
return api; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.