1
0
mirror of https://github.com/spacebarchat/server.git synced 2024-11-26 04:03:03 +01:00

🚧 new body parser (bans route)

This commit is contained in:
Flam3rboy 2021-09-12 21:21:08 +02:00
parent 0a0a61565e
commit e2c66a1fe5
5 changed files with 1323 additions and 15 deletions

939
api/assets/schemas.json Normal file
View File

@ -0,0 +1,939 @@
{
"DmChannelCreateSchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"recipients": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false,
"required": [
"recipients"
],
"$schema": "http://json-schema.org/draft-07/schema#"
},
"ChannelModifySchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"type": {
"type": "integer"
},
"topic": {
"type": "string"
},
"bitrate": {
"type": "integer"
},
"user_limit": {
"type": "integer"
},
"rate_limit_per_user": {
"type": "integer"
},
"position": {
"type": "integer"
},
"permission_overwrites": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "integer"
},
"allow": {
"type": "bigint"
},
"deny": {
"type": "bigint"
}
},
"additionalProperties": false,
"required": [
"allow",
"deny",
"id",
"type"
]
}
},
"parent_id": {
"type": "string"
},
"id": {
"type": "string"
},
"nsfw": {
"type": "boolean"
},
"rtc_region": {
"type": "string"
},
"default_auto_archive_duration": {
"type": "integer"
}
},
"additionalProperties": false,
"required": [
"name",
"type"
]
},
"ChannelGuildPositionUpdateSchema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"position": {
"type": "integer"
}
},
"additionalProperties": false,
"required": [
"id"
]
},
"$schema": "http://json-schema.org/draft-07/schema#"
},
"InviteCreateSchema": {
"type": "object",
"properties": {
"target_user_id": {
"type": "string"
},
"target_type": {
"type": "string"
},
"validate": {
"type": "string"
},
"max_age": {
"type": "integer"
},
"max_uses": {
"type": "integer"
},
"temporary": {
"type": "boolean"
},
"unique": {
"type": "boolean"
},
"target_user": {
"type": "string"
},
"target_user_type": {
"type": "integer"
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
},
"EmbedType": {
"enum": [
"article",
"gifv",
"image",
"link",
"rich",
"video"
],
"type": "string"
},
"EmbedImage": {
"type": "object",
"properties": {
"url": {
"type": "string"
},
"proxy_url": {
"type": "string"
},
"height": {
"type": "integer"
},
"width": {
"type": "integer"
}
},
"additionalProperties": false
},
"MessageCreateSchema": {
"type": "object",
"properties": {
"content": {
"type": "string"
},
"nonce": {
"type": "string"
},
"tts": {
"type": "boolean"
},
"flags": {
"type": "string"
},
"embed": {
"additionalProperties": false,
"type": "object",
"properties": {
"title": {
"type": "string"
},
"type": {
"$ref": "#/definitions/EmbedType"
},
"description": {
"type": "string"
},
"url": {
"type": "string"
},
"timestamp": {
"type": "string"
},
"color": {
"type": "integer"
},
"footer": {
"type": "object",
"properties": {
"text": {
"type": "string"
},
"icon_url": {
"type": "string"
},
"proxy_icon_url": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"text"
]
},
"image": {
"$ref": "#/definitions/EmbedImage"
},
"thumbnail": {
"$ref": "#/definitions/EmbedImage"
},
"video": {
"$ref": "#/definitions/EmbedImage"
},
"provider": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"url": {
"type": "string"
}
},
"additionalProperties": false
},
"author": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"url": {
"type": "string"
},
"icon_url": {
"type": "string"
},
"proxy_icon_url": {
"type": "string"
}
},
"additionalProperties": false
},
"fields": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
},
"inline": {
"type": "boolean"
}
},
"additionalProperties": false,
"required": [
"name",
"value"
]
}
}
}
},
"allowed_mentions": {
"type": "object",
"properties": {
"parse": {
"type": "array",
"items": {
"type": "string"
}
},
"roles": {
"type": "array",
"items": {
"type": "string"
}
},
"users": {
"type": "array",
"items": {
"type": "string"
}
},
"replied_user": {
"type": "boolean"
}
},
"additionalProperties": false
},
"message_reference": {
"type": "object",
"properties": {
"message_id": {
"type": "string"
},
"channel_id": {
"type": "string"
},
"guild_id": {
"type": "string"
},
"fail_if_not_exists": {
"type": "boolean"
}
},
"additionalProperties": false,
"required": [
"channel_id",
"message_id"
]
},
"payload_json": {
"type": "string"
},
"file": {}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
},
"BanCreateSchema": {
"type": "object",
"properties": {
"delete_message_days": {
"type": "string"
},
"reason": {
"type": "string"
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
},
"GuildCreateSchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"region": {
"type": "string"
},
"icon": {
"type": "string"
},
"channels": {
"type": "array",
"items": {
"$ref": "#/definitions/ChannelModifySchema"
}
},
"guild_template_code": {
"type": "string"
},
"system_channel_id": {
"type": "string"
},
"rules_channel_id": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"name"
],
"$schema": "http://json-schema.org/draft-07/schema#"
},
"GuildUpdateSchema": {
"type": "object",
"properties": {
"banner": {
"type": "string"
},
"splash": {
"type": "string"
},
"description": {
"type": "string"
},
"features": {
"type": "array",
"items": {
"type": "string"
}
},
"verification_level": {
"type": "integer"
},
"default_message_notifications": {
"type": "integer"
},
"system_channel_flags": {
"type": "integer"
},
"explicit_content_filter": {
"type": "integer"
},
"public_updates_channel_id": {
"type": "string"
},
"afk_timeout": {
"type": "integer"
},
"afk_channel_id": {
"type": "string"
},
"preferred_locale": {
"type": "string"
},
"name": {
"type": "string"
},
"region": {
"type": "string"
},
"icon": {
"type": "string"
},
"guild_template_code": {
"type": "string"
},
"system_channel_id": {
"type": "string"
},
"rules_channel_id": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"name"
],
"$schema": "http://json-schema.org/draft-07/schema#"
},
"GuildTemplateCreateSchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"avatar": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"name"
],
"$schema": "http://json-schema.org/draft-07/schema#"
},
"GuildUpdateWelcomeScreenSchema": {
"type": "object",
"properties": {
"welcome_channels": {
"type": "array",
"items": {
"type": "object",
"properties": {
"channel_id": {
"type": "string"
},
"description": {
"type": "string"
},
"emoji_id": {
"type": "string"
},
"emoji_name": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"channel_id",
"description",
"emoji_name"
]
}
},
"enabled": {
"type": "boolean"
},
"description": {
"type": "string"
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
},
"VoiceStateUpdateSchema": {
"type": "object",
"properties": {
"channel_id": {
"type": "string"
},
"suppress": {
"type": "boolean"
},
"request_to_speak_timestamp": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"channel_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
},
"MemberCreateSchema": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"nick": {
"type": "string"
},
"guild_id": {
"type": "string"
},
"joined_at": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": false,
"required": [
"guild_id",
"id",
"joined_at",
"nick"
],
"$schema": "http://json-schema.org/draft-07/schema#"
},
"MemberNickChangeSchema": {
"type": "object",
"properties": {
"nick": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"nick"
],
"$schema": "http://json-schema.org/draft-07/schema#"
},
"MemberChangeSchema": {
"type": "object",
"properties": {
"roles": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
},
"RoleModifySchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"permissions": {
"type": "bigint"
},
"color": {
"type": "integer"
},
"hoist": {
"type": "boolean"
},
"mentionable": {
"type": "boolean"
},
"position": {
"type": "integer"
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
},
"RolePositionUpdateSchema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"position": {
"type": "integer"
}
},
"additionalProperties": false,
"required": [
"id",
"position"
]
},
"$schema": "http://json-schema.org/draft-07/schema#"
},
"TemplateCreateSchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"name"
],
"$schema": "http://json-schema.org/draft-07/schema#"
},
"TemplateModifySchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"name"
],
"$schema": "http://json-schema.org/draft-07/schema#"
},
"EmojiCreateSchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"image": {
"type": "string"
},
"roles": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false,
"required": [
"image",
"name"
],
"$schema": "http://json-schema.org/draft-07/schema#"
},
"UserModifySchema": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"avatar": {
"type": "string"
},
"bio": {
"type": "string"
},
"accent_color": {
"type": "integer"
},
"banner": {
"type": "string"
},
"password": {
"type": "string"
},
"new_password": {
"type": "string"
},
"code": {
"type": "string"
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
},
"UserSettingsSchema": {
"type": "object",
"properties": {
"afk_timeout": {
"type": "integer"
},
"allow_accessibility_detection": {
"type": "boolean"
},
"animate_emoji": {
"type": "boolean"
},
"animate_stickers": {
"type": "integer"
},
"contact_sync_enabled": {
"type": "boolean"
},
"convert_emoticons": {
"type": "boolean"
},
"custom_status": {
"type": "object",
"properties": {
"emoji_id": {
"type": "string"
},
"emoji_name": {
"type": "string"
},
"expires_at": {
"type": "integer"
},
"text": {
"type": "string"
}
},
"additionalProperties": false
},
"default_guilds_restricted": {
"type": "boolean"
},
"detect_platform_accounts": {
"type": "boolean"
},
"developer_mode": {
"type": "boolean"
},
"disable_games_tab": {
"type": "boolean"
},
"enable_tts_command": {
"type": "boolean"
},
"explicit_content_filter": {
"type": "integer"
},
"friend_source_flags": {
"type": "object",
"properties": {
"all": {
"type": "boolean"
}
},
"additionalProperties": false,
"required": [
"all"
]
},
"gateway_connected": {
"type": "boolean"
},
"gif_auto_play": {
"type": "boolean"
},
"guild_folders": {
"type": "array",
"items": {
"type": "object",
"properties": {
"color": {
"type": "integer"
},
"guild_ids": {
"type": "array",
"items": {
"type": "string"
}
},
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"color",
"guild_ids",
"id",
"name"
]
}
},
"guild_positions": {
"type": "array",
"items": {
"type": "string"
}
},
"inline_attachment_media": {
"type": "boolean"
},
"inline_embed_media": {
"type": "boolean"
},
"locale": {
"type": "string"
},
"message_display_compact": {
"type": "boolean"
},
"native_phone_integration_enabled": {
"type": "boolean"
},
"render_embeds": {
"type": "boolean"
},
"render_reactions": {
"type": "boolean"
},
"restricted_guilds": {
"type": "array",
"items": {
"type": "string"
}
},
"show_current_game": {
"type": "boolean"
},
"status": {
"enum": [
"dnd",
"idle",
"offline",
"online"
],
"type": "string"
},
"stream_notifications_enabled": {
"type": "boolean"
},
"theme": {
"enum": [
"dark",
"white"
],
"type": "string"
},
"timezone_offset": {
"type": "integer"
}
},
"additionalProperties": false,
"required": [
"afk_timeout",
"allow_accessibility_detection",
"animate_emoji",
"animate_stickers",
"contact_sync_enabled",
"convert_emoticons",
"custom_status",
"default_guilds_restricted",
"detect_platform_accounts",
"developer_mode",
"disable_games_tab",
"enable_tts_command",
"explicit_content_filter",
"friend_source_flags",
"gateway_connected",
"gif_auto_play",
"guild_folders",
"guild_positions",
"inline_attachment_media",
"inline_embed_media",
"locale",
"message_display_compact",
"native_phone_integration_enabled",
"render_embeds",
"render_reactions",
"restricted_guilds",
"show_current_game",
"status",
"stream_notifications_enabled",
"theme",
"timezone_offset"
],
"$schema": "http://json-schema.org/draft-07/schema#"
},
"WidgetModifySchema": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"channel_id": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"channel_id",
"enabled"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
}

