diff --git a/assets/schemas.json b/assets/schemas.json index f0b47515f..e545acb8a 100644 Binary files a/assets/schemas.json and b/assets/schemas.json differ diff --git a/package-lock.json b/package-lock.json index 490bc4420..fd43bef51 100644 Binary files a/package-lock.json and b/package-lock.json differ diff --git a/package.json b/package.json index 57f4600be..8a7374246 100644 --- a/package.json +++ b/package.json @@ -72,15 +72,16 @@ "sqlite3": "^5.1.1", "typeorm": "^0.3.10", "typescript-json-schema": "^0.50.1", - "ws": "^8.9.0" - }, - "optionalDependencies": { + "ws": "^8.9.0", + "@aws-sdk/client-s3": "^3.178.0", "@sentry/node": "^7.13.0", "@sentry/tracing": "^7.13.0", - "@yukikaze-bot/erlpack": "^1.0.1", "amqplib": "^0.10.3" }, + "optionalDependencies": { + "@yukikaze-bot/erlpack": "^1.0.1" + }, "_moduleAliases": { "@fosscord/api": "dist/api", "@fosscord/cdn": "dist/cdn", diff --git a/scripts/schema.js b/scripts/schema.js index 01dd21467..de062d637 100644 --- a/scripts/schema.js +++ b/scripts/schema.js @@ -3,7 +3,6 @@ const path = require("path"); const fs = require("fs"); const TJS = require("typescript-json-schema"); -require("missing-native-js-functions"); const schemaPath = path.join(__dirname, "..", "assets", "schemas.json"); const settings = { diff --git a/src/api/routes/auth/login.ts b/src/api/routes/auth/login.ts index bcaccb307..9bed5aabc 100644 --- a/src/api/routes/auth/login.ts +++ b/src/api/routes/auth/login.ts @@ -1,21 +1,12 @@ import { Request, Response, Router } from "express"; import { route, getIpAdress, verifyCaptcha } from "@fosscord/api"; import bcrypt from "bcrypt"; -import { Config, User, generateToken, adjustEmail, FieldErrors } from "@fosscord/util"; +import { Config, User, generateToken, adjustEmail, FieldErrors, LoginSchema } from "@fosscord/util"; import crypto from "crypto"; const router: Router = Router(); export default router; -export interface LoginSchema { - login: string; - password: string; - undelete?: boolean; - captcha_key?: string; - login_source?: string; - gift_code_sku_id?: string; -} - router.post("/", route({ body: "LoginSchema" }), async (req: Request, res: Response) => { const { login, password, captcha_key, undelete } = req.body as LoginSchema; const email = adjustEmail(login); diff --git a/src/api/routes/auth/mfa/totp.ts b/src/api/routes/auth/mfa/totp.ts index 50b9e9c84..96a48b661 100644 --- a/src/api/routes/auth/mfa/totp.ts +++ b/src/api/routes/auth/mfa/totp.ts @@ -1,17 +1,10 @@ import { Router, Request, Response } from "express"; import { route } from "@fosscord/api"; -import { BackupCode, FieldErrors, generateToken, User } from "@fosscord/util"; +import { BackupCode, generateToken, User, TotpSchema } from "@fosscord/util"; import { verifyToken } from "node-2fa"; import { HTTPError } from "lambert-server"; const router = Router(); -export interface TotpSchema { - code: string, - ticket: string, - gift_code_sku_id?: string | null, - login_source?: string | null, -} - router.post("/", route({ body: "TotpSchema" }), async (req: Request, res: Response) => { const { code, ticket, gift_code_sku_id, login_source } = req.body as TotpSchema; diff --git a/src/api/routes/auth/register.ts b/src/api/routes/auth/register.ts index b7122dadd..84f8f838e 100644 --- a/src/api/routes/auth/register.ts +++ b/src/api/routes/auth/register.ts @@ -1,40 +1,11 @@ import { Request, Response, Router } from "express"; -import { Config, generateToken, Invite, FieldErrors, User, adjustEmail } from "@fosscord/util"; +import { Config, generateToken, Invite, FieldErrors, User, adjustEmail, RegisterSchema } from "@fosscord/util"; import { route, getIpAdress, IPAnalysis, isProxy, verifyCaptcha } from "@fosscord/api"; -import "missing-native-js-functions"; import bcrypt from "bcrypt"; import { HTTPError } from "lambert-server"; const router: Router = Router(); -export interface RegisterSchema { - /** - * @minLength 2 - * @maxLength 32 - */ - username: string; - /** - * @minLength 1 - * @maxLength 72 - */ - password?: string; - consent: boolean; - /** - * @TJS-format email - */ - email?: string; - fingerprint?: string; - invite?: string; - /** - * @TJS-type string - */ - date_of_birth?: Date; // "2000-04-03" - gift_code_sku_id?: string; - captcha_key?: string; - - promotional_email_opt_in?: boolean; -} - router.post("/", route({ body: "RegisterSchema" }), async (req: Request, res: Response) => { const body = req.body as RegisterSchema; const { register, security } = Config.get(); diff --git a/src/api/routes/auth/verify/view-backup-codes-challenge.ts b/src/api/routes/auth/verify/view-backup-codes-challenge.ts index 36bfeb0c4..24de8ec50 100644 --- a/src/api/routes/auth/verify/view-backup-codes-challenge.ts +++ b/src/api/routes/auth/verify/view-backup-codes-challenge.ts @@ -1,13 +1,9 @@ import { Router, Request, Response } from "express"; import { route } from "@fosscord/api"; -import { FieldErrors, User } from "@fosscord/util"; +import { FieldErrors, User, BackupCodesChallengeSchema } from "@fosscord/util"; import bcrypt from "bcrypt"; const router = Router(); -export interface BackupCodesChallengeSchema { - password: string; -} - router.post("/", route({ body: "BackupCodesChallengeSchema" }), async (req: Request, res: Response) => { const { password } = req.body as BackupCodesChallengeSchema; diff --git a/src/api/routes/channels/#channel_id/index.ts b/src/api/routes/channels/#channel_id/index.ts index 0340a6168..8dbefe1b0 100644 --- a/src/api/routes/channels/#channel_id/index.ts +++ b/src/api/routes/channels/#channel_id/index.ts @@ -1,12 +1,12 @@ import { Channel, ChannelDeleteEvent, - ChannelPermissionOverwriteType, ChannelType, ChannelUpdateEvent, emitEvent, Recipient, - handleFile + handleFile, + ChannelModifySchema } from "@fosscord/util"; import { Request, Response, Router } from "express"; import { route } from "@fosscord/api"; @@ -47,35 +47,6 @@ router.delete("/", route({ permission: "MANAGE_CHANNELS" }), async (req: Request res.send(channel); }); -export interface ChannelModifySchema { - /** - * @maxLength 100 - */ - name?: string; - type?: ChannelType; - topic?: string; - icon?: string | null; - bitrate?: number; - user_limit?: number; - rate_limit_per_user?: number; - position?: number; - permission_overwrites?: { - id: string; - type: ChannelPermissionOverwriteType; - allow: string; - deny: string; - }[]; - parent_id?: string; - id?: string; // is not used (only for guild create) - nsfw?: boolean; - rtc_region?: string; - default_auto_archive_duration?: number; - default_reaction_emoji?: string | null; - flags?: number; - default_thread_rate_limit_per_user?: number; - video_quality_mode?: number; -} - router.patch("/", route({ body: "ChannelModifySchema", permission: "MANAGE_CHANNELS" }), async (req: Request, res: Response) => { var payload = req.body as ChannelModifySchema; const { channel_id } = req.params; diff --git a/src/api/routes/channels/#channel_id/invites.ts b/src/api/routes/channels/#channel_id/invites.ts index fd8339ad3..246a2c690 100644 --- a/src/api/routes/channels/#channel_id/invites.ts +++ b/src/api/routes/channels/#channel_id/invites.ts @@ -7,18 +7,6 @@ import { isTextChannel } from "./messages"; const router: Router = Router(); -export interface InviteCreateSchema { - target_user_id?: string; - target_type?: string; - validate?: string; // ? what is this - max_age?: number; - max_uses?: number; - temporary?: boolean; - unique?: boolean; - target_user?: string; - target_user_type?: number; -} - router.post("/", route({ body: "InviteCreateSchema", permission: "CREATE_INSTANT_INVITE", right: "CREATE_INVITES" }), async (req: Request, res: Response) => { const { user_id } = req; diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts b/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts index 3abae7ce8..bedd453ca 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/ack.ts @@ -1,4 +1,4 @@ -import { emitEvent, getPermission, MessageAckEvent, ReadState, Snowflake } from "@fosscord/util"; +import { emitEvent, getPermission, MessageAckEvent, ReadState } from "@fosscord/util"; import { Request, Response, Router } from "express"; import { route } from "@fosscord/api"; @@ -8,11 +8,6 @@ const router = Router(); // TODO: send read state event to all channel members // TODO: advance-only notification cursor -export interface MessageAcknowledgeSchema { - manual?: boolean; - mention_count?: number; -} - router.post("/", route({ body: "MessageAcknowledgeSchema" }), async (req: Request, res: Response) => { const { channel_id, message_id } = req.params; diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/index.ts b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts index a02a9abea..46b0d6bd0 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/index.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/index.ts @@ -1,8 +1,6 @@ import { Attachment, Channel, - Embed, - DiscordApiErrors, emitEvent, FosscordApiErrors, getPermission, @@ -12,13 +10,13 @@ import { MessageDeleteEvent, MessageUpdateEvent, Snowflake, - uploadFile + uploadFile, + MessageCreateSchema, } 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(); diff --git a/src/api/routes/channels/#channel_id/messages/bulk-delete.ts b/src/api/routes/channels/#channel_id/messages/bulk-delete.ts index b6fd37f41..6493c16af 100644 --- a/src/api/routes/channels/#channel_id/messages/bulk-delete.ts +++ b/src/api/routes/channels/#channel_id/messages/bulk-delete.ts @@ -2,16 +2,11 @@ import { Router, Response, Request } from "express"; 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"; const router: Router = Router(); export default router; -export interface BulkDeleteSchema { - messages: string[]; -} - // 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 diff --git a/src/api/routes/channels/#channel_id/messages/index.ts b/src/api/routes/channels/#channel_id/messages/index.ts index 154dc8ed2..bee93e805 100644 --- a/src/api/routes/channels/#channel_id/messages/index.ts +++ b/src/api/routes/channels/#channel_id/messages/index.ts @@ -5,16 +5,15 @@ import { ChannelType, Config, DmChannelDTO, - Embed, emitEvent, getPermission, - getRights, Message, MessageCreateEvent, Snowflake, uploadFile, Member, Role, + MessageCreateSchema, } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { handleMessage, postHandleMessage, route } from "@fosscord/api"; @@ -50,38 +49,6 @@ export function isTextChannel(type: ChannelType): boolean { } } -export interface MessageCreateSchema { - type?: number; - content?: string; - nonce?: string; - channel_id?: string; - tts?: boolean; - flags?: string; - embeds?: Embed[]; - embed?: Embed; - // TODO: ^ embed is deprecated in favor of embeds (https://discord.com/developers/docs/resources/channel#message-object) - allowed_mentions?: { - parse?: string[]; - roles?: string[]; - users?: string[]; - replied_user?: boolean; - }; - message_reference?: { - message_id: string; - channel_id: string; - guild_id?: string; - fail_if_not_exists?: boolean; - }; - payload_json?: string; - file?: any; - /** - TODO: we should create an interface for attachments - TODO: OpenWAAO<-->attachment-style metadata conversion - **/ - attachments?: any[]; - sticker_ids?: string[]; -} - // https://discord.com/developers/docs/resources/channel#create-message // get messages router.get("/", async (req: Request, res: Response) => { diff --git a/src/api/routes/channels/#channel_id/purge.ts b/src/api/routes/channels/#channel_id/purge.ts index bfac27eee..9fe6b658d 100644 --- a/src/api/routes/channels/#channel_id/purge.ts +++ b/src/api/routes/channels/#channel_id/purge.ts @@ -3,33 +3,21 @@ 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 + PurgeSchema, } 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 **/ diff --git a/src/api/routes/channels/#channel_id/webhooks.ts b/src/api/routes/channels/#channel_id/webhooks.ts index 93f70a41b..99c104ca8 100644 --- a/src/api/routes/channels/#channel_id/webhooks.ts +++ b/src/api/routes/channels/#channel_id/webhooks.ts @@ -1,19 +1,12 @@ import { Router, Response, Request } from "express"; import { route } from "@fosscord/api"; -import { Channel, Config, getPermission, trimSpecial, Webhook } from "@fosscord/util"; +import { Channel, Config, trimSpecial, Webhook } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { isTextChannel } from "./messages/index"; import { DiscordApiErrors } from "@fosscord/util"; const router: Router = Router(); -// TODO: webhooks -export interface WebhookCreateSchema { - /** - * @maxLength 80 - */ - name: string; - avatar: string; -} + //TODO: implement webhooks router.get("/", route({}), async (req: Request, res: Response) => { res.json([]); diff --git a/src/api/routes/guilds/#guild_id/audit-logs.ts b/src/api/routes/guilds/#guild_id/audit-logs.ts index a4f2f800b..b54835fc2 100644 --- a/src/api/routes/guilds/#guild_id/audit-logs.ts +++ b/src/api/routes/guilds/#guild_id/audit-logs.ts @@ -1,8 +1,5 @@ import { Router, Response, Request } from "express"; -import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util"; -import { HTTPError } from "lambert-server"; import { route } from "@fosscord/api"; -import { ChannelModifySchema } from "../../channels/#channel_id"; const router = Router(); //TODO: implement audit logs diff --git a/src/api/routes/guilds/#guild_id/bans.ts b/src/api/routes/guilds/#guild_id/bans.ts index 51d3ca674..ed00f9c0a 100644 --- a/src/api/routes/guilds/#guild_id/bans.ts +++ b/src/api/routes/guilds/#guild_id/bans.ts @@ -1,30 +1,8 @@ import { Request, Response, Router } from "express"; -import { DiscordApiErrors, emitEvent, GuildBanAddEvent, GuildBanRemoveEvent, Ban, User, Member } from "@fosscord/util"; +import { DiscordApiErrors, emitEvent, GuildBanAddEvent, GuildBanRemoveEvent, Ban, User, Member, BanRegistrySchema, BanModeratorSchema } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { getIpAdress, route } from "@fosscord/api"; -export interface BanCreateSchema { - delete_message_days?: string; - reason?: string; -}; - -export interface BanRegistrySchema { - id: string; - user_id: string; - guild_id: string; - executor_id: string; - ip?: string; - reason?: string | undefined; -}; - -export interface BanModeratorSchema { - id: string; - user_id: string; - guild_id: string; - executor_id: string; - reason?: string | undefined; -}; - const router: Router = Router(); /* TODO: Deleting the secrets is just a temporary go-around. Views should be implemented for both safety and better handling. */ diff --git a/src/api/routes/guilds/#guild_id/channels.ts b/src/api/routes/guilds/#guild_id/channels.ts index 11f727fc5..7a5b50d13 100644 --- a/src/api/routes/guilds/#guild_id/channels.ts +++ b/src/api/routes/guilds/#guild_id/channels.ts @@ -1,8 +1,7 @@ import { Router, Response, Request } from "express"; -import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util"; +import { Channel, ChannelUpdateEvent, emitEvent, ChannelModifySchema } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { route } from "@fosscord/api"; -import { ChannelModifySchema } from "../../channels/#channel_id"; const router = Router(); router.get("/", route({}), async (req: Request, res: Response) => { diff --git a/src/api/routes/guilds/#guild_id/emojis.ts b/src/api/routes/guilds/#guild_id/emojis.ts index 75998e04e..cf9d742aa 100644 --- a/src/api/routes/guilds/#guild_id/emojis.ts +++ b/src/api/routes/guilds/#guild_id/emojis.ts @@ -1,21 +1,9 @@ import { Router, Request, Response } from "express"; -import { Config, DiscordApiErrors, emitEvent, Emoji, GuildEmojisUpdateEvent, handleFile, Member, Snowflake, User } from "@fosscord/util"; +import { Config, DiscordApiErrors, emitEvent, Emoji, GuildEmojisUpdateEvent, handleFile, Member, Snowflake, User, EmojiCreateSchema, EmojiModifySchema } from "@fosscord/util"; import { route } from "@fosscord/api"; const router = Router(); -export interface EmojiCreateSchema { - name?: string; - image: string; - require_colons?: boolean | null; - roles?: string[]; -} - -export interface EmojiModifySchema { - name?: string; - roles?: string[]; -} - router.get("/", route({}), async (req: Request, res: Response) => { const { guild_id } = req.params; diff --git a/src/api/routes/guilds/#guild_id/index.ts b/src/api/routes/guilds/#guild_id/index.ts index 45bbe3480..afeb0938b 100644 --- a/src/api/routes/guilds/#guild_id/index.ts +++ b/src/api/routes/guilds/#guild_id/index.ts @@ -1,9 +1,7 @@ import { Request, Response, Router } from "express"; -import { DiscordApiErrors, emitEvent, getPermission, getRights, Guild, GuildUpdateEvent, handleFile, Member } from "@fosscord/util"; +import { DiscordApiErrors, emitEvent, getPermission, getRights, Guild, GuildUpdateEvent, handleFile, Member, GuildCreateSchema } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { route } from "@fosscord/api"; -import "missing-native-js-functions"; -import { GuildCreateSchema } from "../index"; const router = Router(); diff --git a/src/api/routes/guilds/#guild_id/integrations.ts b/src/api/routes/guilds/#guild_id/integrations.ts index abf997c9d..a8e78062c 100644 --- a/src/api/routes/guilds/#guild_id/integrations.ts +++ b/src/api/routes/guilds/#guild_id/integrations.ts @@ -1,8 +1,5 @@ import { Router, Response, Request } from "express"; -import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util"; -import { HTTPError } from "lambert-server"; import { route } from "@fosscord/api"; -import { ChannelModifySchema } from "../../channels/#channel_id"; const router = Router(); //TODO: implement integrations list diff --git a/src/api/routes/guilds/#guild_id/members/#member_id/index.ts b/src/api/routes/guilds/#guild_id/members/#member_id/index.ts index d785eb00e..407619d36 100644 --- a/src/api/routes/guilds/#guild_id/members/#member_id/index.ts +++ b/src/api/routes/guilds/#guild_id/members/#member_id/index.ts @@ -1,15 +1,9 @@ import { Request, Response, Router } from "express"; -import { Member, getPermission, getRights, Role, GuildMemberUpdateEvent, emitEvent, Sticker, Emoji, Rights, Guild } from "@fosscord/util"; -import { HTTPError } from "lambert-server"; +import { Member, getPermission, getRights, Role, GuildMemberUpdateEvent, emitEvent, Sticker, Emoji, Guild, MemberChangeSchema } from "@fosscord/util"; import { route } from "@fosscord/api"; const router = Router(); -export interface MemberChangeSchema { - roles?: string[]; - nick?: string; -} - router.get("/", route({}), async (req: Request, res: Response) => { const { guild_id, member_id } = req.params; await Member.IsInGuildOrFail(req.user_id, guild_id); diff --git a/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts b/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts index 27f7f65d9..edd476058 100644 --- a/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts +++ b/src/api/routes/guilds/#guild_id/members/#member_id/nick.ts @@ -4,10 +4,6 @@ import { Request, Response, Router } from "express"; const router = Router(); -export interface MemberNickChangeSchema { - nick: string; -} - router.patch("/", route({ body: "MemberNickChangeSchema" }), async (req: Request, res: Response) => { var { guild_id, member_id } = req.params; var permissionString: PermissionResolvable = "MANAGE_NICKNAMES"; diff --git a/src/api/routes/guilds/#guild_id/prune.ts b/src/api/routes/guilds/#guild_id/prune.ts index cf3466f10..2e674349c 100644 --- a/src/api/routes/guilds/#guild_id/prune.ts +++ b/src/api/routes/guilds/#guild_id/prune.ts @@ -62,13 +62,6 @@ router.get("/", route({}), async (req: Request, res: Response) => { res.send({ pruned: members.length }); }); -export interface PruneSchema { - /** - * @min 0 - */ - days: number; -} - router.post("/", route({ permission: "KICK_MEMBERS", right: "KICK_BAN_MEMBERS" }), async (req: Request, res: Response) => { const days = parseInt(req.body.days); diff --git a/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts b/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts index a01068c0f..87cf52615 100644 --- a/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts +++ b/src/api/routes/guilds/#guild_id/roles/#role_id/index.ts @@ -1,8 +1,7 @@ import { Router, Request, Response } from "express"; -import { Role, Member, GuildRoleUpdateEvent, GuildRoleDeleteEvent, emitEvent, handleFile } from "@fosscord/util"; +import { Role, Member, GuildRoleUpdateEvent, GuildRoleDeleteEvent, emitEvent, handleFile, RoleModifySchema } from "@fosscord/util"; import { route } from "@fosscord/api"; import { HTTPError } from "lambert-server"; -import { RoleModifySchema } from "../"; const router = Router(); diff --git a/src/api/routes/guilds/#guild_id/roles/index.ts b/src/api/routes/guilds/#guild_id/roles/index.ts index 7e839f08a..c5a86400b 100644 --- a/src/api/routes/guilds/#guild_id/roles/index.ts +++ b/src/api/routes/guilds/#guild_id/roles/index.ts @@ -5,28 +5,15 @@ import { Member, GuildRoleCreateEvent, GuildRoleUpdateEvent, - GuildRoleDeleteEvent, emitEvent, Config, DiscordApiErrors, - handleFile + RoleModifySchema, } from "@fosscord/util"; -import { HTTPError } from "lambert-server"; import { route } from "@fosscord/api"; const router: Router = Router(); -export interface RoleModifySchema { - name?: string; - permissions?: string; - color?: number; - hoist?: boolean; // whether the role should be displayed separately in the sidebar - mentionable?: boolean; // whether the role should be mentionable - position?: number; - icon?: string; - unicode_emoji?: string; -} - export type RolePositionUpdateSchema = { id: string; position: number; diff --git a/src/api/routes/guilds/#guild_id/stickers.ts b/src/api/routes/guilds/#guild_id/stickers.ts index 7a4e71ee5..fc0f49aba 100644 --- a/src/api/routes/guilds/#guild_id/stickers.ts +++ b/src/api/routes/guilds/#guild_id/stickers.ts @@ -1,13 +1,13 @@ import { emitEvent, GuildStickersUpdateEvent, - handleFile, Member, Snowflake, Sticker, StickerFormatType, StickerType, - uploadFile + uploadFile, + ModifyGuildStickerSchema, } from "@fosscord/util"; import { Router, Request, Response } from "express"; import { route } from "@fosscord/api"; @@ -82,22 +82,6 @@ router.get("/:sticker_id", route({}), async (req: Request, res: Response) => { res.json(await Sticker.findOneOrFail({ where: { guild_id, id: sticker_id } })); }); -export interface ModifyGuildStickerSchema { - /** - * @minLength 2 - * @maxLength 30 - */ - name: string; - /** - * @maxLength 100 - */ - description?: string; - /** - * @maxLength 200 - */ - tags: string; -} - router.patch( "/:sticker_id", route({ body: "ModifyGuildStickerSchema", permission: "MANAGE_EMOJIS_AND_STICKERS" }), diff --git a/src/api/routes/guilds/#guild_id/templates.ts b/src/api/routes/guilds/#guild_id/templates.ts index 0444c4029..628321f51 100644 --- a/src/api/routes/guilds/#guild_id/templates.ts +++ b/src/api/routes/guilds/#guild_id/templates.ts @@ -23,16 +23,6 @@ const TemplateGuildProjection: (keyof Guild)[] = [ "icon" ]; -export interface TemplateCreateSchema { - name: string; - description?: string; -} - -export interface TemplateModifySchema { - name: string; - description?: string; -} - router.get("/", route({}), async (req: Request, res: Response) => { const { guild_id } = req.params; diff --git a/src/api/routes/guilds/#guild_id/vanity-url.ts b/src/api/routes/guilds/#guild_id/vanity-url.ts index 040bc1fd0..d1fe47262 100644 --- a/src/api/routes/guilds/#guild_id/vanity-url.ts +++ b/src/api/routes/guilds/#guild_id/vanity-url.ts @@ -1,4 +1,4 @@ -import { Channel, ChannelType, getPermission, Guild, Invite, trimSpecial } from "@fosscord/util"; +import { Channel, ChannelType, Guild, Invite, VanityUrlSchema } from "@fosscord/util"; import { Router, Request, Response } from "express"; import { route } from "@fosscord/api"; import { HTTPError } from "lambert-server"; @@ -24,14 +24,6 @@ router.get("/", route({ permission: "MANAGE_GUILD" }), async (req: Request, res: } }); -export interface VanityUrlSchema { - /** - * @minLength 1 - * @maxLength 20 - */ - code?: string; -} - router.patch("/", route({ body: "VanityUrlSchema", permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => { const { guild_id } = req.params; const body = req.body as VanityUrlSchema; diff --git a/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts b/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts index b7fdfecde..006e997f5 100644 --- a/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts +++ b/src/api/routes/guilds/#guild_id/voice-states/#user_id/index.ts @@ -1,20 +1,10 @@ -import { Channel, ChannelType, DiscordApiErrors, emitEvent, getPermission, VoiceState, VoiceStateUpdateEvent } from "@fosscord/util"; +import { Channel, ChannelType, DiscordApiErrors, emitEvent, getPermission, VoiceState, VoiceStateUpdateEvent, VoiceStateUpdateSchema } from "@fosscord/util"; import { route } from "@fosscord/api"; import { Request, Response, Router } from "express"; const router = Router(); //TODO need more testing when community guild and voice stage channel are working -export interface VoiceStateUpdateSchema { - channel_id: string; - guild_id?: string; - suppress?: boolean; - request_to_speak_timestamp?: Date; - self_mute?: boolean; - self_deaf?: boolean; - self_video?: boolean; -} - router.patch("/", route({ body: "VoiceStateUpdateSchema" }), async (req: Request, res: Response) => { const body = req.body as VoiceStateUpdateSchema; var { guild_id, user_id } = req.params; diff --git a/src/api/routes/guilds/#guild_id/webhooks.ts b/src/api/routes/guilds/#guild_id/webhooks.ts index 8b2febeac..9c4e8a8da 100644 --- a/src/api/routes/guilds/#guild_id/webhooks.ts +++ b/src/api/routes/guilds/#guild_id/webhooks.ts @@ -1,8 +1,5 @@ import { Router, Response, Request } from "express"; -import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util"; -import { HTTPError } from "lambert-server"; import { route } from "@fosscord/api"; -import { ChannelModifySchema } from "../../channels/#channel_id"; const router = Router(); //TODO: implement webhooks diff --git a/src/api/routes/guilds/#guild_id/welcome-screen.ts b/src/api/routes/guilds/#guild_id/welcome-screen.ts index a57255f03..57da062da 100644 --- a/src/api/routes/guilds/#guild_id/welcome-screen.ts +++ b/src/api/routes/guilds/#guild_id/welcome-screen.ts @@ -1,21 +1,10 @@ import { Request, Response, Router } from "express"; -import { Guild, getPermission, Snowflake, Member } from "@fosscord/util"; +import { Guild, Member, GuildUpdateWelcomeScreenSchema } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import { route } from "@fosscord/api"; const router: Router = Router(); -export interface GuildUpdateWelcomeScreenSchema { - welcome_channels?: { - channel_id: string; - description: string; - emoji_id?: string; - emoji_name?: string; - }[]; - enabled?: boolean; - description?: string; -} - router.get("/", route({}), async (req: Request, res: Response) => { const guild_id = req.params.guild_id; diff --git a/src/api/routes/guilds/#guild_id/widget.ts b/src/api/routes/guilds/#guild_id/widget.ts index 103f84a30..dbb4cc0c8 100644 --- a/src/api/routes/guilds/#guild_id/widget.ts +++ b/src/api/routes/guilds/#guild_id/widget.ts @@ -1,12 +1,7 @@ import { Request, Response, Router } from "express"; -import { Guild } from "@fosscord/util"; +import { Guild, WidgetModifySchema } from "@fosscord/util"; import { route } from "@fosscord/api"; -export interface WidgetModifySchema { - enabled: boolean; // whether the widget is enabled - channel_id: string; // the widget channel id -} - const router: Router = Router(); // https://discord.com/developers/docs/resources/guild#get-guild-widget-settings diff --git a/src/api/routes/guilds/index.ts b/src/api/routes/guilds/index.ts index d44cd7356..0807cb961 100644 --- a/src/api/routes/guilds/index.ts +++ b/src/api/routes/guilds/index.ts @@ -1,23 +1,9 @@ import { Router, Request, Response } from "express"; -import { Role, Guild, Snowflake, Config, getRights, Member, Channel, DiscordApiErrors, handleFile } from "@fosscord/util"; +import { Role, Guild, Config, getRights, Member, DiscordApiErrors, GuildCreateSchema } from "@fosscord/util"; import { route } from "@fosscord/api"; -import { ChannelModifySchema } from "../channels/#channel_id"; const router: Router = Router(); -export interface GuildCreateSchema { - /** - * @maxLength 100 - */ - name?: string; - region?: string; - icon?: string | null; - channels?: ChannelModifySchema[]; - guild_template_code?: string; - system_channel_id?: string; - rules_channel_id?: string; -} - //TODO: create default channel router.post("/", route({ body: "GuildCreateSchema", right: "CREATE_GUILDS" }), async (req: Request, res: Response) => { diff --git a/src/api/routes/guilds/templates/index.ts b/src/api/routes/guilds/templates/index.ts index e281214f8..4e7abcc5a 100644 --- a/src/api/routes/guilds/templates/index.ts +++ b/src/api/routes/guilds/templates/index.ts @@ -1,15 +1,10 @@ import { Request, Response, Router } from "express"; -import { Template, Guild, Role, Snowflake, Config, User, Member } from "@fosscord/util"; +import { Template, Guild, Role, Snowflake, Config, Member, GuildTemplateCreateSchema } from "@fosscord/util"; import { route } from "@fosscord/api"; import { DiscordApiErrors } from "@fosscord/util"; import fetch from "node-fetch"; const router: Router = Router(); -export interface GuildTemplateCreateSchema { - name: string; - avatar?: string | null; -} - router.get("/:code", route({}), async (req: Request, res: Response) => { const { allowDiscordTemplates, allowRaws, enabled } = Config.get().templates; if (!enabled) res.json({ code: 403, message: "Template creation & usage is disabled on this instance." }).sendStatus(403); diff --git a/src/api/routes/users/@me/channels.ts b/src/api/routes/users/@me/channels.ts index 78f531e19..ad483529f 100644 --- a/src/api/routes/users/@me/channels.ts +++ b/src/api/routes/users/@me/channels.ts @@ -1,5 +1,5 @@ import { Request, Response, Router } from "express"; -import { Recipient, DmChannelDTO, Channel } from "@fosscord/util"; +import { Recipient, DmChannelDTO, Channel, DmChannelCreateSchema } from "@fosscord/util"; import { route } from "@fosscord/api"; const router: Router = Router(); @@ -12,11 +12,6 @@ router.get("/", route({}), async (req: Request, res: Response) => { res.json(await Promise.all(recipients.map((r) => DmChannelDTO.from(r.channel, [req.user_id])))); }); -export interface DmChannelCreateSchema { - name?: string; - recipients: string[]; -} - router.post("/", route({ body: "DmChannelCreateSchema" }), async (req: Request, res: Response) => { const body = req.body as DmChannelCreateSchema; res.json(await Channel.createDMChannel(body.recipients, req.user_id, body.name)); diff --git a/src/api/routes/users/@me/index.ts b/src/api/routes/users/@me/index.ts index 36b62b556..e849b72ab 100644 --- a/src/api/routes/users/@me/index.ts +++ b/src/api/routes/users/@me/index.ts @@ -1,31 +1,11 @@ import { Router, Request, Response } from "express"; -import { User, PrivateUserProjection, emitEvent, UserUpdateEvent, handleFile, FieldErrors, adjustEmail, Config } from "@fosscord/util"; +import { User, PrivateUserProjection, emitEvent, UserUpdateEvent, handleFile, FieldErrors, adjustEmail, Config, UserModifySchema } from "@fosscord/util"; import { route } from "@fosscord/api"; import bcrypt from "bcrypt"; import { HTTPError } from "lambert-server"; const router: Router = Router(); -export interface UserModifySchema { - /** - * @minLength 1 - * @maxLength 100 - */ - username?: string; - avatar?: string | null; - /** - * @maxLength 1024 - */ - bio?: string; - accent_color?: number; - banner?: string | null; - password?: string; - new_password?: string; - code?: string; - email?: string; - discriminator?: string; -} - router.get("/", route({}), async (req: Request, res: Response) => { res.json(await User.findOne({ select: PrivateUserProjection, where: { id: req.user_id } })); }); diff --git a/src/api/routes/users/@me/mfa/codes-verification.ts b/src/api/routes/users/@me/mfa/codes-verification.ts index 09000d07a..071c71fa8 100644 --- a/src/api/routes/users/@me/mfa/codes-verification.ts +++ b/src/api/routes/users/@me/mfa/codes-verification.ts @@ -1,15 +1,9 @@ import { Router, Request, Response } from "express"; import { route } from "@fosscord/api"; -import { BackupCode, generateMfaBackupCodes, User } from "@fosscord/util"; +import { BackupCode, generateMfaBackupCodes, User, CodesVerificationSchema } from "@fosscord/util"; const router = Router(); -export interface CodesVerificationSchema { - key: string; - nonce: string; - regenerate?: boolean; -} - router.post("/", route({ body: "CodesVerificationSchema" }), async (req: Request, res: Response) => { const { key, nonce, regenerate } = req.body as CodesVerificationSchema; diff --git a/src/api/routes/users/@me/mfa/codes.ts b/src/api/routes/users/@me/mfa/codes.ts index 67bd3d5b1..58466b9c5 100644 --- a/src/api/routes/users/@me/mfa/codes.ts +++ b/src/api/routes/users/@me/mfa/codes.ts @@ -1,15 +1,10 @@ import { Router, Request, Response } from "express"; import { route } from "@fosscord/api"; -import { BackupCode, FieldErrors, generateMfaBackupCodes, User } from "@fosscord/util"; +import { BackupCode, FieldErrors, generateMfaBackupCodes, User, MfaCodesSchema } from "@fosscord/util"; import bcrypt from "bcrypt"; const router = Router(); -export interface MfaCodesSchema { - password: string; - regenerate?: boolean; -} - // TODO: This route is replaced with users/@me/mfa/codes-verification in newer clients router.post("/", route({ body: "MfaCodesSchema" }), async (req: Request, res: Response) => { diff --git a/src/api/routes/users/@me/mfa/totp/disable.ts b/src/api/routes/users/@me/mfa/totp/disable.ts index 2d385fdaa..2fe9355cb 100644 --- a/src/api/routes/users/@me/mfa/totp/disable.ts +++ b/src/api/routes/users/@me/mfa/totp/disable.ts @@ -2,14 +2,10 @@ import { Router, Request, Response } from "express"; import { route } from "@fosscord/api"; import { verifyToken } from 'node-2fa'; import { HTTPError } from "lambert-server"; -import { User, generateToken, BackupCode } from "@fosscord/util"; +import { User, generateToken, BackupCode, TotpDisableSchema } from "@fosscord/util"; const router = Router(); -export interface TotpDisableSchema { - code: string; -} - router.post("/", route({ body: "TotpDisableSchema" }), async (req: Request, res: Response) => { const body = req.body as TotpDisableSchema; diff --git a/src/api/routes/users/@me/mfa/totp/enable.ts b/src/api/routes/users/@me/mfa/totp/enable.ts index e4ce9ce0a..adafe1806 100644 --- a/src/api/routes/users/@me/mfa/totp/enable.ts +++ b/src/api/routes/users/@me/mfa/totp/enable.ts @@ -1,19 +1,12 @@ import { Router, Request, Response } from "express"; -import { User, generateToken, BackupCode, generateMfaBackupCodes } from "@fosscord/util"; +import { User, generateToken, generateMfaBackupCodes, TotpEnableSchema } from "@fosscord/util"; import { route } from "@fosscord/api"; import bcrypt from "bcrypt"; import { HTTPError } from "lambert-server"; import { verifyToken } from 'node-2fa'; -import crypto from "crypto"; const router = Router(); -export interface TotpEnableSchema { - password: string; - code?: string; - secret?: string; -} - router.post("/", route({ body: "TotpEnableSchema" }), async (req: Request, res: Response) => { const body = req.body as TotpEnableSchema; diff --git a/src/api/routes/users/@me/relationships.ts b/src/api/routes/users/@me/relationships.ts index 00d4da0b8..cd33704d1 100644 --- a/src/api/routes/users/@me/relationships.ts +++ b/src/api/routes/users/@me/relationships.ts @@ -37,10 +37,6 @@ router.get("/", route({}), async (req: Request, res: Response) => { return res.json(related_users); }); -export interface RelationshipPutSchema { - type?: RelationshipType; -} - router.put("/:id", route({ body: "RelationshipPutSchema" }), async (req: Request, res: Response) => { return await updateRelationship( req, @@ -50,11 +46,6 @@ router.put("/:id", route({ body: "RelationshipPutSchema" }), async (req: Request ); }); -export interface RelationshipPostSchema { - discriminator: string; - username: string; -} - router.post("/", route({ body: "RelationshipPostSchema" }), async (req: Request, res: Response) => { return await updateRelationship( req, diff --git a/src/api/util/handlers/Message.ts b/src/api/util/handlers/Message.ts index 7e91fb7b6..0d29c2e6c 100644 --- a/src/api/util/handlers/Message.ts +++ b/src/api/util/handlers/Message.ts @@ -22,11 +22,11 @@ import { Attachment, Config, Sticker, + MessageCreateSchema, } from "@fosscord/util"; import { HTTPError } from "lambert-server"; import fetch from "node-fetch"; import cheerio from "cheerio"; -import { MessageCreateSchema } from "../../routes/channels/#channel_id/messages"; import { In } from "typeorm"; const allow_empty = false; // TODO: check webhook, application, system author, stickers diff --git a/src/gateway/events/Message.ts b/src/gateway/events/Message.ts index db7dbad21..4699f1afc 100644 --- a/src/gateway/events/Message.ts +++ b/src/gateway/events/Message.ts @@ -36,7 +36,7 @@ export async function Message(this: WebSocket, buffer: WS.Data) { data = bigIntJson.parse(buffer as string); } else if (typeof buffer == "string") { - data = bigIntJson.parse(buffer as string) + data = bigIntJson.parse(buffer as string); } else return; @@ -51,14 +51,14 @@ export async function Message(this: WebSocket, buffer: WS.Data) { return; } - // const transaction = Sentry.startTransaction({ - // op: OPCODES[data.op], - // name: `GATEWAY ${OPCODES[data.op]}`, - // data: { - // ...data.d, - // token: data?.d?.token ? "[Redacted]" : undefined, - // }, - // }); + const transaction = Sentry.startTransaction({ + op: OPCODES[data.op], + name: `GATEWAY ${OPCODES[data.op]}`, + data: { + ...data.d, + token: data?.d?.token ? "[Redacted]" : undefined, + }, + }); try { var ret = await OPCodeHandler.call(this, data); @@ -66,7 +66,7 @@ export async function Message(this: WebSocket, buffer: WS.Data) { return ret; } catch (error) { Sentry.captureException(error); - // transaction.finish(); + transaction.finish(); console.error(`Error: Op ${data.op}`, error); // if (!this.CLOSED && this.CLOSING) return this.close(CLOSECODES.Unknown_error); diff --git a/src/gateway/opcodes/Identify.ts b/src/gateway/opcodes/Identify.ts index 3c40962c0..b4b360754 100644 --- a/src/gateway/opcodes/Identify.ts +++ b/src/gateway/opcodes/Identify.ts @@ -20,12 +20,12 @@ import { PresenceUpdateEvent, DefaultUserGuildSettings, UserGuildSettings, + IdentifySchema, } from "@fosscord/util"; import { Send } from "../util/Send"; import { CLOSECODES, OPCODES } from "../util/Constants"; import { genSessionId } from "../util/SessionUtils"; import { setupListener } from "../listener/listener"; -import { IdentifySchema } from "../schema/Identify"; // import experiments from "./experiments.json"; const experiments: any = []; import { check } from "./instanceOf"; diff --git a/src/gateway/opcodes/LazyRequest.ts b/src/gateway/opcodes/LazyRequest.ts index 823422241..0f21d0878 100644 --- a/src/gateway/opcodes/LazyRequest.ts +++ b/src/gateway/opcodes/LazyRequest.ts @@ -1,6 +1,5 @@ -import { getDatabase, getPermission, listenEvent, Member, Role, Session } from "@fosscord/util"; +import { getDatabase, getPermission, listenEvent, Member, Role, Session, LazyRequestSchema } from "@fosscord/util"; import { WebSocket, Payload, handlePresenceUpdate, OPCODES, Send } from "@fosscord/gateway"; -import { LazyRequest } from "../schema/LazyRequest"; import { check } from "./instanceOf"; // TODO: only show roles/members that have access to this channel @@ -137,8 +136,8 @@ async function getMembers(guild_id: string, range: [number, number]) { export async function onLazyRequest(this: WebSocket, { d }: Payload) { // TODO: check data - check.call(this, LazyRequest, d); - const { guild_id, typing, channels, activities } = d as LazyRequest; + check.call(this, LazyRequestSchema, d); + const { guild_id, typing, channels, activities } = d as LazyRequestSchema; const channel_id = Object.keys(channels || {}).first(); if (!channel_id) return; diff --git a/src/gateway/opcodes/PresenceUpdate.ts b/src/gateway/opcodes/PresenceUpdate.ts index 415df6eea..d17b7dd74 100644 --- a/src/gateway/opcodes/PresenceUpdate.ts +++ b/src/gateway/opcodes/PresenceUpdate.ts @@ -1,6 +1,5 @@ import { WebSocket, Payload } from "@fosscord/gateway"; -import { emitEvent, PresenceUpdateEvent, Session, User } from "@fosscord/util"; -import { ActivitySchema } from "../schema/Activity"; +import { emitEvent, PresenceUpdateEvent, Session, User, ActivitySchema } from "@fosscord/util"; import { check } from "./instanceOf"; export async function onPresenceUpdate(this: WebSocket, { d }: Payload) { diff --git a/src/gateway/opcodes/VoiceStateUpdate.ts b/src/gateway/opcodes/VoiceStateUpdate.ts index fa63f7fcb..8e1585ec8 100644 --- a/src/gateway/opcodes/VoiceStateUpdate.ts +++ b/src/gateway/opcodes/VoiceStateUpdate.ts @@ -1,4 +1,3 @@ -import { VoiceStateUpdateSchema } from "../schema/VoiceStateUpdateSchema"; import { Payload, WebSocket } from "@fosscord/gateway"; import { genVoiceToken } from "../util/SessionUtils"; import { check } from "./instanceOf"; @@ -11,6 +10,7 @@ import { VoiceServerUpdateEvent, VoiceState, VoiceStateUpdateEvent, + VoiceStateUpdateSchema, } from "@fosscord/util"; // TODO: check if a voice server is setup // Notice: Bot users respect the voice channel's user limit, if set. When the voice channel is full, you will not receive the Voice State Update or Voice Server Update events in response to your own Voice State Update. Having MANAGE_CHANNELS permission bypasses this limit and allows you to join regardless of the channel being full or not. diff --git a/src/gateway/schema/Activity.ts b/src/util/schemas/ActivitySchema.ts similarity index 99% rename from src/gateway/schema/Activity.ts rename to src/util/schemas/ActivitySchema.ts index f58b0fa94..d316420e4 100644 --- a/src/gateway/schema/Activity.ts +++ b/src/util/schemas/ActivitySchema.ts @@ -57,4 +57,4 @@ export interface ActivitySchema { status: Status; activities?: Activity[]; since?: number; // unix time (in milliseconds) of when the client went idle, or null if the client is not idle -} +} \ No newline at end of file diff --git a/src/util/schemas/BackupCodesChallengeSchema.ts b/src/util/schemas/BackupCodesChallengeSchema.ts new file mode 100644 index 000000000..d6b519b79 --- /dev/null +++ b/src/util/schemas/BackupCodesChallengeSchema.ts @@ -0,0 +1,3 @@ +export interface BackupCodesChallengeSchema { + password: string; +} \ No newline at end of file diff --git a/src/util/schemas/BanCreateSchema.ts b/src/util/schemas/BanCreateSchema.ts new file mode 100644 index 000000000..876b2a89f --- /dev/null +++ b/src/util/schemas/BanCreateSchema.ts @@ -0,0 +1,4 @@ +export interface BanCreateSchema { + delete_message_days?: string; + reason?: string; +}; \ No newline at end of file diff --git a/src/util/schemas/BanModeratorSchema.ts b/src/util/schemas/BanModeratorSchema.ts new file mode 100644 index 000000000..8efa24020 --- /dev/null +++ b/src/util/schemas/BanModeratorSchema.ts @@ -0,0 +1,7 @@ +export interface BanModeratorSchema { + id: string; + user_id: string; + guild_id: string; + executor_id: string; + reason?: string | undefined; +}; \ No newline at end of file diff --git a/src/util/schemas/BanRegistrySchema.ts b/src/util/schemas/BanRegistrySchema.ts new file mode 100644 index 000000000..8680d3dbd --- /dev/null +++ b/src/util/schemas/BanRegistrySchema.ts @@ -0,0 +1,8 @@ +export interface BanRegistrySchema { + id: string; + user_id: string; + guild_id: string; + executor_id: string; + ip?: string; + reason?: string | undefined; +}; \ No newline at end of file diff --git a/src/util/schemas/BulkDeleteSchema.ts b/src/util/schemas/BulkDeleteSchema.ts new file mode 100644 index 000000000..6a71e0524 --- /dev/null +++ b/src/util/schemas/BulkDeleteSchema.ts @@ -0,0 +1,3 @@ +export interface BulkDeleteSchema { + messages: string[]; +} \ No newline at end of file diff --git a/src/util/schemas/ChannelModifySchema.ts b/src/util/schemas/ChannelModifySchema.ts new file mode 100644 index 000000000..835ea2d7a --- /dev/null +++ b/src/util/schemas/ChannelModifySchema.ts @@ -0,0 +1,30 @@ +import { ChannelPermissionOverwriteType, ChannelType } from "@fosscord/util"; + +export interface ChannelModifySchema { + /** + * @maxLength 100 + */ + name?: string; + type?: ChannelType; + topic?: string; + icon?: string | null; + bitrate?: number; + user_limit?: number; + rate_limit_per_user?: number; + position?: number; + permission_overwrites?: { + id: string; + type: ChannelPermissionOverwriteType; + allow: string; + deny: string; + }[]; + parent_id?: string; + id?: string; // is not used (only for guild create) + nsfw?: boolean; + rtc_region?: string; + default_auto_archive_duration?: number; + default_reaction_emoji?: string | null; + flags?: number; + default_thread_rate_limit_per_user?: number; + video_quality_mode?: number; +} \ No newline at end of file diff --git a/src/util/schemas/CodesVerificationSchema.ts b/src/util/schemas/CodesVerificationSchema.ts new file mode 100644 index 000000000..e8e2e7b4e --- /dev/null +++ b/src/util/schemas/CodesVerificationSchema.ts @@ -0,0 +1,5 @@ +export interface CodesVerificationSchema { + key: string; + nonce: string; + regenerate?: boolean; +} \ No newline at end of file diff --git a/src/util/schemas/DmChannelCreateSchema.ts b/src/util/schemas/DmChannelCreateSchema.ts new file mode 100644 index 000000000..04b8ff69d --- /dev/null +++ b/src/util/schemas/DmChannelCreateSchema.ts @@ -0,0 +1,4 @@ +export interface DmChannelCreateSchema { + name?: string; + recipients: string[]; +} \ No newline at end of file diff --git a/src/util/schemas/EmojiCreateSchema.ts b/src/util/schemas/EmojiCreateSchema.ts new file mode 100644 index 000000000..8e2a23079 --- /dev/null +++ b/src/util/schemas/EmojiCreateSchema.ts @@ -0,0 +1,6 @@ +export interface EmojiCreateSchema { + name?: string; + image: string; + require_colons?: boolean | null; + roles?: string[]; +} \ No newline at end of file diff --git a/src/util/schemas/EmojiModifySchema.ts b/src/util/schemas/EmojiModifySchema.ts new file mode 100644 index 000000000..cd5b7e3ea --- /dev/null +++ b/src/util/schemas/EmojiModifySchema.ts @@ -0,0 +1,4 @@ +export interface EmojiModifySchema { + name?: string; + roles?: string[]; +} \ No newline at end of file diff --git a/src/util/schemas/GuildCreateSchema.ts b/src/util/schemas/GuildCreateSchema.ts new file mode 100644 index 000000000..9b5f7dc23 --- /dev/null +++ b/src/util/schemas/GuildCreateSchema.ts @@ -0,0 +1,14 @@ +import { ChannelModifySchema } from "."; + +export interface GuildCreateSchema { + /** + * @maxLength 100 + */ + name?: string; + region?: string; + icon?: string | null; + channels?: ChannelModifySchema[]; + guild_template_code?: string; + system_channel_id?: string; + rules_channel_id?: string; +} \ No newline at end of file diff --git a/src/util/schemas/GuildTemplateCreateSchema.ts b/src/util/schemas/GuildTemplateCreateSchema.ts new file mode 100644 index 000000000..7caefcb85 --- /dev/null +++ b/src/util/schemas/GuildTemplateCreateSchema.ts @@ -0,0 +1,4 @@ +export interface GuildTemplateCreateSchema { + name: string; + avatar?: string | null; +} \ No newline at end of file diff --git a/src/util/schemas/GuildUpdateWelcomeScreenSchema.ts b/src/util/schemas/GuildUpdateWelcomeScreenSchema.ts new file mode 100644 index 000000000..0022da6e6 --- /dev/null +++ b/src/util/schemas/GuildUpdateWelcomeScreenSchema.ts @@ -0,0 +1,10 @@ +export interface GuildUpdateWelcomeScreenSchema { + welcome_channels?: { + channel_id: string; + description: string; + emoji_id?: string; + emoji_name?: string; + }[]; + enabled?: boolean; + description?: string; +} \ No newline at end of file diff --git a/src/gateway/schema/Identify.ts b/src/util/schemas/IdentifySchema.ts similarity index 98% rename from src/gateway/schema/Identify.ts rename to src/util/schemas/IdentifySchema.ts index 6f68b515c..409a03da5 100644 --- a/src/gateway/schema/Identify.ts +++ b/src/util/schemas/IdentifySchema.ts @@ -1,4 +1,4 @@ -import { ActivitySchema } from "./Activity"; +import { ActivitySchema } from "@fosscord/util"; export const IdentifySchema = { token: String, diff --git a/src/util/schemas/InviteCreateSchema.ts b/src/util/schemas/InviteCreateSchema.ts new file mode 100644 index 000000000..83ae22ddc --- /dev/null +++ b/src/util/schemas/InviteCreateSchema.ts @@ -0,0 +1,11 @@ +export interface InviteCreateSchema { + target_user_id?: string; + target_type?: string; + validate?: string; // ? what is this + max_age?: number; + max_uses?: number; + temporary?: boolean; + unique?: boolean; + target_user?: string; + target_user_type?: number; +} \ No newline at end of file diff --git a/src/gateway/schema/LazyRequest.ts b/src/util/schemas/LazyRequestSchema.ts similarity index 82% rename from src/gateway/schema/LazyRequest.ts rename to src/util/schemas/LazyRequestSchema.ts index 1fe658bbd..e9f2df20c 100644 --- a/src/gateway/schema/LazyRequest.ts +++ b/src/util/schemas/LazyRequestSchema.ts @@ -1,4 +1,4 @@ -export interface LazyRequest { +export interface LazyRequestSchema { guild_id: string; channels?: Record; activities?: boolean; @@ -8,7 +8,7 @@ export interface LazyRequest { thread_member_lists?: any[]; } -export const LazyRequest = { +export const LazyRequestSchema = { guild_id: String, $activities: Boolean, $channels: Object, diff --git a/src/util/schemas/LoginSchema.ts b/src/util/schemas/LoginSchema.ts new file mode 100644 index 000000000..543d236c2 --- /dev/null +++ b/src/util/schemas/LoginSchema.ts @@ -0,0 +1,8 @@ +export interface LoginSchema { + login: string; + password: string; + undelete?: boolean; + captcha_key?: string; + login_source?: string; + gift_code_sku_id?: string; +} \ No newline at end of file diff --git a/src/util/schemas/MemberChangeSchema.ts b/src/util/schemas/MemberChangeSchema.ts new file mode 100644 index 000000000..566d7e203 --- /dev/null +++ b/src/util/schemas/MemberChangeSchema.ts @@ -0,0 +1,4 @@ +export interface MemberChangeSchema { + roles?: string[]; + nick?: string; +} \ No newline at end of file diff --git a/src/util/schemas/MemberNickChangeSchema.ts b/src/util/schemas/MemberNickChangeSchema.ts new file mode 100644 index 000000000..ed9fdb7bf --- /dev/null +++ b/src/util/schemas/MemberNickChangeSchema.ts @@ -0,0 +1,3 @@ +export interface MemberNickChangeSchema { + nick: string; +} \ No newline at end of file diff --git a/src/util/schemas/MessageAcknowledgeSchema.ts b/src/util/schemas/MessageAcknowledgeSchema.ts new file mode 100644 index 000000000..1e7fb80d2 --- /dev/null +++ b/src/util/schemas/MessageAcknowledgeSchema.ts @@ -0,0 +1,4 @@ +export interface MessageAcknowledgeSchema { + manual?: boolean; + mention_count?: number; +} \ No newline at end of file diff --git a/src/util/schemas/MessageCreateSchema.ts b/src/util/schemas/MessageCreateSchema.ts new file mode 100644 index 000000000..9d77c485e --- /dev/null +++ b/src/util/schemas/MessageCreateSchema.ts @@ -0,0 +1,33 @@ +import { Embed } from "@fosscord/util"; + +export interface MessageCreateSchema { + type?: number; + content?: string; + nonce?: string; + channel_id?: string; + tts?: boolean; + flags?: string; + embeds?: Embed[]; + embed?: Embed; + // TODO: ^ embed is deprecated in favor of embeds (https://discord.com/developers/docs/resources/channel#message-object) + allowed_mentions?: { + parse?: string[]; + roles?: string[]; + users?: string[]; + replied_user?: boolean; + }; + message_reference?: { + message_id: string; + channel_id: string; + guild_id?: string; + fail_if_not_exists?: boolean; + }; + payload_json?: string; + file?: any; + /** + TODO: we should create an interface for attachments + TODO: OpenWAAO<-->attachment-style metadata conversion + **/ + attachments?: any[]; + sticker_ids?: string[]; +} \ No newline at end of file diff --git a/src/util/schemas/MfaCodesSchema.ts b/src/util/schemas/MfaCodesSchema.ts new file mode 100644 index 000000000..226c43f17 --- /dev/null +++ b/src/util/schemas/MfaCodesSchema.ts @@ -0,0 +1,4 @@ +export interface MfaCodesSchema { + password: string; + regenerate?: boolean; +} \ No newline at end of file diff --git a/src/util/schemas/ModifyGuildStickerSchema.ts b/src/util/schemas/ModifyGuildStickerSchema.ts new file mode 100644 index 000000000..06bf4ffe8 --- /dev/null +++ b/src/util/schemas/ModifyGuildStickerSchema.ts @@ -0,0 +1,15 @@ +export interface ModifyGuildStickerSchema { + /** + * @minLength 2 + * @maxLength 30 + */ + name: string; + /** + * @maxLength 100 + */ + description?: string; + /** + * @maxLength 200 + */ + tags: string; +} \ No newline at end of file diff --git a/src/util/schemas/PruneSchema.ts b/src/util/schemas/PruneSchema.ts new file mode 100644 index 000000000..60601d817 --- /dev/null +++ b/src/util/schemas/PruneSchema.ts @@ -0,0 +1,6 @@ +export interface PruneSchema { + /** + * @min 0 + */ + days: number; +} \ No newline at end of file diff --git a/src/util/schemas/PurgeSchema.ts b/src/util/schemas/PurgeSchema.ts new file mode 100644 index 000000000..8916be92e --- /dev/null +++ b/src/util/schemas/PurgeSchema.ts @@ -0,0 +1,4 @@ +export interface PurgeSchema { + before: string; + after: string; +} \ No newline at end of file diff --git a/src/util/schemas/RegisterSchema.ts b/src/util/schemas/RegisterSchema.ts new file mode 100644 index 000000000..c0cc3805f --- /dev/null +++ b/src/util/schemas/RegisterSchema.ts @@ -0,0 +1,27 @@ +export interface RegisterSchema { + /** + * @minLength 2 + * @maxLength 32 + */ + username: string; + /** + * @minLength 1 + * @maxLength 72 + */ + password?: string; + consent: boolean; + /** + * @TJS-format email + */ + email?: string; + fingerprint?: string; + invite?: string; + /** + * @TJS-type string + */ + date_of_birth?: Date; // "2000-04-03" + gift_code_sku_id?: string; + captcha_key?: string; + + promotional_email_opt_in?: boolean; +} \ No newline at end of file diff --git a/src/util/schemas/RelationshipPostSchema.ts b/src/util/schemas/RelationshipPostSchema.ts new file mode 100644 index 000000000..3ff6eade8 --- /dev/null +++ b/src/util/schemas/RelationshipPostSchema.ts @@ -0,0 +1,4 @@ +export interface RelationshipPostSchema { + discriminator: string; + username: string; +} \ No newline at end of file diff --git a/src/util/schemas/RelationshipPutSchema.ts b/src/util/schemas/RelationshipPutSchema.ts new file mode 100644 index 000000000..455f854e6 --- /dev/null +++ b/src/util/schemas/RelationshipPutSchema.ts @@ -0,0 +1,5 @@ +import { RelationshipType } from "@fosscord/util"; + +export interface RelationshipPutSchema { + type?: RelationshipType; +} \ No newline at end of file diff --git a/src/util/schemas/RoleModifySchema.ts b/src/util/schemas/RoleModifySchema.ts new file mode 100644 index 000000000..adb0c1a6d --- /dev/null +++ b/src/util/schemas/RoleModifySchema.ts @@ -0,0 +1,10 @@ +export interface RoleModifySchema { + name?: string; + permissions?: string; + color?: number; + hoist?: boolean; // whether the role should be displayed separately in the sidebar + mentionable?: boolean; // whether the role should be mentionable + position?: number; + icon?: string; + unicode_emoji?: string; +} \ No newline at end of file diff --git a/src/util/schemas/SelectProtocolSchema.ts b/src/util/schemas/SelectProtocolSchema.ts new file mode 100644 index 000000000..92958e976 --- /dev/null +++ b/src/util/schemas/SelectProtocolSchema.ts @@ -0,0 +1,19 @@ +export interface SelectProtocolSchema { + protocol: "webrtc" | "udp"; + data: + | string + | { + address: string; + port: number; + mode: string; + }; + sdp?: string; + codecs?: { + name: "opus" | "VP8" | "VP9" | "H264"; + type: "audio" | "video"; + priority: number; + payload_type: number; + rtx_payload_type?: number | null; + }[]; + rtc_connection_id?: string; // uuid +} \ No newline at end of file diff --git a/src/util/schemas/TemplateCreateSchema.ts b/src/util/schemas/TemplateCreateSchema.ts new file mode 100644 index 000000000..3f98f692d --- /dev/null +++ b/src/util/schemas/TemplateCreateSchema.ts @@ -0,0 +1,4 @@ +export interface TemplateCreateSchema { + name: string; + description?: string; +} \ No newline at end of file diff --git a/src/util/schemas/TemplateModifySchema.ts b/src/util/schemas/TemplateModifySchema.ts new file mode 100644 index 000000000..3e6efb744 --- /dev/null +++ b/src/util/schemas/TemplateModifySchema.ts @@ -0,0 +1,4 @@ +export interface TemplateModifySchema { + name: string; + description?: string; +} \ No newline at end of file diff --git a/src/util/schemas/TotpDisableSchema.ts b/src/util/schemas/TotpDisableSchema.ts new file mode 100644 index 000000000..05192bfa0 --- /dev/null +++ b/src/util/schemas/TotpDisableSchema.ts @@ -0,0 +1,3 @@ +export interface TotpDisableSchema { + code: string; +} \ No newline at end of file diff --git a/src/util/schemas/TotpEnableSchema.ts b/src/util/schemas/TotpEnableSchema.ts new file mode 100644 index 000000000..7f6fb5a97 --- /dev/null +++ b/src/util/schemas/TotpEnableSchema.ts @@ -0,0 +1,5 @@ +export interface TotpEnableSchema { + password: string; + code?: string; + secret?: string; +} \ No newline at end of file diff --git a/src/util/schemas/TotpSchema.ts b/src/util/schemas/TotpSchema.ts new file mode 100644 index 000000000..889cb443d --- /dev/null +++ b/src/util/schemas/TotpSchema.ts @@ -0,0 +1,6 @@ +export interface TotpSchema { + code: string, + ticket: string, + gift_code_sku_id?: string | null, + login_source?: string | null, +} \ No newline at end of file diff --git a/src/util/schemas/UserModifySchema.ts b/src/util/schemas/UserModifySchema.ts new file mode 100644 index 000000000..34e0f1353 --- /dev/null +++ b/src/util/schemas/UserModifySchema.ts @@ -0,0 +1,19 @@ +export interface UserModifySchema { + /** + * @minLength 1 + * @maxLength 100 + */ + username?: string; + avatar?: string | null; + /** + * @maxLength 1024 + */ + bio?: string; + accent_color?: number; + banner?: string | null; + password?: string; + new_password?: string; + code?: string; + email?: string; + discriminator?: string; +} \ No newline at end of file diff --git a/src/util/schemas/VanityUrlSchema.ts b/src/util/schemas/VanityUrlSchema.ts new file mode 100644 index 000000000..28bf7f2b8 --- /dev/null +++ b/src/util/schemas/VanityUrlSchema.ts @@ -0,0 +1,7 @@ +export interface VanityUrlSchema { + /** + * @minLength 1 + * @maxLength 20 + */ + code?: string; +} \ No newline at end of file diff --git a/src/util/schemas/VoiceIdentifySchema.ts b/src/util/schemas/VoiceIdentifySchema.ts new file mode 100644 index 000000000..d48de3471 --- /dev/null +++ b/src/util/schemas/VoiceIdentifySchema.ts @@ -0,0 +1,12 @@ +export interface VoiceIdentifySchema { + server_id: string; + user_id: string; + session_id: string; + token: string; + video?: boolean; + streams?: { + type: string; + rid: string; + quality: number; + }[]; +} \ No newline at end of file diff --git a/src/gateway/schema/VoiceStateUpdateSchema.ts b/src/util/schemas/VoiceStateUpdateSchema.ts similarity index 66% rename from src/gateway/schema/VoiceStateUpdateSchema.ts rename to src/util/schemas/VoiceStateUpdateSchema.ts index f6480414c..5f805f4d9 100644 --- a/src/gateway/schema/VoiceStateUpdateSchema.ts +++ b/src/util/schemas/VoiceStateUpdateSchema.ts @@ -1,12 +1,4 @@ -export const VoiceStateUpdateSchema = { - $guild_id: String, - $channel_id: String, - self_mute: Boolean, - self_deaf: Boolean, - $self_video: Boolean, //required in docs but bots don't always send it - $preferred_region: String, -}; - +//TODO need more testing when community guild and voice stage channel are working export interface VoiceStateUpdateSchema { guild_id?: string; channel_id?: string; @@ -14,4 +6,17 @@ export interface VoiceStateUpdateSchema { self_deaf: boolean; self_video?: boolean; preferred_region?: string; -} \ No newline at end of file + request_to_speak_timestamp?: Date; + suppress?: boolean; +} + +export const VoiceStateUpdateSchema = { + $guild_id: String, + $channel_id: String, + self_mute: Boolean, + self_deaf: Boolean, + $self_video: Boolean, //required in docs but bots don't always send it + $preferred_region: String, + $request_to_speak_timestamp: Date, + $suppress: Boolean, +}; \ No newline at end of file diff --git a/src/util/schemas/VoiceVideoSchema.ts b/src/util/schemas/VoiceVideoSchema.ts new file mode 100644 index 000000000..837ee1e75 --- /dev/null +++ b/src/util/schemas/VoiceVideoSchema.ts @@ -0,0 +1,17 @@ +export interface VoiceVideoSchema { + audio_ssrc: number; + video_ssrc: number; + rtx_ssrc?: number; + user_id?: string; + streams?: { + type: "video" | "audio"; + rid: string; + ssrc: number; + active: boolean; + quality: number; + rtx_ssrc: number; + max_bitrate: number; + max_framerate: number; + max_resolution: { type: string; width: number; height: number; }; + }[]; +} \ No newline at end of file diff --git a/src/util/schemas/WebhookCreateSchema.ts b/src/util/schemas/WebhookCreateSchema.ts new file mode 100644 index 000000000..c32b642da --- /dev/null +++ b/src/util/schemas/WebhookCreateSchema.ts @@ -0,0 +1,8 @@ +// TODO: webhooks +export interface WebhookCreateSchema { + /** + * @maxLength 80 + */ + name: string; + avatar: string; +} \ No newline at end of file diff --git a/src/util/schemas/WidgetModifySchema.ts b/src/util/schemas/WidgetModifySchema.ts new file mode 100644 index 000000000..3c84b3a1e --- /dev/null +++ b/src/util/schemas/WidgetModifySchema.ts @@ -0,0 +1,4 @@ +export interface WidgetModifySchema { + enabled: boolean; // whether the widget is enabled + channel_id: string; // the widget channel id +} \ No newline at end of file diff --git a/src/util/schemas/index.ts b/src/util/schemas/index.ts index 662152dcd..f86552f37 100644 --- a/src/util/schemas/index.ts +++ b/src/util/schemas/index.ts @@ -1,2 +1,41 @@ export * from "./Validator"; -export * from "./voice"; \ No newline at end of file +export * from "./SelectProtocolSchema"; +export * from "./LoginSchema"; +export * from "./RegisterSchema"; +export * from "./TotpSchema"; +export * from "./BackupCodesChallengeSchema"; +export * from "./ChannelModifySchema"; +export * from "./InviteCreateSchema"; +export * from "./PurgeSchema"; +export * from "./WebhookCreateSchema"; +export * from "./MessageCreateSchema"; +export * from "./MessageAcknowledgeSchema"; +export * from "./GuildCreateSchema"; +export * from "./BanCreateSchema"; +export * from "./BanModeratorSchema"; +export * from "./BanRegistrySchema"; +export * from "./EmojiCreateSchema"; +export * from "./EmojiModifySchema"; +export * from "./ModifyGuildStickerSchema"; +export * from "./TemplateCreateSchema"; +export * from "./TemplateModifySchema"; +export * from "./VanityUrlSchema"; +export * from "./GuildUpdateWelcomeScreenSchema"; +export * from "./WidgetModifySchema"; +export * from "./MemberChangeSchema"; +export * from "./RoleModifySchema"; +export * from "./GuildTemplateCreateSchema"; +export * from "./DmChannelCreateSchema"; +export * from "./UserModifySchema"; +export * from "./RelationshipPostSchema"; +export * from "./RelationshipPutSchema"; +export * from "./CodesVerificationSchema"; +export * from "./MfaCodesSchema"; +export * from "./TotpDisableSchema"; +export * from "./TotpEnableSchema"; +export * from "./VoiceIdentifySchema"; +export * from "./VoiceStateUpdateSchema"; +export * from "./VoiceVideoSchema"; +export * from "./IdentifySchema"; +export * from "./ActivitySchema"; +export * from "./LazyRequestSchema"; \ No newline at end of file diff --git a/src/util/schemas/voice.ts b/src/util/schemas/voice.ts deleted file mode 100644 index 61c12f926..000000000 --- a/src/util/schemas/voice.ts +++ /dev/null @@ -1,69 +0,0 @@ -export interface VoiceVideoSchema { - audio_ssrc: number; - video_ssrc: number; - rtx_ssrc?: number; - user_id?: string; - streams?: { - type: "video" | "audio"; - rid: string; - ssrc: number; - active: boolean; - quality: number; - rtx_ssrc: number; - max_bitrate: number; - max_framerate: number; - max_resolution: { type: string; width: number; height: number; }; - }[]; -} - -export const VoiceStateUpdateSchema = { - $guild_id: String, - $channel_id: String, - self_mute: Boolean, - self_deaf: Boolean, - self_video: Boolean -}; - -//TODO need more testing when community guild and voice stage channel are working -export interface VoiceStateUpdateSchema { - channel_id: string; - guild_id?: string; - suppress?: boolean; - request_to_speak_timestamp?: Date; - self_mute?: boolean; - self_deaf?: boolean; - self_video?: boolean; -} - -export interface VoiceIdentifySchema { - server_id: string; - user_id: string; - session_id: string; - token: string; - video?: boolean; - streams?: { - type: string; - rid: string; - quality: number; - }[]; -} - -export interface SelectProtocolSchema { - protocol: "webrtc" | "udp"; - data: - | string - | { - address: string; - port: number; - mode: string; - }; - sdp?: string; - codecs?: { - name: "opus" | "VP8" | "VP9" | "H264"; - type: "audio" | "video"; - priority: number; - payload_type: number; - rtx_payload_type?: number | null; - }[]; - rtc_connection_id?: string; // uuid -} \ No newline at end of file