Split schemas into files in util

This commit is contained in:
TheArcaneBrony
2022-08-13 21:57:51 +02:00
parent dd0a6e9709
commit 10bd812747
90 changed files with 2045 additions and 1528 deletions
+1592 -1113
View File
File diff suppressed because it is too large Load Diff
+1 -10
View File
@@ -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);
+1 -8
View File
@@ -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;
+1 -28
View File
@@ -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();
+2 -28
View File
@@ -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;
@@ -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;
@@ -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;
@@ -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();
@@ -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
@@ -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) => {
@@ -1,6 +1,7 @@
import {
Channel,
ChannelPermissionOverwrite,
ChannelPermissionOverwriteSchema,
ChannelPermissionOverwriteType,
ChannelUpdateEvent,
emitEvent,
@@ -10,14 +11,10 @@ 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 {}
router.put(
"/:overwrite_id",
route({ body: "ChannelPermissionOverwriteSchema", permission: "MANAGE_ROLES" }),
+1 -6
View File
@@ -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
**/
@@ -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([]);
@@ -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
+1 -23
View File
@@ -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. */
+1 -2
View File
@@ -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) => {
+1 -13
View File
@@ -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;
+1 -19
View File
@@ -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;
@@ -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
@@ -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);
@@ -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";
-7
View File
@@ -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);
@@ -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();
+2 -12
View File
@@ -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;
+1 -16
View File
@@ -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" }),
@@ -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;
@@ -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;
@@ -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;
@@ -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
@@ -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;
+1 -6
View File
@@ -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
+1 -15
View File
@@ -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) => {
+1 -8
View File
@@ -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;
+1 -6
View File
@@ -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));
+1 -20
View File
@@ -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 } }));
});
+1 -6
View File
@@ -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) => {
+1 -5
View File
@@ -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;
+1 -7
View File
@@ -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;
@@ -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,
-2
View File
@@ -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
+2 -1
View File
@@ -21,12 +21,13 @@ import {
Webhook,
Attachment,
Config,
MessageCreateSchema,
} from "@fosscord/util";
import { HTTPError } from "@fosscord/util";
import fetch from "node-fetch";
import cheerio from "cheerio";
import { MessageCreateSchema } from "../../routes/channels/#channel_id/messages";
import { OrmUtils } from "@fosscord/util";
const allow_empty = false;
// TODO: check webhook, application, system author, stickers
// TODO: embed gifs/videos/images
+1 -1
View File
@@ -19,12 +19,12 @@ import {
MemberPrivateProjection,
PresenceUpdateEvent,
UserSettings,
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";
+1 -2
View File
@@ -1,5 +1,4 @@
import { getPermission, listenEvent, Member, Role, getOrInitialiseDatabase } from "@fosscord/util";
import { LazyRequest } from "../schema/LazyRequest";
import { getPermission, listenEvent, Member, Role, getOrInitialiseDatabase, LazyRequest } from "@fosscord/util";
import { Send } from "../util/Send";
import { OPCODES } from "../util/Constants";
import { WebSocket, Payload, handlePresenceUpdate } from "@fosscord/gateway";
+1 -2
View File
@@ -1,6 +1,5 @@
import { WebSocket, Payload } from "@fosscord/gateway";
import { emitEvent, PresenceUpdateEvent, Session, User } from "@fosscord/util";
import { ActivitySchema } from "../schema/Activity";
import { ActivitySchema, emitEvent, PresenceUpdateEvent, Session, User } from "@fosscord/util";
import { check } from "./instanceOf";
export async function onPresenceUpdate(this: WebSocket, { d }: Payload) {
+1 -1
View File
@@ -1,4 +1,3 @@
import { VoiceStateUpdateSchema } from "../schema/VoiceStateUpdateSchema";
import { Payload, WebSocket } from "@fosscord/gateway";
import { genVoiceToken } from "../util/SessionUtils";
import { check } from "./instanceOf";
@@ -10,6 +9,7 @@ import {
VoiceServerUpdateEvent,
VoiceState,
VoiceStateUpdateEvent,
VoiceStateUpdateSchema,
} from "@fosscord/util";
import { OrmUtils } from "@fosscord/util";
import { Region } from "@fosscord/util/src/config";
@@ -1,15 +0,0 @@
export const VoiceStateUpdateSchema = {
$guild_id: String,
$channel_id: String,
self_mute: Boolean,
self_deaf: Boolean,
self_video: Boolean,
};
export interface VoiceStateUpdateSchema {
guild_id?: string;
channel_id?: string;
self_mute: boolean;
self_deaf: boolean;
self_video: boolean;
}
+2 -1
View File
@@ -4,4 +4,5 @@ export * from "./util/index";
export * from "./interfaces/index";
export * from "./entities/index";
export * from "./dtos/index";
export * from "./util/MFA";
export * from "./util/MFA";
export * from "./schemas";
+5
View File
@@ -0,0 +1,5 @@
export interface BanCreateSchema {
delete_message_days?: string;
reason?: string;
}
+8
View File
@@ -0,0 +1,8 @@
export interface BanModeratorSchema {
id: string;
user_id: string;
guild_id: string;
executor_id: string;
reason?: string | undefined;
}
+9
View File
@@ -0,0 +1,9 @@
export interface BanRegistrySchema {
id: string;
user_id: string;
guild_id: string;
executor_id: string;
ip?: string;
reason?: string | undefined;
}
+4
View File
@@ -0,0 +1,4 @@
export interface BulkDeleteSchema {
messages: string[];
}
+29
View File
@@ -0,0 +1,29 @@
import { ChannelPermissionOverwriteType, ChannelType } from "..";
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;
}
@@ -0,0 +1,5 @@
import { ChannelPermissionOverwrite } from "@fosscord/util";
// 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 { }
@@ -0,0 +1,5 @@
export interface DmChannelCreateSchema {
name?: string;
recipients: string[];
}
+7
View File
@@ -0,0 +1,7 @@
export interface EmojiCreateSchema {
name?: string;
image: string;
require_colons?: boolean | null;
roles?: string[];
}
+5
View File
@@ -0,0 +1,5 @@
export interface EmojiModifySchema {
name?: string;
roles?: string[];
}
+14
View File
@@ -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;
}
@@ -0,0 +1,5 @@
export interface GuildTemplateCreateSchema {
name: string;
avatar?: string | null;
}
+18
View File
@@ -0,0 +1,18 @@
import { GuildCreateSchema } from ".";
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;
}
@@ -0,0 +1,11 @@
export interface GuildUpdateWelcomeScreenSchema {
welcome_channels?: {
channel_id: string;
description: string;
emoji_id?: string;
emoji_name: string;
}[];
enabled?: boolean;
description?: string;
}
@@ -1,4 +1,4 @@
import { ActivitySchema } from "./Activity";
import { ActivitySchema } from "./ActivitySchema";
export const IdentifySchema = {
token: String,
+12
View File
@@ -0,0 +1,12 @@
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;
}
+9
View File
@@ -0,0 +1,9 @@
export interface LoginSchema {
login: string;
password: string;
undelete?: boolean;
captcha_key?: string;
login_source?: string;
gift_code_sku_id?: string;
}
+4
View File
@@ -0,0 +1,4 @@
export interface MemberChangeSchema {
roles?: string[];
}
@@ -0,0 +1,4 @@
export interface MemberNickChangeSchema {
nick: string;
}
@@ -0,0 +1,8 @@
// 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;
}
+34
View File
@@ -0,0 +1,34 @@
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[];
}
+5
View File
@@ -0,0 +1,5 @@
export interface MfaCodesSchema {
password: string;
regenerate?: boolean;
}
@@ -0,0 +1,16 @@
export interface ModifyGuildStickerSchema {
/**
* @minLength 2
* @maxLength 30
*/
name: string;
/**
* @maxLength 100
*/
description?: string;
/**
* @maxLength 200
*/
tags: string;
}
+7
View File
@@ -0,0 +1,7 @@
export interface PruneSchema {
/**
* @min 0
*/
days: number;
}
+5
View File
@@ -0,0 +1,5 @@
export interface PurgeSchema {
before: string;
after: string;
}
+27
View File
@@ -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;
}
@@ -0,0 +1,5 @@
export interface RelationshipPostSchema {
discriminator: string;
username: string;
}
@@ -0,0 +1,6 @@
import { RelationshipType } from "@fosscord/util";
export interface RelationshipPutSchema {
type?: RelationshipType;
}
+11
View File
@@ -0,0 +1,11 @@
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;
}
+5
View File
@@ -0,0 +1,5 @@
export interface TemplateCreateSchema {
name: string;
description?: string;
}
+5
View File
@@ -0,0 +1,5 @@
export interface TemplateModifySchema {
name: string;
description?: string;
}
+4
View File
@@ -0,0 +1,4 @@
export interface TotpDisableSchema {
code: string;
}
+6
View File
@@ -0,0 +1,6 @@
export interface TotpEnableSchema {
password: string;
code?: string;
secret?: string;
}
+7
View File
@@ -0,0 +1,7 @@
export interface TotpSchema {
code: string;
ticket: string;
gift_code_sku_id?: string | null;
login_source?: string | null;
}
+19
View File
@@ -0,0 +1,19 @@
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;
}
+4
View File
@@ -0,0 +1,4 @@
import { UserSettings } from "@fosscord/util";
export interface UserSettingsSchema extends Partial<UserSettings> { }
+8
View File
@@ -0,0 +1,8 @@
export interface VanityUrlSchema {
/**
* @minLength 1
* @maxLength 20
*/
code?: string;
}
@@ -0,0 +1,18 @@
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;
}
+8
View File
@@ -0,0 +1,8 @@
// TODO: webhooks
export interface WebhookCreateSchema {
/**
* @maxLength 80
*/
name: string;
avatar?: string;
}
+5
View File
@@ -0,0 +1,5 @@
export interface WidgetModifySchema {
enabled: boolean; // whether the widget is enabled
channel_id: string; // the widget channel id
}
+41
View File
@@ -0,0 +1,41 @@
export * from "./ActivitySchema";
export * from "./BanCreateSchema";
export * from "./BanModeratorSchema";
export * from "./BanRegistrySchema";
export * from "./BulkDeleteSchema";
export * from "./ChannelModifySchema";
export * from "./ChannelPermissionOverwriteSchema";
export * from "./DmChannelCreateSchema";
export * from "./EmojiCreateSchema";
export * from "./EmojiModifySchema";
export * from "./GuildCreateSchema";
export * from "./GuildTemplateCreateSchema";
export * from "./GuildUpdateSchema";
export * from "./GuildUpdateWelcomeScreenSchema";
export * from "./IdentifySchema";
export * from "./InviteCreateSchema";
export * from "./LazyRequestSchema";
export * from "./LoginSchema";
export * from "./MemberChangeSchema";
export * from "./MemberNickChangeSchema";
export * from "./MessageAcknowledgeSchema";
export * from "./MessageCreateSchema";
export * from "./MfaCodesSchema";
export * from "./ModifyGuildStickerSchema";
export * from "./PruneSchema";
export * from "./PurgeSchema";
export * from "./RegisterSchema";
export * from "./RelationshipPostSchema";
export * from "./RelationshipPutSchema";
export * from "./RoleModifySchema";
export * from "./TemplateCreateSchema";
export * from "./TemplateModifySchema";
export * from "./TotpDisableSchema";
export * from "./TotpEnableSchema";
export * from "./TotpSchema";
export * from "./UserModifySchema";
export * from "./UserSettingsSchema";
export * from "./VanityUrlSchema";
export * from "./VoiceStateUpdateSchema";
export * from "./WebhookCreateSchema";
export * from "./WidgetModifySchema";
+4 -1
View File
@@ -60,8 +60,11 @@ function applyConfig(val: ConfigValue) {
pair.value = obj;
return pair.save();
}
if(process.env.CONFIG_PATH)
if(process.env.CONFIG_PATH) {
if(/--debug|--inspect/.test(process.execArgv.join(' ')))
console.log(`Writing config: ${process.env.CONFIG_PATH}`)
fs.writeFileSync(overridePath, JSON.stringify(val, null, 4));
}
return apply(val);
}