249
api/patches/ajv+8.6.2.patch Normal file
View File

@ -0,0 +1,249 @@
diff --git a/node_modules/ajv/dist/compile/jtd/parse.js b/node_modules/ajv/dist/compile/jtd/parse.js
index 1eeb1be..7684121 100644
--- a/node_modules/ajv/dist/compile/jtd/parse.js
+++ b/node_modules/ajv/dist/compile/jtd/parse.js
@@ -239,6 +239,9 @@ function parseType(cxt) {
gen.if(fail, () => parsingError(cxt, codegen_1.str `invalid timestamp`));
break;
}
+ case "bigint":
+ parseBigInt(cxt);
+ break
case "float32":
case "float64":
parseNumber(cxt);
@@ -284,6 +287,15 @@ function parseNumber(cxt, maxDigits) {
skipWhitespace(cxt);
gen.if(codegen_1._ `"-0123456789".indexOf(${jsonSlice(1)}) < 0`, () => jsonSyntaxError(cxt), () => parseWith(cxt, parseJson_1.parseJsonNumber, maxDigits));
}
+function parseBigInt(cxt, maxDigits) {
+ const {gen} = cxt
+ skipWhitespace(cxt)
+ gen.if(
+ _`"-0123456789".indexOf(${jsonSlice(1)}) < 0`,
+ () => jsonSyntaxError(cxt),
+ () => parseWith(cxt, parseJson_1.parseJsonBigInt, maxDigits)
+ )
+}
function parseBooleanToken(bool, fail) {
return (cxt) => {
const { gen, data } = cxt;
diff --git a/node_modules/ajv/dist/compile/rules.js b/node_modules/ajv/dist/compile/rules.js
index 82a591f..1ebd8fe 100644
--- a/node_modules/ajv/dist/compile/rules.js
+++ b/node_modules/ajv/dist/compile/rules.js
@@ -1,7 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRules = exports.isJSONType = void 0;
-const _jsonTypes = ["string", "number", "integer", "boolean", "null", "object", "array"];
+const _jsonTypes = ["string", "number", "integer", "boolean", "null", "object", "array","bigint"];
const jsonTypes = new Set(_jsonTypes);
function isJSONType(x) {
return typeof x == "string" && jsonTypes.has(x);
@@ -13,10 +13,11 @@ function getRules() {
string: { type: "string", rules: [] },
array: { type: "array", rules: [] },
object: { type: "object", rules: [] },
+ bigint: {type: "bigint", rules: []}
};
return {
- types: { ...groups, integer: true, boolean: true, null: true },
- rules: [{ rules: [] }, groups.number, groups.string, groups.array, groups.object],
+ types: { ...groups, integer: true, boolean: true, null: true, bigint: true },
+ rules: [{ rules: [] }, groups.number, groups.string, groups.array, groups.object, groups.bigint],
post: { rules: [] },
all: {},
keywords: {},
diff --git a/node_modules/ajv/dist/compile/validate/dataType.js b/node_modules/ajv/dist/compile/validate/dataType.js
index 6319e76..8b50b4c 100644
--- a/node_modules/ajv/dist/compile/validate/dataType.js
+++ b/node_modules/ajv/dist/compile/validate/dataType.js
@@ -52,7 +52,7 @@ function coerceAndCheckDataType(it, types) {
return checkTypes;
}
exports.coerceAndCheckDataType = coerceAndCheckDataType;
-const COERCIBLE = new Set(["string", "number", "integer", "boolean", "null"]);
+const COERCIBLE = new Set(["string", "number", "integer", "boolean", "null","bigint"]);
function coerceToTypes(types, coerceTypes) {
return coerceTypes
? types.filter((t) => COERCIBLE.has(t) || (coerceTypes === "array" && t === "array"))
@@ -83,6 +83,14 @@ function coerceData(it, types, coerceTo) {
});
function coerceSpecificType(t) {
switch (t) {
+ case "bigint":
+ gen
+ .elseIf(
+ codegen_1._`${dataType} == "boolean" || ${data} === null
+ || (${dataType} == "string" && ${data} && ${data} == BigInt(${data}))`
+ )
+ .assign(coerced, codegen_1._`BigInt(${data})`)
+ return
case "string":
gen
.elseIf(codegen_1._ `${dataType} == "number" || ${dataType} == "boolean"`)
@@ -143,6 +151,9 @@ function checkDataType(dataType, data, strictNums, correct = DataType.Correct) {
case "number":
cond = numCond();
break;
+ case "bigint":
+ cond = codegen_1._`typeof ${data} == "bigint" && isFinite(${data})`
+ break
default:
return codegen_1._ `typeof ${data} ${EQ} ${dataType}`;
}
diff --git a/node_modules/ajv/dist/refs/json-schema-2019-09/meta/validation.json b/node_modules/ajv/dist/refs/json-schema-2019-09/meta/validation.json
index 7027a12..25679c8 100644
--- a/node_modules/ajv/dist/refs/json-schema-2019-09/meta/validation.json
+++ b/node_modules/ajv/dist/refs/json-schema-2019-09/meta/validation.json
@@ -78,7 +78,7 @@
"default": 0
},
"simpleTypes": {
- "enum": ["array", "boolean", "integer", "null", "number", "object", "string"]
+ "enum": ["array", "boolean", "integer", "null", "number", "object", "string","bigint"]
},
"stringArray": {
"type": "array",
diff --git a/node_modules/ajv/dist/refs/json-schema-2020-12/meta/validation.json b/node_modules/ajv/dist/refs/json-schema-2020-12/meta/validation.json
index e0ae13d..57c9036 100644
--- a/node_modules/ajv/dist/refs/json-schema-2020-12/meta/validation.json
+++ b/node_modules/ajv/dist/refs/json-schema-2020-12/meta/validation.json
@@ -78,7 +78,7 @@
"default": 0
},
"simpleTypes": {
- "enum": ["array", "boolean", "integer", "null", "number", "object", "string"]
+ "enum": ["array", "boolean", "integer", "null", "number", "object", "string","bigint"]
},
"stringArray": {
"type": "array",
diff --git a/node_modules/ajv/dist/refs/json-schema-draft-06.json b/node_modules/ajv/dist/refs/json-schema-draft-06.json
index 5410064..774435b 100644
--- a/node_modules/ajv/dist/refs/json-schema-draft-06.json
+++ b/node_modules/ajv/dist/refs/json-schema-draft-06.json
@@ -16,7 +16,7 @@
"allOf": [{"$ref": "#/definitions/nonNegativeInteger"}, {"default": 0}]
},
"simpleTypes": {
- "enum": ["array", "boolean", "integer", "null", "number", "object", "string"]
+ "enum": ["array", "boolean", "integer", "null", "number", "object", "string","bigint"]
},
"stringArray": {
"type": "array",
diff --git a/node_modules/ajv/dist/refs/json-schema-draft-07.json b/node_modules/ajv/dist/refs/json-schema-draft-07.json
index 6a74851..fc6dd7d 100644
--- a/node_modules/ajv/dist/refs/json-schema-draft-07.json
+++ b/node_modules/ajv/dist/refs/json-schema-draft-07.json
@@ -16,7 +16,7 @@
"allOf": [{"$ref": "#/definitions/nonNegativeInteger"}, {"default": 0}]
},
"simpleTypes": {
- "enum": ["array", "boolean", "integer", "null", "number", "object", "string"]
+ "enum": ["array", "boolean", "integer", "null", "number", "object", "string","bigint"]
},
"stringArray": {
"type": "array",
diff --git a/node_modules/ajv/dist/refs/jtd-schema.js b/node_modules/ajv/dist/refs/jtd-schema.js
index 1ee940a..1148887 100644
--- a/node_modules/ajv/dist/refs/jtd-schema.js
+++ b/node_modules/ajv/dist/refs/jtd-schema.js
@@ -38,6 +38,7 @@ const typeForm = (root) => ({
"uint16",
"int32",
"uint32",
+ "bigint",
],
},
},
diff --git a/node_modules/ajv/dist/runtime/parseJson.js b/node_modules/ajv/dist/runtime/parseJson.js
index 2576a6e..e7447b1 100644
--- a/node_modules/ajv/dist/runtime/parseJson.js
+++ b/node_modules/ajv/dist/runtime/parseJson.js
@@ -97,6 +97,71 @@ exports.parseJsonNumber = parseJsonNumber;
parseJsonNumber.message = undefined;
parseJsonNumber.position = 0;
parseJsonNumber.code = 'require("ajv/dist/runtime/parseJson").parseJsonNumber';
+
+function parseJsonBigInt(s, pos, maxDigits) {
+ let numStr = "";
+ let c;
+ parseJsonBigInt.message = undefined;
+ if (s[pos] === "-") {
+ numStr += "-";
+ pos++;
+ }
+ if (s[pos] === "0") {
+ numStr += "0";
+ pos++;
+ }
+ else {
+ if (!parseDigits(maxDigits)) {
+ errorMessage();
+ return undefined;
+ }
+ }
+ if (maxDigits) {
+ parseJsonBigInt.position = pos;
+ return BigInt(numStr);
+ }
+ if (s[pos] === ".") {
+ numStr += ".";
+ pos++;
+ if (!parseDigits()) {
+ errorMessage();
+ return undefined;
+ }
+ }
+ if (((c = s[pos]), c === "e" || c === "E")) {
+ numStr += "e";
+ pos++;
+ if (((c = s[pos]), c === "+" || c === "-")) {
+ numStr += c;
+ pos++;
+ }
+ if (!parseDigits()) {
+ errorMessage();
+ return undefined;
+ }
+ }
+ parseJsonBigInt.position = pos;
+ return BigInt(numStr);
+ function parseDigits(maxLen) {
+ let digit = false;
+ while (((c = s[pos]), c >= "0" && c <= "9" && (maxLen === undefined || maxLen-- > 0))) {
+ digit = true;
+ numStr += c;
+ pos++;
+ }
+ return digit;
+ }
+ function errorMessage() {
+ parseJsonBigInt.position = pos;
+ parseJsonBigInt.message = pos < s.length ? `unexpected token ${s[pos]}` : "unexpected end";
+ }
+}
+exports.parseJsonBigInt = parseJsonBigInt;
+parseJsonBigInt.message = undefined;
+parseJsonBigInt.position = 0;
+parseJsonBigInt.code = 'require("ajv/dist/runtime/parseJson").parseJsonBigInt';
+
+
const escapedChars = {
b: "\b",
f: "\f",
diff --git a/node_modules/ajv/dist/vocabularies/jtd/type.js b/node_modules/ajv/dist/vocabularies/jtd/type.js
index 428bddb..fbc3070 100644
--- a/node_modules/ajv/dist/vocabularies/jtd/type.js
+++ b/node_modules/ajv/dist/vocabularies/jtd/type.js
@@ -45,6 +45,9 @@ const def = {
cond = timestampCode(cxt);
break;
}
+ case "bigint":
+ cond = codegen_1._`typeof ${data} == "bigint" || typeof ${data} == "string"`
+ break
case "float32":
case "float64":
cond = codegen_1._ `typeof ${data} == "number"`;

View File

@ -0,0 +1,59 @@
// https://mermade.github.io/openapi-gui/#
// https://editor.swagger.io/
import path from "path";
import fs from "fs";
import * as TJS from "typescript-json-schema";
import "missing-native-js-functions";
const schemaPath = path.join(__dirname, "..", "assets", "schemas.json");
const settings: TJS.PartialArgs = {
required: true,
ignoreErrors: true,
excludePrivate: true,
defaultNumberType: "integer",
noExtraProps: true,
defaultProps: false
};
const compilerOptions: TJS.CompilerOptions = {
strictNullChecks: false
};
const ExcludedSchemas = ["DefaultSchema", "Schema", "EntitySchema"];
function main() {
const program = TJS.getProgramFromFiles(walk(path.join(__dirname, "..", "src", "routes")), compilerOptions);
const generator = TJS.buildGenerator(program, settings);
if (!generator || !program) return;
const schemas = generator.getUserSymbols().filter((x) => x.endsWith("Schema") && !ExcludedSchemas.includes(x));
console.log(schemas);
var definitions: any = {};
for (const name of schemas) {
const part = TJS.generateSchema(program, name, settings, [], generator as TJS.JsonSchemaGenerator);
if (!part) continue;
definitions = { ...definitions, ...part.definitions, [name]: { ...part, definitions: undefined } };
}
fs.writeFileSync(schemaPath, JSON.stringify(definitions, null, 4));
}
main();
function walk(dir: string) {
var results = [] as string[];
var list = fs.readdirSync(dir);
list.forEach(function (file) {
file = dir + "/" + file;
var stat = fs.statSync(file);
if (stat && stat.isDirectory()) {
/* Recurse into a subdirectory */
results = results.concat(walk(file));
} else {
if (!file.endsWith(".ts")) return;
results.push(file);
}
});
return results;
}

View File

@ -1,19 +1,18 @@
import { Request, Response, Router } from "express";
import { emitEvent, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, Guild, Ban, User, Member } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { getIpAdress, check } from "@fosscord/api";
import { getIpAdress, check, route } from "@fosscord/api";
import { BanCreateSchema } from "@fosscord/api/schema/Ban";
const router: Router = Router();
router.get("/", async (req: Request, res: Response) => {
router.get("/", route({ permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => {
const { guild_id } = req.params;
var bans = await Ban.find({ guild_id: guild_id });
return res.json(bans);
});
router.get("/:user", async (req: Request, res: Response) => {
router.get("/:user", route({ permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => {
const { guild_id } = req.params;
const user_id = req.params.ban;
@ -21,15 +20,14 @@ router.get("/:user", async (req: Request, res: Response) => {
return res.json(ban);
});
router.put("/:user_id", check(BanCreateSchema), async (req: Request, res: Response) => {
router.put("/:user_id", route({ body: "BanCreateSchema", permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => {
const { guild_id } = req.params;
const banned_user_id = req.params.user_id;
const banned_user = await User.getPublicUser(banned_user_id);
const perms = await getPermission(req.user_id, guild_id);
perms.hasThrow("BAN_MEMBERS");
if (req.user_id === banned_user_id) throw new HTTPError("You can't ban yourself", 400);
if (perms.cache.guild?.owner_id === banned_user_id) throw new HTTPError("You can't ban the owner", 400);
if (req.permission?.cache.guild?.owner_id === banned_user_id) throw new HTTPError("You can't ban the owner", 400);
const ban = new Ban({
user_id: banned_user_id,
@ -55,17 +53,14 @@ router.put("/:user_id", check(BanCreateSchema), async (req: Request, res: Respon
return res.json(ban);
});
router.delete("/:user_id", async (req: Request, res: Response) => {
var { guild_id } = req.params;
var banned_user_id = req.params.user_id;
router.delete("/:user_id", route({ permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => {
const { guild_id, user_id } = req.params;
const banned_user = await User.getPublicUser(banned_user_id);
const perms = await getPermission(req.user_id, guild_id);
perms.hasThrow("BAN_MEMBERS");
const banned_user = await User.getPublicUser(user_id);
await Promise.all([
Ban.delete({
user_id: banned_user_id,
user_id: user_id,
guild_id
}),

66
api/src/util/route.ts Normal file
View File

@ -0,0 +1,66 @@
import { DiscordApiErrors, Event, EventData, getPermission, PermissionResolvable, Permissions } from "@fosscord/util";
import { NextFunction, Request, Response } from "express";
import fs from "fs";
import path from "path";
import Ajv from "ajv";
import { AnyValidateFunction } from "ajv/dist/core";
import { FieldErrors } from "..";
const SchemaPath = path.join(__dirname, "..", "..", "assets", "schemas.json");
const schemas = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" }));
export const ajv = new Ajv({ allErrors: true, parseDate: true, allowDate: true, schemas, messages: true });
declare global {
namespace Express {
interface Request {
permission?: Permissions;
}
}
}
export type RouteSchema = string; // typescript interface name
export type RouteResponse = { status: number; body?: RouteSchema; headers?: Record<string, string> };
export interface RouteOptions {
permission?: PermissionResolvable;
body?: RouteSchema;
response?: RouteResponse;
example?: {
body?: any;
path?: string;
event?: EventData;
headers?: Record<string, string>;
};
}
export function route(opts: RouteOptions) {
var validate: AnyValidateFunction<any>;
if (opts.body) {
// @ts-ignore
validate = ajv.getSchema(opts.body);
if (!validate) throw new Error(`Body schema ${opts.body} not found`);
}
return async (req: Request, res: Response, next: NextFunction) => {
if (opts.permission) {
const required = new Permissions(opts.permission);
const permission = await getPermission(req.user_id, req.params.guild_id, req.params.channel_id);
console.log(required.bitfield, permission.bitfield, permission.bitfield & required.bitfield);
// bitfield comparison: check if user lacks certain permission
if (!permission.has(required)) {
throw DiscordApiErrors.MISSING_PERMISSIONS.withParams(opts.permission as string);
}
if (validate) {
const valid = validate(req.body);
if (!valid) {
const fields: Record<string, { code?: string; message: string }> = {};
validate.errors?.forEach((x) => (fields[x.instancePath] = { code: x.keyword, message: x.message || "" }));
throw FieldErrors(fields);
}
}
}
next();
};
}