summary refs log tree commit diff
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2025-12-19 05:43:23 +0100
committerRory& <root@rory.gay>2025-12-19 05:43:23 +0100
commit62123f6a6e8639bf415125e1969043926fec7602 (patch)
tree47101a78720ba6adade6d6cba7c65c708ee6e1ab
parentFix initial database setup (diff)
downloadserver-ts-62123f6a6e8639bf415125e1969043926fec7602.tar.xz
Send HTTP 401 on token errors
-rw-r--r--assets/openapi.json135
-rw-r--r--assets/schemas.json139
-rw-r--r--scripts/schemaExclusions.json14
-rw-r--r--src/api/middlewares/Authentication.ts3
-rw-r--r--src/util/util/Token.ts27
5 files changed, 168 insertions, 150 deletions
diff --git a/assets/openapi.json b/assets/openapi.json

index ad4bd98a..e7868ddc 100644 --- a/assets/openapi.json +++ b/assets/openapi.json
@@ -300,71 +300,6 @@ "success" ] }, - "AbuseIpDbBlacklistResponse": { - "type": "object", - "properties": { - "meta": { - "type": "object", - "properties": { - "generatedAt": { - "type": "string", - "default": "2020-09-24T19:54:11+00:00" - } - }, - "additionalProperties": false, - "required": [ - "generatedAt" - ] - }, - "data": { - "type": "array", - "items": { - "type": "object", - "properties": { - "ipAddress": { - "type": "string", - "default": "5.188.10.179" - }, - "abuseConfidenceScore": { - "type": "integer", - "default": 100 - }, - "lastReportedAt": { - "type": "string", - "default": "2020-09-24T19:17:02+00:00" - } - }, - "additionalProperties": false, - "required": [ - "abuseConfidenceScore", - "ipAddress", - "lastReportedAt" - ] - }, - "default": [ - { - "ipAddress": "5.188.10.179", - "abuseConfidenceScore": 100, - "lastReportedAt": "2020-09-24T19:17:02+00:00" - }, - { - "ipAddress": "185.222.209.14", - "abuseConfidenceScore": 100, - "lastReportedAt": "2020-09-24T19:17:02+00:00" - }, - { - "ipAddress": "191.96.249.183", - "abuseConfidenceScore": 100, - "lastReportedAt": "2020-09-24T19:17:01+00:00" - } - ] - } - }, - "required": [ - "data", - "meta" - ] - }, "StoredEmailResponse": { "type": "object", "properties": { @@ -679,6 +614,71 @@ "message" ] }, + "AbuseIpDbBlacklistResponse": { + "type": "object", + "properties": { + "meta": { + "type": "object", + "properties": { + "generatedAt": { + "type": "string", + "default": "2020-09-24T19:54:11+00:00" + } + }, + "additionalProperties": false, + "required": [ + "generatedAt" + ] + }, + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ipAddress": { + "type": "string", + "default": "5.188.10.179" + }, + "abuseConfidenceScore": { + "type": "integer", + "default": 100 + }, + "lastReportedAt": { + "type": "string", + "default": "2020-09-24T19:17:02+00:00" + } + }, + "additionalProperties": false, + "required": [ + "abuseConfidenceScore", + "ipAddress", + "lastReportedAt" + ] + }, + "default": [ + { + "ipAddress": "5.188.10.179", + "abuseConfidenceScore": 100, + "lastReportedAt": "2020-09-24T19:17:02+00:00" + }, + { + "ipAddress": "185.222.209.14", + "abuseConfidenceScore": 100, + "lastReportedAt": "2020-09-24T19:17:02+00:00" + }, + { + "ipAddress": "191.96.249.183", + "abuseConfidenceScore": 100, + "lastReportedAt": "2020-09-24T19:17:01+00:00" + } + ] + } + }, + "required": [ + "data", + "meta" + ] + }, "InteractionSchema": { "type": "object", "properties": { @@ -2968,6 +2968,10 @@ "region": { "type": "string" }, + "insert": { + "type": "object", + "additionalProperties": false + }, "id": { "type": "string" }, @@ -3158,6 +3162,7 @@ "emojis", "features", "id", + "insert", "invites", "members", "name", diff --git a/assets/schemas.json b/assets/schemas.json
index 08eea064..710cbb31 100644 --- a/assets/schemas.json +++ b/assets/schemas.json
@@ -289,73 +289,6 @@ ], "$schema": "http://json-schema.org/draft-07/schema#" }, - "AbuseIpDbBlacklistResponse": { - "type": "object", - "properties": { - "meta": { - "type": "object", - "properties": { - "generatedAt": { - "type": "string", - "default": "2020-09-24T19:54:11+00:00" - } - }, - "additionalProperties": false, - "required": [ - "generatedAt" - ] - }, - "data": { - "type": "array", - "items": { - "type": "object", - "properties": { - "ipAddress": { - "type": "string", - "default": "5.188.10.179" - }, - "abuseConfidenceScore": { - "type": "integer", - "default": 100 - }, - "lastReportedAt": { - "type": "string", - "default": "2020-09-24T19:17:02+00:00" - } - }, - "additionalProperties": false, - "required": [ - "abuseConfidenceScore", - "ipAddress", - "lastReportedAt" - ] - }, - "default": [ - { - "ipAddress": "5.188.10.179", - "abuseConfidenceScore": 100, - "lastReportedAt": "2020-09-24T19:17:02+00:00" - }, - { - "ipAddress": "185.222.209.14", - "abuseConfidenceScore": 100, - "lastReportedAt": "2020-09-24T19:17:02+00:00" - }, - { - "ipAddress": "191.96.249.183", - "abuseConfidenceScore": 100, - "lastReportedAt": "2020-09-24T19:17:01+00:00" - } - ] - } - }, - "additionalProperties": false, - "required": [ - "data", - "meta" - ], - "$schema": "http://json-schema.org/draft-07/schema#" - }, "StoredEmailResponse": { "type": "object", "properties": { @@ -686,6 +619,73 @@ ], "$schema": "http://json-schema.org/draft-07/schema#" }, + "AbuseIpDbBlacklistResponse": { + "type": "object", + "properties": { + "meta": { + "type": "object", + "properties": { + "generatedAt": { + "type": "string", + "default": "2020-09-24T19:54:11+00:00" + } + }, + "additionalProperties": false, + "required": [ + "generatedAt" + ] + }, + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ipAddress": { + "type": "string", + "default": "5.188.10.179" + }, + "abuseConfidenceScore": { + "type": "integer", + "default": 100 + }, + "lastReportedAt": { + "type": "string", + "default": "2020-09-24T19:17:02+00:00" + } + }, + "additionalProperties": false, + "required": [ + "abuseConfidenceScore", + "ipAddress", + "lastReportedAt" + ] + }, + "default": [ + { + "ipAddress": "5.188.10.179", + "abuseConfidenceScore": 100, + "lastReportedAt": "2020-09-24T19:17:02+00:00" + }, + { + "ipAddress": "185.222.209.14", + "abuseConfidenceScore": 100, + "lastReportedAt": "2020-09-24T19:17:02+00:00" + }, + { + "ipAddress": "191.96.249.183", + "abuseConfidenceScore": 100, + "lastReportedAt": "2020-09-24T19:17:01+00:00" + } + ] + } + }, + "additionalProperties": false, + "required": [ + "data", + "meta" + ], + "$schema": "http://json-schema.org/draft-07/schema#" + }, "InteractionSchema": { "type": "object", "properties": { @@ -3116,6 +3116,10 @@ "region": { "type": "string" }, + "insert": { + "type": "object", + "additionalProperties": false + }, "id": { "type": "string" }, @@ -3315,6 +3319,7 @@ "emojis", "features", "id", + "insert", "invites", "members", "name", diff --git a/scripts/schemaExclusions.json b/scripts/schemaExclusions.json
index b2847670..64e2bbf0 100644 --- a/scripts/schemaExclusions.json +++ b/scripts/schemaExclusions.json
@@ -1,6 +1,10 @@ { - "include": ["MessageInteractionSchema"], - "includeRe": ["^MessageComponentType\\..*"], + "include": [ + "MessageInteractionSchema" + ], + "includeRe": [ + "^MessageComponentType\\..*" + ], "manual": [ "DefaultSchema", "Schema", @@ -83,7 +87,9 @@ "^Job" ], "manualWarn": [], - "manualWarnRe": [".*<.*>$"], + "manualWarnRe": [ + ".*<.*>$" + ], "auto": [ { "value": "StringSchema", @@ -406,4 +412,4 @@ "reason": "Schema with only uppercase properties" } ] -} +} \ No newline at end of file diff --git a/src/api/middlewares/Authentication.ts b/src/api/middlewares/Authentication.ts
index 865d1aa3..548ab5b5 100644 --- a/src/api/middlewares/Authentication.ts +++ b/src/api/middlewares/Authentication.ts
@@ -132,6 +132,9 @@ export async function Authentication(req: Request, res: Response, next: NextFunc req.rights = new Rights(Number(user.rights)); return next(); } catch (error) { + if (error instanceof HTTPError) { + return next(error); + } return next(new HTTPError(error!.toString(), 400)); } } diff --git a/src/util/util/Token.ts b/src/util/util/Token.ts
index 56280e7a..3c077d9a 100644 --- a/src/util/util/Token.ts +++ b/src/util/util/Token.ts
@@ -23,11 +23,10 @@ import crypto from "node:crypto"; import fs from "fs/promises"; import { existsSync } from "fs"; // TODO: dont use deprecated APIs lol -import { FindManyOptions, FindOptions, FindOptionsRelationByString, FindOptionsSelect, FindOptionsSelectByString, FindOptionsWhere } from "typeorm"; -import * as console from "node:console"; +import { FindOptionsRelationByString, FindOptionsSelectByString } from "typeorm"; import { randomUpperString } from "@spacebar/api"; -import { IpDataClient } from "./networking"; import { TimeSpan } from "./Timespan"; +import { HTTPError } from "lambert-server"; /// Change history: /// 1 - Initial version with HS256 @@ -52,9 +51,9 @@ function logAuth(text: string) { console.log(`[AUTH] ${text}`); } -function rejectAndLog(rejectFunction: (reason?: string) => void, reason: string) { +function rejectAndLog(rejectFunction: (reason?: unknown) => void, httpCode: number | undefined, reason: string) { console.error(reason); - rejectFunction(reason); + rejectFunction(new HTTPError(reason, httpCode ?? 400)); } export const checkToken = ( @@ -76,7 +75,7 @@ export const checkToken = ( const decoded = out as UserTokenData["decoded"]; if (err || !decoded) { logAuth("validateUser rejected: " + err); - return rejectAndLog(reject, "Invalid Token meow " + err); + return rejectAndLog(reject, 401, "Invalid Token meow " + err); } const [user, session] = await Promise.all([ @@ -90,34 +89,34 @@ export const checkToken = ( if (!user) { logAuth("validateUser rejected: User not found"); - return rejectAndLog(reject, "User not found"); + return rejectAndLog(reject, 401, "User not found"); } if (decoded.did && !session) { logAuth("validateUser rejected: Session not found"); - return rejectAndLog(reject, "Invalid Token"); + return rejectAndLog(reject, 401, "Invalid Token"); } // we need to round it to seconds as it saved as seconds in jwt iat and valid_tokens_since is stored in milliseconds if (decoded.iat * 1000 < new Date(user.data.valid_tokens_since).setSeconds(0, 0)) { logAuth("validateUser rejected: Token not yet valid"); - return rejectAndLog(reject, "Invalid Token"); + return rejectAndLog(reject, 401, "Invalid Token"); } if (user.disabled) { logAuth("validateUser rejected: User disabled"); - return rejectAndLog(reject, "User disabled"); + return rejectAndLog(reject, 401, "User disabled"); } if (user.deleted) { logAuth("validateUser rejected: User deleted"); - return rejectAndLog(reject, "User not found"); + return rejectAndLog(reject, 401, "User not found"); } const banReasons = await InstanceBan.findInstanceBans({ userId: user.id, ipAddress: opts?.ipAddress, fingerprint: opts?.fingerprint, propagateBan: true }); if (banReasons.length > 0) { logAuth("validateUser rejected: User banned for reasons: " + banReasons.join(", ")); - return rejectAndLog(reject, "Invalid Token"); + return rejectAndLog(reject, 418, "Invalid Token"); } if (session && TimeSpan.fromDates(session.last_seen?.getTime() ?? 0, new Date().getTime()).totalSeconds >= 15) { @@ -145,7 +144,7 @@ export const checkToken = ( }; const dec = jwt.decode(token, { complete: true }); - if (!dec) return reject("Could not parse token"); + if (!dec) return rejectAndLog(reject, 500, "Failed to decode token"); logAuth("Decoded token: " + JSON.stringify(dec)); if (dec.header.alg == "HS256" && Config.get().security.jwtSecret !== null) { @@ -155,7 +154,7 @@ export const checkToken = ( loadOrGenerateKeypair().then((keyPair) => { jwt.verify(token, keyPair.publicKey, { algorithms: ["ES512"] }, validateUser); }); - } else return reject("Invalid token algorithm"); + } else return rejectAndLog(reject, 400, "Unsupported token algorithm: " + dec.header.alg); }); };