summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--README.md23
-rw-r--r--api/LICENSE14
-rw-r--r--api/assets/background.pngbin0 -> 319351 bytes
-rw-r--r--api/assets/fosscord-login.css23
-rw-r--r--api/assets/schemas.json12481
-rw-r--r--api/client_test/index.html12
-rw-r--r--api/crowdin.yml3
-rw-r--r--api/locales/he/auth.json20
-rw-r--r--api/locales/he/common.json22
-rw-r--r--api/locales/sv/auth.json20
-rw-r--r--api/locales/sv/common.json28
-rw-r--r--api/package.json2
-rw-r--r--api/scripts/generate_schema.js1
-rw-r--r--api/src/middlewares/RateLimit.ts22
-rw-r--r--api/src/routes/auth/register.ts2
-rw-r--r--api/src/routes/channels/#channel_id/messages/#message_id/ack.ts3
-rw-r--r--api/src/routes/channels/#channel_id/messages/#message_id/index.ts117
-rw-r--r--api/src/routes/channels/#channel_id/messages/#message_id/reactions.ts2
-rw-r--r--api/src/routes/channels/#channel_id/messages/bulk-delete.ts20
-rw-r--r--api/src/routes/channels/#channel_id/messages/index.ts55
-rw-r--r--api/src/routes/channels/#channel_id/purge.ts84
-rw-r--r--api/src/routes/guilds/#guild_id/members/index.ts1
-rw-r--r--api/src/routes/guilds/#guild_id/prune.ts8
-rw-r--r--api/src/start.ts7
-rw-r--r--api/src/util/handlers/Message.ts3
-rw-r--r--api/src/util/handlers/route.ts3
-rw-r--r--api/src/util/utility/passwordStrength.ts10
-rw-r--r--bundle/package-lock.json83
-rw-r--r--bundle/package.json1
-rw-r--r--bundle/scripts/benchmark/connections.js7
-rw-r--r--bundle/src/Server.ts28
-rw-r--r--bundle/src/start.ts7
-rw-r--r--bundle/src/stats.ts8
-rw-r--r--cdn/CONTRIBUTE.md18
-rw-r--r--cdn/package.json4
-rw-r--r--dashboard/LICENSE14
-rw-r--r--dashboard/package.json4
-rw-r--r--gateway/LICENSE14
-rw-r--r--gateway/client.js51
-rw-r--r--gateway/package.json2
-rw-r--r--gateway/src/opcodes/Identify.ts10
-rw-r--r--gateway/src/schema/VoiceStateUpdateSchema.ts8
-rw-r--r--package.json17
-rw-r--r--rtc/LICENSE14
-rw-r--r--util/LICENSE14
-rw-r--r--util/package.json2
-rw-r--r--util/src/entities/AuditLog.ts60
-rw-r--r--util/src/entities/Channel.ts36
-rw-r--r--util/src/entities/Config.ts31
-rw-r--r--util/src/entities/Group.ts33
-rw-r--r--util/src/entities/Message.ts4
-rw-r--r--util/src/entities/User.ts7
-rw-r--r--util/src/entities/UserGroup.ts37
-rw-r--r--util/src/util/Constants.ts25
-rw-r--r--util/src/util/Email.ts7
-rw-r--r--util/src/util/Intents.ts43
-rw-r--r--util/src/util/InvisibleCharacters.ts2
-rw-r--r--util/src/util/MessageFlags.ts12
-rw-r--r--util/src/util/Token.ts7
-rw-r--r--webrtc/.vscode/launch.json25
-rw-r--r--webrtc/LICENSE14
-rw-r--r--webrtc/package-lock.json614
-rw-r--r--webrtc/package.json11
-rw-r--r--webrtc/src/Server.ts123
-rw-r--r--webrtc/src/opcodes/Connect.ts40
-rw-r--r--webrtc/src/opcodes/Heartbeat.ts8
-rw-r--r--webrtc/src/opcodes/Identify.ts66
-rw-r--r--webrtc/src/opcodes/Resume.ts24
-rw-r--r--webrtc/src/opcodes/SelectProtocol.ts150
-rw-r--r--webrtc/src/opcodes/Speaking.ts7
-rw-r--r--webrtc/src/opcodes/Version.ts14
-rw-r--r--webrtc/src/opcodes/index.ts40
-rw-r--r--webrtc/src/start.ts7
-rw-r--r--webrtc/src/util/Heartbeat.ts23
-rw-r--r--webrtc/src/util/index.ts1
-rw-r--r--webrtc/tsconfig.json19
76 files changed, 14193 insertions, 589 deletions
diff --git a/README.md b/README.md

