summary refs log tree commit diff
path: root/api/src/routes
diff options
context:
space:
mode:
authorTheArcaneBrony <myrainbowdash949@gmail.com>2022-08-12 11:36:39 +0200
committerTheArcaneBrony <myrainbowdash949@gmail.com>2022-08-13 21:57:51 +0200
commit10bd81274722823f875ba31eaf5fc670bfb22ceb (patch)
tree9c622935ca99e791f7ee1e27ef67c9d23388012a /api/src/routes
parentMove some invite defaults into class (diff)
downloadserver-10bd81274722823f875ba31eaf5fc670bfb22ceb.tar.xz
Split schemas into files in util
Diffstat (limited to '')
-rw-r--r--api/src/routes/auth/login.ts11
-rw-r--r--api/src/routes/auth/mfa/totp.ts9
-rw-r--r--api/src/routes/auth/register.ts29
-rw-r--r--api/src/routes/channels/#channel_id/index.ts30
-rw-r--r--api/src/routes/channels/#channel_id/invites.ts12
-rw-r--r--api/src/routes/channels/#channel_id/messages/#message_id/ack.ts9
-rw-r--r--api/src/routes/channels/#channel_id/messages/#message_id/index.ts4
-rw-r--r--api/src/routes/channels/#channel_id/messages/bulk-delete.ts4
-rw-r--r--api/src/routes/channels/#channel_id/messages/index.ts36
-rw-r--r--api/src/routes/channels/#channel_id/permissions.ts7
-rw-r--r--api/src/routes/channels/#channel_id/purge.ts7
-rw-r--r--api/src/routes/channels/#channel_id/webhooks.ts8
-rw-r--r--api/src/routes/guilds/#guild_id/audit-logs.ts3
-rw-r--r--api/src/routes/guilds/#guild_id/bans.ts24
-rw-r--r--api/src/routes/guilds/#guild_id/channels.ts3
-rw-r--r--api/src/routes/guilds/#guild_id/emojis.ts14
-rw-r--r--api/src/routes/guilds/#guild_id/index.ts20
-rw-r--r--api/src/routes/guilds/#guild_id/integrations.ts1
-rw-r--r--api/src/routes/guilds/#guild_id/members/#member_id/index.ts6
-rw-r--r--api/src/routes/guilds/#guild_id/members/#member_id/nick.ts4
-rw-r--r--api/src/routes/guilds/#guild_id/prune.ts7
-rw-r--r--api/src/routes/guilds/#guild_id/roles/#role_id/index.ts3
-rw-r--r--api/src/routes/guilds/#guild_id/roles/index.ts14
-rw-r--r--api/src/routes/guilds/#guild_id/stickers.ts17
-rw-r--r--api/src/routes/guilds/#guild_id/templates.ts10
-rw-r--r--api/src/routes/guilds/#guild_id/vanity-url.ts10
-rw-r--r--api/src/routes/guilds/#guild_id/voice-states/#user_id/index.ts14
-rw-r--r--api/src/routes/guilds/#guild_id/webhooks.ts1
-rw-r--r--api/src/routes/guilds/#guild_id/welcome_screen.ts13
-rw-r--r--api/src/routes/guilds/#guild_id/widget.ts7
-rw-r--r--api/src/routes/guilds/index.ts16
-rw-r--r--api/src/routes/guilds/templates/index.ts9
-rw-r--r--api/src/routes/users/@me/channels.ts7
-rw-r--r--api/src/routes/users/@me/index.ts21
-rw-r--r--api/src/routes/users/@me/mfa/codes.ts7
-rw-r--r--api/src/routes/users/@me/mfa/totp/disable.ts6
-rw-r--r--api/src/routes/users/@me/mfa/totp/enable.ts8
-rw-r--r--api/src/routes/users/@me/relationships.ts9
-rw-r--r--api/src/routes/users/@me/settings.ts2
39 files changed, 32 insertions, 390 deletions
diff --git a/api/src/routes/auth/login.ts b/api/src/routes/auth/login.ts
index daef6056..9fc5924d 100644
--- a/api/src/routes/auth/login.ts
+++ b/api/src/routes/auth/login.ts
@@ -1,21 +1,12 @@
 import { Request, Response, Router } from "express";
 import { route } 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/api/src/routes/auth/mfa/totp.ts b/api/src/routes/auth/mfa/totp.ts
