mirror of
https://github.com/spacebarchat/server.git
synced 2026-08-22 03:20:10 +00:00
Remove authentication import from ratelimit
This commit is contained in:
@@ -17,53 +17,9 @@
|
||||
*/
|
||||
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import { HTTPError } from "lambert-server/HTTPError";
|
||||
import { Session, User } from "@spacebar/database";
|
||||
import { Random } from "@spacebar/extensions";
|
||||
import { checkToken, DiscordApiErrors, Rights, UserTokenData } from "@spacebar/util";
|
||||
|
||||
export const NO_AUTHORIZATION_ROUTES = [
|
||||
// Authentication routes
|
||||
"POST /auth/login",
|
||||
"POST /auth/register",
|
||||
"GET /auth/location-metadata",
|
||||
"POST /auth/mfa/",
|
||||
"POST /auth/verify",
|
||||
"POST /auth/forgot",
|
||||
"POST /auth/reset",
|
||||
"POST /auth/fingerprint",
|
||||
"GET /invites/",
|
||||
// Routes with a seperate auth system
|
||||
/^(POST|HEAD|GET|PATCH|DELETE) \/webhooks\/\d+\/[\w-]+\/?/, // no token requires auth
|
||||
/^POST \/interactions\/\d+\/[A-Za-z0-9_-]+\/callback/,
|
||||
// Public information endpoints
|
||||
"GET /ping",
|
||||
"GET /gateway",
|
||||
"GET /experiments",
|
||||
"GET /updates",
|
||||
"GET /download",
|
||||
"GET /scheduled-maintenances/upcoming.json",
|
||||
// Public kubernetes integration
|
||||
"GET /-/readyz",
|
||||
"GET /-/healthz",
|
||||
// Client analytics
|
||||
"POST /science",
|
||||
"POST /track",
|
||||
// Public policy pages
|
||||
"GET /policies/instance/",
|
||||
// Oauth callback
|
||||
"/oauth2/callback",
|
||||
// Asset delivery
|
||||
/^(GET|HEAD) \/guilds\/\d+\/widget\.(json|png)/,
|
||||
/^(GET|HEAD) \/guilds\/\d+\/shield\.svg/,
|
||||
// Connections
|
||||
/^(POST|HEAD) \/connections\/\w+\/callback/,
|
||||
// Image proxy
|
||||
/^(GET|HEAD) \/imageproxy\/[A-Za-z0-9+/]\/\d+x\d+\/.+/,
|
||||
];
|
||||
|
||||
export const API_PREFIX = /^\/api(\/v\d+)?/;
|
||||
export const API_PREFIX_TRAILING_SLASH = /^\/api(\/v\d+)?\//;
|
||||
import { checkToken, Rights, UserTokenData } from "@spacebar/util";
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
@@ -84,7 +40,6 @@ declare global {
|
||||
|
||||
export async function Authentication(req: Request, res: Response, next: NextFunction) {
|
||||
if (req.method === "OPTIONS") return res.sendStatus(204);
|
||||
const url = req.url.replace(API_PREFIX, "");
|
||||
|
||||
if (req.headers.cookie?.split("; ").find((x) => x.startsWith("__sb_sessid=")))
|
||||
req.fingerprint = req.headers.cookie
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
|
||||
import { Config, getRights, listenEvent, RabbitMQ } from "@spacebar/util";
|
||||
import { NextFunction, Request, Response, Router } from "express";
|
||||
import { API_PREFIX_TRAILING_SLASH } from "./Authentication";
|
||||
|
||||
export const API_PREFIX_TRAILING_SLASH = /^\/api(\/v\d+)?\//;
|
||||
|
||||
// Docs: https://discord.com/developers/docs/topics/rate-limits
|
||||
|
||||
|
||||
@@ -22,10 +22,18 @@ import { getDatabase } from "@spacebar/database";
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
router.get("/", route({ deprecated: true, spacebarOnly: true }), (req: Request, res: Response) => {
|
||||
if (!getDatabase()) return res.sendStatus(503);
|
||||
router.get(
|
||||
"/",
|
||||
route({
|
||||
deprecated: true,
|
||||
spacebarOnly: true,
|
||||
authentication: "never",
|
||||
}),
|
||||
(req: Request, res: Response) => {
|
||||
if (!getDatabase()) return res.sendStatus(503);
|
||||
|
||||
return res.sendStatus(200);
|
||||
});
|
||||
return res.sendStatus(200);
|
||||
},
|
||||
);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -22,10 +22,18 @@ import { getDatabase } from "@spacebar/database";
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
router.get("/", route({ deprecated: true, spacebarOnly: true }), (req: Request, res: Response) => {
|
||||
if (!getDatabase()) return res.sendStatus(503);
|
||||
router.get(
|
||||
"/",
|
||||
route({
|
||||
deprecated: true,
|
||||
spacebarOnly: true,
|
||||
authentication: "never",
|
||||
}),
|
||||
(req: Request, res: Response) => {
|
||||
if (!getDatabase()) return res.sendStatus(503);
|
||||
|
||||
return res.sendStatus(200);
|
||||
});
|
||||
return res.sendStatus(200);
|
||||
},
|
||||
);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -20,11 +20,13 @@ import { createHash } from "node:crypto";
|
||||
import { Snowflake } from "@spacebar/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
router.post(
|
||||
"/",
|
||||
route({
|
||||
responses: { 200: { body: "CreateFingerprintResponse" } },
|
||||
spacebarOnly: false, // not part of public openapi
|
||||
authentication: "never",
|
||||
}),
|
||||
(req: Request, res: Response) => {
|
||||
const snowflake = Snowflake.generate();
|
||||
@@ -33,4 +35,5 @@ router.post(
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -35,6 +35,7 @@ router.post(
|
||||
body: "APIErrorOrCaptchaResponse",
|
||||
},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { login, captcha_key } = req.body as ForgotPasswordSchema;
|
||||
|
||||
@@ -29,6 +29,7 @@ router.get(
|
||||
body: "LocationMetadataResponse",
|
||||
},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
//TODO
|
||||
|
||||
@@ -39,6 +39,7 @@ router.post(
|
||||
body: "APIErrorOrCaptchaResponse",
|
||||
},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { login, password, captcha_key, undelete } = req.body as LoginSchema;
|
||||
|
||||
@@ -39,6 +39,7 @@ router.post(
|
||||
},
|
||||
},
|
||||
spacebarOnly: false, // not part of public openapi
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
// const { code, ticket, gift_code_sku_id, login_source } =
|
||||
|
||||
@@ -44,6 +44,7 @@ router.post(
|
||||
400: { body: "APIErrorResponse" },
|
||||
},
|
||||
spacebarOnly: false, // not part of public openapi
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
if (!WebAuthn.fido2) {
|
||||
|
||||
@@ -47,6 +47,7 @@ router.post(
|
||||
200: { body: "TokenOnlyResponse" },
|
||||
400: { body: "APIErrorOrCaptchaResponse" },
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const totalSw = Stopwatch.startNew();
|
||||
|
||||
@@ -38,6 +38,7 @@ router.post(
|
||||
body: "APIErrorOrCaptchaResponse",
|
||||
},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { password, token } = req.body as PasswordResetSchema;
|
||||
|
||||
@@ -47,6 +47,7 @@ router.post(
|
||||
body: "APIErrorOrCaptchaResponse",
|
||||
},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { captcha_key, token } = req.body;
|
||||
|
||||
@@ -37,6 +37,7 @@ router.post(
|
||||
body: "APIErrorResponse",
|
||||
},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const user = await User.findOneOrFail({
|
||||
|
||||
@@ -33,6 +33,7 @@ router.post(
|
||||
200: { body: "BackupCodesChallengeResponse" },
|
||||
400: { body: "APIErrorResponse" },
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { password } = req.body as BackupCodesChallengeSchema;
|
||||
|
||||
@@ -23,39 +23,46 @@ import { ConnectionCallbackSchema } from "@spacebar/schemas";
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
router.post("/", route({ requestBody: "ConnectionCallbackSchema" }), async (req: Request, res: Response) => {
|
||||
const { connection_name } = req.params as { [key: string]: string };
|
||||
const connection = ConnectionStore.connections.get(connection_name);
|
||||
if (!connection)
|
||||
throw FieldErrors({
|
||||
provider_id: {
|
||||
code: "BASE_TYPE_CHOICES",
|
||||
message: req.t("common:field.BASE_TYPE_CHOICES", {
|
||||
types: Array.from(ConnectionStore.connections.keys()).join(", "),
|
||||
}),
|
||||
},
|
||||
});
|
||||
router.post(
|
||||
"/",
|
||||
route({
|
||||
requestBody: "ConnectionCallbackSchema",
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { connection_name } = req.params as { [key: string]: string };
|
||||
const connection = ConnectionStore.connections.get(connection_name);
|
||||
if (!connection)
|
||||
throw FieldErrors({
|
||||
provider_id: {
|
||||
code: "BASE_TYPE_CHOICES",
|
||||
message: req.t("common:field.BASE_TYPE_CHOICES", {
|
||||
types: Array.from(ConnectionStore.connections.keys()).join(", "),
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
if (!connection.settings.enabled)
|
||||
throw FieldErrors({
|
||||
provider_id: {
|
||||
message: "This connection has been disabled server-side.",
|
||||
},
|
||||
});
|
||||
if (!connection.settings.enabled)
|
||||
throw FieldErrors({
|
||||
provider_id: {
|
||||
message: "This connection has been disabled server-side.",
|
||||
},
|
||||
});
|
||||
|
||||
const body = req.body as ConnectionCallbackSchema;
|
||||
const userId = connection.getUserId(body.state);
|
||||
const connectedAccnt = await connection.handleCallback(body);
|
||||
const body = req.body as ConnectionCallbackSchema;
|
||||
const userId = connection.getUserId(body.state);
|
||||
const connectedAccnt = await connection.handleCallback(body);
|
||||
|
||||
// whether we should emit a connections update event, only used when a connection doesnt already exist
|
||||
if (connectedAccnt)
|
||||
await emitEvent({
|
||||
event: "USER_CONNECTIONS_UPDATE",
|
||||
data: { ...connectedAccnt, token_data: undefined },
|
||||
user_id: userId,
|
||||
});
|
||||
// whether we should emit a connections update event, only used when a connection doesnt already exist
|
||||
if (connectedAccnt)
|
||||
await emitEvent({
|
||||
event: "USER_CONNECTIONS_UPDATE",
|
||||
data: { ...connectedAccnt, token_data: undefined },
|
||||
user_id: userId,
|
||||
});
|
||||
|
||||
res.sendStatus(204);
|
||||
});
|
||||
res.sendStatus(204);
|
||||
},
|
||||
);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -32,6 +32,7 @@ router.get(
|
||||
body: "APIErrorResponse",
|
||||
},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { platform } = req.query;
|
||||
|
||||
@@ -21,9 +21,15 @@ import { route } from "@spacebar/api/middlewares";
|
||||
|
||||
const router = Router({ mergeParams: true });
|
||||
|
||||
router.get("/", route({}), (req: Request, res: Response) => {
|
||||
// TODO:
|
||||
res.send({ fingerprint: "", assignments: [], guild_experiments: [] });
|
||||
});
|
||||
router.get(
|
||||
"/",
|
||||
route({
|
||||
authentication: "optional",
|
||||
}),
|
||||
(req: Request, res: Response) => {
|
||||
// TODO:
|
||||
res.send({ fingerprint: "", assignments: [], guild_experiments: [] });
|
||||
},
|
||||
);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -30,6 +30,7 @@ router.get(
|
||||
body: "GatewayBotResponse",
|
||||
},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
(req: Request, res: Response) => {
|
||||
const { endpointPublic } = Config.get().gateway;
|
||||
|
||||
@@ -30,6 +30,7 @@ router.get(
|
||||
body: "GatewayResponse",
|
||||
},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
(req: Request, res: Response) => {
|
||||
const { endpointPublic } = Config.get().gateway;
|
||||
|
||||
@@ -47,6 +47,7 @@ router.get(
|
||||
body: "APIErrorResponse",
|
||||
},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { guild_id } = req.params as { [key: string]: string };
|
||||
|
||||
@@ -45,6 +45,7 @@ router.get(
|
||||
body: "APIErrorResponse",
|
||||
},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { guild_id } = req.params as { [key: string]: string };
|
||||
|
||||
@@ -31,6 +31,7 @@ router.post(
|
||||
route({
|
||||
stripNulls: true,
|
||||
requestBody: "InteractionCallbacksSchema",
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const body = req.body as InteractionCallbacksSchema;
|
||||
|
||||
@@ -36,6 +36,7 @@ router.get(
|
||||
body: "APIErrorResponse",
|
||||
},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { invite_code } = req.params as { [key: string]: string };
|
||||
|
||||
@@ -31,6 +31,7 @@ router.get(
|
||||
},
|
||||
},
|
||||
spacebarOnly: true,
|
||||
authentication: "never",
|
||||
}),
|
||||
(req: Request, res: Response) => {
|
||||
const { general } = Config.get();
|
||||
|
||||
@@ -31,10 +31,12 @@ router.get(
|
||||
},
|
||||
},
|
||||
spacebarOnly: true,
|
||||
authentication: "optional",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const general = Config.get();
|
||||
let outputtedConfig;
|
||||
// TODO: clean up
|
||||
if (req.user_id) {
|
||||
const rights = await getRights(req.user_id);
|
||||
if (rights.has("OPERATOR")) outputtedConfig = general;
|
||||
|
||||
@@ -30,6 +30,7 @@ router.get(
|
||||
},
|
||||
},
|
||||
spacebarOnly: true,
|
||||
authentication: "never",
|
||||
}),
|
||||
(req: Request, res: Response) => {
|
||||
const { cdn, gateway, api } = Config.get();
|
||||
|
||||
@@ -30,6 +30,7 @@ router.get(
|
||||
},
|
||||
},
|
||||
spacebarOnly: true,
|
||||
authentication: "never",
|
||||
}),
|
||||
(req: Request, res: Response) => {
|
||||
const { general } = Config.get();
|
||||
|
||||
@@ -30,9 +30,11 @@ router.get(
|
||||
},
|
||||
},
|
||||
spacebarOnly: true,
|
||||
authentication: "optional",
|
||||
}),
|
||||
(req: Request, res: Response) => {
|
||||
const { limits } = Config.get();
|
||||
// TODO: handle rights
|
||||
res.json(limits);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -24,6 +24,7 @@ router.get(
|
||||
"/",
|
||||
route({
|
||||
spacebarOnly: false, // not part of public openapi
|
||||
authentication: "never",
|
||||
}),
|
||||
(req: Request, res: Response) => {
|
||||
res.json({
|
||||
|
||||
@@ -27,6 +27,7 @@ router.post(
|
||||
responses: {
|
||||
204: {},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
(req: Request, res: Response) => {
|
||||
// TODO:
|
||||
|
||||
@@ -25,6 +25,7 @@ router.post(
|
||||
"/",
|
||||
route({
|
||||
spacebarOnly: false, // Not part of the public OpenAPI schema
|
||||
authentication: "never",
|
||||
}),
|
||||
(req: Request, res: Response) => {
|
||||
// TODO:
|
||||
|
||||
@@ -37,6 +37,7 @@ router.get(
|
||||
body: "APIErrorResponse",
|
||||
},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const platform = req.query.platform;
|
||||
|
||||
@@ -421,6 +421,7 @@ router.post(
|
||||
},
|
||||
404: {},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
executeWebhook,
|
||||
);
|
||||
|
||||
@@ -37,6 +37,7 @@ router.get(
|
||||
},
|
||||
404: {},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { webhook_id, webhook_token } = req.params as { [key: string]: string };
|
||||
@@ -109,6 +110,7 @@ router.post(
|
||||
},
|
||||
404: {},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
executeWebhook,
|
||||
);
|
||||
@@ -123,6 +125,7 @@ router.delete(
|
||||
},
|
||||
404: {},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { webhook_id, webhook_token } = req.params as { [key: string]: string };
|
||||
@@ -166,6 +169,7 @@ router.patch(
|
||||
403: {},
|
||||
404: {},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { webhook_id, webhook_token } = req.params as { [key: string]: string };
|
||||
|
||||
@@ -63,6 +63,7 @@ router.patch(
|
||||
403: {},
|
||||
404: {},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { webhook_id, webhook_token, message_id } = req.params as { [key: string]: string };
|
||||
@@ -116,6 +117,7 @@ router.get(
|
||||
403: {},
|
||||
404: {},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { webhook_id, webhook_token, message_id } = req.params as { [key: string]: string };
|
||||
@@ -144,6 +146,7 @@ router.delete(
|
||||
},
|
||||
404: {},
|
||||
},
|
||||
authentication: "never",
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
const { webhook_id, webhook_token, message_id } = req.params as { [key: string]: string };
|
||||
|
||||
Reference in New Issue
Block a user