index a15a4b64..b05bed13 100644 --- a/README.md +++ b/README.md
@@ -3,7 +3,7 @@ </p> <h1 align="center">Fosscord Server</h1> -<p> +<p align="center"> <a href="https://discord.gg/ZrnGQP6p3d"> <img src="https://img.shields.io/discord/806142446094385153?color=7489d5&logo=discord&logoColor=ffffff" /> </a> @@ -14,22 +14,5 @@ </a> </p> -## [About](https://fosscord.com) - -This repository contains: - -- [Fosscord HTTP API Server](/api) -- [WebSocket Gateway Server](/gateway) -- [HTTP CDN Server](/cdn) -- [Utility and Database Models](/util) -- [RTC Server](/rtc) -- [WebRTC Server](/webrtc) -- [Admin Dashboard](/dashboard) - -## [Resources](https://docs.fosscord.com/resources/) - -- [Contributing](https://docs.fosscord.com/contributing/server/) - -## [Setup](https://docs.fosscord.com/server/setup/) - -- [Download](https://github.com/fosscord/fosscord-server/releases) +Branch that [slowcord.maddy.k.vu](https://slowcord.maddy.k.vu) runs. +Generally up to date with master, also contains my fixes/etc that aren't yet merged. \ No newline at end of file diff --git a/api/LICENSE b/api/LICENSE deleted file mode 100644
index f19bf520..00000000 --- a/api/LICENSE +++ /dev/null
@@ -1,14 +0,0 @@ -Copyright (C) 2021 Fosscord and contributors - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <https://www.gnu.org/licenses/>. \ No newline at end of file diff --git a/api/assets/background.png b/api/assets/background.png new file mode 100644
index 00000000..58369ab8 --- /dev/null +++ b/api/assets/background.png
Binary files differdiff --git a/api/assets/fosscord-login.css b/api/assets/fosscord-login.css
index d507c545..ca0af064 100644 --- a/api/assets/fosscord-login.css +++ b/api/assets/fosscord-login.css
@@ -14,7 +14,7 @@ } h3.title-jXR8lp.marginBottom8-AtZOdT.base-1x0h_U.size24-RIRrxO::after { margin-top: -32px; - content: "Welcome to Fosscord!"; + content: "Welcome to Slowcord!"; visibility: visible; display: block; } @@ -62,7 +62,22 @@ h3.title-jXR8lp.marginBottom8-AtZOdT.base-1x0h_U.size24-RIRrxO::after { margin-top: -16px; } -/* shrink login box to same size as register */ -.authBoxExpanded-2jqaBe { - width: 480px !important; +/* funny styling */ +.wrapper-6URcxg { + justify-content: flex-start !important; + + background: url("/assets/background.png"); + background-size: 100% 100%; + background-repeat: no-repeat; +} + +.authBoxExpanded-2jqaBe, +.authBox-hW6HRx { + width: max(40vw, 500px) !important; + height: 100vh !important; + padding: 100px !important; + display: flex; + justify-content: center; + align-items: center; + border-radius: 0 !important; } diff --git a/api/assets/schemas.json b/api/assets/schemas.json
index 555129e3..4afddfb6 100644 --- a/api/assets/schemas.json +++ b/api/assets/schemas.json
@@ -1,4 +1,5 @@ { +<<<<<<< HEAD "LoginSchema": { "type": "object", "properties": { @@ -8150,3 +8151,12483 @@ "$schema": "http://json-schema.org/draft-07/schema#" } } +======= + "LoginSchema": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "undelete": { + "type": "boolean" + }, + "captcha_key": { + "type": "string" + }, + "login_source": { + "type": "string" + }, + "gift_code_sku_id": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "login", + "password" + ], + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "RegisterSchema": { + "type": "object", + "properties": { + "username": { + "minLength": 2, + "maxLength": 32, + "type": "string" + }, + "password": { + "minLength": 1, + "maxLength": 72, + "type": "string" + }, + "consent": { + "type": "boolean" + }, + "email": { + "format": "email", + "type": "string" + }, + "fingerprint": { + "type": "string" + }, + "invite": { + "type": "string" + }, + "date_of_birth": { + "type": "string" + }, + "gift_code_sku_id": { + "type": "string" + }, + "captcha_key": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "consent", + "username" + ], + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "MessageCreateSchema": { + "type": "object", + "properties": { + "content": { + "type": "string" + }, + "nonce": { + "type": "string" + }, + "tts": { + "type": "boolean" + }, + "flags": { + "type": "string" + }, + "embeds": { + "type": "array", + "items": { + "$ref": "#/definitions/Embed" + } + }, + "embed": { + "$ref": "#/definitions/Embed" + }, + "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": {}, + "attachments": { + "type": "array", + "items": {} + }, + "sticker_ids": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$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, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "MessageAcknowledgeSchema": { + "type": "object", + "properties": { + "manual": { + "type": "boolean" + }, + "mention_count": { + "type": "integer" + } + }, + "additionalProperties": false, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "BulkDeleteSchema": { + "type": "object", + "properties": { + "messages": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false, + "required": [ + "messages" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "ChannelPermissionOverwriteSchema": { + "type": "object", + "properties": { + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + }, + "id": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + } + }, + "additionalProperties": false, + "required": [ + "allow", + "deny", + "id", + "type" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "WebhookCreateSchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 80, + "type": "string" + }, + "avatar": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "avatar", + "name" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "GatewayBotResponse": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "shards": { + "type": "integer" + }, + "session_start_limit": { + "type": "object", + "properties": { + "total": { + "type": "integer" + }, + "remaining": { + "type": "integer" + }, + "reset_after": { + "type": "integer" + }, + "max_concurrency": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "max_concurrency", + "remaining", + "reset_after", + "total" + ] + } + }, + "additionalProperties": false, + "required": [ + "session_start_limit", + "shards", + "url" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "GatewayResponse": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "url" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "BanCreateSchema": { + "type": "object", + "properties": { + "delete_message_days": { + "type": "string" + }, + "reason": { + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "BanRegistrySchema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "user_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "executor_id": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "reason": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "executor_id", + "guild_id", + "id", + "user_id" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "BanModeratorSchema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "user_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "executor_id": { + "type": "string" + }, + "reason": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "executor_id", + "guild_id", + "id", + "user_id" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "ChannelReorderSchema": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "position": { + "type": "integer" + }, + "lock_permissions": { + "type": "boolean" + }, + "parent_id": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "id" + ] + }, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "EmojiCreateSchema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "image": { + "type": "string" + }, + "require_colons": { + "type": [ + "null", + "boolean" + ] + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false, + "required": [ + "image" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "EmojiModifySchema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "GuildCreateSchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "region": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "GuildUpdateSchema": { + "type": "object", + "properties": { + "banner": { + "type": [ + "null", + "string" + ] + }, + "splash": { + "type": [ + "null", + "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": { + "maxLength": 100, + "type": "string" + }, + "region": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "string" + ] + }, + "guild_template_code": { + "type": "string" + }, + "system_channel_id": { + "type": "string" + }, + "rules_channel_id": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "name" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "MemberChangeSchema": { + "type": "object", + "properties": { + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "MemberNickChangeSchema": { + "type": "object", + "properties": { + "nick": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "nick" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "PruneSchema": { + "type": "object", + "properties": { + "days": { + "type": "integer" + } + }, + "additionalProperties": false, + "required": [ + "days" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "RoleModifySchema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "permissions": { + "type": "string" + }, + "color": { + "type": "integer" + }, + "hoist": { + "type": "boolean" + }, + "mentionable": { + "type": "boolean" + }, + "position": { + "type": "integer" + }, + "icon": { + "type": "string" + }, + "unicode_emoji": { + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$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" + ] + }, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "ModifyGuildStickerSchema": { + "type": "object", + "properties": { + "name": { + "minLength": 2, + "maxLength": 30, + "type": "string" + }, + "description": { + "maxLength": 100, + "type": "string" + }, + "tags": { + "maxLength": 200, + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "name", + "tags" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "TemplateCreateSchema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "name" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "TemplateModifySchema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "name" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "VanityUrlSchema": { + "type": "object", + "properties": { + "code": { + "minLength": 1, + "maxLength": 20, + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "VoiceStateUpdateSchema": { + "type": "object", + "properties": { + "channel_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "suppress": { + "type": "boolean" + }, + "request_to_speak_timestamp": { + "type": "string", + "format": "date-time" + }, + "self_mute": { + "type": "boolean" + }, + "self_deaf": { + "type": "boolean" + }, + "self_video": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "channel_id" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$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, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$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" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "GuildTemplateCreateSchema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "avatar": { + "type": [ + "null", + "string" + ] + } + }, + "additionalProperties": false, + "required": [ + "name" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "UserProfileResponse": { + "type": "object", + "properties": { + "user": { + "$ref": "#/definitions/UserPublic" + }, + "connected_accounts": { + "$ref": "#/definitions/PublicConnectedAccount" + }, + "premium_guild_since": { + "type": "string", + "format": "date-time" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "connected_accounts", + "user" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "UserRelationsResponse": { + "type": "object", + "properties": { + "object": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "username": { + "type": "string" + }, + "avatar": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "public_flags": { + "type": "integer" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false, + "required": [ + "object" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "DmChannelCreateSchema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "recipients": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false, + "required": [ + "recipients" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "UserModifySchema": { + "additionalProperties": false, + "type": "object", + "properties": { + "username": { + "minLength": 1, + "maxLength": 100, + "type": "string" + }, + "avatar": { + "type": [ + "null", + "string" + ] + }, + "bio": { + "maxLength": 1024, + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": [ + "null", + "string" + ] + }, + "password": { + "type": "string" + }, + "new_password": { + "type": "string" + }, + "code": { + "type": "string" + } + }, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "RelationshipPutSchema": { + "type": "object", + "properties": { + "type": { + "enum": [ + 1, + 2, + 3, + 4 + ], + "type": "number" + } + }, + "additionalProperties": false, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + }, + "RelationshipPostSchema": { + "type": "object", + "properties": { + "discriminator": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "discriminator", + "username" + ], + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$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": { + "anyOf": [ + { + "type": "object", + "properties": { + "emoji_id": { + "type": "string" + }, + "emoji_name": { + "type": "string" + }, + "expires_at": { + "type": "integer" + }, + "text": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "null" + } + ] + }, + "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", + "invisible", + "offline", + "online" + ], + "type": "string" + }, + "stream_notifications_enabled": { + "type": "boolean" + }, + "theme": { + "enum": [ + "dark", + "white" + ], + "type": "string" + }, + "timezone_offset": { + "type": "integer" + } + }, + "additionalProperties": false, + "definitions": { + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1, + 2 + ], + "type": "number" + }, + "Embed": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "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" + ] + } + } + }, + "additionalProperties": false + }, + "EmbedImage": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "width": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "ChannelModifySchema": { + "type": "object", + "properties": { + "name": { + "maxLength": 100, + "type": "string" + }, + "type": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 13, + 2, + 255, + 3, + 33, + 34, + 35, + 4, + 5, + 6, + 64, + 7, + 8, + 9 + ], + "type": "number" + }, + "topic": { + "type": "string" + }, + "icon": { + "type": [ + "null", + "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": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + }, + "allow": { + "type": "string" + }, + "deny": { + "type": "string" + } + }, + "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 + }, + "UserPublic": { + "type": "object", + "properties": { + "username": { + "type": "string" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "integer" + }, + "avatar": { + "type": "string" + }, + "accent_color": { + "type": "integer" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "premium_since": { + "type": "string", + "format": "date-time" + } + }, + "additionalProperties": false, + "required": [ + "bio", + "bot", + "discriminator", + "id", + "premium_since", + "public_flags", + "username" + ] + }, + "PublicConnectedAccount": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": [ + "name", + "type", + "verified" + ] + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" + } +} +>>>>>>> fix/sanitisation diff --git a/api/client_test/index.html b/api/client_test/index.html
index 39ff346d..b438b492 100644 --- a/api/client_test/index.html +++ b/api/client_test/index.html
@@ -24,20 +24,20 @@ ASSET_ENDPOINT: "", MEDIA_PROXY_ENDPOINT: "https://media.discordapp.net", WIDGET_ENDPOINT: `//${location.host}/widget`, - INVITE_HOST: `${location.host}/invite`, - GUILD_TEMPLATE_HOST: "discord.new", - GIFT_CODE_HOST: "discord.gift", + INVITE_HOST: `${location.hostname}/invite`, + GUILD_TEMPLATE_HOST: "${location.host}", + GIFT_CODE_HOST: "${location.hostname}", RELEASE_CHANNEL: "stable", MARKETING_ENDPOINT: "//discord.com", BRAINTREE_KEY: "production_5st77rrc_49pp2rp4phym7387", STRIPE_KEY: "pk_live_CUQtlpQUF0vufWpnpUmQvcdi", NETWORKING_ENDPOINT: "//router.discordapp.net", - RTC_LATENCY_ENDPOINT: "//latency.discord.media/rtc", + RTC_LATENCY_ENDPOINT: "//${location.hostname}/rtc", PROJECT_ENV: "production", REMOTE_AUTH_ENDPOINT: "//localhost:3020", SENTRY_TAGS: { buildId: "75e36d9", buildType: "normal" }, - MIGRATION_SOURCE_ORIGIN: "https://discordapp.com", - MIGRATION_DESTINATION_ORIGIN: "https://discord.com", + MIGRATION_SOURCE_ORIGIN: "https://${location.hostname}", + MIGRATION_DESTINATION_ORIGIN: "https://${location.hostname}", HTML_TIMESTAMP: Date.now(), ALGOLIA_KEY: "aca0d7082e4e63af5ba5917d5e96bed0" }; diff --git a/api/crowdin.yml b/api/crowdin.yml deleted file mode 100644
index 7228117f..00000000 --- a/api/crowdin.yml +++ /dev/null
@@ -1,3 +0,0 @@ -files: - - source: /locales/en/*.json - translation: /locales/%two_letters_code%/%original_file_name% diff --git a/api/locales/he/auth.json b/api/locales/he/auth.json
index e19547a0..b7296868 100644 --- a/api/locales/he/auth.json +++ b/api/locales/he/auth.json
@@ -1,16 +1,16 @@ { "login": { - "INVALID_LOGIN": "E-Mail or Phone not found", - "INVALID_PASSWORD": "Invalid Password", - "ACCOUNT_DISABLED": "This account is disabled" + "INVALID_LOGIN": "מייל או מספר טלפון לא נמצאים במאגר", + "INVALID_PASSWORD": "סיסמא שגויה", + "ACCOUNT_DISABLED": "משתמש זה חסום / מבוטל" }, "register": { - "REGISTRATION_DISABLED": "New user registration is disabled", - "INVITE_ONLY": "You must be invited to register", - "EMAIL_INVALID": "Invalid Email", - "EMAIL_ALREADY_REGISTERED": "Email is already registered", - "DATE_OF_BIRTH_UNDERAGE": "You need to be {{years}} years or older", - "CONSENT_REQUIRED": "You must agree to the Terms of Service and Privacy Policy.", - "USERNAME_TOO_MANY_USERS": "Too many users have this username, please try another" + "REGISTRATION_DISABLED": "לא ניתן לאפשר רישום משתמשים חדשים", + "INVITE_ONLY": "עליך להיות מוזמן בכדי להרשם", + "EMAIL_INVALID": "מייל שגוי", + "EMAIL_ALREADY_REGISTERED": "מייל זה כבר רשום", + "DATE_OF_BIRTH_UNDERAGE": "{{years}} עלייך להיות מעל גיל", + "CONSENT_REQUIRED": ".עליך להסכים לתנאי השירות ולמדיניות הפרטיות", + "USERNAME_TOO_MANY_USERS": "ליותר מדי משתמשים יש שם משתמש זהה, אנא נסה אחר" } } diff --git a/api/locales/he/common.json b/api/locales/he/common.json
index 9e72e941..4101eac4 100644 --- a/api/locales/he/common.json +++ b/api/locales/he/common.json
@@ -1,18 +1,18 @@ { "field": { - "BASE_TYPE_REQUIRED": "This field is required", - "BASE_TYPE_STRING": "This field must be a string", - "BASE_TYPE_NUMBER": "This field must be a number", - "BASE_TYPE_BIGINT": "This field must be a bigint", - "BASE_TYPE_BOOLEAN": "This field must be a boolean", - "BASE_TYPE_CHOICES": "This field must be one of ({{types}})", - "BASE_TYPE_CLASS": "This field must be an instance of {{type}}", + "BASE_TYPE_REQUIRED": "שדה זה חובה", + "BASE_TYPE_STRING": "שדה זה חייב להיות כטקסט", + "BASE_TYPE_NUMBER": "שדה זה חייב להיות מספר", + "BASE_TYPE_BIGINT": "השדה הזה חייב להיות ביגינט", + "BASE_TYPE_BOOLEAN": "השדה הזה חייב להיות בוליאני", + "BASE_TYPE_CHOICES": "({{types}}) שדה זה חייב להיות אחד מ", + "BASE_TYPE_CLASS": "{{type}} מסוג instance שדה זה חייב להיות", "BASE_TYPE_OBJECT": "שדה זה חייב להיות אובייקט", "BASE_TYPE_ARRAY": "שדה זה חייב להיות מערך", - "UNKOWN_FIELD": "מפתח לא ידוע: {{key}}", - "BASE_TYPE_CONSTANT": "שדה זה להיות {{value}}", + "UNKOWN_FIELD": "{{key}} :מפתח לא ידוע", + "BASE_TYPE_CONSTANT": "{{value}} שדה זה חייב להיות", "EMAIL_TYPE_INVALID_EMAIL": "כתובת דואר אלקטרוני לא חוקית", - "DATE_TYPE_PARSE": "לא ניתן לנתח {{date}}. צריך להיות ISO8601", - "BASE_TYPE_BAD_LENGTH": "האורך חייב להיות בין {{length}}" + "DATE_TYPE_PARSE": "ISO8601 אמור להיות {{date}} לא ניתן לאתר", + "BASE_TYPE_BAD_LENGTH": "{{length}} האורך חייב להיות בין" } } diff --git a/api/locales/sv/auth.json b/api/locales/sv/auth.json
index e19547a0..04e55752 100644 --- a/api/locales/sv/auth.json +++ b/api/locales/sv/auth.json
@@ -1,16 +1,16 @@ { "login": { - "INVALID_LOGIN": "E-Mail or Phone not found", - "INVALID_PASSWORD": "Invalid Password", - "ACCOUNT_DISABLED": "This account is disabled" + "INVALID_LOGIN": "E-post eller telefon hittades inte", + "INVALID_PASSWORD": "Ogiltigt lösenord", + "ACCOUNT_DISABLED": "Detta konto är inaktiverat" }, "register": { - "REGISTRATION_DISABLED": "New user registration is disabled", - "INVITE_ONLY": "You must be invited to register", - "EMAIL_INVALID": "Invalid Email", - "EMAIL_ALREADY_REGISTERED": "Email is already registered", - "DATE_OF_BIRTH_UNDERAGE": "You need to be {{years}} years or older", - "CONSENT_REQUIRED": "You must agree to the Terms of Service and Privacy Policy.", - "USERNAME_TOO_MANY_USERS": "Too many users have this username, please try another" + "REGISTRATION_DISABLED": "Registrering av nya användare är inaktiverat", + "INVITE_ONLY": "Du måste vara inbjuden för att registrera dig", + "EMAIL_INVALID": "Ogiltig e-post", + "EMAIL_ALREADY_REGISTERED": "E-postadressen är redan registrerad", + "DATE_OF_BIRTH_UNDERAGE": "Du måste vara {{years}} år eller äldre", + "CONSENT_REQUIRED": "Du måste godkänna användarvillkoren och sekretesspolicyn.", + "USERNAME_TOO_MANY_USERS": "För många användare har detta användarnamn, försök med ett annat" } } diff --git a/api/locales/sv/common.json b/api/locales/sv/common.json
index 8bb9c042..56c02a64 100644 --- a/api/locales/sv/common.json +++ b/api/locales/sv/common.json
@@ -1,18 +1,18 @@ { "field": { - "BASE_TYPE_REQUIRED": "This field is required", - "BASE_TYPE_STRING": "This field must be a string", - "BASE_TYPE_NUMBER": "This field must be a number", - "BASE_TYPE_BIGINT": "This field must be a bigint", - "BASE_TYPE_BOOLEAN": "This field must be a boolean", - "BASE_TYPE_CHOICES": "This field must be one of ({{types}})", - "BASE_TYPE_CLASS": "This field must be an instance of {{type}}", - "BASE_TYPE_OBJECT": "This field must be an object", - "BASE_TYPE_ARRAY": "This field must be an array", - "UNKOWN_FIELD": "Unknown key: {{key}}", - "BASE_TYPE_CONSTANT": "This field must be {{value}}", - "EMAIL_TYPE_INVALID_EMAIL": "Not a well-formed email address", - "DATE_TYPE_PARSE": "Could not parse {{date}}. Should be ISO8601", - "BASE_TYPE_BAD_LENGTH": "Must be between {{length}} in length" + "BASE_TYPE_REQUIRED": "Detta fältet krävs", + "BASE_TYPE_STRING": "Detta fält måste vara en sträng", + "BASE_TYPE_NUMBER": "Detta fält måste vara ett nummer", + "BASE_TYPE_BIGINT": "Detta fält måste vara av typen bigint", + "BASE_TYPE_BOOLEAN": "Detta fält måste vara booleskt", + "BASE_TYPE_CHOICES": "Detta fält måste vara av typen av ett av följande ({{types}})", + "BASE_TYPE_CLASS": "Det här fältet måste vara en instans av {{type}}", + "BASE_TYPE_OBJECT": "Detta fält måste vara ett objekt", + "BASE_TYPE_ARRAY": "Detta fält måste vara en array", + "UNKOWN_FIELD": "Okänd nyckel: {{key}}", + "BASE_TYPE_CONSTANT": "Det här fältet måste vara {{value}}", + "EMAIL_TYPE_INVALID_EMAIL": "E-postadressen har inte korrekt format", + "DATE_TYPE_PARSE": "Kunde inte tolka {{date}}. Bör vara ISO8601", + "BASE_TYPE_BAD_LENGTH": "Måste vara mellan {{length}} i längd" } } diff --git a/api/package.json b/api/package.json
index c586c9fe..65472522 100644 --- a/api/package.json +++ b/api/package.json
@@ -30,7 +30,7 @@ "discord-open-source" ], "author": "Fosscord", - "license": "GPLV3", + "license": "AGPLV3", "bugs": { "url": "https://github.com/fosscord/fosscord-server/issues" }, diff --git a/api/scripts/generate_schema.js b/api/scripts/generate_schema.js
index c12f6b1a..7e742ec1 100644 --- a/api/scripts/generate_schema.js +++ b/api/scripts/generate_schema.js
@@ -31,7 +31,6 @@ const Excluded = [ ]; function modify(obj) { - delete obj.additionalProperties; for (var k in obj) { if (typeof obj[k] === "object" && obj[k] !== null) { modify(obj[k]); diff --git a/api/src/middlewares/RateLimit.ts b/api/src/middlewares/RateLimit.ts
index 1a38cfcf..ca6de98f 100644 --- a/api/src/middlewares/RateLimit.ts +++ b/api/src/middlewares/RateLimit.ts
@@ -1,4 +1,4 @@ -import { Config, listenEvent } from "@fosscord/util"; +import { Config, getRights, listenEvent, Rights } from "@fosscord/util"; import { NextFunction, Request, Response, Router } from "express"; import { getIpAdress } from "@fosscord/api"; import { API_PREFIX_TRAILING_SLASH } from "./Authentication"; @@ -9,6 +9,7 @@ import { API_PREFIX_TRAILING_SLASH } from "./Authentication"; /* ? bucket limit? Max actions/sec per bucket? +(ANSWER: a small fosscord instance might not need a complex rate limiting system) TODO: delay database requests to include multiple queries TODO: different for methods (GET/POST) @@ -44,21 +45,25 @@ export default function rateLimit(opts: { onlyIp?: boolean; }): any { return async (req: Request, res: Response, next: NextFunction): Promise<any> => { + // exempt user? if so, immediately short circuit + const rights = await getRights(req.user_id); + if (rights.has("BYPASS_RATE_LIMITS")) return; + const bucket_id = opts.bucket || req.originalUrl.replace(API_PREFIX_TRAILING_SLASH, ""); var executor_id = getIpAdress(req); - if (!opts.onlyIp && req.user_id) executor_id = req.user_id; + if (!opts.onlyIp && req.user_id) executor_id = req.user_id; var max_hits = opts.count; if (opts.bot && req.user_bot) max_hits = opts.bot; if (opts.GET && ["GET", "OPTIONS", "HEAD"].includes(req.method)) max_hits = opts.GET; else if (opts.MODIFY && ["POST", "DELETE", "PATCH", "PUT"].includes(req.method)) max_hits = opts.MODIFY; - const offender = Cache.get(executor_id + bucket_id); + let offender = Cache.get(executor_id + bucket_id); if (offender) { - const reset = offender.expires_at.getTime(); - const resetAfterMs = reset - Date.now(); - const resetAfterSec = resetAfterMs / 1000; + let reset = offender.expires_at.getTime(); + let resetAfterMs = reset - Date.now(); + let resetAfterSec = Math.ceil(resetAfterMs / 1000); if (resetAfterMs <= 0) { offender.hits = 0; @@ -70,6 +75,11 @@ export default function rateLimit(opts: { if (offender.blocked) { const global = bucket_id === "global"; + // each block violation pushes the expiry one full window further + reset += opts.window * 1000; + offender.expires_at = new Date(offender.expires_at.getTime() + opts.window * 1000); + resetAfterMs = reset - Date.now(); + resetAfterSec = Math.ceil(resetAfterMs / 1000); console.log("blocked bucket: " + bucket_id, { resetAfterMs }); return ( diff --git a/api/src/routes/auth/register.ts b/api/src/routes/auth/register.ts
index cd1bcb72..94dd6502 100644 --- a/api/src/routes/auth/register.ts +++ b/api/src/routes/auth/register.ts
@@ -128,7 +128,7 @@ router.post("/", route({ body: "RegisterSchema" }), async (req: Request, res: Re throw FieldErrors({ date_of_birth: { code: "BASE_TYPE_REQUIRED", message: req.t("common:field.BASE_TYPE_REQUIRED") } }); - } else if (register.dateOfBirth.minimum) { + } else if (register.dateOfBirth.required && register.dateOfBirth.minimum) { const minimum = new Date(); minimum.setFullYear(minimum.getFullYear() - register.dateOfBirth.minimum); body.date_of_birth = new Date(body.date_of_birth as Date); diff --git a/api/src/routes/channels/#channel_id/messages/#message_id/ack.ts b/api/src/routes/channels/#channel_id/messages/#message_id/ack.ts
index 208c1da4..885c5eca 100644 --- a/api/src/routes/channels/#channel_id/messages/#message_id/ack.ts +++ b/api/src/routes/channels/#channel_id/messages/#message_id/ack.ts
@@ -4,8 +4,9 @@ import { route } from "@fosscord/api"; const router = Router(); -// TODO: check if message exists +// TODO: public read receipts & privacy scoping // TODO: send read state event to all channel members +// TODO: advance-only notification cursor export interface MessageAcknowledgeSchema { manual?: boolean; diff --git a/api/src/routes/channels/#channel_id/messages/#message_id/index.ts b/api/src/routes/channels/#channel_id/messages/#message_id/index.ts
index 58dfb1cc..63fee9b9 100644 --- a/api/src/routes/channels/#channel_id/messages/#message_id/index.ts +++ b/api/src/routes/channels/#channel_id/messages/#message_id/index.ts
@@ -1,12 +1,38 @@ -import { Channel, emitEvent, getPermission, getRights, MessageDeleteEvent, Message, MessageUpdateEvent } from "@fosscord/util"; +import { + Attachment, + Channel, + Embed, + DiscordApiErrors, + emitEvent, + FosscordApiErrors, + getPermission, + getRights, + Message, + MessageCreateEvent, + MessageDeleteEvent, + MessageUpdateEvent, + Snowflake, + uploadFile +} from "@fosscord/util"; import { Router, Response, Request } from "express"; +import multer from "multer"; import { route } from "@fosscord/api"; import { handleMessage, postHandleMessage } from "@fosscord/api"; import { MessageCreateSchema } from "../index"; +import { HTTPError } from "lambert-server"; const router = Router(); // TODO: message content/embed string length limit +const messageUpload = multer({ + limits: { + fileSize: 1024 * 1024 * 100, + fields: 10, + files: 1 + }, + storage: multer.memoryStorage() +}); // max upload 50 mb + router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGES", right: "SEND_MESSAGES" }), async (req: Request, res: Response) => { const { message_id, channel_id } = req.params; var body = req.body as MessageCreateSchema; @@ -51,6 +77,95 @@ router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGE return res.json(message); }); + +// Backfill message with specific timestamp +router.put( + "/", + messageUpload.single("file"), + async (req, res, next) => { + if (req.body.payload_json) { + req.body = JSON.parse(req.body.payload_json); + } + + next(); + }, + route({ body: "MessageCreateSchema", permission: "SEND_MESSAGES", right: "SEND_BACKDATED_EVENTS" }), + async (req: Request, res: Response) => { + const { channel_id, message_id } = req.params; + var body = req.body as MessageCreateSchema; + const attachments: Attachment[] = []; + + const rights = await getRights(req.user_id); + rights.hasThrow("SEND_MESSAGES"); + + // regex to check if message contains anything other than numerals ( also no decimals ) + if (!message_id.match(/^\+?\d+$/)) { + throw new HTTPError("Message IDs must be positive integers", 400); + } + + const snowflake = Snowflake.deconstruct(message_id) + if (Date.now() < snowflake.timestamp) { + // message is in the future + throw FosscordApiErrors.CANNOT_BACKFILL_TO_THE_FUTURE; + } + + const exists = await Message.findOne({ where: { id: message_id, channel_id: channel_id }}); + if (exists) { + throw FosscordApiErrors.CANNOT_REPLACE_BY_BACKFILL; + } + + if (req.file) { + try { + const file = await uploadFile(`/attachments/${req.params.channel_id}`, req.file); + attachments.push({ ...file, proxy_url: file.url }); + } catch (error) { + return res.status(400).json(error); + } + } + const channel = await Channel.findOneOrFail({ where: { id: channel_id }, relations: ["recipients", "recipients.user"] }); + + const embeds = body.embeds || []; + if (body.embed) embeds.push(body.embed); + let message = await handleMessage({ + ...body, + type: 0, + pinned: false, + author_id: req.user_id, + id: message_id, + embeds, + channel_id, + attachments, + edited_timestamp: undefined, + timestamp: new Date(snowflake.timestamp), + }); + + //Fix for the client bug + delete message.member + + await Promise.all([ + message.save(), + emitEvent({ event: "MESSAGE_CREATE", channel_id: channel_id, data: message } as MessageCreateEvent), + channel.save() + ]); + + postHandleMessage(message).catch((e) => { }); // no await as it shouldnt block the message send function and silently catch error + + return res.json(message); + } +); + +router.get("/", route({ permission: "VIEW_CHANNEL" }), async (req: Request, res: Response) => { + const { message_id, channel_id } = req.params; + + const message = await Message.findOneOrFail({ where: { id: message_id, channel_id }, relations: ["attachments"] }); + + const permissions = await getPermission(req.user_id, undefined, channel_id); + + if (message.author_id !== req.user_id) permissions.hasThrow("READ_MESSAGE_HISTORY"); + + return res.json(message); +}); + router.delete("/", route({}), async (req: Request, res: Response) => { const { message_id, channel_id } = req.params; diff --git a/api/src/routes/channels/#channel_id/messages/#message_id/reactions.ts b/api/src/routes/channels/#channel_id/messages/#message_id/reactions.ts
index 6b6a66b2..d93cf70f 100644 --- a/api/src/routes/channels/#channel_id/messages/#message_id/reactions.ts +++ b/api/src/routes/channels/#channel_id/messages/#message_id/reactions.ts
@@ -101,7 +101,7 @@ router.get("/:emoji", route({ permission: "VIEW_CHANNEL" }), async (req: Request res.json(users); }); -router.put("/:emoji/:user_id", route({ permission: "READ_MESSAGE_HISTORY" }), async (req: Request, res: Response) => { +router.put("/:emoji/:user_id", route({ permission: "READ_MESSAGE_HISTORY", right: "SELF_ADD_REACTIONS" }), async (req: Request, res: Response) => { const { message_id, channel_id, user_id } = req.params; if (user_id !== "@me") throw new HTTPError("Invalid user"); const emoji = getEmoji(req.params.emoji); diff --git a/api/src/routes/channels/#channel_id/messages/bulk-delete.ts b/api/src/routes/channels/#channel_id/messages/bulk-delete.ts
index 7a711cb0..6eacf249 100644 --- a/api/src/routes/channels/#channel_id/messages/bulk-delete.ts +++ b/api/src/routes/channels/#channel_id/messages/bulk-delete.ts
@@ -1,5 +1,5 @@ import { Router, Response, Request } from "express"; -import { Channel, Config, emitEvent, getPermission, MessageDeleteBulkEvent, Message } from "@fosscord/util"; +import { Channel, Config, emitEvent, getPermission, getRights, MessageDeleteBulkEvent, Message } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { route } from "@fosscord/api"; import { In } from "typeorm"; @@ -12,22 +12,28 @@ export interface BulkDeleteSchema { messages: string[]; } -// TODO: should users be able to bulk delete messages or only bots? -// TODO: should this request fail, if you provide messages older than 14 days/invalid ids? +// should users be able to bulk delete messages or only bots? ANSWER: all users +// should this request fail, if you provide messages older than 14 days/invalid ids? ANSWER: NO // https://discord.com/developers/docs/resources/channel#bulk-delete-messages router.post("/", route({ body: "BulkDeleteSchema" }), async (req: Request, res: Response) => { const { channel_id } = req.params; const channel = await Channel.findOneOrFail({ id: channel_id }); if (!channel.guild_id) throw new HTTPError("Can't bulk delete dm channel messages", 400); + const rights = await getRights(req.user_id); + rights.hasThrow("SELF_DELETE_MESSAGES"); + + let superuser = rights.has("MANAGE_MESSAGES"); const permission = await getPermission(req.user_id, channel?.guild_id, channel_id); - permission.hasThrow("MANAGE_MESSAGES"); - + const { maxBulkDelete } = Config.get().limits.message; const { messages } = req.body as { messages: string[] }; - if (messages.length < 2) throw new HTTPError("You must at least specify 2 messages to bulk delete"); - if (messages.length > maxBulkDelete) throw new HTTPError(`You cannot delete more than ${maxBulkDelete} messages`); + if (messages.length === 0) throw new HTTPError("You must specify messages to bulk delete"); + if (!superuser) { + permission.hasThrow("MANAGE_MESSAGES"); + if (messages.length > maxBulkDelete) throw new HTTPError(`You cannot delete more than ${maxBulkDelete} messages`); + } await Message.delete(messages.map((x) => ({ id: x }))); diff --git a/api/src/routes/channels/#channel_id/messages/index.ts b/api/src/routes/channels/#channel_id/messages/index.ts
index 2fd08b04..2d6a2977 100644 --- a/api/src/routes/channels/#channel_id/messages/index.ts +++ b/api/src/routes/channels/#channel_id/messages/index.ts
@@ -8,8 +8,10 @@ import { Embed, emitEvent, getPermission, + getRights, Message, MessageCreateEvent, + Snowflake, uploadFile, Member } from "@fosscord/util"; @@ -29,6 +31,8 @@ export function isTextChannel(type: ChannelType): boolean { case ChannelType.GUILD_VOICE: case ChannelType.GUILD_STAGE_VOICE: case ChannelType.GUILD_CATEGORY: + case ChannelType.GUILD_FORUM: + case ChannelType.DIRECTORY: throw new HTTPError("not a text channel", 400); case ChannelType.DM: case ChannelType.GROUP_DM: @@ -67,7 +71,11 @@ export interface MessageCreateSchema { }; payload_json?: string; file?: any; - attachments?: any[]; //TODO we should create an interface for attachments + /** + TODO: we should create an interface for attachments + TODO: OpenWAAO<-->attachment-style metadata conversion + **/ + attachments?: any[]; sticker_ids?: string[]; } @@ -83,7 +91,7 @@ router.get("/", async (req: Request, res: Response) => { const before = req.query.before ? `${req.query.before}` : undefined; const after = req.query.after ? `${req.query.after}` : undefined; const limit = Number(req.query.limit) || 50; - if (limit < 1 || limit > 100) throw new HTTPError("limit must be between 1 and 100"); + if (limit < 1 || limit > 100) throw new HTTPError("limit must be between 1 and 100", 422); var halfLimit = Math.floor(limit / 2); @@ -97,9 +105,16 @@ router.get("/", async (req: Request, res: Response) => { where: { channel_id }, relations: ["author", "webhook", "application", "mentions", "mention_roles", "mention_channels", "sticker_items", "attachments"] }; + - if (after) query.where.id = MoreThan(after); - else if (before) query.where.id = LessThan(before); + if (after) { + if (after > new Snowflake()) return res.status(422); + query.where.id = MoreThan(after); + } + else if (before) { + if (before < req.params.channel_id) return res.status(422); + query.where.id = LessThan(before); + } else if (around) { query.where.id = [ MoreThan((BigInt(around) - BigInt(halfLimit)).toString()), @@ -119,15 +134,18 @@ router.get("/", async (req: Request, res: Response) => { delete x.user_ids; }); // @ts-ignore - if (!x.author) x.author = { discriminator: "0000", username: "Deleted User", public_flags: "0", avatar: null }; + if (!x.author) x.author = { id: "4", discriminator: "0000", username: "Fosscord Ghost", public_flags: "0", avatar: null }; x.attachments?.forEach((y: any) => { // dynamically set attachment proxy_url in case the endpoint changed const uri = y.proxy_url.startsWith("http") ? y.proxy_url : `https://example.org${y.proxy_url}`; y.proxy_url = `${endpoint == null ? "" : endpoint}${new URL(uri).pathname}`; }); - - //Some clients ( discord.js ) only check if a property exists within the response, - //which causes erorrs when, say, the `application` property is `null`. + + /** + Some clients ( discord.js ) only check if a property exists within the response, + which causes erorrs when, say, the `application` property is `null`. + **/ + for (var curr in x) { if (x[curr] === null) delete x[curr]; @@ -147,15 +165,14 @@ const messageUpload = multer({ }, storage: multer.memoryStorage() }); // max upload 50 mb +/** + TODO: dynamically change limit of MessageCreateSchema with config -// TODO: dynamically change limit of MessageCreateSchema with config -// TODO: check: sum of all characters in an embed structure must not exceed 6000 characters - -// https://discord.com/developers/docs/resources/channel#create-message -// TODO: text channel slowdown -// TODO: trim and replace message content and every embed field -// TODO: check allowed_mentions - + https://discord.com/developers/docs/resources/channel#create-message + TODO: text channel slowdown (per-user and across-users) + Q: trim and replace message content and every embed field A: NO, given this cannot be implemented in E2EE channels + TODO: only dispatch notifications for mentions denoted in allowed_mentions +**/ // Send message router.post( "/", @@ -167,7 +184,7 @@ router.post( next(); }, - route({ body: "MessageCreateSchema", permission: "SEND_MESSAGES" }), + route({ body: "MessageCreateSchema", permission: "SEND_MESSAGES", right: "SEND_MESSAGES" }), async (req: Request, res: Response) => { const { channel_id } = req.params; var body = req.body as MessageCreateSchema; @@ -182,6 +199,9 @@ router.post( } } const channel = await Channel.findOneOrFail({ where: { id: channel_id }, relations: ["recipients", "recipients.user"] }); + if (!channel.isWritable()) { + throw new HTTPError(`Cannot send messages to channel of type ${channel.type}`, 400) + } const embeds = body.embeds || []; if (body.embed) embeds.push(body.embed); @@ -235,3 +255,4 @@ router.post( return res.json(message); } ); + diff --git a/api/src/routes/channels/#channel_id/purge.ts b/api/src/routes/channels/#channel_id/purge.ts new file mode 100644
index 00000000..28b52b50 --- /dev/null +++ b/api/src/routes/channels/#channel_id/purge.ts
@@ -0,0 +1,84 @@ +import { HTTPError } from "lambert-server"; +import { route } from "@fosscord/api"; +import { isTextChannel } from "./messages"; +import { FindManyOptions, Between, Not } from "typeorm"; +import { + Attachment, + Channel, + Config, + Embed, + DiscordApiErrors, + emitEvent, + FosscordApiErrors, + getPermission, + getRights, + Message, + MessageDeleteBulkEvent, + Snowflake, + uploadFile +} from "@fosscord/util"; +import { Router, Response, Request } from "express"; +import multer from "multer"; +import { handleMessage, postHandleMessage } from "@fosscord/api"; + +const router: Router = Router(); + +export default router; + +export interface PurgeSchema { + before: string; + after: string +} + +/** +TODO: apply the delete bit by bit to prevent client and database stress +**/ +router.post("/", route({ /*body: "PurgeSchema",*/ }), async (req: Request, res: Response) => { + const { channel_id } = req.params; + const channel = await Channel.findOneOrFail({ id: channel_id }); + + if (!channel.guild_id) throw new HTTPError("Can't purge dm channels", 400); + isTextChannel(channel.type); + + const rights = await getRights(req.user_id); + if (!rights.has("MANAGE_MESSAGES")) { + const permissions = await getPermission(req.user_id, channel.guild_id, channel_id); + permissions.hasThrow("MANAGE_MESSAGES"); + permissions.hasThrow("MANAGE_CHANNELS"); + } + + const { before, after } = req.body as PurgeSchema; + + // TODO: send the deletion event bite-by-bite to prevent client stress + + var query: FindManyOptions<Message> & { where: { id?: any; }; } = { + order: { id: "ASC" }, + // take: limit, + where: { + channel_id, + id: Between(after, before), // the right way around + author_id: rights.has("SELF_DELETE_MESSAGES") ? undefined : Not(req.user_id) + // if you lack the right of self-deletion, you can't delete your own messages, even in purges + }, + relations: ["author", "webhook", "application", "mentions", "mention_roles", "mention_channels", "sticker_items", "attachments"] + }; + + + const messages = await Message.find(query); + const endpoint = Config.get().cdn.endpointPublic; + + if (messages.length == 0) { + res.sendStatus(304); + return; + } + + await Message.delete(messages.map((x) => ({ id: x }))); + + await emitEvent({ + event: "MESSAGE_DELETE_BULK", + channel_id, + data: { ids: messages.map(x => x.id), channel_id, guild_id: channel.guild_id } + } as MessageDeleteBulkEvent); + + res.sendStatus(204); +}); diff --git a/api/src/routes/guilds/#guild_id/members/index.ts b/api/src/routes/guilds/#guild_id/members/index.ts
index 386276c8..b730a4e7 100644 --- a/api/src/routes/guilds/#guild_id/members/index.ts +++ b/api/src/routes/guilds/#guild_id/members/index.ts
@@ -6,7 +6,6 @@ import { HTTPError } from "lambert-server"; const router = Router(); -// TODO: not allowed for user -> only allowed for bots with privileged intents // TODO: send over websocket // TODO: check for GUILD_MEMBERS intent diff --git a/api/src/routes/guilds/#guild_id/prune.ts b/api/src/routes/guilds/#guild_id/prune.ts
index 0dd4d610..0e587d22 100644 --- a/api/src/routes/guilds/#guild_id/prune.ts +++ b/api/src/routes/guilds/#guild_id/prune.ts
@@ -11,6 +11,10 @@ export const inactiveMembers = async (guild_id: string, user_id: string, days: n //Snowflake should have `generateFromTime` method? Or similar? var minId = BigInt(date.valueOf() - Snowflake.EPOCH) << BigInt(22); + /** + idea: ability to customise the cutoff variable + possible candidates: public read receipt, last presence, last VC leave + **/ var members = await Member.find({ where: [ { @@ -47,7 +51,7 @@ export const inactiveMembers = async (guild_id: string, user_id: string, days: n return members; }; -router.get("/", route({ permission: "KICK_MEMBERS" }), async (req: Request, res: Response) => { +router.get("/", route({}), async (req: Request, res: Response) => { const days = parseInt(req.query.days as string); var roles = req.query.include_roles; @@ -65,7 +69,7 @@ export interface PruneSchema { days: number; } -router.post("/", route({ permission: "KICK_MEMBERS" }), async (req: Request, res: Response) => { +router.post("/", route({ permission: "KICK_MEMBERS", right: "KICK_BAN_MEMBERS" }), async (req: Request, res: Response) => { const days = parseInt(req.body.days); var roles = req.query.include_roles; diff --git a/api/src/start.ts b/api/src/start.ts
index 717e1b8f..ccb4d108 100644 --- a/api/src/start.ts +++ b/api/src/start.ts
@@ -7,7 +7,12 @@ config(); import { FosscordServer } from "./Server"; import cluster from "cluster"; import os from "os"; -const cores = Number(process.env.THREADS) || os.cpus().length; +var cores = 1; +try { + cores = Number(process.env.THREADS) || os.cpus().length; +} catch { + console.log("[API] Failed to get thread count! Using 1...") +} if (cluster.isMaster && process.env.NODE_ENV == "production") { console.log(`Primary ${process.pid} is running`); diff --git a/api/src/util/handlers/Message.ts b/api/src/util/handlers/Message.ts
index 5a5ac666..e9f0ac55 100644 --- a/api/src/util/handlers/Message.ts +++ b/api/src/util/handlers/Message.ts
@@ -91,7 +91,8 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> { if (opts.message_reference.channel_id !== opts.channel_id) throw new HTTPError("You can only reference messages from this channel"); } } - // Q: should be checked if the referenced message exists? ANSWER: NO + /** Q: should be checked if the referenced message exists? ANSWER: NO + otherwise backfilling won't work **/ // @ts-ignore message.type = MessageType.REPLY; } diff --git a/api/src/util/handlers/route.ts b/api/src/util/handlers/route.ts
index 0048c4dd..3d3bbc37 100644 --- a/api/src/util/handlers/route.ts +++ b/api/src/util/handlers/route.ts
@@ -6,6 +6,7 @@ import { FieldErrors, FosscordApiErrors, getPermission, + getRights, PermissionResolvable, Permissions, RightResolvable, @@ -105,6 +106,8 @@ export function route(opts: RouteOptions) { if (opts.right) { const required = new Rights(opts.right); + req.rights = await getRights(req.user_id); + if (!req.rights || !req.rights.has(required)) { throw FosscordApiErrors.MISSING_RIGHTS.withParams(opts.right as string); } diff --git a/api/src/util/utility/passwordStrength.ts b/api/src/util/utility/passwordStrength.ts
index e75e48f6..439700d0 100644 --- a/api/src/util/utility/passwordStrength.ts +++ b/api/src/util/utility/passwordStrength.ts
@@ -13,7 +13,7 @@ const blocklist: string[] = []; // TODO: update ones passwordblocklist is stored * - min <n> numbers * - min <n> symbols * - min <n> uppercase chars - * - shannon entropy divided by password entropy + * - shannon entropy folded into [0, 1) interval * * Returns: 0 > pw > 1 */ @@ -46,15 +46,15 @@ export function checkPassword(password: string): number { strength = 0; } - let entropyMap; + let entropyMap: { [key: string]: number } = {}; for (let i = 0; i < password.length; i++) { if (entropyMap[password[i]]) entropyMap[password[i]]++; else entropyMap[password[i]] = 1; } - let entropies = Array(entropyMap); - + let entropies = Object.values(entropyMap); + entropies.map(x => (x / entropyMap.length)); - strength += entropies.reduceRight((a, x), a - (x * Math.log2(x))) / Math.log2(password.length); + strength += entropies.reduceRight((a: number, x: number) => a - (x * Math.log2(x))) / Math.log2(password.length); return strength; } diff --git a/bundle/package-lock.json b/bundle/package-lock.json
index 4742b4a4..2434f250 100644 --- a/bundle/package-lock.json +++ b/bundle/package-lock.json
@@ -18,6 +18,7 @@ "@fosscord/gateway": "file:../gateway", "@sentry/node": "^6.16.1", "@sentry/tracing": "^6.16.1", + "@yukikaze-bot/erlpack": "^1.0.1", "ajv": "8.6.2", "ajv-formats": "^2.1.1", "amqplib": "^0.8.0", @@ -101,7 +102,7 @@ "name": "@fosscord/api", "version": "1.0.0", "hasInstallScript": true, - "license": "GPLV3", + "license": "AGPLV3", "dependencies": { "@babel/preset-env": "^7.15.8", "@babel/preset-typescript": "^7.15.0", @@ -164,7 +165,7 @@ "../cdn": { "name": "@fosscord/cdn", "version": "1.0.0", - "license": "GPLV3", + "license": "AGPLV3", "dependencies": { "@aws-sdk/client-s3": "^3.36.1", "@aws-sdk/node-http-handler": "^3.36.0", @@ -208,7 +209,7 @@ "name": "@fosscord/gateway", "version": "1.0.0", "hasInstallScript": true, - "license": "GPLV3", + "license": "AGPLV3", "dependencies": { "@fosscord/util": "file:../util", "amqplib": "^0.8.0", @@ -3770,6 +3771,21 @@ "version": "1.1.0", "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" }, + "node_modules/@yukikaze-bot/erlpack": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@yukikaze-bot/erlpack/-/erlpack-1.0.1.tgz", + "integrity": "sha512-PCJ2lGCf8DsQtrE411PY+NTsolK48l4InNn1kcBo0iUllKZYGLqeqXEWGA/INrmwanKcoYkU4pBySqUFLQDEoA==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.5", + "node-addon-api": "^4.0.0" + } + }, + "node_modules/@yukikaze-bot/erlpack/node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, "node_modules/@zerollup/ts-helpers": { "version": "1.7.18", "integrity": "sha512-S9zN+y+i5yN/evfWquzSO3lubqPXIsPQf6p9OiPMpRxDx/0totPLF39XoRw48Dav5dSvbIE8D2eAPpXXJxvKwg==", @@ -13897,6 +13913,22 @@ "version": "1.1.0", "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" }, + "@yukikaze-bot/erlpack": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@yukikaze-bot/erlpack/-/erlpack-1.0.1.tgz", + "integrity": "sha512-PCJ2lGCf8DsQtrE411PY+NTsolK48l4InNn1kcBo0iUllKZYGLqeqXEWGA/INrmwanKcoYkU4pBySqUFLQDEoA==", + "requires": { + "@mapbox/node-pre-gyp": "^1.0.5", + "node-addon-api": "^4.0.0" + }, + "dependencies": { + "node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + } + } + }, "@zerollup/ts-helpers": { "version": "1.7.18", "integrity": "sha512-S9zN+y+i5yN/evfWquzSO3lubqPXIsPQf6p9OiPMpRxDx/0totPLF39XoRw48Dav5dSvbIE8D2eAPpXXJxvKwg==", @@ -18836,6 +18868,51 @@ } } }, + "typescript-cached-transpile": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typescript-cached-transpile/-/typescript-cached-transpile-0.0.6.tgz", + "integrity": "sha512-bfPc7YUW0PrVkQHU0xN0ANRuxdPgoYYXtZEW6PNkH5a97/AOM+kPPxSTMZbpWA3BG1do22JUkfC60KoCKJ9VZQ==", + "requires": { + "@types/node": "^12.12.7", + "fs-extra": "^8.1.0", + "tslib": "^1.10.0" + }, + "dependencies": { + "@types/node": { + "version": "12.20.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.41.tgz", + "integrity": "sha512-f6xOqucbDirG7LOzedpvzjP3UTmHttRou3Mosx3vL9wr9AIQGhcPgVnqa8ihpZYnxyM1rxeNCvTyukPKZtq10Q==" + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + } + } + }, "typescript-json-schema": { "version": "0.50.1", "integrity": "sha512-GCof/SDoiTDl0qzPonNEV4CHyCsZEIIf+mZtlrjoD8vURCcEzEfa2deRuxYid8Znp/e27eDR7Cjg8jgGrimBCA==", diff --git a/bundle/package.json b/bundle/package.json
index 7d68427f..aedd963b 100644 --- a/bundle/package.json +++ b/bundle/package.json
@@ -66,6 +66,7 @@ "@fosscord/gateway": "file:../gateway", "@sentry/node": "^6.16.1", "@sentry/tracing": "^6.16.1", + "@yukikaze-bot/erlpack": "^1.0.1", "ajv": "8.6.2", "ajv-formats": "^2.1.1", "amqplib": "^0.8.0", diff --git a/bundle/scripts/benchmark/connections.js b/bundle/scripts/benchmark/connections.js
index 2a4125b4..ffca2628 100644 --- a/bundle/scripts/benchmark/connections.js +++ b/bundle/scripts/benchmark/connections.js
@@ -3,8 +3,13 @@ const cluster = require("cluster"); const WebSocket = require("ws"); const endpoint = process.env.GATEWAY || "ws://localhost:3001"; const connections = Number(process.env.CONNECTIONS) || 50; -const threads = Number(process.env.THREADS) || require("os").cpus().length || 1; const token = process.env.TOKEN; +var cores = 1; +try { + cores = Number(process.env.THREADS) || os.cpus().length; +} catch { + console.log("[Bundle] Failed to get thread count! Using 1...") +} if (!token) { console.error("TOKEN env var missing"); diff --git a/bundle/src/Server.ts b/bundle/src/Server.ts
index 71a60d49..bc1d7cbc 100644 --- a/bundle/src/Server.ts +++ b/bundle/src/Server.ts
@@ -50,20 +50,20 @@ async function main() { endpointPublic: `ws://localhost:${port}`, }), }, - // regions: { - // default: "fosscord", - // useDefaultAsOptimal: true, - // available: [ - // { - // id: "fosscord", - // name: "Fosscord", - // endpoint: "127.0.0.1:3001", - // vip: false, - // custom: false, - // deprecated: false, - // }, - // ], - // }, + regions: { + default: "fosscord", + useDefaultAsOptimal: true, + available: [ + { + id: "fosscord", + name: "Fosscord", + endpoint: "127.0.0.1:3004", + vip: false, + custom: false, + deprecated: false, + }, + ], + }, } as any); //Sentry diff --git a/bundle/src/start.ts b/bundle/src/start.ts
index 7660b296..de3b5848 100644 --- a/bundle/src/start.ts +++ b/bundle/src/start.ts
@@ -9,7 +9,12 @@ config(); import { execSync } from "child_process"; // TODO: add socket event transmission -let cores = Number(process.env.THREADS) || os.cpus().length; +var cores = 1; +try { + cores = Number(process.env.THREADS) || os.cpus().length; +} catch { + console.log("[API] Failed to get thread count! Using 1...") +} if (cluster.isMaster) { function getCommitOrFail() { diff --git a/bundle/src/stats.ts b/bundle/src/stats.ts
index 3c5163c3..0234e0b4 100644 --- a/bundle/src/stats.ts +++ b/bundle/src/stats.ts
@@ -4,7 +4,13 @@ import { red } from "picocolors"; export function initStats() { console.log(`[Path] running in ${__dirname}`); - console.log(`[CPU] ${osu.cpu.model()} Cores x${osu.cpu.count()}`); + try { + console.log(`[CPU] ${osu.cpu.model()} Cores x${osu.cpu.count()}`); + } + catch { + console.log('[CPU] Failed to get cpu model!') + } + console.log(`[System] ${os.platform()} ${os.arch()}`); console.log(`[Process] running with PID: ${process.pid}`); if (process.getuid && process.getuid() === 0) { diff --git a/cdn/CONTRIBUTE.md b/cdn/CONTRIBUTE.md deleted file mode 100644
index 7cc673d9..00000000 --- a/cdn/CONTRIBUTE.md +++ /dev/null
@@ -1,18 +0,0 @@ -# CONTRIBUTE - -### Setup: - -``` -npm i -npm start -``` - -### Run tests: - -``` -npm test -``` - -#### common errors: - -- db not connecting --> start mongod in a seperate terminal window diff --git a/cdn/package.json b/cdn/package.json
index 7a1f43c9..f1d12ba5 100644 --- a/cdn/package.json +++ b/cdn/package.json
@@ -14,8 +14,8 @@ "url": "git+https://github.com/fosscord/fosscord-server.git" }, "keywords": [], - "author": "", - "license": "GPLV3", + "author": "Fosscord", + "license": "AGPLV3", "bugs": { "url": "https://github.com/fosscord/fosscord-server/issues" }, diff --git a/dashboard/LICENSE b/dashboard/LICENSE deleted file mode 100644
index f19bf520..00000000 --- a/dashboard/LICENSE +++ /dev/null
@@ -1,14 +0,0 @@ -Copyright (C) 2021 Fosscord and contributors - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <https://www.gnu.org/licenses/>. \ No newline at end of file diff --git a/dashboard/package.json b/dashboard/package.json
index 1009d658..e71de793 100644 --- a/dashboard/package.json +++ b/dashboard/package.json
@@ -14,8 +14,8 @@ "url": "git+https://github.com/fosscord/fosscord-server.git" }, "keywords": [], - "author": "", - "license": "GPLV3", + "author": "Fosscord", + "license": "AGPLV3", "bugs": { "url": "https://github.com/fosscord/fosscord-server/issues" }, diff --git a/gateway/LICENSE b/gateway/LICENSE deleted file mode 100644
index f19bf520..00000000 --- a/gateway/LICENSE +++ /dev/null
@@ -1,14 +0,0 @@ -Copyright (C) 2021 Fosscord and contributors - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <https://www.gnu.org/licenses/>. \ No newline at end of file diff --git a/gateway/client.js b/gateway/client.js deleted file mode 100644
index c841c6a0..00000000 --- a/gateway/client.js +++ /dev/null
@@ -1,51 +0,0 @@ -require("missing-native-js-functions"); -const WebSocket = require("ws"); -const Constants = require("./dist/util/Constants"); - -// const ws = new WebSocket("ws://127.0.0.1:8080"); -const ws = new WebSocket("wss://dev.fosscord.com"); - -ws.on("open", () => { - // ws.send(JSON.stringify({ req_type: "new_auth" })); - // ws.send(JSON.stringify({ req_type: "check_auth", token: "" })); - // op: 0, - // d: {}, - // s: 42, - // t: "GATEWAY_EVENT_NAME", -}); - -function send(data) { - ws.send(JSON.stringify(data)); -} - -ws.on("message", (buffer) => { - let data = JSON.parse(buffer.toString()); - console.log(data); - - switch (data.op) { - case 10: - setIntervalNow(() => { - send({ op: 1 }); - }, data.d.heartbeat_interval); - - // send({ - // op: 2, - // d: { - // token: - // "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjgxMTY0MjkxNzQzMjA2NjA0OCIsImlhdCI6MTYxMzU4MTE1MX0.7Qj_z2lYIgJ0rc7NfGtpW5DKGqecQfv1mLpoBUQHKDc", - // intents: 0n, - // properties: {}, - // }, - // }); - - send({ - op: 6, - }); - - break; - } -}); - -ws.on("close", (code, reason) => { - console.log(code, reason, Constants.CLOSECODES[code]); -}); diff --git a/gateway/package.json b/gateway/package.json
index 6d0d2d1c..92d812b4 100644 --- a/gateway/package.json +++ b/gateway/package.json
@@ -13,7 +13,7 @@ }, "keywords": [], "author": "Fosscord", - "license": "GPLV3", + "license": "AGPLV3", "devDependencies": { "@types/amqplib": "^0.8.1", "@types/jsonwebtoken": "^8.5.0", diff --git a/gateway/src/opcodes/Identify.ts b/gateway/src/opcodes/Identify.ts
index eb15c28f..860000da 100644 --- a/gateway/src/opcodes/Identify.ts +++ b/gateway/src/opcodes/Identify.ts
@@ -29,8 +29,8 @@ const experiments: any = []; import { check } from "./instanceOf"; import { Recipient } from "@fosscord/util"; -// TODO: bot sharding -// TODO: check priviliged intents +// TODO: user sharding +// TODO: check privileged intents, if defined in the config // TODO: check if already identified export async function onIdentify(this: WebSocket, data: Payload) { @@ -87,7 +87,7 @@ export async function onIdentify(this: WebSocket, data: Payload) { user_id: this.user_id, session_id: session_id, // TODO: check if status is only one of: online, dnd, offline, idle - status: identify.presence?.status || "online", //does the session always start as online? + status: identify.presence?.status || "offline", //does the session always start as online? client_info: { //TODO read from identity client: "desktop", @@ -101,7 +101,7 @@ export async function onIdentify(this: WebSocket, data: Payload) { if (!user) return this.close(CLOSECODES.Authentication_failed); - if (!identify.intents) identify.intents = BigInt("0b11111111111111"); + if (!identify.intents) identify.intents = BigInt("0x6ffffffff"); this.intents = new Intents(identify.intents); if (identify.shard) { this.shard_id = identify.shard[0]; @@ -271,7 +271,7 @@ export async function onIdentify(this: WebSocket, data: Payload) { guild_join_requests: [], // TODO what is this? users: users.filter((x) => x).unique(), merged_members: merged_members, - // shard // TODO: only for bots sharding + // shard // TODO: only for user sharding }; // TODO: send real proper data structure diff --git a/gateway/src/schema/VoiceStateUpdateSchema.ts b/gateway/src/schema/VoiceStateUpdateSchema.ts
index 9efa191e..f6480414 100644 --- a/gateway/src/schema/VoiceStateUpdateSchema.ts +++ b/gateway/src/schema/VoiceStateUpdateSchema.ts
@@ -3,7 +3,8 @@ export const VoiceStateUpdateSchema = { $channel_id: String, self_mute: Boolean, self_deaf: Boolean, - self_video: Boolean, + $self_video: Boolean, //required in docs but bots don't always send it + $preferred_region: String, }; export interface VoiceStateUpdateSchema { @@ -11,5 +12,6 @@ export interface VoiceStateUpdateSchema { channel_id?: string; self_mute: boolean; self_deaf: boolean; - self_video: boolean; -} + self_video?: boolean; + preferred_region?: string; +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644
index 00000000..3395122e --- /dev/null +++ b/package.json
@@ -0,0 +1,17 @@ +{ + "name": "fosscord-server", + "version": "1.0.0", + "description": "A Fosscord server written in Node.js", + "workspaces": ["api", "cdn", "gateway"], + "scripts": {}, + "repository": { + "type": "git", + "url": "git+https://github.com/fosscord/fosscord-server.git" + }, + "author": "Fosscord", + "license": "AGPLV3", + "bugs": { + "url": "https://github.com/fosscord/fosscord-server/issues" + }, + "homepage": "https://fosscord.com" +} diff --git a/rtc/LICENSE b/rtc/LICENSE deleted file mode 100644
index f19bf520..00000000 --- a/rtc/LICENSE +++ /dev/null
@@ -1,14 +0,0 @@ -Copyright (C) 2021 Fosscord and contributors - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <https://www.gnu.org/licenses/>. \ No newline at end of file diff --git a/util/LICENSE b/util/LICENSE deleted file mode 100644
index f19bf520..00000000 --- a/util/LICENSE +++ /dev/null
@@ -1,14 +0,0 @@ -Copyright (C) 2021 Fosscord and contributors - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <https://www.gnu.org/licenses/>. \ No newline at end of file diff --git a/util/package.json b/util/package.json
index d7baed9a..7251d3e4 100644 --- a/util/package.json +++ b/util/package.json
@@ -23,7 +23,7 @@ "discord-open-source" ], "author": "Fosscord", - "license": "GPLV3", + "license": "AGPLV3", "bugs": { "url": "https://github.com/fosscord/fosscord-server/issues" }, diff --git a/util/src/entities/AuditLog.ts b/util/src/entities/AuditLog.ts
index 4b81ed6a..b003e7ba 100644 --- a/util/src/entities/AuditLog.ts +++ b/util/src/entities/AuditLog.ts
@@ -4,41 +4,93 @@ import { ChannelPermissionOverwrite } from "./Channel"; import { User } from "./User"; export enum AuditLogEvents { - GUILD_UPDATE = 1, - CHANNEL_CREATE = 10, + // guild level + GUILD_UPDATE = 1, + GUILD_IMPORT = 2, + GUILD_EXPORTED = 3, + GUILD_ARCHIVE = 4, + GUILD_UNARCHIVE = 5, + // join-leave + USER_JOIN = 6, + USER_LEAVE = 7, + // channels + CHANNEL_CREATE = 10, CHANNEL_UPDATE = 11, CHANNEL_DELETE = 12, - CHANNEL_OVERWRITE_CREATE = 13, + // permission overrides + CHANNEL_OVERWRITE_CREATE = 13, CHANNEL_OVERWRITE_UPDATE = 14, CHANNEL_OVERWRITE_DELETE = 15, - MEMBER_KICK = 20, + // kick and ban + MEMBER_KICK = 20, MEMBER_PRUNE = 21, MEMBER_BAN_ADD = 22, MEMBER_BAN_REMOVE = 23, + // member updates MEMBER_UPDATE = 24, MEMBER_ROLE_UPDATE = 25, MEMBER_MOVE = 26, MEMBER_DISCONNECT = 27, BOT_ADD = 28, + // roles ROLE_CREATE = 30, ROLE_UPDATE = 31, ROLE_DELETE = 32, + ROLE_SWAP = 33, + // invites INVITE_CREATE = 40, INVITE_UPDATE = 41, INVITE_DELETE = 42, + // webhooks WEBHOOK_CREATE = 50, WEBHOOK_UPDATE = 51, WEBHOOK_DELETE = 52, + WEBHOOK_SWAP = 53, + // custom emojis EMOJI_CREATE = 60, EMOJI_UPDATE = 61, EMOJI_DELETE = 62, + EMOJI_SWAP = 63, + // deletion + MESSAGE_CREATE = 70, // messages sent using non-primary seat of the user only + MESSAGE_EDIT = 71, // non-self edits only MESSAGE_DELETE = 72, MESSAGE_BULK_DELETE = 73, + // pinning MESSAGE_PIN = 74, MESSAGE_UNPIN = 75, + // integrations INTEGRATION_CREATE = 80, INTEGRATION_UPDATE = 81, INTEGRATION_DELETE = 82, + // stage actions + STAGE_INSTANCE_CREATE = 83, + STAGE_INSTANCE_UPDATE = 84, + STAGE_INSTANCE_DELETE = 85, + // stickers + STICKER_CREATE = 90, + STICKER_UPDATE = 91, + STICKER_DELETE = 92, + STICKER_SWAP = 93, + // threads + THREAD_CREATE = 110, + THREAD_UPDATE = 111, + THREAD_DELETE = 112, + // application commands + APPLICATION_COMMAND_PERMISSION_UPDATE = 121, + // automod + POLICY_CREATE = 140, + POLICY_UPDATE = 141, + POLICY_DELETE = 142, + MESSAGE_BLOCKED_BY_POLICIES = 143, // in fosscord, blocked messages are stealth-dropped + // instance policies affecting the guild + GUILD_AFFECTED_BY_POLICIES = 216, + // message moves + IN_GUILD_MESSAGE_MOVE = 223, + CROSS_GUILD_MESSAGE_MOVE = 224, + // message routing + ROUTE_CREATE = 225, + ROUTE_UPDATE = 226, } @Entity("audit_logs") diff --git a/util/src/entities/Channel.ts b/util/src/entities/Channel.ts
index 4bf81901..f3c40c83 100644 --- a/util/src/entities/Channel.ts +++ b/util/src/entities/Channel.ts
@@ -3,7 +3,7 @@ import { BaseClass } from "./BaseClass"; import { Guild } from "./Guild"; import { PublicUserProjection, User } from "./User"; import { HTTPError } from "lambert-server"; -import { containsAll, emitEvent, getPermission, Snowflake, trimSpecial, InvisibleCharacters } from "../util"; +import { containsAll, emitEvent, getPermission, Snowflake, trimSpecial, InvisibleCharacters, ChannelTypes } from "../util"; import { ChannelCreateEvent, ChannelRecipientRemoveEvent } from "../interfaces"; import { Recipient } from "./Recipient"; import { Message } from "./Message"; @@ -28,6 +28,8 @@ export enum ChannelType { GUILD_PUBLIC_THREAD = 11, // a temporary sub-channel within a GUILD_TEXT channel GUILD_PRIVATE_THREAD = 12, // a temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission GUILD_STAGE_VOICE = 13, // a voice channel for hosting events with an audience + DIRECTORY = 14, // guild directory listing channel + GUILD_FORUM = 15, // forum composed of IM threads TICKET_TRACKER = 33, // ticket tracker, individual ticket items shall have type 12 KANBAN = 34, // confluence like kanban board VOICELESS_WHITEBOARD = 35, // whiteboard but without voice (whiteboard + voice is the same as stage) @@ -147,7 +149,7 @@ export class Channel extends BaseClass { orphanedRowAction: "delete", }) webhooks?: Webhook[]; - + // TODO: DM channel static async createChannel( channel: Partial<Channel>, @@ -173,12 +175,20 @@ export class Channel extends BaseClass { if (channel.name.includes(character)) throw new HTTPError("Channel name cannot include invalid characters", 403); - if (channel.name.match(/\-\-+/g)) - throw new HTTPError("Channel name cannot include multiple adjacent dashes.", 403) + // Categories skip these checks on discord.com + if (channel.type !== ChannelType.GUILD_CATEGORY) { + if (channel.name.includes(" ")) + throw new HTTPError("Channel name cannot include invalid characters", 403); + + if (channel.name.match(/\-\-+/g)) + throw new HTTPError("Channel name cannot include multiple adjacent dashes.", 403); - if (channel.name.charAt(0) === "-" || - channel.name.charAt(channel.name.length - 1) === "-") - throw new HTTPError("Channel name cannot start/end with dash.", 403) + if (channel.name.charAt(0) === "-" || + channel.name.charAt(channel.name.length - 1) === "-") + throw new HTTPError("Channel name cannot start/end with dash.", 403); + } + else + channel.name = channel.name.trim(); //category names are trimmed client side on discord.com } if (!guild.features.includes("ALLOW_UNNAMED_CHANNELS")) { @@ -297,7 +307,7 @@ export class Channel extends BaseClass { await emitEvent({ event: "CHANNEL_CREATE", data: channel_dto, user_id: creator_user_id }); } - if (recipients.length === 1) return channel_dto; + if (recipients.length === 1) return channel_dto; else return channel_dto.excludedRecipients([creator_user_id]); } @@ -352,6 +362,16 @@ export class Channel extends BaseClass { isDm() { return this.type === ChannelType.DM || this.type === ChannelType.GROUP_DM; } + + // Does the channel support sending messages ( eg categories do not ) + isWritable() { + const disallowedChannelTypes = [ + ChannelType.GUILD_CATEGORY, + ChannelType.GUILD_STAGE_VOICE, + ChannelType.VOICELESS_WHITEBOARD, + ]; + return disallowedChannelTypes.indexOf(this.type) == -1; + } } export interface ChannelPermissionOverwrite { diff --git a/util/src/entities/Config.ts b/util/src/entities/Config.ts
index 8d29b387..f77991a9 100644 --- a/util/src/entities/Config.ts +++ b/util/src/entities/Config.ts
@@ -4,6 +4,7 @@ import crypto from "crypto"; import { Snowflake } from "../util/Snowflake"; import { SessionsReplace } from ".."; import { hostname } from "os"; +import { Rights } from "../util/Rights"; @Entity("config") export class ConfigEntity extends BaseClassWithoutId { @@ -120,6 +121,7 @@ export interface ConfigValue { secret: string | null; }; ipdataApiKey: string | null; + defaultRights: string; }; login: { requireCaptcha: boolean; @@ -311,6 +313,33 @@ export const DefaultConfigOptions: ConfigValue = { secret: null, }, ipdataApiKey: "eca677b284b3bac29eb72f5e496aa9047f26543605efe99ff2ce35c9", + defaultRights: ( + Rights.FLAGS.CREATE_CHANNELS + + Rights.FLAGS.CREATE_DMS + + Rights.FLAGS.CREATE_DM_GROUPS + + Rights.FLAGS.CREATE_GUILDS + + Rights.FLAGS.CREATE_INVITES + + Rights.FLAGS.CREATE_ROLES + + Rights.FLAGS.CREATE_TEMPLATES + + Rights.FLAGS.CREATE_WEBHOOKS + + Rights.FLAGS.JOIN_GUILDS + + Rights.FLAGS.PIN_MESSAGES + + Rights.FLAGS.SELF_ADD_REACTIONS + + Rights.FLAGS.SELF_DELETE_MESSAGES + + Rights.FLAGS.SELF_EDIT_MESSAGES + + Rights.FLAGS.SELF_EDIT_NAME + + Rights.FLAGS.SEND_MESSAGES + + Rights.FLAGS.USE_ACTIVITIES + + Rights.FLAGS.USE_VIDEO + + Rights.FLAGS.USE_VOICE + + Rights.FLAGS.INVITE_USERS + + Rights.FLAGS.SELF_DELETE_DISABLE + + Rights.FLAGS.DEBTABLE + + Rights.FLAGS.KICK_BAN_MEMBERS + + Rights.FLAGS.SELF_LEAVE_GROUPS + + Rights.FLAGS.SELF_ADD_DISCOVERABLE + + Rights.FLAGS.USE_ACHIEVEMENTS + ).toString() }, login: { requireCaptcha: false, @@ -324,7 +353,7 @@ export const DefaultConfigOptions: ConfigValue = { // domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"), }, dateOfBirth: { - required: false, + required: true, minimum: 13, }, disabled: false, diff --git a/util/src/entities/Group.ts b/util/src/entities/Group.ts new file mode 100644
index 00000000..b24d38cf --- /dev/null +++ b/util/src/entities/Group.ts
@@ -0,0 +1,33 @@ +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; + +import { BaseClass } from "./BaseClass"; + +@Entity("groups") +export class UserGroup extends BaseClass { + @Column({ nullable: true }) + parent?: BigInt; + + @Column() + color: number; + + @Column() + hoist: boolean; + + @Column() + mentionable: boolean; + + @Column() + name: string; + + @Column() + rights: BigInt; + + @Column() + position: number; + + @Column({ nullable: true }) + icon: BigInt; + + @Column({ nullable: true }) + unicode_emoji: BigInt; +} diff --git a/util/src/entities/Message.ts b/util/src/entities/Message.ts
index b32bbd94..e18cf691 100644 --- a/util/src/entities/Message.ts +++ b/util/src/entities/Message.ts
@@ -39,13 +39,15 @@ export enum MessageType { USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 10, USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 11, CHANNEL_FOLLOW_ADD = 12, + ACTION = 13, // /me messages GUILD_DISCOVERY_DISQUALIFIED = 14, GUILD_DISCOVERY_REQUALIFIED = 15, ENCRYPTED = 16, REPLY = 19, - APPLICATION_COMMAND = 20, + APPLICATION_COMMAND = 20, // application command or self command invocation ROUTE_ADDED = 41, // custom message routing: new route affecting that channel ROUTE_DISABLED = 42, // custom message routing: given route no longer affecting that channel + SELF_COMMAND_SCRIPT = 43, // self command scripts ENCRYPTION = 50, CUSTOM_START = 63, UNHANDLED = 255 diff --git a/util/src/entities/User.ts b/util/src/entities/User.ts
index a5c4c136..49a7fbc6 100644 --- a/util/src/entities/User.ts +++ b/util/src/entities/User.ts
@@ -163,6 +163,10 @@ export class User extends BaseClass { @Column({ type: "simple-json", select: false }) settings: UserSettings; + + // workaround to prevent fossord-unaware clients from deleting settings not used by them + @Column({ type: "simple-json", select: false }) + extended_settings: string; @Column({ type: "simple-json" }) notes: { [key: string]: string }; //key is ID of user @@ -264,7 +268,7 @@ export class User extends BaseClass { disabled: false, deleted: false, email: email, - rights: "0", // TODO: grant rights correctly, as 0 actually stands for no rights at all + rights: Config.get().security.defaultRights, nsfw_allowed: true, // TODO: depending on age public_flags: "0", flags: "0", // TODO: generate @@ -273,6 +277,7 @@ export class User extends BaseClass { valid_tokens_since: new Date(), }, settings: { ...defaultSettings, locale: language }, + extended_settings: {}, fingerprints: [], notes: {}, }); diff --git a/util/src/entities/UserGroup.ts b/util/src/entities/UserGroup.ts new file mode 100644
index 00000000..709b9d0b --- /dev/null +++ b/util/src/entities/UserGroup.ts
@@ -0,0 +1,37 @@ +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; + +import { BaseClass } from "./BaseClass"; +import { Guild } from "./Guild"; +import { User } from "./User"; + +@Entity("groups") +export class UserGroup extends BaseClass { + @Column() + color: number; + + @Column() + hoist: boolean; + + @JoinColumn({ name: "controller", referencedColumnName: "id" }) + @ManyToOne(() => User) + controller?: User; + + @Column() + mentionable_by?: string; + + @Column() + name: string; + + @Column() + rights: string; + + @Column({ nullable: true }) + icon: string; + + @Column({ nullable: true }) + parent?: string; + + @Column({ type: "simple-array", nullable: true}) + associciations: string[]; + +} diff --git a/util/src/util/Constants.ts b/util/src/util/Constants.ts
index 8d61b9b4..81a7165d 100644 --- a/util/src/util/Constants.ts +++ b/util/src/util/Constants.ts
@@ -73,9 +73,13 @@ export const VoiceOPCodes = { HEARTBEAT: 3, SESSION_DESCRIPTION: 4, SPEAKING: 5, + HEARTBEAT_ACK: 6, + RESUME: 7, HELLO: 8, - CLIENT_CONNECT: 12, - CLIENT_DISCONNECT: 13, + RESUMED: 9, + CLIENT_CONNECT: 12, // incorrect, op 12 is probably used for video + CLIENT_DISCONNECT: 13, // incorrect + VERSION: 16, //not documented }; export const Events = { @@ -727,21 +731,23 @@ export const DiscordApiErrors = { * An error encountered while performing an API request (Fosscord only). Here are the potential errors: */ export const FosscordApiErrors = { - MANUALLY_TRIGGERED_ERROR: new ApiError("This is an artificial error", 1), + MANUALLY_TRIGGERED_ERROR: new ApiError("This is an artificial error", 1, 500), PREMIUM_DISABLED_FOR_GUILD: new ApiError("This guild cannot be boosted", 25001), NO_FURTHER_PREMIUM: new ApiError("This guild does not receive further boosts", 25002), - GUILD_PREMIUM_DISABLED_FOR_YOU: new ApiError("This guild cannot be boosted by you", 25003), + GUILD_PREMIUM_DISABLED_FOR_YOU: new ApiError("This guild cannot be boosted by you", 25003, 403), CANNOT_FRIEND_SELF: new ApiError("Cannot friend oneself", 25009), USER_SPECIFIC_INVITE_WRONG_RECIPIENT: new ApiError("This invite is not meant for you", 25010), USER_SPECIFIC_INVITE_FAILED: new ApiError("Failed to invite user", 25011), - CANNOT_MODIFY_USER_GROUP: new ApiError("This user cannot manipulate this group", 25050), + CANNOT_MODIFY_USER_GROUP: new ApiError("This user cannot manipulate this group", 25050, 403), CANNOT_REMOVE_SELF_FROM_GROUP: new ApiError("This user cannot remove oneself from user group", 25051), CANNOT_BAN_OPERATOR: new ApiError("Non-OPERATOR cannot ban OPERATOR from instance", 25052), - CANNOT_LEAVE_GUILD: new ApiError("You are not allowed to leave guilds that you joined by yourself", 25059), - EDITS_DISABLED: new ApiError("You are not allowed to edit your own messages", 25060), - DELETE_MESSAGE_DISABLED: new ApiError("You are not allowed to delete your own messages", 25061), - FEATURE_PERMANENTLY_DISABLED: new ApiError("This feature has been disabled server-side", 45006), + CANNOT_LEAVE_GUILD: new ApiError("You are not allowed to leave guilds that you joined by yourself", 25059, 403), + EDITS_DISABLED: new ApiError("You are not allowed to edit your own messages", 25060, 403), + DELETE_MESSAGE_DISABLED: new ApiError("You are not allowed to delete your own messages", 25061, 403), + FEATURE_PERMANENTLY_DISABLED: new ApiError("This feature has been disabled server-side", 45006, 501), MISSING_RIGHTS: new ApiError("You lack rights to perform that action ({})", 50013, undefined, [""]), + CANNOT_REPLACE_BY_BACKFILL: new ApiError("Cannot backfill to message ID that already exists", 55002, 409), + CANNOT_BACKFILL_TO_THE_FUTURE: new ApiError("You cannot backfill messages in the future", 55003), CANNOT_GRANT_PERMISSIONS_EXCEEDING_RIGHTS: new ApiError("You cannot grant permissions exceeding your own rights", 50050), ROUTES_LOOPING: new ApiError("Loops in the route definition ({})", 50060, undefined, [""]), CANNOT_REMOVE_ROUTE: new ApiError("Cannot remove message route while it is in effect and being used", 50061), @@ -787,3 +793,4 @@ function keyMirror(arr: string[]) { for (const value of arr) tmp[value] = value; return tmp; } + diff --git a/util/src/util/Email.ts b/util/src/util/Email.ts
index b1a7599b..6885da33 100644 --- a/util/src/util/Email.ts +++ b/util/src/util/Email.ts
@@ -13,7 +13,12 @@ export function adjustEmail(email?: string): string | undefined { // TODO: check accounts with uncommon email domains if (domain === "gmail.com" || domain === "googlemail.com") { // replace .dots and +alternatives -> Gmail Dot Trick https://support.google.com/mail/answer/7436150 and https://generator.email/blog/gmail-generator - return user.replace(/[.]|(\+.*)/g, "") + "@gmail.com"; + let v = user.replace(/[.]|(\+.*)/g, "") + "@gmail.com"; + } + + if (domain === "google.com") { + // replace .dots and +alternatives -> Google Staff GMail Dot Trick + let v = user.replace(/[.]|(\+.*)/g, "") + "@google.com"; } return email; diff --git a/util/src/util/Intents.ts b/util/src/util/Intents.ts
index 943b29cf..1e840b76 100644 --- a/util/src/util/Intents.ts +++ b/util/src/util/Intents.ts
@@ -2,20 +2,33 @@ import { BitField } from "./BitField"; export class Intents extends BitField { static FLAGS = { - GUILDS: BigInt(1) << BigInt(0), - GUILD_MEMBERS: BigInt(1) << BigInt(1), - GUILD_BANS: BigInt(1) << BigInt(2), - GUILD_EMOJIS: BigInt(1) << BigInt(3), - GUILD_INTEGRATIONS: BigInt(1) << BigInt(4), - GUILD_WEBHOOKS: BigInt(1) << BigInt(5), - GUILD_INVITES: BigInt(1) << BigInt(6), - GUILD_VOICE_STATES: BigInt(1) << BigInt(7), - GUILD_PRESENCES: BigInt(1) << BigInt(8), - GUILD_MESSAGES: BigInt(1) << BigInt(9), - GUILD_MESSAGE_REACTIONS: BigInt(1) << BigInt(10), - GUILD_MESSAGE_TYPING: BigInt(1) << BigInt(11), - DIRECT_MESSAGES: BigInt(1) << BigInt(12), - DIRECT_MESSAGE_REACTIONS: BigInt(1) << BigInt(13), - DIRECT_MESSAGE_TYPING: BigInt(1) << BigInt(14), + GUILDS: BigInt(1) << BigInt(0), // guilds and guild merge-split events affecting the user + GUILD_MEMBERS: BigInt(1) << BigInt(1), // memberships + GUILD_BANS: BigInt(1) << BigInt(2), // bans and ban lists + GUILD_EMOJIS: BigInt(1) << BigInt(3), // custom emojis + GUILD_INTEGRATIONS: BigInt(1) << BigInt(4), // applications + GUILD_WEBHOOKS: BigInt(1) << BigInt(5), // webhooks + GUILD_INVITES: BigInt(1) << BigInt(6), // mass invites (no user can receive user specific invites of another user) + GUILD_VOICE_STATES: BigInt(1) << BigInt(7), // voice updates + GUILD_PRESENCES: BigInt(1) << BigInt(8), // presence updates + GUILD_MESSAGES_METADATA: BigInt(1) << BigInt(9), // guild message metadata + GUILD_MESSAGE_REACTIONS: BigInt(1) << BigInt(10), // guild message reactions + GUILD_MESSAGE_TYPING: BigInt(1) << BigInt(11), // guild channel typing notifications + DIRECT_MESSAGES: BigInt(1) << BigInt(12), // DM or orphan channels + DIRECT_MESSAGE_REACTIONS: BigInt(1) << BigInt(13), // DM or orphan channel message reactions + DIRECT_MESSAGE_TYPING: BigInt(1) << BigInt(14), // DM typing notifications + GUILD_MESSAGES_CONTENT: BigInt(1) << BigInt(15), // guild message content + GUILD_POLICIES: BigInt(1) << BigInt(20), // guild policies + GUILD_POLICY_EXECUTION: BigInt(1) << BigInt(21), // guild policy execution + LIVE_MESSAGE_COMPOSITION: BigInt(1) << BigInt(32), // allow composing messages using the gateway + GUILD_ROUTES: BigInt(1) << BigInt(41), // message routes affecting the guild + DIRECT_MESSAGES_THREADS: BigInt(1) << BigInt(42), // direct message threads + JUMBO_EVENTS: BigInt(1) << BigInt(43), // jumbo events (size limits to be defined later) + LOBBIES: BigInt(1) << BigInt(44), // lobbies + INSTANCE_ROUTES: BigInt(1) << BigInt(60), // all message route changes + INSTANCE_GUILD_CHANGES: BigInt(1) << BigInt(61), // all guild create, guild object patch, split, merge and delete events + INSTANCE_POLICY_UPDATES: BigInt(1) << BigInt(62), // all instance policy updates + INSTANCE_USER_UPDATES: BigInt(1) << BigInt(63) // all instance user updates }; } + diff --git a/util/src/util/InvisibleCharacters.ts b/util/src/util/InvisibleCharacters.ts
index 2b014e14..a48cfab0 100644 --- a/util/src/util/InvisibleCharacters.ts +++ b/util/src/util/InvisibleCharacters.ts
@@ -1,7 +1,7 @@ // List from https://invisible-characters.com/ export const InvisibleCharacters = [ '\u{9}', //Tab - '\u{20}', //Space + //'\u{20}', //Space //categories can have spaces in them '\u{ad}', //Soft hyphen '\u{34f}', //Combining grapheme joiner '\u{61c}', //Arabic letter mark diff --git a/util/src/util/MessageFlags.ts b/util/src/util/MessageFlags.ts
index c76be4c8..b59295c4 100644 --- a/util/src/util/MessageFlags.ts +++ b/util/src/util/MessageFlags.ts
@@ -1,5 +1,5 @@ -// https://github.com/discordjs/discord.js/blob/master/src/util/MessageFlags.js -// Apache License Version 2.0 Copyright 2015 - 2021 Amish Shah +// based on https://github.com/discordjs/discord.js/blob/master/src/util/MessageFlags.js +// Apache License Version 2.0 Copyright 2015 - 2021 Amish Shah, 2022 Erkin Alp Güney import { BitField } from "./BitField"; @@ -8,7 +8,13 @@ export class MessageFlags extends BitField { CROSSPOSTED: BigInt(1) << BigInt(0), IS_CROSSPOST: BigInt(1) << BigInt(1), SUPPRESS_EMBEDS: BigInt(1) << BigInt(2), - SOURCE_MESSAGE_DELETED: BigInt(1) << BigInt(3), + // SOURCE_MESSAGE_DELETED: BigInt(1) << BigInt(3), // fosscord will delete them from destination too, making this redundant URGENT: BigInt(1) << BigInt(4), + // HAS_THREAD: BigInt(1) << BigInt(5) // does not apply to fosscord due to infrastructural differences + PRIVATE_ROUTE: BigInt(1) << BigInt(6), // it that has been routed to only some of the users that can see the channel + INTERACTION_WAIT: BigInt(1) << BigInt(7), // discord.com calls this LOADING + // FAILED_TO_MENTION_SOME_ROLES_IN_THREAD: BigInt(1) << BigInt(8) + SCRIPT_WAIT: BigInt(1) << BigInt(24), // waiting for the self command to complete + IMPORT_WAIT: BigInt(1) << BigInt(25), // latest message of a bulk import, waiting for the rest of the channel to be backfilled }; } diff --git a/util/src/util/Token.ts b/util/src/util/Token.ts
index 7c4cc61d..500ace45 100644 --- a/util/src/util/Token.ts +++ b/util/src/util/Token.ts
@@ -6,7 +6,12 @@ export const JWTOptions: VerifyOptions = { algorithms: ["HS256"] }; export function checkToken(token: string, jwtSecret: string): Promise<any> { return new Promise((res, rej) => { - token = token.replace("Bot ", ""); // TODO: proper bot support + token = token.replace("Bot ", ""); + /** + in fosscord, even with instances that have bot distinction; we won't enforce "Bot" prefix, + as we don't really have separate pathways for bots + **/ + jwt.verify(token, jwtSecret, JWTOptions, async (err, decoded: any) => { if (err || !decoded) return rej("Invalid Token"); diff --git a/webrtc/.vscode/launch.json b/webrtc/.vscode/launch.json new file mode 100644
index 00000000..49584172 --- /dev/null +++ b/webrtc/.vscode/launch.json
@@ -0,0 +1,25 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "ts-node", + "type": "node", + "request": "launch", + "args": [ + "src/start.ts" + ], + "runtimeArgs": [ + "-r", + "ts-node/register" + ], + "cwd": "${workspaceRoot}", + "protocol": "inspector", + "internalConsoleOptions": "openOnSessionStart", + "sourceMaps": true, + "resolveSourceMapLocations": null, + } + ] +} \ No newline at end of file diff --git a/webrtc/LICENSE b/webrtc/LICENSE deleted file mode 100644
index f19bf520..00000000 --- a/webrtc/LICENSE +++ /dev/null
@@ -1,14 +0,0 @@ -Copyright (C) 2021 Fosscord and contributors - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see <https://www.gnu.org/licenses/>. \ No newline at end of file diff --git a/webrtc/package-lock.json b/webrtc/package-lock.json
index a5db2de1..afba7e76 100644 --- a/webrtc/package-lock.json +++ b/webrtc/package-lock.json
@@ -9,22 +9,83 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "mediasoup": "^3.7.16", + "dotenv": "^12.0.4", + "mediasoup": "^3.9.5", "node-turn": "^0.0.6", + "sdp-transform": "^2.14.1", + "tsconfig-paths": "^3.12.0", "ws": "^7.4.6" }, "devDependencies": { "@types/node": "^15.6.1", + "@types/sdp-transform": "^2.4.5", "@types/ws": "^7.4.4", + "ts-node": "^10.4.0", "typescript": "^4.3.2" } }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" + }, "node_modules/@types/node": { "version": "15.6.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-15.6.1.tgz", "integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==", "dev": true }, + "node_modules/@types/sdp-transform": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@types/sdp-transform/-/sdp-transform-2.4.5.tgz", + "integrity": "sha512-GVO0gnmbyO3Oxm2HdPsYUNcyihZE3GyCY8ysMYHuQGfLhGZq89Nm4lSzULWTzZoyHtg+VO/IdrnxZHPnPSGnAg==", + "dev": true + }, "node_modules/@types/ws": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.4.tgz", @@ -34,6 +95,33 @@ "@types/node": "*" } }, + "node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -42,14 +130,6 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/awaitqueue": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/awaitqueue/-/awaitqueue-2.3.3.tgz", - "integrity": "sha512-RbzQg6VtPUtyErm55iuQLTrBJ2uihy5BKBOEkyBwv67xm5Fn2o/j+Bz+a5BmfSoe2oZ5dcz9Z3fExS8pL+LLhw==", - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -100,6 +180,12 @@ "buffer": "^5.1.0" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "node_modules/date-format": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", @@ -108,6 +194,39 @@ "node": ">=4.0" } }, + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-12.0.4.tgz", + "integrity": "sha512-oWdqbSywffzH1l4WXKPHWA0TWYpqp7IyLfqjipT4upoIFS0HPMqtNotykQpD4iIg0BqtNmdgPCh2WMvMt7yTiw==", + "engines": { + "node": ">=12" + } + }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -154,35 +273,6 @@ "node": ">=8.0.0" } }, - "node_modules/h264-profile-level-id/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/h264-profile-level-id/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -214,6 +304,17 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -237,44 +338,27 @@ "node": ">=8.0" } }, - "node_modules/log4js/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/log4js/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "node_modules/mediasoup": { - "version": "3.7.16", - "resolved": "https://registry.npmjs.org/mediasoup/-/mediasoup-3.7.16.tgz", - "integrity": "sha512-eD7VJj117zVYF8f4KYgQh2DzaYyzTvBtNa4ocT45eCjt0Y47dveKmfL5LW0LQL1LMYkBhfx/etHLjE/1AhNmwg==", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/mediasoup/-/mediasoup-3.9.5.tgz", + "integrity": "sha512-8lISnN5cbtSvdqHeuyxhCTFTHudoq/EpgLcDB0d0pT5RG18mZlHF5BwIBSkGxB/nWyeTfTGPpGBiNtKoubbRXA==", "hasInstallScript": true, "dependencies": { - "@types/node": "^14.14.43", - "awaitqueue": "^2.3.3", - "debug": "^4.3.1", + "@types/node": "^16.11.10", + "debug": "^4.3.3", "h264-profile-level-id": "^1.0.1", - "netstring": "^0.3.0", "random-number": "^0.0.9", - "supports-color": "^8.1.1", + "supports-color": "^9.2.1", "uuid": "^8.3.2" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "type": "opencollective", @@ -282,39 +366,20 @@ } }, "node_modules/mediasoup/node_modules/@types/node": { - "version": "14.17.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.3.tgz", - "integrity": "sha512-e6ZowgGJmTuXa3GyaPbTGxX17tnThl2aSSizrFthQ7m9uLGZBXiGhgE55cjRZTF5kjZvYn9EOPOMljdjwbflxw==" - }, - "node_modules/mediasoup/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } + "version": "16.11.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.19.tgz", + "integrity": "sha512-BPAcfDPoHlRQNKktbsbnpACGdypPFBuX4xQlsWDE7B8XXcfII+SpOLay3/qZmCLb39kV5S1RTYwXdkx2lwLYng==" }, - "node_modules/mediasoup/node_modules/ms": { + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/netstring": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/netstring/-/netstring-0.3.0.tgz", - "integrity": "sha1-ho3FsgxY0/cwVTHUk2jqqr0ZtxI=", - "engines": { - "node": ">=0.6" - } - }, "node_modules/node-turn": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/node-turn/-/node-turn-0.0.6.tgz", @@ -335,6 +400,14 @@ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" }, + "node_modules/sdp-transform": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.1.tgz", + "integrity": "sha512-RjZyX3nVwJyCuTo5tGPx+PZWkDMCg7oOLpSlhjDdZfwUoNqG1mM8nyj31IGHyaPWXhjbP7cdK3qZ2bmkJ1GzRw==", + "bin": { + "sdp-verify": "checker.js" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -361,39 +434,75 @@ "node": ">=4.0" } }, - "node_modules/streamroller/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-color": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.1.tgz", + "integrity": "sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ts-node": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "dev": true, "dependencies": { - "ms": "2.1.2" + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" }, - "engines": { - "node": ">=6.0" + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" }, "peerDependenciesMeta": { - "supports-color": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { "optional": true } } }, - "node_modules/streamroller/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/tsconfig-paths": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" } }, "node_modules/typescript": { @@ -444,15 +553,74 @@ "optional": true } } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } } }, "dependencies": { + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" + }, "@types/node": { "version": "15.6.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-15.6.1.tgz", "integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==", "dev": true }, + "@types/sdp-transform": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@types/sdp-transform/-/sdp-transform-2.4.5.tgz", + "integrity": "sha512-GVO0gnmbyO3Oxm2HdPsYUNcyihZE3GyCY8ysMYHuQGfLhGZq89Nm4lSzULWTzZoyHtg+VO/IdrnxZHPnPSGnAg==", + "dev": true + }, "@types/ws": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.4.tgz", @@ -462,6 +630,24 @@ "@types/node": "*" } }, + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -470,11 +656,6 @@ "sprintf-js": "~1.0.2" } }, - "awaitqueue": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/awaitqueue/-/awaitqueue-2.3.3.tgz", - "integrity": "sha512-RbzQg6VtPUtyErm55iuQLTrBJ2uihy5BKBOEkyBwv67xm5Fn2o/j+Bz+a5BmfSoe2oZ5dcz9Z3fExS8pL+LLhw==" - }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -497,11 +678,36 @@ "buffer": "^5.1.0" } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "date-format": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==" }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "requires": { + "ms": "2.1.2" + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "dotenv": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-12.0.4.tgz", + "integrity": "sha512-oWdqbSywffzH1l4WXKPHWA0TWYpqp7IyLfqjipT4upoIFS0HPMqtNotykQpD4iIg0BqtNmdgPCh2WMvMt7yTiw==" + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -533,28 +739,8 @@ "integrity": "sha512-D3Rln/jKNjKDW5ZTJTK3niSoOGE+pFqPvRHHVgQN3G7umcn/zWGPUo8Q8VpDj16x3hKz++zVviRNRmXu5cpN+Q==", "requires": { "debug": "^4.1.1" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -569,6 +755,14 @@ "esprima": "^4.0.0" } }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -587,62 +781,43 @@ "flatted": "^2.0.1", "rfdc": "^1.1.4", "streamroller": "^2.2.4" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "mediasoup": { - "version": "3.7.16", - "resolved": "https://registry.npmjs.org/mediasoup/-/mediasoup-3.7.16.tgz", - "integrity": "sha512-eD7VJj117zVYF8f4KYgQh2DzaYyzTvBtNa4ocT45eCjt0Y47dveKmfL5LW0LQL1LMYkBhfx/etHLjE/1AhNmwg==", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/mediasoup/-/mediasoup-3.9.5.tgz", + "integrity": "sha512-8lISnN5cbtSvdqHeuyxhCTFTHudoq/EpgLcDB0d0pT5RG18mZlHF5BwIBSkGxB/nWyeTfTGPpGBiNtKoubbRXA==", "requires": { - "@types/node": "^14.14.43", - "awaitqueue": "^2.3.3", - "debug": "^4.3.1", + "@types/node": "^16.11.10", + "debug": "^4.3.3", "h264-profile-level-id": "^1.0.1", - "netstring": "^0.3.0", "random-number": "^0.0.9", - "supports-color": "^8.1.1", + "supports-color": "^9.2.1", "uuid": "^8.3.2" }, "dependencies": { "@types/node": { - "version": "14.17.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.3.tgz", - "integrity": "sha512-e6ZowgGJmTuXa3GyaPbTGxX17tnThl2aSSizrFthQ7m9uLGZBXiGhgE55cjRZTF5kjZvYn9EOPOMljdjwbflxw==" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "16.11.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.19.tgz", + "integrity": "sha512-BPAcfDPoHlRQNKktbsbnpACGdypPFBuX4xQlsWDE7B8XXcfII+SpOLay3/qZmCLb39kV5S1RTYwXdkx2lwLYng==" } } }, - "netstring": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/netstring/-/netstring-0.3.0.tgz", - "integrity": "sha1-ho3FsgxY0/cwVTHUk2jqqr0ZtxI=" + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node-turn": { "version": "0.0.6", @@ -664,6 +839,11 @@ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" }, + "sdp-transform": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/sdp-transform/-/sdp-transform-2.14.1.tgz", + "integrity": "sha512-RjZyX3nVwJyCuTo5tGPx+PZWkDMCg7oOLpSlhjDdZfwUoNqG1mM8nyj31IGHyaPWXhjbP7cdK3qZ2bmkJ1GzRw==" + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -683,28 +863,48 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.1.tgz", + "integrity": "sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ==" + }, + "ts-node": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "dev": true, "requires": { - "has-flag": "^4.0.0" + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + } + }, + "tsconfig-paths": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" } }, "typescript": { @@ -728,6 +928,12 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", "requires": {} + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/webrtc/package.json b/webrtc/package.json
index 0f700728..2a4705ab 100644 --- a/webrtc/package.json +++ b/webrtc/package.json
@@ -9,16 +9,21 @@ "start": "npm run build && node dist/start.js" }, "keywords": [], - "author": "", - "license": "ISC", + "author": "Fosscord", + "license": "AGPLV3", "devDependencies": { "@types/node": "^15.6.1", + "@types/sdp-transform": "^2.4.5", "@types/ws": "^7.4.4", + "ts-node": "^10.4.0", "typescript": "^4.3.2" }, "dependencies": { - "mediasoup": "^3.7.16", + "dotenv": "^12.0.4", + "mediasoup": "^3.9.5", "node-turn": "^0.0.6", + "sdp-transform": "^2.14.1", + "tsconfig-paths": "^3.12.0", "ws": "^7.4.6" } } diff --git a/webrtc/src/Server.ts b/webrtc/src/Server.ts
index 6591691c..42b82c6a 100644 --- a/webrtc/src/Server.ts +++ b/webrtc/src/Server.ts
@@ -1,46 +1,125 @@ import { Server as WebSocketServer } from "ws"; -import { Config, db } from "@fosscord/util"; -import mediasoup from "mediasoup"; +import { WebSocket, CLOSECODES } from "@fosscord/gateway"; +import { Config, initDatabase } from "@fosscord/util"; +import OPCodeHandlers, { Payload } from "./opcodes"; +import { setHeartbeat } from "./util"; +import * as mediasoup from "mediasoup"; +import { types as MediasoupTypes } from "mediasoup"; + +import udp from "dgram"; var port = Number(process.env.PORT); if (isNaN(port)) port = 3004; export class Server { public ws: WebSocketServer; - public turn: any; + public mediasoupWorkers: MediasoupTypes.Worker[] = []; + public mediasoupRouters: MediasoupTypes.Router[] = []; + public mediasoupTransports: MediasoupTypes.WebRtcTransport[] = []; + public mediasoupProducers: MediasoupTypes.Producer[] = []; + public mediasoupConsumers: MediasoupTypes.Consumer[] = []; constructor() { this.ws = new WebSocketServer({ port, maxPayload: 4096, }); - this.ws.on("connection", (socket) => { - socket.on("message", (message) => { - socket.emit( - JSON.stringify({ - op: 2, - d: { - ssrc: 1, - ip: "127.0.0.1", - port: 3004, - modes: [ - "xsalsa20_poly1305", - "xsalsa20_poly1305_suffix", - "xsalsa20_poly1305_lite", - ], - heartbeat_interval: 1, - }, - }) - ); + this.ws.on("connection", async (socket: WebSocket) => { + await setHeartbeat(socket); + + socket.on("message", async (message: string) => { + const payload: Payload = JSON.parse(message); + + if (OPCodeHandlers[payload.op]) + try { + await OPCodeHandlers[payload.op].call(this, socket, payload); + } + catch (e) { + console.error(e); + socket.close(CLOSECODES.Unknown_error); + } + else { + console.error(`Unimplemented`, payload); + socket.close(CLOSECODES.Unknown_opcode); + } }); }); + } async listen(): Promise<void> { // @ts-ignore - await (db as Promise<Connection>); + await initDatabase(); await Config.init(); + await this.createWorkers(); console.log("[DB] connected"); console.log(`[WebRTC] online on 0.0.0.0:${port}`); } + + async createWorkers(): Promise<void> { + const numWorkers = 1; + for (let i = 0; i < numWorkers; i++) { + const worker = await mediasoup.createWorker({ logLevel: "debug" }); + if (!worker) return; + + worker.on("died", () => { + console.error("mediasoup worker died"); + }); + + worker.observer.on("newrouter", async (router: MediasoupTypes.Router) => { + console.log("new router created [id:%s]", router.id); + + this.mediasoupRouters.push(router); + + router.observer.on("newtransport", async (transport: MediasoupTypes.WebRtcTransport) => { + console.log("new transport created [id:%s]", transport.id); + + await transport.enableTraceEvent(); + + transport.on("connect", () => { + console.log("transport connect") + }) + + transport.observer.on("newproducer", (producer: MediasoupTypes.Producer) => { + console.log("new producer created [id:%s]", producer.id); + + this.mediasoupProducers.push(producer); + }); + + transport.observer.on("newconsumer", (consumer: MediasoupTypes.Consumer) => { + console.log("new consumer created [id:%s]", consumer.id); + + this.mediasoupConsumers.push(consumer); + + consumer.on("rtp", (rtpPacket) => { + console.log(rtpPacket); + }); + }); + + transport.observer.on("newdataproducer", (dataProducer) => { + console.log("new data producer created [id:%s]", dataProducer.id); + }); + + transport.on("trace", (trace) => { + console.log(trace); + }); + + this.mediasoupTransports.push(transport); + }); + }); + + await worker.createRouter({ + mediaCodecs: [ + { + kind: "audio", + mimeType: "audio/opus", + clockRate: 48000, + channels: 2 + }, + ] + }); + + this.mediasoupWorkers.push(worker); + } + } } diff --git a/webrtc/src/opcodes/Connect.ts b/webrtc/src/opcodes/Connect.ts new file mode 100644
index 00000000..1f874a44 --- /dev/null +++ b/webrtc/src/opcodes/Connect.ts
@@ -0,0 +1,40 @@ +import { WebSocket } from "@fosscord/gateway"; +import { Payload } from "./index"; +import { Server } from "../Server" + +/* +Sent by client: + +{ + "op": 12, + "d": { + "audio_ssrc": 0, + "video_ssrc": 0, + "rtx_ssrc": 0, + "streams": [ + { + "type": "video", + "rid": "100", + "ssrc": 0, + "active": false, + "quality": 100, + "rtx_ssrc": 0, + "max_bitrate": 2500000, + "max_framerate": 20, + "max_resolution": { + "type": "fixed", + "width": 1280, + "height": 720 + } + } + ] + } +} +*/ + +export async function onConnect(this: Server, socket: WebSocket, data: Payload) { + socket.send(JSON.stringify({ //what is op 15? + op: 15, + d: { any: 100 } + })) +} \ No newline at end of file diff --git a/webrtc/src/opcodes/Heartbeat.ts b/webrtc/src/opcodes/Heartbeat.ts new file mode 100644
index 00000000..47f33f76 --- /dev/null +++ b/webrtc/src/opcodes/Heartbeat.ts
@@ -0,0 +1,8 @@ +import { WebSocket } from "@fosscord/gateway"; +import { Payload } from "./index"; +import { setHeartbeat } from "../util"; +import { Server } from "../Server" + +export async function onHeartbeat(this: Server, socket: WebSocket, data: Payload) { + await setHeartbeat(socket, data.d); +} \ No newline at end of file diff --git a/webrtc/src/opcodes/Identify.ts b/webrtc/src/opcodes/Identify.ts new file mode 100644
index 00000000..9baa16e3 --- /dev/null +++ b/webrtc/src/opcodes/Identify.ts
@@ -0,0 +1,66 @@ +import { WebSocket, CLOSECODES } from "@fosscord/gateway"; +import { Payload } from "./index"; +import { VoiceOPCodes, Session, User, Guild } from "@fosscord/util"; +import { Server } from "../Server"; + +export interface IdentifyPayload extends Payload { + d: { + server_id: string, //guild id + session_id: string, //gateway session + streams: Array<{ + type: string, + rid: string, //number + quality: number, + }>, + token: string, //voice_states token + user_id: string, + video: boolean, + }; +} + +export async function onIdentify(this: Server, socket: WebSocket, data: IdentifyPayload) { + + const session = await Session.findOneOrFail( + { session_id: data.d.session_id, }, + { + where: { user_id: data.d.user_id }, + relations: ["user"] + } + ); + const user = session.user; + const guild = await Guild.findOneOrFail({ id: data.d.server_id }, { relations: ["members"] }); + + if (!guild.members.find(x => x.id === user.id)) + return socket.close(CLOSECODES.Invalid_intent); + + var transport = this.mediasoupTransports[0] || await this.mediasoupRouters[0].createWebRtcTransport({ + listenIps: [{ ip: "10.22.64.69" }], + enableUdp: true, + enableTcp: true, + preferUdp: true, + enableSctp: true, + }); + + socket.send(JSON.stringify({ + op: VoiceOPCodes.READY, + d: { + streams: [...data.d.streams.map(x => ({ ...x, rtx_ssrc: Math.floor(Math.random() * 10000), ssrc: Math.floor(Math.random() * 10000), active: false, }))], + ssrc: Math.floor(Math.random() * 10000), + ip: transport.iceCandidates[0].ip, + port: transport.iceCandidates[0].port, + modes: [ + "aead_aes256_gcm_rtpsize", + "aead_aes256_gcm", + "xsalsa20_poly1305_lite_rtpsize", + "xsalsa20_poly1305_lite", + "xsalsa20_poly1305_suffix", + "xsalsa20_poly1305" + ], + experiments: [ + "bwe_conservative_link_estimate", + "bwe_remote_locus_client", + "fixed_keyframe_interval" + ] + }, + })); +} \ No newline at end of file diff --git a/webrtc/src/opcodes/Resume.ts b/webrtc/src/opcodes/Resume.ts new file mode 100644
index 00000000..856b550c --- /dev/null +++ b/webrtc/src/opcodes/Resume.ts
@@ -0,0 +1,24 @@ +import { CLOSECODES, WebSocket } from "@fosscord/gateway"; +import { Payload } from "./index"; +import { Server } from "../Server" +import { Guild, Session, VoiceOPCodes } from "@fosscord/util"; + +export async function onResume(this: Server, socket: WebSocket, data: Payload) { + const session = await Session.findOneOrFail( + { session_id: data.d.session_id, }, + { + where: { user_id: data.d.user_id }, + relations: ["user"] + } + ); + const user = session.user; + const guild = await Guild.findOneOrFail({ id: data.d.server_id }, { relations: ["members"] }); + + if (!guild.members.find(x => x.id === user.id)) + return socket.close(CLOSECODES.Invalid_intent); + + socket.send(JSON.stringify({ + op: VoiceOPCodes.RESUMED, + d: null, + })) +} \ No newline at end of file diff --git a/webrtc/src/opcodes/SelectProtocol.ts b/webrtc/src/opcodes/SelectProtocol.ts new file mode 100644
index 00000000..dc9d2b88 --- /dev/null +++ b/webrtc/src/opcodes/SelectProtocol.ts
@@ -0,0 +1,150 @@ +import { WebSocket } from "@fosscord/gateway"; +import { Payload } from "./index"; +import { VoiceOPCodes } from "@fosscord/util"; +import { Server } from "../Server"; +import * as mediasoup from "mediasoup"; +import { RtpCodecCapability } from "mediasoup/node/lib/RtpParameters"; +import * as sdpTransform from 'sdp-transform'; + + +/* + + Sent by client: +{ + "op": 1, + "d": { + "protocol": "webrtc", + "data": " + a=extmap-allow-mixed + a=ice-ufrag:vNxb + a=ice-pwd:tZvpbVPYEKcnW0gGRPq0OOnh + a=ice-options:trickle + a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level + a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time + a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 + a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid + a=rtpmap:111 opus/48000/2 + a=extmap:14 urn:ietf:params:rtp-hdrext:toffset + a=extmap:13 urn:3gpp:video-orientation + a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay + a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type + a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing + a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space + a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id + a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id + a=rtpmap:96 VP8/90000 + a=rtpmap:97 rtx/90000 + ", + "codecs": [ + { + "name": "opus", + "type": "audio", + "priority": 1000, + "payload_type": 111, + "rtx_payload_type": null + }, + { + "name": "H264", + "type": "video", + "priority": 1000, + "payload_type": 102, + "rtx_payload_type": 121 + }, + { + "name": "VP8", + "type": "video", + "priority": 2000, + "payload_type": 96, + "rtx_payload_type": 97 + }, + { + "name": "VP9", + "type": "video", + "priority": 3000, + "payload_type": 98, + "rtx_payload_type": 99 + } + ], + "rtc_connection_id": "3faa0b80-b3e2-4bae-b291-273801fbb7ab" + } +} + +Sent by server: + +{ + "op": 4, + "d": { + "video_codec": "H264", + "sdp": " + m=audio 50001 ICE/SDP + a=fingerprint:sha-256 4A:79:94:16:44:3F:BD:05:41:5A:C7:20:F3:12:54:70:00:73:5D:33:00:2D:2C:80:9B:39:E1:9F:2D:A7:49:87 + c=IN IP4 109.200.214.158 + a=rtcp:50001 + a=ice-ufrag:CLzn + a=ice-pwd:qEmIcNwigd07mu46Ok0XCh + a=fingerprint:sha-256 4A:79:94:16:44:3F:BD:05:41:5A:C7:20:F3:12:54:70:00:73:5D:33:00:2D:2C:80:9B:39:E1:9F:2D:A7:49:87 + a=candidate:1 1 UDP 4261412862 109.200.214.158 50001 typ host + ", + "media_session_id": "807955cb953e98c5b90704cf048e81ec", + "audio_codec": "opus" + } +} + +*/ + + +export async function onSelectProtocol(this: Server, socket: WebSocket, data: Payload) { + const rtpCapabilities = this.mediasoupRouters[0].rtpCapabilities; + const codecs = rtpCapabilities.codecs as RtpCodecCapability[]; + + const transport = this.mediasoupTransports[0]; //whatever + + const res = sdpTransform.parse(data.d.sdp); + + const videoCodec = this.mediasoupRouters[0].rtpCapabilities.codecs!.find((x: any) => x.kind === "video"); + const audioCodec = this.mediasoupRouters[0].rtpCapabilities.codecs!.find((x: any) => x.kind === "audio"); + + const producer = this.mediasoupProducers[0] || await transport.produce({ + kind: "audio", + rtpParameters: { + mid: "audio", + codecs: [{ + clockRate: audioCodec!.clockRate, + payloadType: audioCodec!.preferredPayloadType as number, + mimeType: audioCodec!.mimeType, + channels: audioCodec?.channels, + }], + headerExtensions: res.ext?.map(x => ({ + id: x.value, + uri: x.uri, + })), + }, + paused: false, + }); + + console.log("can consume: " + this.mediasoupRouters[0].canConsume({ producerId: producer.id, rtpCapabilities: rtpCapabilities })); + + const consumer = this.mediasoupConsumers[0] || await transport.consume({ + producerId: producer.id, + paused: false, + rtpCapabilities, + }); + + socket.send(JSON.stringify({ + op: VoiceOPCodes.SESSION_DESCRIPTION, + d: { + video_codec: videoCodec?.mimeType?.substring(6) || undefined, + mode: "xsalsa20_poly1305_lite", + media_session_id: transport.id, + audio_codec: audioCodec?.mimeType.substring(6), + sdp: `m=audio ${transport.iceCandidates[0].port} ICE/SDP\n` + + `a=fingerprint:sha-256 ${transport.dtlsParameters.fingerprints.find(x => x.algorithm === "sha-256")?.value}\n` + + `c=IN IPV4 ${transport.iceCandidates[0].ip}\n` + + `a=rtcp: ${transport.iceCandidates[0].port}\n` + + `a=ice-ufrag:${transport.iceParameters.usernameFragment}\n` + + `a=ice-pwd:${transport.iceParameters.password}\n` + + `a=fingerprint:sha-1 ${transport.dtlsParameters.fingerprints[0].value}\n` + + `a=candidate:1 1 ${transport.iceCandidates[0].protocol} ${transport.iceCandidates[0].priority} ${transport.iceCandidates[0].ip} ${transport.iceCandidates[0].port} typ ${transport.iceCandidates[0].type}` + } + })); +} \ No newline at end of file diff --git a/webrtc/src/opcodes/Speaking.ts b/webrtc/src/opcodes/Speaking.ts new file mode 100644
index 00000000..861a7c3d --- /dev/null +++ b/webrtc/src/opcodes/Speaking.ts
@@ -0,0 +1,7 @@ +import { WebSocket } from "@fosscord/gateway"; +import { Payload } from "./index" +import { VoiceOPCodes } from "@fosscord/util"; +import { Server } from "../Server" + +export async function onSpeaking(this: Server, socket: WebSocket, data: Payload) { +} \ No newline at end of file diff --git a/webrtc/src/opcodes/Version.ts b/webrtc/src/opcodes/Version.ts new file mode 100644
index 00000000..0ea6eb4d --- /dev/null +++ b/webrtc/src/opcodes/Version.ts
@@ -0,0 +1,14 @@ +import { WebSocket } from "@fosscord/gateway"; +import { Payload } from "./index"; +import { setHeartbeat } from "../util"; +import { Server } from "../Server" + +export async function onVersion(this: Server, socket: WebSocket, data: Payload) { + socket.send(JSON.stringify({ + op: 16, + d: { + voice: "0.8.31", //version numbers? + rtc_worker: "0.3.18", + } + })) +} \ No newline at end of file diff --git a/webrtc/src/opcodes/index.ts b/webrtc/src/opcodes/index.ts new file mode 100644
index 00000000..d0f40bc2 --- /dev/null +++ b/webrtc/src/opcodes/index.ts
@@ -0,0 +1,40 @@ +import { WebSocket } from "@fosscord/gateway"; +import { VoiceOPCodes } from "@fosscord/util"; + +export interface Payload { + op: number; + d: any; + s: number; + t: string; +} + +import { onIdentify } from "./Identify"; +import { onSelectProtocol } from "./SelectProtocol"; +import { onHeartbeat } from "./Heartbeat"; +import { onSpeaking } from "./Speaking"; +import { onResume } from "./Resume"; +import { onConnect } from "./Connect"; + +import { onVersion } from "./Version"; + +export type OPCodeHandler = (this: WebSocket, data: Payload) => any; + +export default { + [VoiceOPCodes.IDENTIFY]: onIdentify, //op 0 + [VoiceOPCodes.SELECT_PROTOCOL]: onSelectProtocol, //op 1 + //op 2 voice_ready + [VoiceOPCodes.HEARTBEAT]: onHeartbeat, //op 3 + //op 4 session_description + [VoiceOPCodes.SPEAKING]: onSpeaking, //op 5 + //op 6 heartbeat_ack + [VoiceOPCodes.RESUME]: onResume, //op 7 + //op 8 hello + //op 9 resumed + //op 10? + //op 11? + [VoiceOPCodes.CLIENT_CONNECT]: onConnect, //op 12 + //op 13? + //op 15? + //op 16? empty data on client send but server sends {"voice":"0.8.24+bugfix.voice.streams.opt.branch-ffcefaff7","rtc_worker":"0.3.14-crypto-collision-copy"} + [VoiceOPCodes.VERSION]: onVersion, +}; \ No newline at end of file diff --git a/webrtc/src/start.ts b/webrtc/src/start.ts
index 68867a2c..98f06ad5 100644 --- a/webrtc/src/start.ts +++ b/webrtc/src/start.ts
@@ -1,3 +1,10 @@ +//testing +process.env.DATABASE = "../bundle/database.db"; + +import { config } from "dotenv"; +config(); + import { Server } from "./Server"; const server = new Server(); +server.listen(); \ No newline at end of file diff --git a/webrtc/src/util/Heartbeat.ts b/webrtc/src/util/Heartbeat.ts new file mode 100644
index 00000000..8c5e3a7a --- /dev/null +++ b/webrtc/src/util/Heartbeat.ts
@@ -0,0 +1,23 @@ +import { WebSocket, CLOSECODES } from "@fosscord/gateway"; +import { VoiceOPCodes } from "@fosscord/util"; + +export async function setHeartbeat(socket: WebSocket, nonce?: Number) { + if (socket.heartbeatTimeout) clearTimeout(socket.heartbeatTimeout); + + socket.heartbeatTimeout = setTimeout(() => { + return socket.close(CLOSECODES.Session_timed_out); + }, 1000 * 45); + + if (!nonce) { + socket.send(JSON.stringify({ + op: VoiceOPCodes.HELLO, + d: { + v: 5, + heartbeat_interval: 13750, + } + })); + } + else { + socket.send(JSON.stringify({ op: VoiceOPCodes.HEARTBEAT_ACK, d: nonce })); + } +} \ No newline at end of file diff --git a/webrtc/src/util/index.ts b/webrtc/src/util/index.ts new file mode 100644
index 00000000..e8557452 --- /dev/null +++ b/webrtc/src/util/index.ts
@@ -0,0 +1 @@ +export * from "./Heartbeat" \ No newline at end of file diff --git a/webrtc/tsconfig.json b/webrtc/tsconfig.json
index 77353db0..fb93b0bd 100644 --- a/webrtc/tsconfig.json +++ b/webrtc/tsconfig.json
@@ -1,5 +1,8 @@ { "include": ["src/**/*.ts"], + "ts-node": { + "require": ["tsconfig-paths/register"], + }, "compilerOptions": { /* Visit https://aka.ms/tsconfig.json to read more about this file */ @@ -18,7 +21,7 @@ "sourceMap": true /* Generates corresponding '.map' file. */, // "outFile": "./", /* Concatenate and emit output to single file. */ "outDir": "./dist/" /* Redirect output structure to the directory. */, - "rootDir": "./src/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, + "rootDir": "../" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, // "composite": true, /* Enable project compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ // "removeComments": true, /* Do not emit comments to output. */ @@ -62,11 +65,19 @@ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Advanced Options */ "skipLibCheck": true /* Skip type checking of declaration files. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ + + "baseUrl": "../", + "paths": { + "@fosscord/api": ["api/src/index"], + "@fosscord/gateway": ["gateway/src/index"], + "@fosscord/cdn": ["cdn/src/index"], + "@fosscord/util": ["util/src/index"] + }, } }