index 255cf889..421dbafa 100644
--- a/api/src/routes/auth/mfa/totp.ts
+++ b/api/src/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, FieldErrors, generateToken, TotpSchema, User } 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/api/src/routes/auth/register.ts b/api/src/routes/auth/register.ts
index 5a3d27e9..09366a12 100644
--- a/api/src/routes/auth/register.ts
+++ b/api/src/routes/auth/register.ts
@@ -1,38 +1,11 @@
 import { Request, Response, Router } from "express";
-import { Config, generateToken, Invite, FieldErrors, User, adjustEmail, trimSpecial } from "@fosscord/util";
+import { Config, generateToken, Invite, FieldErrors, User, adjustEmail, trimSpecial, RegisterSchema } from "@fosscord/util";
 import { route, getIpAdress, IPAnalysis, isProxy } from "@fosscord/api";
 import bcrypt from "bcrypt";
 import { HTTPError } from "@fosscord/util";
 
 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/api/src/routes/channels/#channel_id/index.ts b/api/src/routes/channels/#channel_id/index.ts
index 70c34f05..bb8b868b 100644
--- a/api/src/routes/channels/#channel_id/index.ts
+++ b/api/src/routes/channels/#channel_id/index.ts
@@ -6,7 +6,8 @@ import {
 	ChannelUpdateEvent,
 	emitEvent,
 	Recipient,
-	handleFile
+	handleFile,
+	ChannelModifySchema
 } from "@fosscord/util";
 import { Request, Response, Router } from "express";
 import { route } from "@fosscord/api";
@@ -48,33 +49,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;
-	flags?: number;
-	default_thread_rate_limit_per_user?: number;
-}
-
 router.patch("/", route({ body: "ChannelModifySchema", permission: "MANAGE_CHANNELS" }), async (req: Request, res: Response) => {
 	let payload = req.body as ChannelModifySchema;
 	const { channel_id } = req.params;
diff --git a/api/src/routes/channels/#channel_id/invites.ts b/api/src/routes/channels/#channel_id/invites.ts
index f111cf54..b5c65c0d 100644
--- a/api/src/routes/channels/#channel_id/invites.ts
+++ b/api/src/routes/channels/#channel_id/invites.ts
@@ -8,18 +8,6 @@ import { OrmUtils } from "@fosscord/util";
 
 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/api/src/routes/channels/#channel_id/messages/#message_id/ack.ts b/api/src/routes/channels/#channel_id/messages/#message_id/ack.ts
index c1b8d20f..041f4d5e 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
@@ -5,15 +5,6 @@ import { OrmUtils } from "@fosscord/util";
 
 const router = Router();
 
-// 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;
-	mention_count?: number;
-}
-
 router.post("/", route({ body: "MessageAcknowledgeSchema" }), async (req: Request, res: Response) => {
 	const { channel_id, message_id } = req.params;
 
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 b3b310d3..d7e27062 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
@@ -12,13 +12,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 "@fosscord/util";
 
 const router = Router();
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 2e40f110..24a33d2d 100644
--- a/api/src/routes/channels/#channel_id/messages/bulk-delete.ts
+++ b/api/src/routes/channels/#channel_id/messages/bulk-delete.ts
@@ -8,10 +8,6 @@ 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/api/src/routes/channels/#channel_id/messages/index.ts b/api/src/routes/channels/#channel_id/messages/index.ts
index c2057422..9ab0d97d 100644
--- a/api/src/routes/channels/#channel_id/messages/index.ts
+++ b/api/src/routes/channels/#channel_id/messages/index.ts
@@ -5,7 +5,6 @@ import {
 	ChannelType,
 	Config,
 	DmChannelDTO,
-	Embed,
 	emitEvent,
 	getPermission,
 	getRights,
@@ -13,7 +12,8 @@ import {
 	MessageCreateEvent,
 	Snowflake,
 	uploadFile,
-	Member
+	Member,
+	MessageCreateSchema
 } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { handleMessage, postHandleMessage, route } from "@fosscord/api";
@@ -49,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/api/src/routes/channels/#channel_id/permissions.ts b/api/src/routes/channels/#channel_id/permissions.ts
index 06a124bb..34052fe5 100644
--- a/api/src/routes/channels/#channel_id/permissions.ts
+++ b/api/src/routes/channels/#channel_id/permissions.ts
@@ -1,6 +1,7 @@
 import {
 	Channel,
 	ChannelPermissionOverwrite,
+	ChannelPermissionOverwriteSchema,
 	ChannelPermissionOverwriteType,
 	ChannelUpdateEvent,
 	emitEvent,
@@ -10,13 +11,9 @@ import {
 } from "@fosscord/util";
 import { Router, Response, Request } from "express";
 import { HTTPError } from "@fosscord/util";
-
 import { route } from "@fosscord/api";
-const router: Router = Router();
 
-// TODO: Only permissions your bot has in the guild or channel can be allowed/denied (unless your bot has a MANAGE_ROLES overwrite in the channel)
-
-export interface ChannelPermissionOverwriteSchema extends ChannelPermissionOverwrite {}
+const router: Router = Router();
 
 router.put(
 	"/:overwrite_id",
diff --git a/api/src/routes/channels/#channel_id/purge.ts b/api/src/routes/channels/#channel_id/purge.ts
index 7ab4ad9a..1ef6e1d7 100644
--- a/api/src/routes/channels/#channel_id/purge.ts
+++ b/api/src/routes/channels/#channel_id/purge.ts
@@ -1,4 +1,4 @@
-import { HTTPError } from "@fosscord/util";
+import { HTTPError, PurgeSchema } from "@fosscord/util";
 import { route } from "@fosscord/api";
 import { isTextChannel } from "./messages";
 import { FindManyOptions, Between, Not } from "typeorm";
@@ -10,11 +10,6 @@ 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/api/src/routes/channels/#channel_id/webhooks.ts b/api/src/routes/channels/#channel_id/webhooks.ts
index 00bf4619..b11c8eb9 100644
--- a/api/src/routes/channels/#channel_id/webhooks.ts
+++ b/api/src/routes/channels/#channel_id/webhooks.ts
@@ -6,14 +6,6 @@ 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/api/src/routes/guilds/#guild_id/audit-logs.ts b/api/src/routes/guilds/#guild_id/audit-logs.ts
index 7b1d0062..b54835fc 100644
--- a/api/src/routes/guilds/#guild_id/audit-logs.ts
+++ b/api/src/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 "@fosscord/util";
 import { route } from "@fosscord/api";
-import { ChannelModifySchema } from "../../channels/#channel_id";
 const router = Router();
 
 //TODO: implement audit logs
diff --git a/api/src/routes/guilds/#guild_id/bans.ts b/api/src/routes/guilds/#guild_id/bans.ts
index 0743687d..3d405344 100644
--- a/api/src/routes/guilds/#guild_id/bans.ts
+++ b/api/src/routes/guilds/#guild_id/bans.ts
@@ -1,31 +1,9 @@
 import { Request, Response, Router } from "express";
-import { DiscordApiErrors, emitEvent, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, Guild, Ban, User, Member } from "@fosscord/util";
+import { DiscordApiErrors, emitEvent, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, Guild, Ban, User, Member, BanRegistrySchema, BanModeratorSchema } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { getIpAdress, route } from "@fosscord/api";
 import { OrmUtils } from "@fosscord/util";
 
-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/api/src/routes/guilds/#guild_id/channels.ts b/api/src/routes/guilds/#guild_id/channels.ts
index b952b474..df1b7924 100644
--- a/api/src/routes/guilds/#guild_id/channels.ts
+++ b/api/src/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, getPermission, emitEvent, ChannelModifySchema } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 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/api/src/routes/guilds/#guild_id/emojis.ts b/api/src/routes/guilds/#guild_id/emojis.ts
index 53a44ec3..4bf4bdcd 100644
--- a/api/src/routes/guilds/#guild_id/emojis.ts
+++ b/api/src/routes/guilds/#guild_id/emojis.ts
@@ -1,22 +1,10 @@
 import { Router, Request, Response } from "express";
-import { Config, DiscordApiErrors, emitEvent, Emoji, GuildEmojisUpdateEvent, handleFile, Member, Snowflake, User } from "@fosscord/util";
+import { Config, DiscordApiErrors, emitEvent, Emoji, EmojiCreateSchema, EmojiModifySchema, GuildEmojisUpdateEvent, handleFile, Member, Snowflake, User } from "@fosscord/util";
 import { route } from "@fosscord/api";
 import { OrmUtils } from "@fosscord/util";
 
 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/api/src/routes/guilds/#guild_id/index.ts b/api/src/routes/guilds/#guild_id/index.ts
index 8d61f753..a9712c71 100644
--- a/api/src/routes/guilds/#guild_id/index.ts
+++ b/api/src/routes/guilds/#guild_id/index.ts
@@ -1,29 +1,11 @@
 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, GuildUpdateSchema, handleFile, Member } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { route } from "@fosscord/api";
-import { GuildCreateSchema } from "../index";
 import { OrmUtils } from "@fosscord/util";
 
 const router = Router();
 
-export interface GuildUpdateSchema extends Omit<GuildCreateSchema, "channels" | "name"> {
-	name?: string;
-	banner?: string | null;
-	splash?: string | null;
-	description?: string;
-	features?: string[];
-	verification_level?: number;
-	default_message_notifications?: number;
-	system_channel_flags?: number;
-	explicit_content_filter?: number;
-	public_updates_channel_id?: string;
-	afk_timeout?: number;
-	afk_channel_id?: string;
-	preferred_locale?: string;
-	premium_progress_bar_enabled?: boolean;
-}
-
 router.get("/", route({}), async (req: Request, res: Response) => {
 	const { guild_id } = req.params;
 
diff --git a/api/src/routes/guilds/#guild_id/integrations.ts b/api/src/routes/guilds/#guild_id/integrations.ts
index 19f68563..90650111 100644
--- a/api/src/routes/guilds/#guild_id/integrations.ts
+++ b/api/src/routes/guilds/#guild_id/integrations.ts
@@ -2,7 +2,6 @@ import { Router, Response, Request } from "express";
 import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { route } from "@fosscord/api";
-import { ChannelModifySchema } from "../../channels/#channel_id";
 const router = Router();
 
 //TODO: implement integrations list
diff --git a/api/src/routes/guilds/#guild_id/members/#member_id/index.ts b/api/src/routes/guilds/#guild_id/members/#member_id/index.ts
index 824e34a4..794369d8 100644
--- a/api/src/routes/guilds/#guild_id/members/#member_id/index.ts
+++ b/api/src/routes/guilds/#guild_id/members/#member_id/index.ts
@@ -1,15 +1,11 @@
 import { Request, Response, Router } from "express";
-import { Member, getPermission, getRights, Role, GuildMemberUpdateEvent, emitEvent, Sticker, Emoji, Rights, Guild } from "@fosscord/util";
+import { Member, getPermission, getRights, Role, GuildMemberUpdateEvent, emitEvent, Sticker, Emoji, Rights, Guild, MemberChangeSchema } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { route } from "@fosscord/api";
 import { OrmUtils } from "@fosscord/util";
 
 const router = Router();
 
-export interface MemberChangeSchema {
-	roles?: 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/api/src/routes/guilds/#guild_id/members/#member_id/nick.ts b/api/src/routes/guilds/#guild_id/members/#member_id/nick.ts
index 4dfae8da..a6c71333 100644
--- a/api/src/routes/guilds/#guild_id/members/#member_id/nick.ts
+++ b/api/src/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) => {
 	let { guild_id, member_id } = req.params;
 	let permissionString: PermissionResolvable = "MANAGE_NICKNAMES";
diff --git a/api/src/routes/guilds/#guild_id/prune.ts b/api/src/routes/guilds/#guild_id/prune.ts
index 01f18ce4..673f022f 100644
--- a/api/src/routes/guilds/#guild_id/prune.ts
+++ b/api/src/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/api/src/routes/guilds/#guild_id/roles/#role_id/index.ts b/api/src/routes/guilds/#guild_id/roles/#role_id/index.ts
index 0482b9ca..d4422a9c 100644
--- a/api/src/routes/guilds/#guild_id/roles/#role_id/index.ts
+++ b/api/src/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 "@fosscord/util";
-import { RoleModifySchema } from "../";
 import { OrmUtils } from "@fosscord/util";
 
 const router = Router();
diff --git a/api/src/routes/guilds/#guild_id/roles/index.ts b/api/src/routes/guilds/#guild_id/roles/index.ts
index 6fbb8702..effa4fcd 100644
--- a/api/src/routes/guilds/#guild_id/roles/index.ts
+++ b/api/src/routes/guilds/#guild_id/roles/index.ts
@@ -9,7 +9,8 @@ import {
 	emitEvent,
 	Config,
 	DiscordApiErrors,
-	handleFile
+	handleFile,
+	RoleModifySchema
 } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { route } from "@fosscord/api";
@@ -17,17 +18,6 @@ import { OrmUtils } from "@fosscord/util";
 
 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/api/src/routes/guilds/#guild_id/stickers.ts b/api/src/routes/guilds/#guild_id/stickers.ts
index 157ccff4..71c9dfcd 100644
--- a/api/src/routes/guilds/#guild_id/stickers.ts
+++ b/api/src/routes/guilds/#guild_id/stickers.ts
@@ -3,6 +3,7 @@ import {
 	GuildStickersUpdateEvent,
 	handleFile,
 	Member,
+	ModifyGuildStickerSchema,
 	Snowflake,
 	Sticker,
 	StickerFormatType,
@@ -83,22 +84,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/api/src/routes/guilds/#guild_id/templates.ts b/api/src/routes/guilds/#guild_id/templates.ts
index 3d14de41..9c79692d 100644
--- a/api/src/routes/guilds/#guild_id/templates.ts
+++ b/api/src/routes/guilds/#guild_id/templates.ts
@@ -24,16 +24,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/api/src/routes/guilds/#guild_id/vanity-url.ts b/api/src/routes/guilds/#guild_id/vanity-url.ts
index ac46e18a..ff92ce8d 100644
--- a/api/src/routes/guilds/#guild_id/vanity-url.ts
+++ b/api/src/routes/guilds/#guild_id/vanity-url.ts
@@ -1,4 +1,4 @@
-import { Channel, ChannelType, getPermission, Guild, Invite, trimSpecial } from "@fosscord/util";
+import { Channel, ChannelType, getPermission, Guild, Invite, trimSpecial, VanityUrlSchema } from "@fosscord/util";
 import { Router, Request, Response } from "express";
 import { route } from "@fosscord/api";
 import { HTTPError } from "@fosscord/util";
@@ -25,14 +25,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/api/src/routes/guilds/#guild_id/voice-states/#user_id/index.ts b/api/src/routes/guilds/#guild_id/voice-states/#user_id/index.ts
index 32d1aadf..28a9e8c1 100644
--- a/api/src/routes/guilds/#guild_id/voice-states/#user_id/index.ts
+++ b/api/src/routes/guilds/#guild_id/voice-states/#user_id/index.ts
@@ -1,21 +1,9 @@
-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";
 import { OrmUtils } from "@fosscord/util";
 
 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;
 	let { guild_id, user_id } = req.params;
diff --git a/api/src/routes/guilds/#guild_id/webhooks.ts b/api/src/routes/guilds/#guild_id/webhooks.ts
index 7f5b9592..c8c1eb5c 100644
--- a/api/src/routes/guilds/#guild_id/webhooks.ts
+++ b/api/src/routes/guilds/#guild_id/webhooks.ts
@@ -2,7 +2,6 @@ import { Router, Response, Request } from "express";
 import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 import { route } from "@fosscord/api";
-import { ChannelModifySchema } from "../../channels/#channel_id";
 const router = Router();
 
 //TODO: implement webhooks
diff --git a/api/src/routes/guilds/#guild_id/welcome_screen.ts b/api/src/routes/guilds/#guild_id/welcome_screen.ts
index 4093ec1d..d08300ba 100644
--- a/api/src/routes/guilds/#guild_id/welcome_screen.ts
+++ b/api/src/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, getPermission, Snowflake, Member, GuildUpdateWelcomeScreenSchema } from "@fosscord/util";
 import { HTTPError } from "@fosscord/util";
 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/api/src/routes/guilds/#guild_id/widget.ts b/api/src/routes/guilds/#guild_id/widget.ts
index 103f84a3..dbb4cc0c 100644
--- a/api/src/routes/guilds/#guild_id/widget.ts
+++ b/api/src/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/api/src/routes/guilds/index.ts b/api/src/routes/guilds/index.ts
index 64b9454b..e4d66192 100644
--- a/api/src/routes/guilds/index.ts
+++ b/api/src/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, Snowflake, Config, getRights, Member, Channel, DiscordApiErrors, handleFile, 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/api/src/routes/guilds/templates/index.ts b/api/src/routes/guilds/templates/index.ts
index bac4eb8a..3a0de9e8 100644
--- a/api/src/routes/guilds/templates/index.ts
+++ b/api/src/routes/guilds/templates/index.ts
@@ -1,15 +1,8 @@
 import { Request, Response, Router } from "express";
-import { Template, Guild, Role, Snowflake, Config, User, Member } from "@fosscord/util";
+import { Template, Guild, Role, Snowflake, Config, User, Member, DiscordApiErrors, OrmUtils, GuildTemplateCreateSchema } from "@fosscord/util";
 import { route } from "@fosscord/api";
-import { DiscordApiErrors } from "@fosscord/util";
 import fetch from "node-fetch";
 const router: Router = Router();
-import { OrmUtils } from "@fosscord/util";
-
-export interface GuildTemplateCreateSchema {
-	name: string;
-	avatar?: string | null;
-}
 
 router.get("/:code", route({}), async (req: Request, res: Response) => {
 	const { allowDiscordTemplates, allowRaws, enabled } = Config.get().templates;
diff --git a/api/src/routes/users/@me/channels.ts b/api/src/routes/users/@me/channels.ts
index 78f531e1..ad483529 100644
--- a/api/src/routes/users/@me/channels.ts
+++ b/api/src/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/api/src/routes/users/@me/index.ts b/api/src/routes/users/@me/index.ts
index 4cf96a8d..7d095451 100644
--- a/api/src/routes/users/@me/index.ts
+++ b/api/src/routes/users/@me/index.ts
@@ -1,30 +1,11 @@
 import { Router, Request, Response } from "express";
-import { User, PrivateUserProjection, emitEvent, UserUpdateEvent, handleFile, FieldErrors } from "@fosscord/util";
+import { User, PrivateUserProjection, emitEvent, UserUpdateEvent, handleFile, FieldErrors, UserModifySchema } from "@fosscord/util";
 import { route } from "@fosscord/api";
 import bcrypt from "bcrypt";
 import { OrmUtils, generateToken } from "@fosscord/util";
 
 const router: Router = Router();
 
-export interface UserModifySchema {
-	/**
-	 * @minLength 1
-	 * @maxLength 100
-	 */
-	username?: string;
-	discriminator?: string;
-	avatar?: string | null;
-	/**
-	 * @maxLength 1024
-	 */
-	bio?: string;
-	accent_color?: number;
-	banner?: string | null;
-	password?: string;
-	new_password?: string;
-	code?: string;
-}
-
 router.get("/", route({}), async (req: Request, res: Response) => {
 	res.json(await User.findOne({ select: PrivateUserProjection, where: { id: req.user_id } }));
 });
diff --git a/api/src/routes/users/@me/mfa/codes.ts b/api/src/routes/users/@me/mfa/codes.ts
index 75e3e964..4224a1c0 100644
--- a/api/src/routes/users/@me/mfa/codes.ts
+++ b/api/src/routes/users/@me/mfa/codes.ts
@@ -1,15 +1,10 @@
 import { Router, Request, Response } from "express";
 import { route } from "@fosscord/api";
-import { BackupCode, Config, FieldErrors, generateMfaBackupCodes, User } from "@fosscord/util";
+import { BackupCode, Config, FieldErrors, generateMfaBackupCodes, MfaCodesSchema, User } 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/api/src/routes/users/@me/mfa/totp/disable.ts b/api/src/routes/users/@me/mfa/totp/disable.ts
index 2d385fda..2fe9355c 100644
--- a/api/src/routes/users/@me/mfa/totp/disable.ts
+++ b/api/src/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/api/src/routes/users/@me/mfa/totp/enable.ts b/api/src/routes/users/@me/mfa/totp/enable.ts
index 87f36d55..ac668d1d 100644
--- a/api/src/routes/users/@me/mfa/totp/enable.ts
+++ b/api/src/routes/users/@me/mfa/totp/enable.ts
@@ -1,5 +1,5 @@
 import { Router, Request, Response } from "express";
-import { User, generateToken, BackupCode, generateMfaBackupCodes, Config } from "@fosscord/util";
+import { User, generateToken, BackupCode, generateMfaBackupCodes, Config, TotpEnableSchema } from "@fosscord/util";
 import { route } from "@fosscord/api";
 import bcrypt from "bcrypt";
 import { HTTPError } from "lambert-server";
@@ -7,12 +7,6 @@ import { verifyToken } from 'node-2fa';
 
 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/api/src/routes/users/@me/relationships.ts b/api/src/routes/users/@me/relationships.ts
index 6e22f4f3..f7464b99 100644
--- a/api/src/routes/users/@me/relationships.ts
+++ b/api/src/routes/users/@me/relationships.ts
@@ -38,10 +38,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,
@@ -51,11 +47,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/api/src/routes/users/@me/settings.ts b/api/src/routes/users/@me/settings.ts
index d832575f..7578d36e 100644
--- a/api/src/routes/users/@me/settings.ts
+++ b/api/src/routes/users/@me/settings.ts
@@ -4,8 +4,6 @@ import { route } from "@fosscord/api";
 
 const router = Router();
 
-export interface UserSettingsSchema extends Partial<UserSettings> {}
-
 router.patch("/", route({ body: "UserSettingsSchema" }), async (req: Request, res: Response) => {
 	const body = req.body as UserSettings;
 	if (body.locale === "en") body.locale = "en-US"; // fix discord client crash on unkown locale