diff --git a/src/api/Server.ts b/src/api/Server.ts
index b8d1f9f6..fff94936 100644
--- a/src/api/Server.ts
+++ b/src/api/Server.ts
@@ -14,7 +14,7 @@ import { initInstance } from "./util/handlers/Instance";
import { registerRoutes } from "@fosscord/util";
import { red } from "picocolors";
-export interface FosscordServerOptions extends ServerOptions { }
+export interface FosscordServerOptions extends ServerOptions {}
declare global {
namespace Express {
@@ -76,15 +76,12 @@ export class FosscordServer extends Server {
// 404 is not an error in express, so this should not be an error middleware
// this is a fine place to put the 404 handler because its after we register the routes
// and since its not an error middleware, our error handler below still works.
- api.use(
- "*",
- (req: Request, res: Response, next: NextFunction) => {
- res.status(404).json({
- message: "404 endpoint not found",
- code: 0,
- });
- },
- );
+ api.use("*", (req: Request, res: Response, next: NextFunction) => {
+ res.status(404).json({
+ message: "404 endpoint not found",
+ code: 0,
+ });
+ });
this.app = app;
diff --git a/src/api/routes/applications/#id/bot/index.ts b/src/api/routes/applications/#id/bot/index.ts
index c21e19ca..c4cfccd8 100644
--- a/src/api/routes/applications/#id/bot/index.ts
+++ b/src/api/routes/applications/#id/bot/index.ts
@@ -1,13 +1,23 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
-import { Application, generateToken, User, BotModifySchema, handleFile, DiscordApiErrors } from "@fosscord/util";
+import {
+ Application,
+ generateToken,
+ User,
+ BotModifySchema,
+ handleFile,
+ DiscordApiErrors,
+} from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { verifyToken } from "node-2fa";
const router: Router = Router();
router.post("/", route({}), async (req: Request, res: Response) => {
- const app = await Application.findOneOrFail({ where: { id: req.params.id }, relations: ["owner"] });
+ const app = await Application.findOneOrFail({
+ where: { id: req.params.id },
+ relations: ["owner"],
+ });
if (app.owner.id != req.user_id)
throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION;
@@ -31,7 +41,7 @@ router.post("/", route({}), async (req: Request, res: Response) => {
await app.save();
res.send({
- token: await generateToken(user.id)
+ token: await generateToken(user.id),
}).status(204);
});
@@ -42,7 +52,10 @@ router.post("/reset", route({}), async (req: Request, res: Response) => {
if (owner.id != req.user_id)
throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION;
- if (owner.totp_secret && (!req.body.code || verifyToken(owner.totp_secret, req.body.code)))
+ if (
+ owner.totp_secret &&
+ (!req.body.code || verifyToken(owner.totp_secret, req.body.code))
+ )
throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008);
bot.data = { hash: undefined, valid_tokens_since: new Date() };
@@ -54,30 +67,36 @@ router.post("/reset", route({}), async (req: Request, res: Response) => {
res.json({ token }).status(200);
});
-router.patch("/", route({ body: "BotModifySchema" }), async (req: Request, res: Response) => {
- const body = req.body as BotModifySchema;
- if (!body.avatar?.trim()) delete body.avatar;
+router.patch(
+ "/",
+ route({ body: "BotModifySchema" }),
+ async (req: Request, res: Response) => {
+ const body = req.body as BotModifySchema;
+ if (!body.avatar?.trim()) delete body.avatar;
- const app = await Application.findOneOrFail({ where: { id: req.params.id }, relations: ["bot", "owner"] });
+ const app = await Application.findOneOrFail({
+ where: { id: req.params.id },
+ relations: ["bot", "owner"],
+ });
- if (!app.bot)
- throw DiscordApiErrors.BOT_ONLY_ENDPOINT;
+ if (!app.bot) throw DiscordApiErrors.BOT_ONLY_ENDPOINT;
- if (app.owner.id != req.user_id)
- throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION;
+ if (app.owner.id != req.user_id)
+ throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION;
- if (body.avatar)
- body.avatar = await handleFile(
- `/avatars/${app.id}`,
- body.avatar as string,
- );
+ if (body.avatar)
+ body.avatar = await handleFile(
+ `/avatars/${app.id}`,
+ body.avatar as string,
+ );
- app.bot.assign(body);
+ app.bot.assign(body);
- app.bot.save();
+ app.bot.save();
- await app.save();
- res.json(app).status(200);
-});
+ await app.save();
+ res.json(app).status(200);
+ },
+);
-export default router;
\ No newline at end of file
+export default router;
diff --git a/src/api/routes/applications/#id/index.ts b/src/api/routes/applications/#id/index.ts
index 79df256a..11cd5a56 100644
--- a/src/api/routes/applications/#id/index.ts
+++ b/src/api/routes/applications/#id/index.ts
@@ -1,57 +1,81 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
-import { Application, OrmUtils, DiscordApiErrors, ApplicationModifySchema, User } from "@fosscord/util";
+import {
+ Application,
+ OrmUtils,
+ DiscordApiErrors,
+ ApplicationModifySchema,
+ User,
+} from "@fosscord/util";
import { verifyToken } from "node-2fa";
import { HTTPError } from "lambert-server";
const router: Router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {
- const app = await Application.findOneOrFail({ where: { id: req.params.id }, relations: ["owner", "bot"] });
+ const app = await Application.findOneOrFail({
+ where: { id: req.params.id },
+ relations: ["owner", "bot"],
+ });
if (app.owner.id != req.user_id)
throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION;
return res.json(app);
});
-router.patch("/", route({ body: "ApplicationModifySchema" }), async (req: Request, res: Response) => {
- const body = req.body as ApplicationModifySchema;
+router.patch(
+ "/",
+ route({ body: "ApplicationModifySchema" }),
+ async (req: Request, res: Response) => {
+ const body = req.body as ApplicationModifySchema;
- const app = await Application.findOneOrFail({ where: { id: req.params.id }, relations: ["owner", "bot"] });
+ const app = await Application.findOneOrFail({
+ where: { id: req.params.id },
+ relations: ["owner", "bot"],
+ });
- if (app.owner.id != req.user_id)
- throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION;
+ if (app.owner.id != req.user_id)
+ throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION;
- if (app.owner.totp_secret && (!req.body.code || verifyToken(app.owner.totp_secret, req.body.code)))
- throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008);
+ if (
+ app.owner.totp_secret &&
+ (!req.body.code ||
+ verifyToken(app.owner.totp_secret, req.body.code))
+ )
+ throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008);
- if (app.bot) {
- app.bot.assign({ bio: body.description });
- await app.bot.save();
- }
+ if (app.bot) {
+ app.bot.assign({ bio: body.description });
+ await app.bot.save();
+ }
- app.assign(body);
+ app.assign(body);
- await app.save();
+ await app.save();
- return res.json(app);
-});
+ return res.json(app);
+ },
+);
router.post("/delete", route({}), async (req: Request, res: Response) => {
- const app = await Application.findOneOrFail({ where: { id: req.params.id }, relations: ["bot", "owner"] });
+ const app = await Application.findOneOrFail({
+ where: { id: req.params.id },
+ relations: ["bot", "owner"],
+ });
if (app.owner.id != req.user_id)
throw DiscordApiErrors.ACTION_NOT_AUTHORIZED_ON_APPLICATION;
- if (app.owner.totp_secret && (!req.body.code || verifyToken(app.owner.totp_secret, req.body.code)))
+ if (
+ app.owner.totp_secret &&
+ (!req.body.code || verifyToken(app.owner.totp_secret, req.body.code))
+ )
throw new HTTPError(req.t("auth:login.INVALID_TOTP_CODE"), 60008);
- if (app.bot)
- await User.delete({ id: app.bot.id });
+ if (app.bot) await User.delete({ id: app.bot.id });
await Application.delete({ id: app.id });
res.send().status(200);
});
-
-export default router;
\ No newline at end of file
+export default router;
diff --git a/src/api/routes/applications/#id/skus.ts b/src/api/routes/applications/#id/skus.ts
index 5b667f36..2383e6f7 100644
--- a/src/api/routes/applications/#id/skus.ts
+++ b/src/api/routes/applications/#id/skus.ts
@@ -8,4 +8,4 @@ router.get("/", route({}), async (req: Request, res: Response) => {
res.json([]).status(200);
});
-export default router;
\ No newline at end of file
+export default router;
diff --git a/src/api/routes/applications/index.ts b/src/api/routes/applications/index.ts
index 94cfa5c5..a6b35bfa 100644
--- a/src/api/routes/applications/index.ts
+++ b/src/api/routes/applications/index.ts
@@ -1,30 +1,42 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
-import { Application, ApplicationCreateSchema, trimSpecial, User } from "@fosscord/util";
+import {
+ Application,
+ ApplicationCreateSchema,
+ trimSpecial,
+ User,
+} from "@fosscord/util";
const router: Router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {
- let results = await Application.find({ where: { owner: { id: req.user_id } }, relations: ["owner", "bot"] });
+ let results = await Application.find({
+ where: { owner: { id: req.user_id } },
+ relations: ["owner", "bot"],
+ });
res.json(results).status(200);
});
-router.post("/", route({ body: "ApplicationCreateSchema" }), async (req: Request, res: Response) => {
- const body = req.body as ApplicationCreateSchema;
- const user = await User.findOneOrFail({ where: { id: req.user_id } });
+router.post(
+ "/",
+ route({ body: "ApplicationCreateSchema" }),
+ async (req: Request, res: Response) => {
+ const body = req.body as ApplicationCreateSchema;
+ const user = await User.findOneOrFail({ where: { id: req.user_id } });
- const app = Application.create({
- name: trimSpecial(body.name),
- description: "",
- bot_public: true,
- owner: user,
- verify_key: "IMPLEMENTME",
- flags: 0,
- });
+ const app = Application.create({
+ name: trimSpecial(body.name),
+ description: "",
+ bot_public: true,
+ owner: user,
+ verify_key: "IMPLEMENTME",
+ flags: 0,
+ });
- await app.save();
+ await app.save();
- res.json(app);
-});
+ res.json(app);
+ },
+);
-export default router;
\ No newline at end of file
+export default router;
diff --git a/src/api/routes/auth/generate-registration-tokens.ts b/src/api/routes/auth/generate-registration-tokens.ts
index e328fe5e..0d4cf067 100644
--- a/src/api/routes/auth/generate-registration-tokens.ts
+++ b/src/api/routes/auth/generate-registration-tokens.ts
@@ -5,24 +5,37 @@ import { Request, Response, Router } from "express";
const router: Router = Router();
export default router;
-router.get("/", route({ right: "OPERATOR" }), async (req: Request, res: Response) => {
- const count = req.query.count ? parseInt(req.query.count as string) : 1;
- const length = req.query.length ? parseInt(req.query.length as string) : 255;
+router.get(
+ "/",
+ route({ right: "OPERATOR" }),
+ async (req: Request, res: Response) => {
+ const count = req.query.count ? parseInt(req.query.count as string) : 1;
+ const length = req.query.length
+ ? parseInt(req.query.length as string)
+ : 255;
- let tokens: ValidRegistrationToken[] = [];
+ let tokens: ValidRegistrationToken[] = [];
- for (let i = 0; i < count; i++) {
- const token = ValidRegistrationToken.create({
- token: random(length),
- expires_at: Date.now() + Config.get().security.defaultRegistrationTokenExpiration
- });
- tokens.push(token);
- }
+ for (let i = 0; i < count; i++) {
+ const token = ValidRegistrationToken.create({
+ token: random(length),
+ expires_at:
+ Date.now() +
+ Config.get().security.defaultRegistrationTokenExpiration,
+ });
+ tokens.push(token);
+ }
- // Why are these options used, exactly?
- await ValidRegistrationToken.save(tokens, { chunk: 1000, reload: false, transaction: false });
+ // Why are these options used, exactly?
+ await ValidRegistrationToken.save(tokens, {
+ chunk: 1000,
+ reload: false,
+ transaction: false,
+ });
- if (req.query.plain) return res.send(tokens.map(x => x.token).join("\n"));
+ if (req.query.plain)
+ return res.send(tokens.map((x) => x.token).join("\n"));
- return res.json({ tokens: tokens.map(x => x.token) });
-});
\ No newline at end of file
+ return res.json({ tokens: tokens.map((x) => x.token) });
+ },
+);
diff --git a/src/api/routes/auth/register.ts b/src/api/routes/auth/register.ts
index c8c515e7..3d968114 100644
--- a/src/api/routes/auth/register.ts
+++ b/src/api/routes/auth/register.ts
@@ -33,16 +33,22 @@ router.post(
// Reg tokens
// They're a one time use token that bypasses registration limits ( rates, disabled reg, etc )
let regTokenUsed = false;
- if (req.get("Referrer") && req.get("Referrer")?.includes("token=")) { // eg theyre on https://staging.fosscord.com/register?token=whatever
+ if (req.get("Referrer") && req.get("Referrer")?.includes("token=")) {
+ // eg theyre on https://staging.fosscord.com/register?token=whatever
const token = req.get("Referrer")!.split("token=")[1].split("&")[0];
if (token) {
- const regToken = await ValidRegistrationToken.findOne({ where: { token, expires_at: MoreThan(new Date()), } });
+ const regToken = await ValidRegistrationToken.findOne({
+ where: { token, expires_at: MoreThan(new Date()) },
+ });
await ValidRegistrationToken.delete({ token });
regTokenUsed = true;
- console.log(`[REGISTER] Registration token ${token} used for registration!`);
- }
- else {
- console.log(`[REGISTER] Invalid registration token ${token} used for registration by ${ip}!`);
+ console.log(
+ `[REGISTER] Registration token ${token} used for registration!`,
+ );
+ } else {
+ console.log(
+ `[REGISTER] Invalid registration token ${token} used for registration by ${ip}!`,
+ );
}
}
@@ -78,7 +84,11 @@ router.post(
});
}
- if (!regTokenUsed && register.requireCaptcha && security.captcha.enabled) {
+ if (
+ !regTokenUsed &&
+ register.requireCaptcha &&
+ security.captcha.enabled
+ ) {
const { sitekey, service } = security.captcha;
if (!body.captcha_key) {
return res?.status(400).json({
@@ -220,14 +230,26 @@ router.post(
if (
!regTokenUsed &&
limits.absoluteRate.register.enabled &&
- (await User.count({ where: { created_at: MoreThan(new Date(Date.now() - limits.absoluteRate.register.window)) } }))
- >= limits.absoluteRate.register.limit
+ (await User.count({
+ where: {
+ created_at: MoreThan(
+ new Date(
+ Date.now() - limits.absoluteRate.register.window,
+ ),
+ ),
+ },
+ })) >= limits.absoluteRate.register.limit
) {
console.log(
- `Global register ratelimit exceeded for ${getIpAdress(req)}, ${req.body.username}, ${req.body.invite || "No invite given"}`
+ `Global register ratelimit exceeded for ${getIpAdress(req)}, ${
+ req.body.username
+ }, ${req.body.invite || "No invite given"}`,
);
throw FieldErrors({
- email: { code: "TOO_MANY_REGISTRATIONS", message: req.t("auth:register.TOO_MANY_REGISTRATIONS") }
+ email: {
+ code: "TOO_MANY_REGISTRATIONS",
+ message: req.t("auth:register.TOO_MANY_REGISTRATIONS"),
+ },
});
}
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 cd9da184..d57d9a1b 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
@@ -179,7 +179,7 @@ router.put(
channel.save(),
]);
- postHandleMessage(message).catch((e) => { }); // no await as it shouldnt block the message send function and silently catch error
+ postHandleMessage(message).catch((e) => {}); // no await as it shouldnt block the message send function and silently catch error
return res.json(message);
},
diff --git a/src/api/routes/channels/#channel_id/messages/index.ts b/src/api/routes/channels/#channel_id/messages/index.ts
index 523b0cf8..2968437d 100644
--- a/src/api/routes/channels/#channel_id/messages/index.ts
+++ b/src/api/routes/channels/#channel_id/messages/index.ts
@@ -21,7 +21,12 @@ import {
Rights,
} from "@fosscord/util";
import { HTTPError } from "lambert-server";
-import { handleMessage, postHandleMessage, route, getIpAdress } from "@fosscord/api";
+import {
+ handleMessage,
+ postHandleMessage,
+ route,
+ getIpAdress,
+} from "@fosscord/api";
import multer from "multer";
import { yellow } from "picocolors";
import { FindManyOptions, LessThan, MoreThan } from "typeorm";
@@ -80,7 +85,7 @@ router.get("/", async (req: Request, res: Response) => {
permissions.hasThrow("VIEW_CHANNEL");
if (!permissions.has("READ_MESSAGE_HISTORY")) return res.json([]);
- var query: FindManyOptions<Message> & { where: { id?: any; }; } = {
+ var query: FindManyOptions<Message> & { where: { id?: any } } = {
order: { timestamp: "DESC" },
take: limit,
where: { channel_id },
@@ -138,8 +143,9 @@ router.get("/", async (req: Request, res: Response) => {
const uri = y.proxy_url.startsWith("http")
? y.proxy_url
: `https://example.org${y.proxy_url}`;
- y.proxy_url = `${endpoint == null ? "" : endpoint}${new URL(uri).pathname
- }`;
+ y.proxy_url = `${endpoint == null ? "" : endpoint}${
+ new URL(uri).pathname
+ }`;
});
/**
@@ -211,8 +217,8 @@ router.post(
where: {
nonce: body.nonce,
channel_id: channel.id,
- author_id: req.user_id
- }
+ author_id: req.user_id,
+ },
});
if (existing) {
return res.json(existing);
@@ -225,13 +231,21 @@ router.post(
const count = await Message.count({
where: {
channel_id,
- timestamp: MoreThan(new Date(Date.now() - limits.absoluteRate.sendMessage.window))
- }
+ timestamp: MoreThan(
+ new Date(
+ Date.now() -
+ limits.absoluteRate.sendMessage.window,
+ ),
+ ),
+ },
});
if (count >= limits.absoluteRate.sendMessage.limit)
throw FieldErrors({
- channel_id: { code: "TOO_MANY_MESSAGES", message: req.t("common:toomany.MESSAGE") }
+ channel_id: {
+ code: "TOO_MANY_MESSAGES",
+ message: req.t("common:toomany.MESSAGE"),
+ },
});
}
}
@@ -247,7 +261,7 @@ router.post(
Attachment.create({ ...file, proxy_url: file.url }),
);
} catch (error) {
- return res.status(400).json({ message: error!.toString() })
+ return res.status(400).json({ message: error!.toString() });
}
}
@@ -296,19 +310,18 @@ router.post(
if (!message.member) {
message.member = await Member.findOneOrFail({
where: { id: req.user_id, guild_id: message.guild_id },
- relations: ["roles"]
+ relations: ["roles"],
});
}
//@ts-ignore
- message.member.roles =
- message.member.roles.
- filter(x => x.id != x.guild_id)
- .map(x => x.id);
+ message.member.roles = message.member.roles
+ .filter((x) => x.id != x.guild_id)
+ .map((x) => x.id);
}
let read_state = await ReadState.findOne({
- where: { user_id: req.user_id, channel_id }
+ where: { user_id: req.user_id, channel_id },
});
if (!read_state)
read_state = ReadState.create({ user_id: req.user_id, channel_id });
@@ -324,14 +337,14 @@ router.post(
} as MessageCreateEvent),
message.guild_id
? Member.update(
- { id: req.user_id, guild_id: message.guild_id },
- { last_message_id: message.id },
- )
+ { id: req.user_id, guild_id: message.guild_id },
+ { last_message_id: message.id },
+ )
: null,
channel.save(),
]);
- postHandleMessage(message).catch((e) => { }); // no await as it shouldnt block the message send function and silently catch error
+ postHandleMessage(message).catch((e) => {}); // no await as it shouldnt block the message send function and silently catch error
return res.json(message);
},
diff --git a/src/api/routes/channels/#channel_id/permissions.ts b/src/api/routes/channels/#channel_id/permissions.ts
index 0a816223..b08cd0c8 100644
--- a/src/api/routes/channels/#channel_id/permissions.ts
+++ b/src/api/routes/channels/#channel_id/permissions.ts
@@ -5,7 +5,7 @@ import {
emitEvent,
Member,
Role,
- ChannelPermissionOverwriteSchema
+ ChannelPermissionOverwriteSchema,
} from "@fosscord/util";
import { Router, Response, Request } from "express";
import { HTTPError } from "lambert-server";
diff --git a/src/api/routes/channels/#channel_id/webhooks.ts b/src/api/routes/channels/#channel_id/webhooks.ts
index 13f421f1..f303ef80 100644
--- a/src/api/routes/channels/#channel_id/webhooks.ts
+++ b/src/api/routes/channels/#channel_id/webhooks.ts
@@ -1,6 +1,15 @@
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
-import { Channel, Config, handleFile, trimSpecial, User, Webhook, WebhookCreateSchema, WebhookType } from "@fosscord/util";
+import {
+ Channel,
+ Config,
+ handleFile,
+ trimSpecial,
+ User,
+ Webhook,
+ WebhookCreateSchema,
+ WebhookType,
+} from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { isTextChannel } from "./messages/index";
import { DiscordApiErrors } from "@fosscord/util";
@@ -38,8 +47,7 @@ router.post(
if (name === "clyde") throw new HTTPError("Invalid name", 400);
if (name === "Fosscord Ghost") throw new HTTPError("Invalid name", 400);
- if (avatar)
- avatar = await handleFile(`/avatars/${channel_id}`, avatar);
+ if (avatar) avatar = await handleFile(`/avatars/${channel_id}`, avatar);
const hook = Webhook.create({
type: WebhookType.Incoming,
diff --git a/src/api/routes/download/index.ts b/src/api/routes/download/index.ts
index 371c0fd7..1c135f25 100644
--- a/src/api/routes/download/index.ts
+++ b/src/api/routes/download/index.ts
@@ -12,19 +12,20 @@ const router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {
const { platform } = req.query;
- if (!platform) throw FieldErrors({
- platform: {
- code: "BASE_TYPE_REQUIRED",
- message: req.t("common:field.BASE_TYPE_REQUIRED"),
- }
- });
+ if (!platform)
+ throw FieldErrors({
+ platform: {
+ code: "BASE_TYPE_REQUIRED",
+ message: req.t("common:field.BASE_TYPE_REQUIRED"),
+ },
+ });
const release = await Release.findOneOrFail({
where: {
enabled: true,
platform: platform as string,
},
- order: { pub_date: "DESC" }
+ order: { pub_date: "DESC" },
});
res.redirect(release.url);
diff --git a/src/api/routes/guild-recommendations.ts b/src/api/routes/guild-recommendations.ts
index 302bbb9c..8bf1e508 100644
--- a/src/api/routes/guild-recommendations.ts
+++ b/src/api/routes/guild-recommendations.ts
@@ -9,7 +9,7 @@ const router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {
const { limit, personalization_disabled } = req.query;
var showAllGuilds = Config.get().guild.discovery.showAllGuilds;
-
+
const genLoadId = (size: Number) =>
[...Array(size)]
.map(() => Math.floor(Math.random() * 16).toString(16))
diff --git a/src/api/routes/guilds/#guild_id/index.ts b/src/api/routes/guilds/#guild_id/index.ts
index 1e976293..79c20678 100644
--- a/src/api/routes/guilds/#guild_id/index.ts
+++ b/src/api/routes/guilds/#guild_id/index.ts
@@ -69,15 +69,21 @@ router.patch(
body.splash,
);
- if (body.discovery_splash && body.discovery_splash !== guild.discovery_splash)
+ if (
+ body.discovery_splash &&
+ body.discovery_splash !== guild.discovery_splash
+ )
body.discovery_splash = await handleFile(
`/discovery-splashes/${guild_id}`,
body.discovery_splash,
);
if (body.features) {
- const diff = guild.features.filter(x => !body.features?.includes(x))
- .concat(body.features.filter(x => !guild.features.includes(x)));
+ const diff = guild.features
+ .filter((x) => !body.features?.includes(x))
+ .concat(
+ body.features.filter((x) => !guild.features.includes(x)),
+ );
// TODO move these
const MUTABLE_FEATURES = [
@@ -89,7 +95,9 @@ router.patch(
for (var feature of diff) {
if (MUTABLE_FEATURES.includes(feature)) continue;
- throw FosscordApiErrors.FEATURE_IS_IMMUTABLE.withParams(feature);
+ throw FosscordApiErrors.FEATURE_IS_IMMUTABLE.withParams(
+ feature,
+ );
}
// for some reason, they don't update in the assign.
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 f1d343d9..0fcdd57c 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
@@ -27,42 +27,56 @@ router.get("/", route({}), async (req: Request, res: Response) => {
return res.json(member);
});
-router.patch("/", route({ body: "MemberChangeSchema" }), async (req: Request, res: Response) => {
- let { guild_id, member_id } = req.params;
- if (member_id === "@me") member_id = req.user_id;
- const body = req.body as MemberChangeSchema;
-
- let member = await Member.findOneOrFail({ where: { id: member_id, guild_id }, relations: ["roles", "user"] });
- const permission = await getPermission(req.user_id, guild_id);
- const everyone = await Role.findOneOrFail({ where: { guild_id: guild_id, name: "@everyone", position: 0 } });
-
- if (body.avatar) body.avatar = await handleFile(`/guilds/${guild_id}/users/${member_id}/avatars`, body.avatar as string);
-
- member.assign(body);
-
- if ('roles' in body) {
- permission.hasThrow("MANAGE_ROLES");
-
- body.roles = body.roles || [];
- body.roles.filter(x => !!x);
-
- if (body.roles.indexOf(everyone.id) === -1) body.roles.push(everyone.id);
- member.roles = body.roles.map((x) => Role.create({ id: x })); // foreign key constraint will fail if role doesn't exist
- }
-
- await member.save();
-
- member.roles = member.roles.filter((x) => x.id !== everyone.id);
-
- // do not use promise.all as we have to first write to db before emitting the event to catch errors
- await emitEvent({
- event: "GUILD_MEMBER_UPDATE",
- guild_id,
- data: { ...member, roles: member.roles.map((x) => x.id) }
- } as GuildMemberUpdateEvent);
-
- res.json(member);
-});
+router.patch(
+ "/",
+ route({ body: "MemberChangeSchema" }),
+ async (req: Request, res: Response) => {
+ let { guild_id, member_id } = req.params;
+ if (member_id === "@me") member_id = req.user_id;
+ const body = req.body as MemberChangeSchema;
+
+ let member = await Member.findOneOrFail({
+ where: { id: member_id, guild_id },
+ relations: ["roles", "user"],
+ });
+ const permission = await getPermission(req.user_id, guild_id);
+ const everyone = await Role.findOneOrFail({
+ where: { guild_id: guild_id, name: "@everyone", position: 0 },
+ });
+
+ if (body.avatar)
+ body.avatar = await handleFile(
+ `/guilds/${guild_id}/users/${member_id}/avatars`,
+ body.avatar as string,
+ );
+
+ member.assign(body);
+
+ if ("roles" in body) {
+ permission.hasThrow("MANAGE_ROLES");
+
+ body.roles = body.roles || [];
+ body.roles.filter((x) => !!x);
+
+ if (body.roles.indexOf(everyone.id) === -1)
+ body.roles.push(everyone.id);
+ member.roles = body.roles.map((x) => Role.create({ id: x })); // foreign key constraint will fail if role doesn't exist
+ }
+
+ await member.save();
+
+ member.roles = member.roles.filter((x) => x.id !== everyone.id);
+
+ // do not use promise.all as we have to first write to db before emitting the event to catch errors
+ await emitEvent({
+ event: "GUILD_MEMBER_UPDATE",
+ guild_id,
+ data: { ...member, roles: member.roles.map((x) => x.id) },
+ } as GuildMemberUpdateEvent);
+
+ res.json(member);
+ },
+);
router.put("/", route({}), async (req: Request, res: Response) => {
// TODO: Lurker mode
diff --git a/src/api/routes/guilds/#guild_id/messages/search.ts b/src/api/routes/guilds/#guild_id/messages/search.ts
index ccee59f7..88488871 100644
--- a/src/api/routes/guilds/#guild_id/messages/search.ts
+++ b/src/api/routes/guilds/#guild_id/messages/search.ts
@@ -72,12 +72,20 @@ router.get("/", route({}), async (req: Request, res: Response) => {
if (channel_id) query.where!.channel = { id: channel_id };
else {
// get all channel IDs that this user can access
- const channels = await Channel.find({ where: { guild_id: req.params.guild_id }, select: ["id"] });
+ const channels = await Channel.find({
+ where: { guild_id: req.params.guild_id },
+ select: ["id"],
+ });
const ids = [];
for (var channel of channels) {
- const perm = await getPermission(req.user_id, req.params.guild_id, channel.id);
- if (!perm.has("VIEW_CHANNEL") || !perm.has("READ_MESSAGE_HISTORY")) continue;
+ const perm = await getPermission(
+ req.user_id,
+ req.params.guild_id,
+ channel.id,
+ );
+ if (!perm.has("VIEW_CHANNEL") || !perm.has("READ_MESSAGE_HISTORY"))
+ continue;
ids.push(channel.id);
}
diff --git a/src/api/routes/guilds/#guild_id/profile/index.ts b/src/api/routes/guilds/#guild_id/profile/index.ts
index ddc30943..20a7fa95 100644
--- a/src/api/routes/guilds/#guild_id/profile/index.ts
+++ b/src/api/routes/guilds/#guild_id/profile/index.ts
@@ -1,30 +1,48 @@
import { route } from "@fosscord/api";
-import { emitEvent, GuildMemberUpdateEvent, handleFile, Member, MemberChangeProfileSchema, OrmUtils } from "@fosscord/util";
+import {
+ emitEvent,
+ GuildMemberUpdateEvent,
+ handleFile,
+ Member,
+ MemberChangeProfileSchema,
+ OrmUtils,
+} from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();
-router.patch("/:member_id", route({ body: "MemberChangeProfileSchema" }), async (req: Request, res: Response) => {
- let { guild_id, member_id } = req.params;
- if (member_id === "@me") member_id = req.user_id;
- const body = req.body as MemberChangeProfileSchema;
-
- let member = await Member.findOneOrFail({ where: { id: req.user_id, guild_id }, relations: ["roles", "user"] });
-
- if (body.banner) body.banner = await handleFile(`/guilds/${guild_id}/users/${req.user_id}/avatars`, body.banner as string);
-
- member = await OrmUtils.mergeDeep(member, body);
-
- await member.save();
-
- // do not use promise.all as we have to first write to db before emitting the event to catch errors
- await emitEvent({
- event: "GUILD_MEMBER_UPDATE",
- guild_id,
- data: { ...member, roles: member.roles.map((x) => x.id) }
- } as GuildMemberUpdateEvent);
-
- res.json(member);
-});
+router.patch(
+ "/:member_id",
+ route({ body: "MemberChangeProfileSchema" }),
+ async (req: Request, res: Response) => {
+ let { guild_id, member_id } = req.params;
+ if (member_id === "@me") member_id = req.user_id;
+ const body = req.body as MemberChangeProfileSchema;
+
+ let member = await Member.findOneOrFail({
+ where: { id: req.user_id, guild_id },
+ relations: ["roles", "user"],
+ });
+
+ if (body.banner)
+ body.banner = await handleFile(
+ `/guilds/${guild_id}/users/${req.user_id}/avatars`,
+ body.banner as string,
+ );
+
+ member = await OrmUtils.mergeDeep(member, body);
+
+ await member.save();
+
+ // do not use promise.all as we have to first write to db before emitting the event to catch errors
+ await emitEvent({
+ event: "GUILD_MEMBER_UPDATE",
+ guild_id,
+ data: { ...member, roles: member.roles.map((x) => x.id) },
+ } as GuildMemberUpdateEvent);
+
+ res.json(member);
+ },
+);
export default router;
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 cd5959ff..84648703 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
@@ -63,12 +63,14 @@ router.patch(
);
else body.icon = undefined;
- const role = await Role.findOneOrFail({ where: { id: role_id, guild: { id: guild_id } } });
+ const role = await Role.findOneOrFail({
+ where: { id: role_id, guild: { id: guild_id } },
+ });
role.assign({
...body,
permissions: String(
- req.permission!.bitfield & BigInt(body.permissions || "0")
- )
+ req.permission!.bitfield & BigInt(body.permissions || "0"),
+ ),
});
await Promise.all([
diff --git a/src/api/routes/guilds/#guild_id/roles/index.ts b/src/api/routes/guilds/#guild_id/roles/index.ts
index 534a5967..4cd47cf3 100644
--- a/src/api/routes/guilds/#guild_id/roles/index.ts
+++ b/src/api/routes/guilds/#guild_id/roles/index.ts
@@ -61,9 +61,13 @@ router.post(
await Promise.all([
role.save(),
// Move all existing roles up one position, to accommodate the new role
- Role.createQueryBuilder('roles')
- .where({ guild: { id: guild_id }, name: Not("@everyone"), id: Not(role.id) })
- .update({ position: () => 'position + 1' })
+ Role.createQueryBuilder("roles")
+ .where({
+ guild: { id: guild_id },
+ name: Not("@everyone"),
+ id: Not(role.id),
+ })
+ .update({ position: () => "position + 1" })
.execute(),
emitEvent({
event: "GUILD_ROLE_CREATE",
diff --git a/src/api/routes/oauth2/authorize.ts b/src/api/routes/oauth2/authorize.ts
index e4c2e986..6374972e 100644
--- a/src/api/routes/oauth2/authorize.ts
+++ b/src/api/routes/oauth2/authorize.ts
@@ -1,17 +1,24 @@
import { Router, Request, Response } from "express";
import { route } from "@fosscord/api";
-import { ApiError, Application, ApplicationAuthorizeSchema, getPermission, DiscordApiErrors, Member, Permissions, User, getRights, Rights, MemberPrivateProjection } from "@fosscord/util";
+import {
+ ApiError,
+ Application,
+ ApplicationAuthorizeSchema,
+ getPermission,
+ DiscordApiErrors,
+ Member,
+ Permissions,
+ User,
+ getRights,
+ Rights,
+ MemberPrivateProjection,
+} from "@fosscord/util";
const router = Router();
// TODO: scopes, other oauth types
router.get("/", route({}), async (req: Request, res: Response) => {
- const {
- client_id,
- scope,
- response_type,
- redirect_url,
- } = req.query;
+ const { client_id, scope, response_type, redirect_url } = req.query;
const app = await Application.findOne({
where: {
@@ -33,7 +40,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
id: req.user_id,
bot: false,
},
- select: ["id", "username", "avatar", "discriminator", "public_flags"]
+ select: ["id", "username", "avatar", "discriminator", "public_flags"],
});
const guilds = await Member.find({
@@ -44,21 +51,23 @@ router.get("/", route({}), async (req: Request, res: Response) => {
},
relations: ["guild", "roles"],
//@ts-ignore
- select: ["guild.id", "guild.name", "guild.icon", "guild.mfa_level", "guild.owner_id", "roles.id"]
+ // prettier-ignore
+ select: ["guild.id", "guild.name", "guild.icon", "guild.mfa_level", "guild.owner_id", "roles.id"],
});
- const guildsWithPermissions = guilds.map(x => {
- const perms = x.guild.owner_id === user.id
- ? new Permissions(Permissions.FLAGS.ADMINISTRATOR)
- : Permissions.finalPermission({
- user: {
- id: user.id,
- roles: x.roles?.map(x => x.id) || [],
- },
- guild: {
- roles: x?.roles || [],
- }
- });
+ const guildsWithPermissions = guilds.map((x) => {
+ const perms =
+ x.guild.owner_id === user.id
+ ? new Permissions(Permissions.FLAGS.ADMINISTRATOR)
+ : Permissions.finalPermission({
+ user: {
+ id: user.id,
+ roles: x.roles?.map((x) => x.id) || [],
+ },
+ guild: {
+ roles: x?.roles || [],
+ },
+ });
return {
id: x.guild.id,
@@ -75,7 +84,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
id: user.id,
username: user.username,
avatar: user.avatar,
- avatar_decoration: null, // TODO
+ avatar_decoration: null, // TODO
discriminator: user.discriminator,
public_flags: user.public_flags,
},
@@ -87,7 +96,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
summary: app.summary,
type: app.type,
hook: app.hook,
- guild_id: null, // TODO support guilds
+ guild_id: null, // TODO support guilds
bot_public: app.bot_public,
bot_require_code_grant: app.bot_require_code_grant,
verify_key: app.verify_key,
@@ -97,50 +106,63 @@ router.get("/", route({}), async (req: Request, res: Response) => {
id: bot.id,
username: bot.username,
avatar: bot.avatar,
- avatar_decoration: null, // TODO
+ avatar_decoration: null, // TODO
discriminator: bot.discriminator,
public_flags: bot.public_flags,
bot: true,
- approximated_guild_count: 0, // TODO
+ approximated_guild_count: 0, // TODO
},
authorized: false,
});
});
-router.post("/", route({ body: "ApplicationAuthorizeSchema" }), async (req: Request, res: Response) => {
- const body = req.body as ApplicationAuthorizeSchema;
- const {
- client_id,
- scope,
- response_type,
- redirect_url
- } = req.query;
-
- // TODO: captcha verification
- // TODO: MFA verification
-
- const perms = await getPermission(req.user_id, body.guild_id, undefined, { member_relations: ["user"] });
- // getPermission cache won't exist if we're owner
- if (Object.keys(perms.cache || {}).length > 0 && perms.cache.member!.user.bot) throw DiscordApiErrors.UNAUTHORIZED;
- perms.hasThrow("MANAGE_GUILD");
-
- const app = await Application.findOne({
- where: {
- id: client_id as string,
- },
- relations: ["bot"],
- });
-
- // TODO: use DiscordApiErrors
- // findOneOrFail throws code 404
- if (!app) throw new ApiError("Unknown Application", 10002, 404);
- if (!app.bot) throw new ApiError("OAuth2 application does not have a bot", 50010, 400);
-
- await Member.addToGuild(app.id, body.guild_id);
-
- return res.json({
- location: "/oauth2/authorized", // redirect URL
- });
-});
+router.post(
+ "/",
+ route({ body: "ApplicationAuthorizeSchema" }),
+ async (req: Request, res: Response) => {
+ const body = req.body as ApplicationAuthorizeSchema;
+ const { client_id, scope, response_type, redirect_url } = req.query;
+
+ // TODO: captcha verification
+ // TODO: MFA verification
+
+ const perms = await getPermission(
+ req.user_id,
+ body.guild_id,
+ undefined,
+ { member_relations: ["user"] },
+ );
+ // getPermission cache won't exist if we're owner
+ if (
+ Object.keys(perms.cache || {}).length > 0 &&
+ perms.cache.member!.user.bot
+ )
+ throw DiscordApiErrors.UNAUTHORIZED;
+ perms.hasThrow("MANAGE_GUILD");
+
+ const app = await Application.findOne({
+ where: {
+ id: client_id as string,
+ },
+ relations: ["bot"],
+ });
+
+ // TODO: use DiscordApiErrors
+ // findOneOrFail throws code 404
+ if (!app) throw new ApiError("Unknown Application", 10002, 404);
+ if (!app.bot)
+ throw new ApiError(
+ "OAuth2 application does not have a bot",
+ 50010,
+ 400,
+ );
+
+ await Member.addToGuild(app.id, body.guild_id);
+
+ return res.json({
+ location: "/oauth2/authorized", // redirect URL
+ });
+ },
+);
export default router;
diff --git a/src/api/routes/policies/stats.ts b/src/api/routes/policies/stats.ts
index 5ef4c3c6..dc4652fc 100644
--- a/src/api/routes/policies/stats.ts
+++ b/src/api/routes/policies/stats.ts
@@ -1,5 +1,12 @@
import { route } from "@fosscord/api";
-import { Config, getRights, Guild, Member, Message, User } from "@fosscord/util";
+import {
+ Config,
+ getRights,
+ Guild,
+ Member,
+ Message,
+ User,
+} from "@fosscord/util";
import { Request, Response, Router } from "express";
const router = Router();
@@ -15,7 +22,7 @@ router.get("/", route({}), async (req: Request, res: Response) => {
guild: await Guild.count(),
message: await Message.count(),
members: await Member.count(),
- }
+ },
});
});
diff --git a/src/api/routes/stop.ts b/src/api/routes/stop.ts
index 1b4e1da9..3f49b360 100644
--- a/src/api/routes/stop.ts
+++ b/src/api/routes/stop.ts
@@ -3,10 +3,14 @@ import { route } from "@fosscord/api";
const router: Router = Router();
-router.post("/", route({ right: "OPERATOR" }), async (req: Request, res: Response) => {
- console.log(`/stop was called by ${req.user_id} at ${new Date()}`);
- res.sendStatus(200);
- process.kill(process.pid, "SIGTERM");
-});
+router.post(
+ "/",
+ route({ right: "OPERATOR" }),
+ async (req: Request, res: Response) => {
+ console.log(`/stop was called by ${req.user_id} at ${new Date()}`);
+ res.sendStatus(200);
+ process.kill(process.pid, "SIGTERM");
+ },
+);
-export default router;
\ No newline at end of file
+export default router;
diff --git a/src/api/routes/store/published-listings/skus/#sku_id/subscription-plans.ts b/src/api/routes/store/published-listings/skus/#sku_id/subscription-plans.ts
index 7c544921..6b49e959 100644
--- a/src/api/routes/store/published-listings/skus/#sku_id/subscription-plans.ts
+++ b/src/api/routes/store/published-listings/skus/#sku_id/subscription-plans.ts
@@ -16,7 +16,7 @@ const skus = new Map([
sku_id: "521842865731534868",
currency: "eur",
price: 0,
- price_tier: null
+ price_tier: null,
},
{
id: "511651860671627264",
@@ -27,9 +27,9 @@ const skus = new Map([
sku_id: "521842865731534868",
currency: "eur",
price: 0,
- price_tier: null
- }
- ]
+ price_tier: null,
+ },
+ ],
],
[
"521846918637420545",
@@ -43,7 +43,7 @@ const skus = new Map([
sku_id: "521846918637420545",
currency: "eur",
price: 0,
- price_tier: null
+ price_tier: null,
},
{
id: "511651876987469824",
@@ -54,7 +54,7 @@ const skus = new Map([
sku_id: "521846918637420545",
currency: "eur",
price: 0,
- price_tier: null
+ price_tier: null,
},
{
id: "978380684370378761",
@@ -65,9 +65,9 @@ const skus = new Map([
sku_id: "521846918637420545",
currency: "eur",
price: 0,
- price_tier: null
- }
- ]
+ price_tier: null,
+ },
+ ],
],
[
"521847234246082599",
@@ -81,7 +81,7 @@ const skus = new Map([
sku_id: "521847234246082599",
currency: "eur",
price: 0,
- price_tier: null
+ price_tier: null,
},
{
id: "511651880837840896",
@@ -92,7 +92,7 @@ const skus = new Map([
sku_id: "521847234246082599",
currency: "eur",
price: 0,
- price_tier: null
+ price_tier: null,
},
{
id: "511651885459963904",
@@ -103,9 +103,9 @@ const skus = new Map([
sku_id: "521847234246082599",
currency: "eur",
price: 0,
- price_tier: null
- }
- ]
+ price_tier: null,
+ },
+ ],
],
[
"590663762298667008",
@@ -120,7 +120,7 @@ const skus = new Map([
discount_price: 0,
currency: "eur",
price: 0,
- price_tier: null
+ price_tier: null,
},
{
id: "590665538238152709",
@@ -132,9 +132,9 @@ const skus = new Map([
discount_price: 0,
currency: "eur",
price: 0,
- price_tier: null
- }
- ]
+ price_tier: null,
+ },
+ ],
],
[
"978380684370378762",
@@ -158,33 +158,33 @@ const skus = new Map([
{
currency: "usd",
amount: 0,
- exponent: 2
- }
- ]
+ exponent: 2,
+ },
+ ],
},
payment_source_prices: {
"775487223059316758": [
{
currency: "usd",
amount: 0,
- exponent: 2
- }
+ exponent: 2,
+ },
],
"736345864146255982": [
{
currency: "usd",
amount: 0,
- exponent: 2
- }
+ exponent: 2,
+ },
],
"683074999590060249": [
{
currency: "usd",
amount: 0,
- exponent: 2
- }
- ]
- }
+ exponent: 2,
+ },
+ ],
+ },
},
"3": {
country_prices: {
@@ -193,33 +193,33 @@ const skus = new Map([
{
currency: "usd",
amount: 0,
- exponent: 2
- }
- ]
+ exponent: 2,
+ },
+ ],
},
payment_source_prices: {
"775487223059316758": [
{
currency: "usd",
amount: 0,
- exponent: 2
- }
+ exponent: 2,
+ },
],
"736345864146255982": [
{
currency: "usd",
amount: 0,
- exponent: 2
- }
+ exponent: 2,
+ },
],
"683074999590060249": [
{
currency: "usd",
amount: 0,
- exponent: 2
- }
- ]
- }
+ exponent: 2,
+ },
+ ],
+ },
},
"4": {
country_prices: {
@@ -228,33 +228,33 @@ const skus = new Map([
{
currency: "usd",
amount: 0,
- exponent: 2
- }
- ]
+ exponent: 2,
+ },
+ ],
},
payment_source_prices: {
"775487223059316758": [
{
currency: "usd",
amount: 0,
- exponent: 2
- }
+ exponent: 2,
+ },
],
"736345864146255982": [
{
currency: "usd",
amount: 0,
- exponent: 2
- }
+ exponent: 2,
+ },
],
"683074999590060249": [
{
currency: "usd",
amount: 0,
- exponent: 2
- }
- ]
- }
+ exponent: 2,
+ },
+ ],
+ },
},
"1": {
country_prices: {
@@ -263,39 +263,39 @@ const skus = new Map([
{
currency: "usd",
amount: 0,
- exponent: 2
- }
- ]
+ exponent: 2,
+ },
+ ],
},
payment_source_prices: {
"775487223059316758": [
{
currency: "usd",
amount: 0,
- exponent: 2
- }
+ exponent: 2,
+ },
],
"736345864146255982": [
{
currency: "usd",
amount: 0,
- exponent: 2
- }
+ exponent: 2,
+ },
],
"683074999590060249": [
{
currency: "usd",
amount: 0,
- exponent: 2
- }
- ]
- }
- }
- }
- }
- ]
- ]
- ]
+ exponent: 2,
+ },
+ ],
+ },
+ },
+ },
+ },
+ ],
+ ],
+ ],
]);
router.get("/", route({}), async (req: Request, res: Response) => {
diff --git a/src/api/routes/updates.ts b/src/api/routes/updates.ts
index 275c458b..7e9128f4 100644
--- a/src/api/routes/updates.ts
+++ b/src/api/routes/updates.ts
@@ -8,19 +8,20 @@ router.get("/", route({}), async (req: Request, res: Response) => {
const { client } = Config.get();
const platform = req.query.platform;
- if (!platform) throw FieldErrors({
- platform: {
- code: "BASE_TYPE_REQUIRED",
- message: req.t("common:field.BASE_TYPE_REQUIRED"),
- }
- });
+ if (!platform)
+ throw FieldErrors({
+ platform: {
+ code: "BASE_TYPE_REQUIRED",
+ message: req.t("common:field.BASE_TYPE_REQUIRED"),
+ },
+ });
const release = await Release.findOneOrFail({
where: {
enabled: true,
platform: platform as string,
},
- order: { pub_date: "DESC" }
+ order: { pub_date: "DESC" },
});
res.json({
diff --git a/src/api/routes/users/#id/profile.ts b/src/api/routes/users/#id/profile.ts
index ac844427..5c649056 100644
--- a/src/api/routes/users/#id/profile.ts
+++ b/src/api/routes/users/#id/profile.ts
@@ -89,79 +89,94 @@ router.get(
bot: user.bot,
};
- const userProfile = {
- bio: req.user_bot ? null : user.bio,
- accent_color: user.accent_color,
- banner: user.banner,
- pronouns: user.pronouns,
- theme_colors: user.theme_colors,
- };
-
- const guildMemberDto = guild_member
- ? {
- avatar: guild_member.avatar,
- banner: guild_member.banner,
- bio: req.user_bot ? null : guild_member.bio,
- communication_disabled_until: guild_member.communication_disabled_until,
- deaf: guild_member.deaf,
- flags: user.flags,
- is_pending: guild_member.pending,
- pending: guild_member.pending, // why is this here twice, discord?
- joined_at: guild_member.joined_at,
- mute: guild_member.mute,
- nick: guild_member.nick,
- premium_since: guild_member.premium_since,
- roles: guild_member.roles.map((x) => x.id).filter((id) => id != guild_id),
- user: userDto
- }
- : undefined;
-
- const guildMemberProfile = {
- accent_color: null,
- banner: guild_member?.banner || null,
- bio: guild_member?.bio || "",
- guild_id
- };
- res.json({
- connected_accounts: user.connected_accounts,
- premium_guild_since: premium_guild_since, // TODO
- premium_since: user.premium_since, // TODO
- mutual_guilds: mutual_guilds, // TODO {id: "", nick: null} when ?with_mutual_guilds=true
- user: userDto,
- premium_type: user.premium_type,
- profile_themes_experiment_bucket: 4, // TODO: This doesn't make it available, for some reason?
- user_profile: userProfile,
- guild_member: guild_id && guildMemberDto,
- guild_member_profile: guild_id && guildMemberProfile
- });
-});
-
-router.patch("/", route({ body: "UserProfileModifySchema" }), async (req: Request, res: Response) => {
- const body = req.body as UserProfileModifySchema;
-
- if (body.banner) body.banner = await handleFile(`/banners/${req.user_id}`, body.banner as string);
- let user = await User.findOneOrFail({ where: { id: req.user_id }, select: [...PrivateUserProjection, "data"] });
-
- user.assign(body);
- await user.save();
-
- // @ts-ignore
- delete user.data;
-
- // TODO: send update member list event in gateway
- await emitEvent({
- event: "USER_UPDATE",
- user_id: req.user_id,
- data: user
- } as UserUpdateEvent);
-
- res.json({
- accent_color: user.accent_color,
- bio: user.bio,
- banner: user.banner,
- theme_colors: user.theme_colors,
- pronouns: user.pronouns,
- });
-});
+ const userProfile = {
+ bio: req.user_bot ? null : user.bio,
+ accent_color: user.accent_color,
+ banner: user.banner,
+ pronouns: user.pronouns,
+ theme_colors: user.theme_colors,
+ };
+
+ const guildMemberDto = guild_member
+ ? {
+ avatar: guild_member.avatar,
+ banner: guild_member.banner,
+ bio: req.user_bot ? null : guild_member.bio,
+ communication_disabled_until:
+ guild_member.communication_disabled_until,
+ deaf: guild_member.deaf,
+ flags: user.flags,
+ is_pending: guild_member.pending,
+ pending: guild_member.pending, // why is this here twice, discord?
+ joined_at: guild_member.joined_at,
+ mute: guild_member.mute,
+ nick: guild_member.nick,
+ premium_since: guild_member.premium_since,
+ roles: guild_member.roles
+ .map((x) => x.id)
+ .filter((id) => id != guild_id),
+ user: userDto,
+ }
+ : undefined;
+
+ const guildMemberProfile = {
+ accent_color: null,
+ banner: guild_member?.banner || null,
+ bio: guild_member?.bio || "",
+ guild_id,
+ };
+ res.json({
+ connected_accounts: user.connected_accounts,
+ premium_guild_since: premium_guild_since, // TODO
+ premium_since: user.premium_since, // TODO
+ mutual_guilds: mutual_guilds, // TODO {id: "", nick: null} when ?with_mutual_guilds=true
+ user: userDto,
+ premium_type: user.premium_type,
+ profile_themes_experiment_bucket: 4, // TODO: This doesn't make it available, for some reason?
+ user_profile: userProfile,
+ guild_member: guild_id && guildMemberDto,
+ guild_member_profile: guild_id && guildMemberProfile,
+ });
+ },
+);
+
+router.patch(
+ "/",
+ route({ body: "UserProfileModifySchema" }),
+ async (req: Request, res: Response) => {
+ const body = req.body as UserProfileModifySchema;
+
+ if (body.banner)
+ body.banner = await handleFile(
+ `/banners/${req.user_id}`,
+ body.banner as string,
+ );
+ let user = await User.findOneOrFail({
+ where: { id: req.user_id },
+ select: [...PrivateUserProjection, "data"],
+ });
+
+ user.assign(body);
+ await user.save();
+
+ // @ts-ignore
+ delete user.data;
+
+ // TODO: send update member list event in gateway
+ await emitEvent({
+ event: "USER_UPDATE",
+ user_id: req.user_id,
+ data: user,
+ } as UserUpdateEvent);
+
+ res.json({
+ accent_color: user.accent_color,
+ bio: user.bio,
+ banner: user.banner,
+ theme_colors: user.theme_colors,
+ pronouns: user.pronouns,
+ });
+ },
+);
export default router;
diff --git a/src/api/routes/users/@me/guilds/#guild_id/settings.ts b/src/api/routes/users/@me/guilds/#guild_id/settings.ts
index 4538785c..436261d4 100644
--- a/src/api/routes/users/@me/guilds/#guild_id/settings.ts
+++ b/src/api/routes/users/@me/guilds/#guild_id/settings.ts
@@ -32,8 +32,7 @@ router.patch(
const user = await Member.findOneOrFail({
where: { id: req.user_id, guild_id: req.params.guild_id },
- select: ["settings"]
-
+ select: ["settings"],
});
OrmUtils.mergeDeep(user.settings || {}, body);
Member.update({ id: req.user_id, guild_id: req.params.guild_id }, user);
diff --git a/src/api/routes/users/@me/index.ts b/src/api/routes/users/@me/index.ts
index 3ac48f27..37356d9d 100644
--- a/src/api/routes/users/@me/index.ts
+++ b/src/api/routes/users/@me/index.ts
@@ -98,7 +98,7 @@ router.patch(
}
user.data.hash = await bcrypt.hash(body.new_password, 12);
user.data.valid_tokens_since = new Date();
- newToken = await generateToken(user.id) as string;
+ newToken = (await generateToken(user.id)) as string;
}
if (body.username) {
diff --git a/src/api/routes/users/@me/settings.ts b/src/api/routes/users/@me/settings.ts
index 0fd8220a..cce366ac 100644
--- a/src/api/routes/users/@me/settings.ts
+++ b/src/api/routes/users/@me/settings.ts
@@ -21,7 +21,7 @@ router.patch(
const user = await User.findOneOrFail({
where: { id: req.user_id, bot: false },
- relations: ["settings"]
+ relations: ["settings"],
});
user.settings.assign(body);
diff --git a/src/api/util/handlers/Message.ts b/src/api/util/handlers/Message.ts
index 37269185..93dc3bf4 100644
--- a/src/api/util/handlers/Message.ts
+++ b/src/api/util/handlers/Message.ts
@@ -53,7 +53,7 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
channel_id: opts.channel_id,
attachments: opts.attachments || [],
embeds: opts.embeds || [],
- reactions: /*opts.reactions ||*/[],
+ reactions: /*opts.reactions ||*/ [],
type: opts.type ?? 0,
});
@@ -180,7 +180,7 @@ export async function handleMessage(opts: MessageOptions): Promise<Message> {
// TODO: cache link result in db
export async function postHandleMessage(message: Message) {
- const content = message.content?.replace(/ *\`[^)]*\` */g, ""); // remove markdown
+ const content = message.content?.replace(/ *\`[^)]*\` */g, ""); // remove markdown
var links = content?.match(LINK_REGEX);
if (!links) return;
@@ -201,8 +201,12 @@ export async function postHandleMessage(message: Message) {
}
// bit gross, but whatever!
- const endpointPublic = Config.get().cdn.endpointPublic || "http://127.0.0.1"; // lol
- const handler = url.hostname == new URL(endpointPublic).hostname ? EmbedHandlers["self"] : EmbedHandlers[url.hostname] || EmbedHandlers["default"];
+ const endpointPublic =
+ Config.get().cdn.endpointPublic || "http://127.0.0.1"; // lol
+ const handler =
+ url.hostname == new URL(endpointPublic).hostname
+ ? EmbedHandlers["self"]
+ : EmbedHandlers[url.hostname] || EmbedHandlers["default"];
try {
let res = await handler(url);
@@ -218,11 +222,10 @@ export async function postHandleMessage(message: Message) {
cachePromises.push(cache.save());
data.embeds.push(embed);
}
- }
- catch (e) {
- Sentry.captureException(e, scope => {
+ } catch (e) {
+ Sentry.captureException(e, (scope) => {
scope.clear();
- scope.setContext("request", { url })
+ scope.setContext("request", { url });
return scope;
});
continue;
@@ -257,7 +260,7 @@ export async function sendMessage(opts: MessageOptions) {
} as MessageCreateEvent),
]);
- postHandleMessage(message).catch((e) => { }); // no await as it should catch error non-blockingly
+ postHandleMessage(message).catch((e) => {}); // no await as it should catch error non-blockingly
return message;
}
diff --git a/src/api/util/index.ts b/src/api/util/index.ts
index ffad0607..5921f011 100644
--- a/src/api/util/index.ts
+++ b/src/api/util/index.ts
@@ -7,4 +7,4 @@ export * from "./handlers/route";
export * from "./utility/String";
export * from "./handlers/Voice";
export * from "./utility/captcha";
-export * from "./utility/EmbedHandlers";
\ No newline at end of file
+export * from "./utility/EmbedHandlers";
diff --git a/src/api/util/utility/EmbedHandlers.ts b/src/api/util/utility/EmbedHandlers.ts
index dca264d0..2549937e 100644
--- a/src/api/util/utility/EmbedHandlers.ts
+++ b/src/api/util/utility/EmbedHandlers.ts
@@ -16,8 +16,13 @@ export const DEFAULT_FETCH_OPTIONS: any = {
method: "GET",
};
-export const getProxyUrl = (url: URL, width: number, height: number): string => {
- const { resizeWidthMax, resizeHeightMax, imagorServerUrl } = Config.get().cdn;
+export const getProxyUrl = (
+ url: URL,
+ width: number,
+ height: number,
+): string => {
+ const { resizeWidthMax, resizeHeightMax, imagorServerUrl } =
+ Config.get().cdn;
const secret = Config.get().security.requestSignature;
width = Math.min(width || 500, resizeWidthMax || width);
height = Math.min(height || 500, resizeHeightMax || width);
@@ -26,16 +31,20 @@ export const getProxyUrl = (url: URL, width: number, height: number): string =>
if (imagorServerUrl) {
let path = `${width}x${height}/${url.host}${url.pathname}`;
- const hash = crypto.createHmac('sha1', secret)
+ const hash = crypto
+ .createHmac("sha1", secret)
.update(path)
- .digest('base64')
- .replace(/\+/g, '-').replace(/\//g, '_');
+ .digest("base64")
+ .replace(/\+/g, "-")
+ .replace(/\//g, "_");
return `${imagorServerUrl}/${hash}/${path}`;
}
// TODO: Imagor documentation
- console.log("Imagor has not been set up correctly. docs.fosscord.com/set/up/a/page/about/this");
+ console.log(
+ "Imagor has not been set up correctly. docs.fosscord.com/set/up/a/page/about/this",
+ );
return "";
};
@@ -69,8 +78,7 @@ const doFetch = async (url: URL) => {
...DEFAULT_FETCH_OPTIONS,
size: Config.get().limits.message.maxEmbedDownloadSize,
});
- }
- catch (e) {
+ } catch (e) {
return null;
}
};
@@ -88,12 +96,10 @@ const genericImageHandler = async (url: URL): Promise<Embed | null> => {
width = result.width;
height = result.height;
image = url.href;
- }
- else if (type.headers.get("content-type")?.indexOf("video") !== -1) {
+ } else if (type.headers.get("content-type")?.indexOf("video") !== -1) {
// TODO
return null;
- }
- else {
+ } else {
// have to download the page, unfortunately
const response = await doFetch(url);
if (!response) return null;
@@ -113,13 +119,15 @@ const genericImageHandler = async (url: URL): Promise<Embed | null> => {
height: height,
url: url.href,
proxy_url: getProxyUrl(new URL(image), width, height),
- }
+ },
};
};
-export const EmbedHandlers: { [key: string]: (url: URL) => Promise<Embed | Embed[] | null>; } = {
+export const EmbedHandlers: {
+ [key: string]: (url: URL) => Promise<Embed | Embed[] | null>;
+} = {
// the url does not have a special handler
- "default": async (url: URL) => {
+ default: async (url: URL) => {
const type = await fetch(url, {
...DEFAULT_FETCH_OPTIONS,
method: "HEAD",
@@ -154,7 +162,13 @@ export const EmbedHandlers: { [key: string]: (url: URL) => Promise<Embed | Embed
width: metas.width,
height: metas.height,
url: metas.image,
- proxy_url: metas.image ? getProxyUrl(new URL(metas.image), metas.width!, metas.height!) : undefined,
+ proxy_url: metas.image
+ ? getProxyUrl(
+ new URL(metas.image),
+ metas.width!,
+ metas.height!,
+ )
+ : undefined,
},
description: metas.description,
};
@@ -169,26 +183,28 @@ export const EmbedHandlers: { [key: string]: (url: URL) => Promise<Embed | Embed
// TODO: facebook
// have to use their APIs or something because they don't send the metas in initial html
- "twitter.com": (url: URL) => { return EmbedHandlers["www.twitter.com"](url); },
+ "twitter.com": (url: URL) => {
+ return EmbedHandlers["www.twitter.com"](url);
+ },
"www.twitter.com": async (url: URL) => {
const token = Config.get().external.twitter;
if (!token) return null;
- if (!url.href.includes("/status/")) return null; // TODO;
- const id = url.pathname.split("/")[3]; // super bad lol
+ if (!url.href.includes("/status/")) return null; // TODO;
+ const id = url.pathname.split("/")[3]; // super bad lol
if (!parseInt(id)) return null;
- const endpointUrl = `https://api.twitter.com/2/tweets/${id}` +
+ const endpointUrl =
+ `https://api.twitter.com/2/tweets/${id}` +
`?expansions=author_id,attachments.media_keys` +
- `&media.fields=url,width,height` +
- `&tweet.fields=created_at,public_metrics` +
- `&user.fields=profile_image_url`;
-
+ `&media.fields=url,width,height` +
+ `&tweet.fields=created_at,public_metrics` +
+ `&user.fields=profile_image_url`;
const response = await fetch(endpointUrl, {
...DEFAULT_FETCH_OPTIONS,
headers: {
authorization: `Bearer ${token}`,
- }
+ },
});
const json = await response.json();
if (json.errors) return null;
@@ -196,7 +212,9 @@ export const EmbedHandlers: { [key: string]: (url: URL) => Promise<Embed | Embed
const text = json.data.text;
const created_at = new Date(json.data.created_at);
const metrics = json.data.public_metrics;
- let media = json.includes.media?.filter((x: any) => x.type == "photo") as any[]; // TODO: video
+ let media = json.includes.media?.filter(
+ (x: any) => x.type == "photo",
+ ) as any[]; // TODO: video
const embed: Embed = {
type: EmbedType.rich,
@@ -205,19 +223,38 @@ export const EmbedHandlers: { [key: string]: (url: URL) => Promise<Embed | Embed
author: {
url: `https://twitter.com/${author.username}`,
name: `${author.name} (@${author.username})`,
- proxy_icon_url: getProxyUrl(new URL(author.profile_image_url), 400, 400),
+ proxy_icon_url: getProxyUrl(
+ new URL(author.profile_image_url),
+ 400,
+ 400,
+ ),
icon_url: author.profile_image_url,
},
timestamp: created_at,
fields: [
- { inline: true, name: "Likes", value: metrics.like_count.toString() },
- { inline: true, name: "Retweet", value: metrics.retweet_count.toString() },
+ {
+ inline: true,
+ name: "Likes",
+ value: metrics.like_count.toString(),
+ },
+ {
+ inline: true,
+ name: "Retweet",
+ value: metrics.retweet_count.toString(),
+ },
],
color: 1942002,
footer: {
text: "Twitter",
- proxy_icon_url: getProxyUrl(new URL("https://abs.twimg.com/icons/apple-touch-icon-192x192.png"), 192, 192),
- icon_url: "https://abs.twimg.com/icons/apple-touch-icon-192x192.png"
+ proxy_icon_url: getProxyUrl(
+ new URL(
+ "https://abs.twimg.com/icons/apple-touch-icon-192x192.png",
+ ),
+ 192,
+ 192,
+ ),
+ icon_url:
+ "https://abs.twimg.com/icons/apple-touch-icon-192x192.png",
},
// Discord doesn't send this?
// provider: {
@@ -231,7 +268,11 @@ export const EmbedHandlers: { [key: string]: (url: URL) => Promise<Embed | Embed
width: media[0].width,
height: media[0].height,
url: media[0].url,
- proxy_url: getProxyUrl(new URL(media[0].url), media[0].width, media[0].height)
+ proxy_url: getProxyUrl(
+ new URL(media[0].url),
+ media[0].width,
+ media[0].height,
+ ),
};
media.shift();
}
@@ -265,17 +306,21 @@ export const EmbedHandlers: { [key: string]: (url: URL) => Promise<Embed | Embed
thumbnail: {
width: 640,
height: 640,
- proxy_url: metas.image ? getProxyUrl(new URL(metas.image!), 640, 640) : undefined,
+ proxy_url: metas.image
+ ? getProxyUrl(new URL(metas.image!), 640, 640)
+ : undefined,
url: metas.image,
},
provider: {
url: "https://spotify.com",
name: "Spotify",
- }
+ },
};
},
- "pixiv.net": (url: URL) => { return EmbedHandlers["www.pixiv.net"](url); },
+ "pixiv.net": (url: URL) => {
+ return EmbedHandlers["www.pixiv.net"](url);
+ },
"www.pixiv.net": async (url: URL) => {
const response = await doFetch(url);
if (!response) return null;
@@ -291,12 +336,18 @@ export const EmbedHandlers: { [key: string]: (url: URL) => Promise<Embed | Embed
width: metas.width,
height: metas.height,
url: url.href,
- proxy_url: metas.image ? getProxyUrl(new URL(metas.image!), metas.width!, metas.height!) : undefined,
+ proxy_url: metas.image
+ ? getProxyUrl(
+ new URL(metas.image!),
+ metas.width!,
+ metas.height!,
+ )
+ : undefined,
},
provider: {
url: "https://pixiv.net",
- name: "Pixiv"
- }
+ name: "Pixiv",
+ },
};
},
@@ -310,35 +361,42 @@ export const EmbedHandlers: { [key: string]: (url: URL) => Promise<Embed | Embed
type: EmbedType.rich,
title: metas.title,
description: metas.description,
- image: { // TODO: meant to be thumbnail.
+ image: {
+ // TODO: meant to be thumbnail.
// isn't this standard across all of steam?
width: 460,
height: 215,
url: metas.image,
- proxy_url: metas.image ? getProxyUrl(new URL(metas.image!), 460, 215) : undefined,
+ proxy_url: metas.image
+ ? getProxyUrl(new URL(metas.image!), 460, 215)
+ : undefined,
},
provider: {
url: "https://store.steampowered.com",
- name: "Steam"
+ name: "Steam",
},
// TODO: fields for release date
// TODO: Video
};
},
- "reddit.com": (url: URL) => { return EmbedHandlers["www.reddit.com"](url); },
+ "reddit.com": (url: URL) => {
+ return EmbedHandlers["www.reddit.com"](url);
+ },
"www.reddit.com": async (url: URL) => {
const res = await EmbedHandlers["default"](url);
return {
...res,
color: 16777215,
provider: {
- name: "reddit"
- }
+ name: "reddit",
+ },
};
},
- "youtube.com": (url: URL) => { return EmbedHandlers["www.youtube.com"](url); },
+ "youtube.com": (url: URL) => {
+ return EmbedHandlers["www.youtube.com"](url);
+ },
"www.youtube.com": async (url: URL): Promise<Embed | null> => {
const response = await doFetch(url);
if (!response) return null;
@@ -358,7 +416,13 @@ export const EmbedHandlers: { [key: string]: (url: URL) => Promise<Embed | Embed
width: metas.width,
height: metas.height,
url: metas.image,
- proxy_url: metas.image ? getProxyUrl(new URL(metas.image!), metas.width!, metas.height!) : undefined,
+ proxy_url: metas.image
+ ? getProxyUrl(
+ new URL(metas.image!),
+ metas.width!,
+ metas.height!,
+ )
+ : undefined,
},
provider: {
url: "https://www.youtube.com",
@@ -369,12 +433,12 @@ export const EmbedHandlers: { [key: string]: (url: URL) => Promise<Embed | Embed
author: {
name: metas.author,
// TODO: author channel url
- }
+ },
};
},
// the url is an image from this instance
- "self": async (url: URL): Promise<Embed | null> => {
+ self: async (url: URL): Promise<Embed | null> => {
const result = await probe(url.href);
return {
@@ -385,7 +449,7 @@ export const EmbedHandlers: { [key: string]: (url: URL) => Promise<Embed | Embed
height: result.height,
url: url.href,
proxy_url: url.href,
- }
+ },
};
},
-};;
\ No newline at end of file
+};
diff --git a/src/bundle/Server.ts b/src/bundle/Server.ts
index 3ceebc06..e6f8d17c 100644
--- a/src/bundle/Server.ts
+++ b/src/bundle/Server.ts
@@ -75,8 +75,14 @@ async function main() {
// Filter breadcrumbs that we don't care about
if (x.message?.includes("identified as")) return false;
if (x.message?.includes("[WebSocket] closed")) return false;
- if (x.message?.includes("Got Resume -> cancel not implemented")) return false;
- if (x.message?.includes("[Gateway] New connection from")) return false;
+ if (
+ x.message?.includes(
+ "Got Resume -> cancel not implemented",
+ )
+ )
+ return false;
+ if (x.message?.includes("[Gateway] New connection from"))
+ return false;
return true;
});
diff --git a/src/cdn/Server.ts b/src/cdn/Server.ts
index 1fd9ca38..7340a735 100644
--- a/src/cdn/Server.ts
+++ b/src/cdn/Server.ts
@@ -56,7 +56,7 @@ export class CDNServer extends Server {
this.app.use("/splashes/", avatarsRoute);
this.log("verbose", "[Server] Route /splashes registered");
-
+
this.app.use("/discovery-splashes/", avatarsRoute);
this.log("verbose", "[Server] Route /discovery-splashes registered");
@@ -75,10 +75,16 @@ export class CDNServer extends Server {
this.app.use("/channel-icons/", avatarsRoute);
this.log("verbose", "[Server] Route /channel-icons registered");
- this.app.use("/guilds/:guild_id/users/:user_id/avatars", guildProfilesRoute);
+ this.app.use(
+ "/guilds/:guild_id/users/:user_id/avatars",
+ guildProfilesRoute,
+ );
this.log("verbose", "[Server] Route /guilds/avatars registered");
- this.app.use("/guilds/:guild_id/users/:user_id/banners", guildProfilesRoute);
+ this.app.use(
+ "/guilds/:guild_id/users/:user_id/banners",
+ guildProfilesRoute,
+ );
this.log("verbose", "[Server] Route /guilds/banners registered");
return super.start();
diff --git a/src/cdn/routes/guild-profiles.ts b/src/cdn/routes/guild-profiles.ts
index 98af7f69..2acc4ab7 100644
--- a/src/cdn/routes/guild-profiles.ts
+++ b/src/cdn/routes/guild-profiles.ts
@@ -12,21 +12,32 @@ import { storage } from "../util/Storage";
// TODO: delete old icons
const ANIMATED_MIME_TYPES = ["image/apng", "image/gif", "image/gifv"];
-const STATIC_MIME_TYPES = ["image/png", "image/jpeg", "image/webp", "image/svg+xml", "image/svg"];
+const STATIC_MIME_TYPES = [
+ "image/png",
+ "image/jpeg",
+ "image/webp",
+ "image/svg+xml",
+ "image/svg",
+];
const ALLOWED_MIME_TYPES = [...ANIMATED_MIME_TYPES, ...STATIC_MIME_TYPES];
const router = Router();
router.post("/", multer.single("file"), async (req: Request, res: Response) => {
- if (req.headers.signature !== Config.get().security.requestSignature) throw new HTTPError("Invalid request signature");
+ if (req.headers.signature !== Config.get().security.requestSignature)
+ throw new HTTPError("Invalid request signature");
if (!req.file) throw new HTTPError("Missing file");
const { buffer, mimetype, size, originalname, fieldname } = req.file;
const { guild_id, user_id } = req.params;
- let hash = crypto.createHash("md5").update(Snowflake.generate()).digest("hex");
+ let hash = crypto
+ .createHash("md5")
+ .update(Snowflake.generate())
+ .digest("hex");
const type = await FileType.fromBuffer(buffer);
- if (!type || !ALLOWED_MIME_TYPES.includes(type.mime)) throw new HTTPError("Invalid file type");
+ if (!type || !ALLOWED_MIME_TYPES.includes(type.mime))
+ throw new HTTPError("Invalid file type");
if (ANIMATED_MIME_TYPES.includes(type.mime)) hash = `a_${hash}`; // animated icons have a_ infront of the hash
const path = `guilds/${guild_id}/users/${user_id}/avatars/${hash}`;
@@ -38,7 +49,7 @@ router.post("/", multer.single("file"), async (req: Request, res: Response) => {
id: hash,
content_type: type.mime,
size,
- url: `${endpoint}${req.baseUrl}/${user_id}/${hash}`
+ url: `${endpoint}${req.baseUrl}/${user_id}/${hash}`,
});
});
@@ -73,7 +84,8 @@ router.get("/:hash", async (req: Request, res: Response) => {
});
router.delete("/:id", async (req: Request, res: Response) => {
- if (req.headers.signature !== Config.get().security.requestSignature) throw new HTTPError("Invalid request signature");
+ if (req.headers.signature !== Config.get().security.requestSignature)
+ throw new HTTPError("Invalid request signature");
const { guild_id, user_id, id } = req.params;
const path = `guilds/${guild_id}/users/${user_id}/avatars/${id}`;
diff --git a/src/cdn/util/FileStorage.ts b/src/cdn/util/FileStorage.ts
index 9386663f..e8d499e2 100644
--- a/src/cdn/util/FileStorage.ts
+++ b/src/cdn/util/FileStorage.ts
@@ -35,7 +35,8 @@ export class FileStorage implements Storage {
async set(path: string, value: any) {
path = getPath(path);
- if (!fs.existsSync(dirname(path))) fs.mkdirSync(dirname(path), { recursive: true });
+ if (!fs.existsSync(dirname(path)))
+ fs.mkdirSync(dirname(path), { recursive: true });
value = Readable.from(value);
const cleaned_file = fs.createWriteStream(path);
diff --git a/src/gateway/events/Connection.ts b/src/gateway/events/Connection.ts
index d47ac314..f3694c51 100644
--- a/src/gateway/events/Connection.ts
+++ b/src/gateway/events/Connection.ts
@@ -12,7 +12,7 @@ import { Config } from "@fosscord/util";
var erlpack: any;
try {
erlpack = require("@yukikaze-bot/erlpack");
-} catch (error) { }
+} catch (error) {}
// TODO: check rate limit
// TODO: specify rate limit in config
@@ -48,7 +48,7 @@ export async function Connection(
"open",
"ping",
"pong",
- "unexpected-response"
+ "unexpected-response",
].forEach((x) => {
socket.on(x, (y) => console.log(x, y));
});
diff --git a/src/gateway/events/Message.ts b/src/gateway/events/Message.ts
index 57af0c69..6645dd22 100644
--- a/src/gateway/events/Message.ts
+++ b/src/gateway/events/Message.ts
@@ -10,30 +10,36 @@ const bigIntJson = BigIntJson({ storeAsString: true });
var erlpack: any;
try {
erlpack = require("@yukikaze-bot/erlpack");
-} catch (error) { }
+} catch (error) {}
export async function Message(this: WebSocket, buffer: WS.Data) {
// TODO: compression
var data: Payload;
- if ((buffer instanceof Buffer && buffer[0] === 123) || // ASCII 123 = `{`. Bad check for JSON
- (typeof buffer === "string")) {
+ if (
+ (buffer instanceof Buffer && buffer[0] === 123) || // ASCII 123 = `{`. Bad check for JSON
+ typeof buffer === "string"
+ ) {
data = bigIntJson.parse(buffer.toString());
- }
- else if (this.encoding === "json" && buffer instanceof Buffer) {
+ } else if (this.encoding === "json" && buffer instanceof Buffer) {
if (this.inflate) {
- try { buffer = this.inflate.process(buffer) as any; }
- catch { buffer = buffer.toString() as any; }
+ try {
+ buffer = this.inflate.process(buffer) as any;
+ } catch {
+ buffer = buffer.toString() as any;
+ }
}
data = bigIntJson.parse(buffer as string);
- }
- else if (this.encoding === "etf" && buffer instanceof Buffer) {
- try { data = erlpack.unpack(buffer); }
- catch { return this.close(CLOSECODES.Decode_error); }
- }
- else return this.close(CLOSECODES.Decode_error);
+ } else if (this.encoding === "etf" && buffer instanceof Buffer) {
+ try {
+ data = erlpack.unpack(buffer);
+ } catch {
+ return this.close(CLOSECODES.Decode_error);
+ }
+ } else return this.close(CLOSECODES.Decode_error);
- if (process.env.WS_VERBOSE) console.log(`[Websocket] Incomming message: ${JSON.stringify(data)}`);
+ if (process.env.WS_VERBOSE)
+ console.log(`[Websocket] Incomming message: ${JSON.stringify(data)}`);
check.call(this, PayloadSchema, data);
@@ -46,14 +52,17 @@ export async function Message(this: WebSocket, buffer: WS.Data) {
return;
}
- const transaction = data.op != 1 ? Sentry.startTransaction({
- op: OPCODES[data.op],
- name: `GATEWAY ${OPCODES[data.op]}`,
- data: {
- ...data.d,
- token: data?.d?.token ? "[Redacted]" : undefined,
- },
- }) : undefined;
+ const transaction =
+ data.op != 1
+ ? Sentry.startTransaction({
+ op: OPCODES[data.op],
+ name: `GATEWAY ${OPCODES[data.op]}`,
+ data: {
+ ...data.d,
+ token: data?.d?.token ? "[Redacted]" : undefined,
+ },
+ })
+ : undefined;
try {
var ret = await OPCodeHandler.call(this, data);
diff --git a/src/gateway/opcodes/Identify.ts b/src/gateway/opcodes/Identify.ts
index ca3ae66f..d1daff04 100644
--- a/src/gateway/opcodes/Identify.ts
+++ b/src/gateway/opcodes/Identify.ts
@@ -259,7 +259,10 @@ export async function onIdentify(this: WebSocket, data: Payload) {
const d: ReadyEventData = {
v: 9,
- application: { id: application?.id ?? '', flags: application?.flags ?? 0 }, //TODO: check this code!
+ application: {
+ id: application?.id ?? "",
+ flags: application?.flags ?? 0,
+ }, //TODO: check this code!
user: privateUser,
user_settings: user.settings,
// @ts-ignore
@@ -267,7 +270,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
return {
...new ReadyGuildDTO(x as Guild & { joined_at: Date }).toJSON(),
guild_hashes: {},
- joined_at: x.joined_at
+ joined_at: x.joined_at,
};
}),
guild_experiments: [], // TODO
diff --git a/src/gateway/opcodes/LazyRequest.ts b/src/gateway/opcodes/LazyRequest.ts
index e54f64a6..f5bee864 100644
--- a/src/gateway/opcodes/LazyRequest.ts
+++ b/src/gateway/opcodes/LazyRequest.ts
@@ -159,7 +159,11 @@ async function getMembers(guild_id: string, range: [number, number]) {
groups,
range,
members: items
- .map((x) => ("member" in x ? { ...x.member, settings: undefined } : undefined))
+ .map((x) =>
+ "member" in x
+ ? { ...x.member, settings: undefined }
+ : undefined,
+ )
.filter((x) => !!x),
};
}
diff --git a/src/gateway/opcodes/VoiceStateUpdate.ts b/src/gateway/opcodes/VoiceStateUpdate.ts
index 49d15425..99160f0d 100644
--- a/src/gateway/opcodes/VoiceStateUpdate.ts
+++ b/src/gateway/opcodes/VoiceStateUpdate.ts
@@ -62,7 +62,7 @@ export async function onVoiceStateUpdate(this: WebSocket, data: Payload) {
}
// 'Fix' for this one voice state error. TODO: Find out why this is sent
- // It seems to be sent on client load,
+ // It seems to be sent on client load,
// so maybe its trying to find which server you were connected to before disconnecting, if any?
if (body.guild_id == null) {
return;
diff --git a/src/util/config/Config.ts b/src/util/config/Config.ts
index b6c725f5..8a057a44 100644
--- a/src/util/config/Config.ts
+++ b/src/util/config/Config.ts
@@ -17,7 +17,7 @@ import {
RegisterConfiguration,
SecurityConfiguration,
SentryConfiguration,
- TemplateConfiguration
+ TemplateConfiguration,
} from "../config";
export class ConfigValue {
@@ -40,4 +40,4 @@ export class ConfigValue {
sentry: SentryConfiguration = new SentryConfiguration();
defaults: DefaultsConfiguration = new DefaultsConfiguration();
external: ExternalTokensConfiguration = new ExternalTokensConfiguration();
-}
\ No newline at end of file
+}
diff --git a/src/util/config/types/ApiConfiguration.ts b/src/util/config/types/ApiConfiguration.ts
index 16b1efba..442a5986 100644
--- a/src/util/config/types/ApiConfiguration.ts
+++ b/src/util/config/types/ApiConfiguration.ts
@@ -2,4 +2,4 @@ export class ApiConfiguration {
defaultVersion: string = "9";
activeVersions: string[] = ["6", "7", "8", "9"];
useFosscordEnhancements: boolean = true;
-}
\ No newline at end of file
+}
diff --git a/src/util/config/types/CdnConfiguration.ts b/src/util/config/types/CdnConfiguration.ts
index 3c4dd163..ef8a003b 100644
--- a/src/util/config/types/CdnConfiguration.ts
+++ b/src/util/config/types/CdnConfiguration.ts
@@ -7,4 +7,4 @@ export class CdnConfiguration extends EndpointConfiguration {
endpointPublic: string | null = "http://localhost:3001";
endpointPrivate: string | null = "http://localhost:3001";
-}
\ No newline at end of file
+}
diff --git a/src/util/config/types/ClientConfiguration.ts b/src/util/config/types/ClientConfiguration.ts
index 0d3c8490..c2d4172c 100644
--- a/src/util/config/types/ClientConfiguration.ts
+++ b/src/util/config/types/ClientConfiguration.ts
@@ -1,6 +1,6 @@
import { ClientReleaseConfiguration } from ".";
export class ClientConfiguration {
- releases: ClientReleaseConfiguration = new ClientReleaseConfiguration();
- useTestClient: boolean = false;
-}
\ No newline at end of file
+ releases: ClientReleaseConfiguration = new ClientReleaseConfiguration();
+ useTestClient: boolean = false;
+}
diff --git a/src/util/config/types/DefaultsConfiguration.ts b/src/util/config/types/DefaultsConfiguration.ts
index 9b02a590..d5ee39e7 100644
--- a/src/util/config/types/DefaultsConfiguration.ts
+++ b/src/util/config/types/DefaultsConfiguration.ts
@@ -1,6 +1,6 @@
import { GuildDefaults, UserDefaults } from ".";
export class DefaultsConfiguration {
- guild: GuildDefaults = new GuildDefaults();
- user: UserDefaults = new UserDefaults();
-}
\ No newline at end of file
+ guild: GuildDefaults = new GuildDefaults();
+ user: UserDefaults = new UserDefaults();
+}
diff --git a/src/util/config/types/EndpointConfiguration.ts b/src/util/config/types/EndpointConfiguration.ts
index 87baea31..5e5e8ca9 100644
--- a/src/util/config/types/EndpointConfiguration.ts
+++ b/src/util/config/types/EndpointConfiguration.ts
@@ -2,4 +2,4 @@ export class EndpointConfiguration {
endpointClient: string | null = null;
endpointPrivate: string | null = null;
endpointPublic: string | null = null;
-}
\ No newline at end of file
+}
diff --git a/src/util/config/types/ExternalTokensConfiguration.ts b/src/util/config/types/ExternalTokensConfiguration.ts
index 5c020745..22c8b862 100644
--- a/src/util/config/types/ExternalTokensConfiguration.ts
+++ b/src/util/config/types/ExternalTokensConfiguration.ts
@@ -1,3 +1,3 @@
export class ExternalTokensConfiguration {
twitter: string | null = null;
-}
\ No newline at end of file
+}
diff --git a/src/util/config/types/GeneralConfiguration.ts b/src/util/config/types/GeneralConfiguration.ts
index 7c0ffa66..462f93e2 100644
--- a/src/util/config/types/GeneralConfiguration.ts
+++ b/src/util/config/types/GeneralConfiguration.ts
@@ -2,11 +2,12 @@ import { Snowflake } from "@fosscord/util";
export class GeneralConfiguration {
instanceName: string = "Fosscord Instance";
- instanceDescription: string | null = "This is a Fosscord instance made in the pre-release days";
+ instanceDescription: string | null =
+ "This is a Fosscord instance made in the pre-release days";
frontPage: string | null = null;
tosPage: string | null = null;
correspondenceEmail: string | null = null;
correspondenceUserID: string | null = null;
image: string | null = null;
instanceId: string = Snowflake.generate();
-}
\ No newline at end of file
+}
diff --git a/src/util/config/types/GifConfiguration.ts b/src/util/config/types/GifConfiguration.ts
index 6a2d520d..565c2ac0 100644
--- a/src/util/config/types/GifConfiguration.ts
+++ b/src/util/config/types/GifConfiguration.ts
@@ -1,5 +1,5 @@
export class GifConfiguration {
- enabled: boolean = true;
- provider: "tenor" = "tenor"; // more coming soon
- apiKey?: string = "LIVDSRZULELA";
-}
\ No newline at end of file
+ enabled: boolean = true;
+ provider: "tenor" = "tenor"; // more coming soon
+ apiKey?: string = "LIVDSRZULELA";
+}
diff --git a/src/util/config/types/GuildConfiguration.ts b/src/util/config/types/GuildConfiguration.ts
index e77d3fce..42ce2044 100644
--- a/src/util/config/types/GuildConfiguration.ts
+++ b/src/util/config/types/GuildConfiguration.ts
@@ -1,7 +1,7 @@
import { DiscoveryConfiguration, AutoJoinConfiguration } from ".";
export class GuildConfiguration {
- discovery: DiscoveryConfiguration = new DiscoveryConfiguration();
- autoJoin: AutoJoinConfiguration = new AutoJoinConfiguration();
+ discovery: DiscoveryConfiguration = new DiscoveryConfiguration();
+ autoJoin: AutoJoinConfiguration = new AutoJoinConfiguration();
defaultFeatures: string[] = [];
}
diff --git a/src/util/config/types/KafkaConfiguration.ts b/src/util/config/types/KafkaConfiguration.ts
index 7932f49e..a3aa8058 100644
--- a/src/util/config/types/KafkaConfiguration.ts
+++ b/src/util/config/types/KafkaConfiguration.ts
@@ -1,5 +1,5 @@
import { KafkaBroker } from ".";
export class KafkaConfiguration {
- brokers: KafkaBroker[] | null = null;
-}
\ No newline at end of file
+ brokers: KafkaBroker[] | null = null;
+}
diff --git a/src/util/config/types/LimitConfigurations.ts b/src/util/config/types/LimitConfigurations.ts
index 105fd1d6..912d6a4b 100644
--- a/src/util/config/types/LimitConfigurations.ts
+++ b/src/util/config/types/LimitConfigurations.ts
@@ -1,4 +1,11 @@
-import { ChannelLimits, GlobalRateLimits, GuildLimits, MessageLimits, RateLimits, UserLimits } from ".";
+import {
+ ChannelLimits,
+ GlobalRateLimits,
+ GuildLimits,
+ MessageLimits,
+ RateLimits,
+ UserLimits,
+} from ".";
export class LimitsConfiguration {
user: UserLimits = new UserLimits();
diff --git a/src/util/config/types/LoginConfiguration.ts b/src/util/config/types/LoginConfiguration.ts
index 255c9451..d8b737b9 100644
--- a/src/util/config/types/LoginConfiguration.ts
+++ b/src/util/config/types/LoginConfiguration.ts
@@ -1,3 +1,3 @@
export class LoginConfiguration {
- requireCaptcha: boolean = false;
-}
\ No newline at end of file
+ requireCaptcha: boolean = false;
+}
diff --git a/src/util/config/types/MetricsConfiguration.ts b/src/util/config/types/MetricsConfiguration.ts
index d7cd4937..f6b1d8e6 100644
--- a/src/util/config/types/MetricsConfiguration.ts
+++ b/src/util/config/types/MetricsConfiguration.ts
@@ -1,3 +1,3 @@
export class MetricsConfiguration {
- timeout: number = 30000;
-}
\ No newline at end of file
+ timeout: number = 30000;
+}
diff --git a/src/util/config/types/RabbitMQConfiguration.ts b/src/util/config/types/RabbitMQConfiguration.ts
index ce4a9123..bd4b6ca3 100644
--- a/src/util/config/types/RabbitMQConfiguration.ts
+++ b/src/util/config/types/RabbitMQConfiguration.ts
@@ -1,3 +1,3 @@
export class RabbitMQConfiguration {
- host: string | null = null;
-}
\ No newline at end of file
+ host: string | null = null;
+}
diff --git a/src/util/config/types/RegionConfiguration.ts b/src/util/config/types/RegionConfiguration.ts
index 09d9271c..ce4bf242 100644
--- a/src/util/config/types/RegionConfiguration.ts
+++ b/src/util/config/types/RegionConfiguration.ts
@@ -1,16 +1,16 @@
import { Region } from ".";
export class RegionConfiguration {
- default: string = "fosscord";
- useDefaultAsOptimal: boolean = true;
- available: Region[] = [
- {
- id: "fosscord",
- name: "Fosscord",
- endpoint: "127.0.0.1:3004",
- vip: false,
- custom: false,
- deprecated: false,
- },
- ];
-}
\ No newline at end of file
+ default: string = "fosscord";
+ useDefaultAsOptimal: boolean = true;
+ available: Region[] = [
+ {
+ id: "fosscord",
+ name: "Fosscord",
+ endpoint: "127.0.0.1:3004",
+ vip: false,
+ custom: false,
+ deprecated: false,
+ },
+ ];
+}
diff --git a/src/util/config/types/RegisterConfiguration.ts b/src/util/config/types/RegisterConfiguration.ts
index 75b40417..b9096e66 100644
--- a/src/util/config/types/RegisterConfiguration.ts
+++ b/src/util/config/types/RegisterConfiguration.ts
@@ -1,16 +1,20 @@
-import { DateOfBirthConfiguration, EmailConfiguration, PasswordConfiguration } from ".";
+import {
+ DateOfBirthConfiguration,
+ EmailConfiguration,
+ PasswordConfiguration,
+} from ".";
export class RegisterConfiguration {
- email: EmailConfiguration = new EmailConfiguration();
- dateOfBirth: DateOfBirthConfiguration = new DateOfBirthConfiguration();
- password: PasswordConfiguration = new PasswordConfiguration();
- disabled: boolean = false;
- requireCaptcha: boolean = true;
- requireInvite: boolean = false;
- guestsRequireInvite: boolean = true;
- allowNewRegistration: boolean = true;
- allowMultipleAccounts: boolean = true;
- blockProxies: boolean = true;
- incrementingDiscriminators: boolean = false; // random otherwise
- defaultRights: string = "30644591655940"; // See `npm run generate:rights`
+ email: EmailConfiguration = new EmailConfiguration();
+ dateOfBirth: DateOfBirthConfiguration = new DateOfBirthConfiguration();
+ password: PasswordConfiguration = new PasswordConfiguration();
+ disabled: boolean = false;
+ requireCaptcha: boolean = true;
+ requireInvite: boolean = false;
+ guestsRequireInvite: boolean = true;
+ allowNewRegistration: boolean = true;
+ allowMultipleAccounts: boolean = true;
+ blockProxies: boolean = true;
+ incrementingDiscriminators: boolean = false; // random otherwise
+ defaultRights: string = "30644591655940"; // See `npm run generate:rights`
}
diff --git a/src/util/config/types/SecurityConfiguration.ts b/src/util/config/types/SecurityConfiguration.ts
index 0fa396c9..6d505140 100644
--- a/src/util/config/types/SecurityConfiguration.ts
+++ b/src/util/config/types/SecurityConfiguration.ts
@@ -11,7 +11,8 @@ export class SecurityConfiguration {
// X-Forwarded-For for nginx/reverse proxies
// CF-Connecting-IP for cloudflare
forwadedFor: string | null = null;
- ipdataApiKey: string | null = "eca677b284b3bac29eb72f5e496aa9047f26543605efe99ff2ce35c9";
+ ipdataApiKey: string | null =
+ "eca677b284b3bac29eb72f5e496aa9047f26543605efe99ff2ce35c9";
mfaBackupCodeCount: number = 10;
statsWorldReadable: boolean = true;
defaultRegistrationTokenExpiration: number = 1000 * 60 * 60 * 24 * 7; //1 week
diff --git a/src/util/config/types/SentryConfiguration.ts b/src/util/config/types/SentryConfiguration.ts
index 836094a1..57f548cd 100644
--- a/src/util/config/types/SentryConfiguration.ts
+++ b/src/util/config/types/SentryConfiguration.ts
@@ -1,8 +1,9 @@
import { hostname } from "os";
export class SentryConfiguration {
- enabled: boolean = false;
- endpoint: string = "https://05e8e3d005f34b7d97e920ae5870a5e5@sentry.thearcanebrony.net/6";
- traceSampleRate: number = 1.0;
- environment: string = hostname();
-}
\ No newline at end of file
+ enabled: boolean = false;
+ endpoint: string =
+ "https://05e8e3d005f34b7d97e920ae5870a5e5@sentry.thearcanebrony.net/6";
+ traceSampleRate: number = 1.0;
+ environment: string = hostname();
+}
diff --git a/src/util/config/types/TemplateConfiguration.ts b/src/util/config/types/TemplateConfiguration.ts
index 4a9aa8f2..aade2934 100644
--- a/src/util/config/types/TemplateConfiguration.ts
+++ b/src/util/config/types/TemplateConfiguration.ts
@@ -1,6 +1,6 @@
export class TemplateConfiguration {
- enabled: boolean = true;
- allowTemplateCreation: boolean = true;
- allowDiscordTemplates: boolean = true;
- allowRaws: boolean = true;
-}
\ No newline at end of file
+ enabled: boolean = true;
+ allowTemplateCreation: boolean = true;
+ allowDiscordTemplates: boolean = true;
+ allowRaws: boolean = true;
+}
diff --git a/src/util/config/types/index.ts b/src/util/config/types/index.ts
index f20fe121..d7251d97 100644
--- a/src/util/config/types/index.ts
+++ b/src/util/config/types/index.ts
@@ -17,4 +17,4 @@ export * from "./RegisterConfiguration";
export * from "./SecurityConfiguration";
export * from "./SentryConfiguration";
export * from "./TemplateConfiguration";
-export * from "./subconfigurations";
\ No newline at end of file
+export * from "./subconfigurations";
diff --git a/src/util/config/types/subconfigurations/client/ClientReleaseConfiguration.ts b/src/util/config/types/subconfigurations/client/ClientReleaseConfiguration.ts
index 54e7f365..b082b711 100644
--- a/src/util/config/types/subconfigurations/client/ClientReleaseConfiguration.ts
+++ b/src/util/config/types/subconfigurations/client/ClientReleaseConfiguration.ts
@@ -1,4 +1,4 @@
export class ClientReleaseConfiguration {
- useLocalRelease: boolean = true; //TODO
- upstreamVersion: string = "0.0.264";
-}
\ No newline at end of file
+ useLocalRelease: boolean = true; //TODO
+ upstreamVersion: string = "0.0.264";
+}
diff --git a/src/util/config/types/subconfigurations/defaults/GuildDefaults.ts b/src/util/config/types/subconfigurations/defaults/GuildDefaults.ts
index 27e8eae7..576cc3bc 100644
--- a/src/util/config/types/subconfigurations/defaults/GuildDefaults.ts
+++ b/src/util/config/types/subconfigurations/defaults/GuildDefaults.ts
@@ -1,7 +1,7 @@
export class GuildDefaults {
- maxPresences: number = 250000;
- maxVideoChannelUsers: number = 200;
- afkTimeout: number = 300;
- defaultMessageNotifications: number = 1;
- explicitContentFilter: number = 0;
-}
\ No newline at end of file
+ maxPresences: number = 250000;
+ maxVideoChannelUsers: number = 200;
+ afkTimeout: number = 300;
+ defaultMessageNotifications: number = 1;
+ explicitContentFilter: number = 0;
+}
diff --git a/src/util/config/types/subconfigurations/defaults/UserDefaults.ts b/src/util/config/types/subconfigurations/defaults/UserDefaults.ts
index f20a14b6..2c2f0043 100644
--- a/src/util/config/types/subconfigurations/defaults/UserDefaults.ts
+++ b/src/util/config/types/subconfigurations/defaults/UserDefaults.ts
@@ -1,5 +1,5 @@
export class UserDefaults {
- premium: boolean = true;
- premiumType: number = 2;
- verified: boolean = true;
-}
\ No newline at end of file
+ premium: boolean = true;
+ premiumType: number = 2;
+ verified: boolean = true;
+}
diff --git a/src/util/config/types/subconfigurations/guild/AutoJoin.ts b/src/util/config/types/subconfigurations/guild/AutoJoin.ts
index 47dfe5ec..4d7af352 100644
--- a/src/util/config/types/subconfigurations/guild/AutoJoin.ts
+++ b/src/util/config/types/subconfigurations/guild/AutoJoin.ts
@@ -1,5 +1,5 @@
export class AutoJoinConfiguration {
- enabled: boolean = true;
- guilds: string[] = [];
- canLeave: boolean = true;
-}
\ No newline at end of file
+ enabled: boolean = true;
+ guilds: string[] = [];
+ canLeave: boolean = true;
+}
diff --git a/src/util/config/types/subconfigurations/guild/Discovery.ts b/src/util/config/types/subconfigurations/guild/Discovery.ts
index 59d8a8ae..a7cb81db 100644
--- a/src/util/config/types/subconfigurations/guild/Discovery.ts
+++ b/src/util/config/types/subconfigurations/guild/Discovery.ts
@@ -1,6 +1,6 @@
export class DiscoveryConfiguration {
- showAllGuilds: boolean = false;
- useRecommendation: boolean = false; // TODO: Recommendation, privacy concern?
- offset: number = 0;
- limit: number = 24;
-}
\ No newline at end of file
+ showAllGuilds: boolean = false;
+ useRecommendation: boolean = false; // TODO: Recommendation, privacy concern?
+ offset: number = 0;
+ limit: number = 24;
+}
diff --git a/src/util/config/types/subconfigurations/kafka/KafkaBroker.ts b/src/util/config/types/subconfigurations/kafka/KafkaBroker.ts
index 4f9a5e51..f7dc1cf7 100644
--- a/src/util/config/types/subconfigurations/kafka/KafkaBroker.ts
+++ b/src/util/config/types/subconfigurations/kafka/KafkaBroker.ts
@@ -1,4 +1,4 @@
export interface KafkaBroker {
ip: string;
port: number;
-}
\ No newline at end of file
+}
diff --git a/src/util/config/types/subconfigurations/limits/ChannelLimits.ts b/src/util/config/types/subconfigurations/limits/ChannelLimits.ts
index 2f8f9485..76eeeb41 100644
--- a/src/util/config/types/subconfigurations/limits/ChannelLimits.ts
+++ b/src/util/config/types/subconfigurations/limits/ChannelLimits.ts
@@ -1,5 +1,5 @@
export class ChannelLimits {
- maxPins: number = 500;
- maxTopic: number = 1024;
- maxWebhooks: number = 100;
-}
\ No newline at end of file
+ maxPins: number = 500;
+ maxTopic: number = 1024;
+ maxWebhooks: number = 100;
+}
diff --git a/src/util/config/types/subconfigurations/limits/GlobalRateLimits.ts b/src/util/config/types/subconfigurations/limits/GlobalRateLimits.ts
index 4029abbe..d7c8a846 100644
--- a/src/util/config/types/subconfigurations/limits/GlobalRateLimits.ts
+++ b/src/util/config/types/subconfigurations/limits/GlobalRateLimits.ts
@@ -1,6 +1,14 @@
export class GlobalRateLimits {
- register: GlobalRateLimit = { limit: 25, window: 60 * 60 * 1000, enabled: true };
- sendMessage: GlobalRateLimit = { limit: 200, window: 60 * 1000, enabled: true };
+ register: GlobalRateLimit = {
+ limit: 25,
+ window: 60 * 60 * 1000,
+ enabled: true,
+ };
+ sendMessage: GlobalRateLimit = {
+ limit: 200,
+ window: 60 * 1000,
+ enabled: true,
+ };
}
export class GlobalRateLimit {
diff --git a/src/util/config/types/subconfigurations/limits/GuildLimits.ts b/src/util/config/types/subconfigurations/limits/GuildLimits.ts
index c5bc7884..ecd49f1e 100644
--- a/src/util/config/types/subconfigurations/limits/GuildLimits.ts
+++ b/src/util/config/types/subconfigurations/limits/GuildLimits.ts
@@ -1,7 +1,7 @@
export class GuildLimits {
- maxRoles: number = 1000;
- maxEmojis: number = 2000;
- maxMembers: number = 25000000;
- maxChannels: number = 65535;
- maxChannelsInCategory: number = 65535;
-}
\ No newline at end of file
+ maxRoles: number = 1000;
+ maxEmojis: number = 2000;
+ maxMembers: number = 25000000;
+ maxChannels: number = 65535;
+ maxChannelsInCategory: number = 65535;
+}
diff --git a/src/util/config/types/subconfigurations/limits/MessageLimits.ts b/src/util/config/types/subconfigurations/limits/MessageLimits.ts
index 51576b90..684a5057 100644
--- a/src/util/config/types/subconfigurations/limits/MessageLimits.ts
+++ b/src/util/config/types/subconfigurations/limits/MessageLimits.ts
@@ -1,8 +1,8 @@
export class MessageLimits {
- maxCharacters: number = 1048576;
- maxTTSCharacters: number = 160;
- maxReactions: number = 2048;
- maxAttachmentSize: number = 1024 * 1024 * 1024;
- maxBulkDelete: number = 1000;
- maxEmbedDownloadSize: number = 1024 * 1024 * 5;
-}
\ No newline at end of file
+ maxCharacters: number = 1048576;
+ maxTTSCharacters: number = 160;
+ maxReactions: number = 2048;
+ maxAttachmentSize: number = 1024 * 1024 * 1024;
+ maxBulkDelete: number = 1000;
+ maxEmbedDownloadSize: number = 1024 * 1024 * 5;
+}
diff --git a/src/util/config/types/subconfigurations/limits/RateLimits.ts b/src/util/config/types/subconfigurations/limits/RateLimits.ts
index 3e05a18b..dfce9341 100644
--- a/src/util/config/types/subconfigurations/limits/RateLimits.ts
+++ b/src/util/config/types/subconfigurations/limits/RateLimits.ts
@@ -4,15 +4,15 @@ export class RateLimits {
enabled: boolean = false;
ip: Omit<RateLimitOptions, "bot_count"> = {
count: 500,
- window: 5
+ window: 5,
};
global: RateLimitOptions = {
count: 250,
- window: 5
+ window: 5,
};
error: RateLimitOptions = {
count: 10,
- window: 5
+ window: 5,
};
routes: RouteRateLimit = new RouteRateLimit();
}
diff --git a/src/util/config/types/subconfigurations/limits/UserLimits.ts b/src/util/config/types/subconfigurations/limits/UserLimits.ts
index 0d10e0b3..b8bdcb2d 100644
--- a/src/util/config/types/subconfigurations/limits/UserLimits.ts
+++ b/src/util/config/types/subconfigurations/limits/UserLimits.ts
@@ -1,5 +1,5 @@
export class UserLimits {
- maxGuilds: number = 1048576;
- maxUsername: number = 127;
- maxFriends: number = 5000;
-}
\ No newline at end of file
+ maxGuilds: number = 1048576;
+ maxUsername: number = 127;
+ maxFriends: number = 5000;
+}
diff --git a/src/util/config/types/subconfigurations/limits/ratelimits/Auth.ts b/src/util/config/types/subconfigurations/limits/ratelimits/Auth.ts
index df171044..bd45c349 100644
--- a/src/util/config/types/subconfigurations/limits/ratelimits/Auth.ts
+++ b/src/util/config/types/subconfigurations/limits/ratelimits/Auth.ts
@@ -1,12 +1,12 @@
import { RateLimitOptions } from "./RateLimitOptions";
export class AuthRateLimit {
- login: RateLimitOptions = {
- count: 5,
- window: 60
- };
- register: RateLimitOptions = {
- count: 2,
- window: 60 * 60 * 12
- };
-}
\ No newline at end of file
+ login: RateLimitOptions = {
+ count: 5,
+ window: 60,
+ };
+ register: RateLimitOptions = {
+ count: 2,
+ window: 60 * 60 * 12,
+ };
+}
diff --git a/src/util/config/types/subconfigurations/limits/ratelimits/RateLimitOptions.ts b/src/util/config/types/subconfigurations/limits/ratelimits/RateLimitOptions.ts
index 7089e28e..829813fb 100644
--- a/src/util/config/types/subconfigurations/limits/ratelimits/RateLimitOptions.ts
+++ b/src/util/config/types/subconfigurations/limits/ratelimits/RateLimitOptions.ts
@@ -3,4 +3,4 @@ export interface RateLimitOptions {
count: number;
window: number;
onyIp?: boolean;
-}
\ No newline at end of file
+}
diff --git a/src/util/config/types/subconfigurations/limits/ratelimits/Route.ts b/src/util/config/types/subconfigurations/limits/ratelimits/Route.ts
index 5d73c2cf..5235334a 100644
--- a/src/util/config/types/subconfigurations/limits/ratelimits/Route.ts
+++ b/src/util/config/types/subconfigurations/limits/ratelimits/Route.ts
@@ -4,15 +4,15 @@ import { RateLimitOptions } from "./RateLimitOptions";
export class RouteRateLimit {
guild: RateLimitOptions = {
count: 5,
- window: 5
+ window: 5,
};
webhook: RateLimitOptions = {
count: 10,
- window: 5
+ window: 5,
};
channel: RateLimitOptions = {
count: 10,
- window: 5
+ window: 5,
};
auth: AuthRateLimit = new AuthRateLimit();
// TODO: rate limit configuration for all routes
diff --git a/src/util/config/types/subconfigurations/region/Region.ts b/src/util/config/types/subconfigurations/region/Region.ts
index a8717e1f..c1bcfd01 100644
--- a/src/util/config/types/subconfigurations/region/Region.ts
+++ b/src/util/config/types/subconfigurations/region/Region.ts
@@ -9,4 +9,4 @@ export interface Region {
vip: boolean;
custom: boolean;
deprecated: boolean;
-}
\ No newline at end of file
+}
diff --git a/src/util/config/types/subconfigurations/register/DateOfBirth.ts b/src/util/config/types/subconfigurations/register/DateOfBirth.ts
index 5a3c4e9d..4831a4b7 100644
--- a/src/util/config/types/subconfigurations/register/DateOfBirth.ts
+++ b/src/util/config/types/subconfigurations/register/DateOfBirth.ts
@@ -1,4 +1,4 @@
export class DateOfBirthConfiguration {
- required: boolean = true;
- minimum: number = 13; // in years
-}
\ No newline at end of file
+ required: boolean = true;
+ minimum: number = 13; // in years
+}
diff --git a/src/util/config/types/subconfigurations/register/Email.ts b/src/util/config/types/subconfigurations/register/Email.ts
index 115d49e0..7f54faa7 100644
--- a/src/util/config/types/subconfigurations/register/Email.ts
+++ b/src/util/config/types/subconfigurations/register/Email.ts
@@ -1,7 +1,7 @@
export class EmailConfiguration {
- required: boolean = false;
- allowlist: boolean = false;
- blocklist: boolean = true;
- domains: string[] = [];// TODO: efficiently save domain blocklist in database
- // domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"),
-}
\ No newline at end of file
+ required: boolean = false;
+ allowlist: boolean = false;
+ blocklist: boolean = true;
+ domains: string[] = []; // TODO: efficiently save domain blocklist in database
+ // domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"),
+}
diff --git a/src/util/config/types/subconfigurations/register/Password.ts b/src/util/config/types/subconfigurations/register/Password.ts
index 977473ac..383bdcfa 100644
--- a/src/util/config/types/subconfigurations/register/Password.ts
+++ b/src/util/config/types/subconfigurations/register/Password.ts
@@ -1,7 +1,7 @@
export class PasswordConfiguration {
- required: boolean = false;
- minLength: number = 8;
- minNumbers: number = 2;
- minUpperCase: number =2;
- minSymbols: number = 0;
-}
\ No newline at end of file
+ required: boolean = false;
+ minLength: number = 8;
+ minNumbers: number = 2;
+ minUpperCase: number = 2;
+ minSymbols: number = 0;
+}
diff --git a/src/util/config/types/subconfigurations/security/Captcha.ts b/src/util/config/types/subconfigurations/security/Captcha.ts
index ad6aa762..21c4ef44 100644
--- a/src/util/config/types/subconfigurations/security/Captcha.ts
+++ b/src/util/config/types/subconfigurations/security/Captcha.ts
@@ -1,6 +1,6 @@
export class CaptchaConfiguration {
- enabled: boolean = false;
- service: "recaptcha" | "hcaptcha" | null = null; // TODO: hcaptcha, custom
- sitekey: string | null = null;
- secret: string | null = null;
-}
\ No newline at end of file
+ enabled: boolean = false;
+ service: "recaptcha" | "hcaptcha" | null = null; // TODO: hcaptcha, custom
+ sitekey: string | null = null;
+ secret: string | null = null;
+}
diff --git a/src/util/config/types/subconfigurations/security/TwoFactor.ts b/src/util/config/types/subconfigurations/security/TwoFactor.ts
index 33a47385..20d2f9ab 100644
--- a/src/util/config/types/subconfigurations/security/TwoFactor.ts
+++ b/src/util/config/types/subconfigurations/security/TwoFactor.ts
@@ -1,3 +1,3 @@
export class TwoFactorConfiguration {
- generateBackupCodes: boolean = true;
-}
\ No newline at end of file
+ generateBackupCodes: boolean = true;
+}
diff --git a/src/util/entities/Application.ts b/src/util/entities/Application.ts
index 67475bdd..e37f5ee5 100644
--- a/src/util/entities/Application.ts
+++ b/src/util/entities/Application.ts
@@ -1,4 +1,11 @@
-import { Column, Entity, JoinColumn, ManyToOne, OneToOne, RelationId } from "typeorm";
+import {
+ Column,
+ Entity,
+ JoinColumn,
+ ManyToOne,
+ OneToOne,
+ RelationId,
+} from "typeorm";
import { BaseClass } from "./BaseClass";
import { Guild } from "./Guild";
import { Team } from "./Team";
@@ -8,78 +15,78 @@ import { User } from "./User";
export class Application extends BaseClass {
@Column()
name: string;
-
+
@Column({ nullable: true })
icon?: string;
-
+
@Column({ nullable: true })
description: string;
-
+
@Column({ nullable: true })
summary: string = "";
-
+
@Column({ type: "simple-json", nullable: true })
type?: any;
-
+
@Column()
hook: boolean = true;
-
+
@Column()
bot_public?: boolean = true;
-
+
@Column()
bot_require_code_grant?: boolean = false;
-
+
@Column()
verify_key: string;
-
+
@JoinColumn({ name: "owner_id" })
@ManyToOne(() => User)
owner: User;
-
+
// TODO: enum this? https://discord.com/developers/docs/resources/application#application-object-application-flags
@Column()
flags: number = 0;
-
+
@Column({ type: "simple-array", nullable: true })
redirect_uris: string[] = [];
-
+
@Column({ nullable: true })
rpc_application_state: number = 0;
-
+
@Column({ nullable: true })
store_application_state: number = 1;
-
+
@Column({ nullable: true })
verification_state: number = 1;
-
+
@Column({ nullable: true })
interactions_endpoint_url?: string;
-
+
@Column({ nullable: true })
integration_public: boolean = true;
-
+
@Column({ nullable: true })
integration_require_code_grant: boolean = false;
-
+
@Column({ nullable: true })
discoverability_state: number = 1;
-
+
@Column({ nullable: true })
discovery_eligibility_flags: number = 2240;
-
+
@JoinColumn({ name: "bot_user_id" })
@OneToOne(() => User)
bot?: User;
-
+
@Column({ type: "simple-array", nullable: true })
tags?: string[];
-
+
@Column({ nullable: true })
cover_image?: string; // the application's default rich presence invite cover image hash
-
+
@Column({ type: "simple-json", nullable: true })
- install_params?: {scopes: string[], permissions: string};
+ install_params?: { scopes: string[]; permissions: string };
@Column({ nullable: true })
terms_of_service_url?: string;
@@ -91,7 +98,7 @@ export class Application extends BaseClass {
//@Column({ type: "simple-array", nullable: true })
//rpc_origins?: string[];
-
+
//@JoinColumn({ name: "guild_id" })
//@ManyToOne(() => Guild)
//guild?: Guild; // if this application is a game sold, this field will be the guild to which it has been linked
@@ -105,11 +112,10 @@ export class Application extends BaseClass {
@JoinColumn({ name: "team_id" })
@ManyToOne(() => Team, {
onDelete: "CASCADE",
- nullable: true
+ nullable: true,
})
team?: Team;
-
- }
+}
export interface ApplicationCommand {
id: string;
diff --git a/src/util/entities/Channel.ts b/src/util/entities/Channel.ts
index e9e631f1..aaddc001 100644
--- a/src/util/entities/Channel.ts
+++ b/src/util/entities/Channel.ts
@@ -209,7 +209,10 @@ export class Channel extends BaseClass {
);
// Categories skip these checks on discord.com
- if (channel.type !== ChannelType.GUILD_CATEGORY || guild.features.includes("IRC_LIKE_CATEGORY_NAMES")) {
+ if (
+ channel.type !== ChannelType.GUILD_CATEGORY ||
+ guild.features.includes("IRC_LIKE_CATEGORY_NAMES")
+ ) {
if (channel.name.includes(" "))
throw new HTTPError(
"Channel name cannot include invalid characters",
@@ -286,10 +289,10 @@ export class Channel extends BaseClass {
Channel.create(channel).save(),
!opts?.skipEventEmit
? emitEvent({
- event: "CHANNEL_CREATE",
- data: channel,
- guild_id: channel.guild_id,
- } as ChannelCreateEvent)
+ event: "CHANNEL_CREATE",
+ data: channel,
+ guild_id: channel.guild_id,
+ } as ChannelCreateEvent)
: Promise.resolve(),
]);
diff --git a/src/util/entities/EmbedCache.ts b/src/util/entities/EmbedCache.ts
index 14881ccf..e182b8c2 100644
--- a/src/util/entities/EmbedCache.ts
+++ b/src/util/entities/EmbedCache.ts
@@ -9,4 +9,4 @@ export class EmbedCache extends BaseClass {
@Column({ type: "simple-json" })
embed: Embed;
-}
\ No newline at end of file
+}
diff --git a/src/util/entities/Guild.ts b/src/util/entities/Guild.ts
index c86a5787..7f3536fa 100644
--- a/src/util/entities/Guild.ts
+++ b/src/util/entities/Guild.ts
@@ -79,7 +79,8 @@ export class Guild extends BaseClass {
banner?: string;
@Column({ nullable: true })
- default_message_notifications?: number = Config.get().defaults.guild.defaultMessageNotifications;
+ default_message_notifications?: number =
+ Config.get().defaults.guild.defaultMessageNotifications;
@Column({ nullable: true })
description?: string;
@@ -88,7 +89,8 @@ export class Guild extends BaseClass {
discovery_splash?: string;
@Column({ nullable: true })
- explicit_content_filter?: number = Config.get().defaults.guild.explicitContentFilter;
+ explicit_content_filter?: number =
+ Config.get().defaults.guild.explicitContentFilter;
@Column({ type: "simple-array" })
features: string[] = Config.get().guild.defaultFeatures || []; //TODO use enum
@@ -110,7 +112,8 @@ export class Guild extends BaseClass {
max_presences?: number = Config.get().defaults.guild.maxPresences;
@Column({ nullable: true })
- max_video_channel_users?: number = Config.get().defaults.guild.maxVideoChannelUsers;
+ max_video_channel_users?: number =
+ Config.get().defaults.guild.maxVideoChannelUsers;
@Column({ nullable: true })
member_count?: number;
diff --git a/src/util/entities/Invite.ts b/src/util/entities/Invite.ts
index 8f5619fc..4b71ed02 100644
--- a/src/util/entities/Invite.ts
+++ b/src/util/entities/Invite.ts
@@ -1,10 +1,4 @@
-import {
- Column,
- Entity,
- JoinColumn,
- ManyToOne,
- RelationId,
-} from "typeorm";
+import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
import { Member } from "./Member";
import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass";
import { Channel } from "./Channel";
@@ -62,7 +56,7 @@ export class Invite extends BaseClassWithoutId {
@JoinColumn({ name: "inviter_id" })
@ManyToOne(() => User, {
- onDelete: "CASCADE"
+ onDelete: "CASCADE",
})
inviter: User;
diff --git a/src/util/entities/Member.ts b/src/util/entities/Member.ts
index eeae181e..f8a91f85 100644
--- a/src/util/entities/Member.ts
+++ b/src/util/entities/Member.ts
@@ -125,9 +125,9 @@ export class Member extends BaseClassWithoutId {
@Column()
bio: string;
-
+
@Column({ nullable: true, type: "simple-array" })
- theme_colors?: number[]; // TODO: Separate `User` and `UserProfile` models
+ theme_colors?: number[]; // TODO: Separate `User` and `UserProfile` models
@Column({ nullable: true })
pronouns?: string;
@@ -309,9 +309,9 @@ export class Member extends BaseClassWithoutId {
guild_id,
user: {
sessions: {
- status: Not("invisible" as "invisible") // lol typescript?
- }
- }
+ status: Not("invisible" as "invisible"), // lol typescript?
+ },
+ },
},
take: 10,
});
@@ -380,7 +380,7 @@ export class Member extends BaseClassWithoutId {
stage_instances: [],
threads: [],
embedded_activities: [],
- voice_states: guild.voice_states
+ voice_states: guild.voice_states,
},
user_id,
} as GuildCreateEvent),
diff --git a/src/util/entities/User.ts b/src/util/entities/User.ts
index e039eb17..34b7ea0e 100644
--- a/src/util/entities/User.ts
+++ b/src/util/entities/User.ts
@@ -15,13 +15,7 @@ import { ConnectedAccount } from "./ConnectedAccount";
import { Member } from "./Member";
import { UserSettings } from "./UserSettings";
import { Session } from "./Session";
-import {
- Config,
- FieldErrors,
- Snowflake,
- trimSpecial,
- adjustEmail,
-} from "..";
+import { Config, FieldErrors, Snowflake, trimSpecial, adjustEmail } from "..";
export enum PublicUserEnum {
username,
@@ -68,7 +62,7 @@ export const PrivateUserProjection = [
// Private user data that should never get sent to the client
export type PublicUser = Pick<User, PublicUserKeys>;
-export interface UserPublic extends Pick<User, PublicUserKeys> { }
+export interface UserPublic extends Pick<User, PublicUserKeys> {}
export interface UserPrivate extends Pick<User, PrivateUserKeys> {
locale: string;
@@ -92,7 +86,7 @@ export class User extends BaseClass {
banner?: string; // hash of the user banner
@Column({ nullable: true, type: "simple-array" })
- theme_colors?: number[]; // TODO: Separate `User` and `UserProfile` models
+ theme_colors?: number[]; // TODO: Separate `User` and `UserProfile` models
@Column({ nullable: true })
pronouns?: string;
@@ -140,7 +134,7 @@ export class User extends BaseClass {
premium_since: Date = new Date(); // premium date
@Column({ select: false })
- verified: boolean = true; // email is verified
+ verified: boolean = true; // email is verified
@Column()
disabled: boolean = false; // if the account is disabled
@@ -203,7 +197,7 @@ export class User extends BaseClass {
@OneToOne(() => UserSettings, {
cascade: true,
orphanedRowAction: "delete",
- eager: false
+ eager: false,
})
@JoinColumn()
settings: UserSettings;
@@ -270,7 +264,9 @@ export class User extends BaseClass {
});
}
- public static async generateDiscriminator(username: string): Promise<string | undefined> {
+ public static async generateDiscriminator(
+ username: string,
+ ): Promise<string | undefined> {
if (Config.get().register.incrementingDiscriminators) {
// discriminator will be incrementally generated
@@ -322,7 +318,7 @@ export class User extends BaseClass {
password?: string;
email?: string;
date_of_birth?: Date; // "2000-04-03"
- id?: string,
+ id?: string;
req?: any;
}) {
// trim special uf8 control characters -> Backspace, Newline, ...
@@ -347,7 +343,7 @@ export class User extends BaseClass {
const settings = UserSettings.create({
locale: language,
- })
+ });
const user = User.create({
username: username,
@@ -367,15 +363,12 @@ export class User extends BaseClass {
});
user.validate();
- await Promise.all([
- user.save(),
- settings.save(),
- ])
+ await Promise.all([user.save(), settings.save()]);
setImmediate(async () => {
if (Config.get().guild.autoJoin.enabled) {
for (const guild of Config.get().guild.autoJoin.guilds || []) {
- await Member.addToGuild(user.id, guild).catch((e) => { });
+ await Member.addToGuild(user.id, guild).catch((e) => {});
}
}
});
diff --git a/src/util/entities/UserSettings.ts b/src/util/entities/UserSettings.ts
index b1a1fe68..995bb262 100644
--- a/src/util/entities/UserSettings.ts
+++ b/src/util/entities/UserSettings.ts
@@ -3,117 +3,117 @@ import { BaseClassWithoutId } from "./BaseClass";
@Entity("user_settings")
export class UserSettings extends BaseClassWithoutId {
- @PrimaryGeneratedColumn()
+ @PrimaryGeneratedColumn()
index: string;
@Column({ nullable: true })
- afk_timeout: number = 3600;
-
- @Column({ nullable: true })
- allow_accessibility_detection: boolean = true;
-
- @Column({ nullable: true })
- animate_emoji: boolean = true;
-
- @Column({ nullable: true })
- animate_stickers: number = 0;
-
- @Column({ nullable: true })
- contact_sync_enabled: boolean = false;
-
- @Column({ nullable: true })
- convert_emoticons: boolean = false;
-
- @Column({ nullable: true, type: "simple-json" })
- custom_status: CustomStatus | null = null;
-
- @Column({ nullable: true })
- default_guilds_restricted: boolean = false;
-
- @Column({ nullable: true })
- detect_platform_accounts: boolean = false;
-
- @Column({ nullable: true })
- developer_mode: boolean = true;
-
- @Column({ nullable: true })
- disable_games_tab: boolean = true;
-
- @Column({ nullable: true })
- enable_tts_command: boolean = false;
-
- @Column({ nullable: true })
- explicit_content_filter: number = 0;
-
- @Column({ nullable: true, type: "simple-json" })
- friend_source_flags: FriendSourceFlags = { all: true };
-
- @Column({ nullable: true })
- gateway_connected: boolean = false;
-
- @Column({ nullable: true })
- gif_auto_play: boolean = false;
-
- @Column({ nullable: true, type: "simple-json" })
- guild_folders: GuildFolder[] = []; // every top guild is displayed as a "folder"
-
- @Column({ nullable: true, type: "simple-json" })
- guild_positions: string[] = []; // guild ids ordered by position
-
- @Column({ nullable: true })
- inline_attachment_media: boolean = true;
-
- @Column({ nullable: true })
- inline_embed_media: boolean = true;
-
- @Column({ nullable: true })
- locale: string = "en-US"; // en_US
-
- @Column({ nullable: true })
- message_display_compact: boolean = false;
-
- @Column({ nullable: true })
- native_phone_integration_enabled: boolean = true;
-
- @Column({ nullable: true })
- render_embeds: boolean = true;
-
- @Column({ nullable: true })
- render_reactions: boolean = true;
-
- @Column({ nullable: true, type: "simple-json" })
- restricted_guilds: string[] = [];
-
- @Column({ nullable: true })
- show_current_game: boolean = true;
-
- @Column({ nullable: true })
- status: "online" | "offline" | "dnd" | "idle" | "invisible" = "online";
-
- @Column({ nullable: true })
- stream_notifications_enabled: boolean = false;
-
- @Column({ nullable: true })
- theme: "dark" | "light" = "dark"; // dark
-
- @Column({ nullable: true })
- timezone_offset: number = 0; // e.g -60
+ afk_timeout: number = 3600;
+
+ @Column({ nullable: true })
+ allow_accessibility_detection: boolean = true;
+
+ @Column({ nullable: true })
+ animate_emoji: boolean = true;
+
+ @Column({ nullable: true })
+ animate_stickers: number = 0;
+
+ @Column({ nullable: true })
+ contact_sync_enabled: boolean = false;
+
+ @Column({ nullable: true })
+ convert_emoticons: boolean = false;
+
+ @Column({ nullable: true, type: "simple-json" })
+ custom_status: CustomStatus | null = null;
+
+ @Column({ nullable: true })
+ default_guilds_restricted: boolean = false;
+
+ @Column({ nullable: true })
+ detect_platform_accounts: boolean = false;
+
+ @Column({ nullable: true })
+ developer_mode: boolean = true;
+
+ @Column({ nullable: true })
+ disable_games_tab: boolean = true;
+
+ @Column({ nullable: true })
+ enable_tts_command: boolean = false;
+
+ @Column({ nullable: true })
+ explicit_content_filter: number = 0;
+
+ @Column({ nullable: true, type: "simple-json" })
+ friend_source_flags: FriendSourceFlags = { all: true };
+
+ @Column({ nullable: true })
+ gateway_connected: boolean = false;
+
+ @Column({ nullable: true })
+ gif_auto_play: boolean = false;
+
+ @Column({ nullable: true, type: "simple-json" })
+ guild_folders: GuildFolder[] = []; // every top guild is displayed as a "folder"
+
+ @Column({ nullable: true, type: "simple-json" })
+ guild_positions: string[] = []; // guild ids ordered by position
+
+ @Column({ nullable: true })
+ inline_attachment_media: boolean = true;
+
+ @Column({ nullable: true })
+ inline_embed_media: boolean = true;
+
+ @Column({ nullable: true })
+ locale: string = "en-US"; // en_US
+
+ @Column({ nullable: true })
+ message_display_compact: boolean = false;
+
+ @Column({ nullable: true })
+ native_phone_integration_enabled: boolean = true;
+
+ @Column({ nullable: true })
+ render_embeds: boolean = true;
+
+ @Column({ nullable: true })
+ render_reactions: boolean = true;
+
+ @Column({ nullable: true, type: "simple-json" })
+ restricted_guilds: string[] = [];
+
+ @Column({ nullable: true })
+ show_current_game: boolean = true;
+
+ @Column({ nullable: true })
+ status: "online" | "offline" | "dnd" | "idle" | "invisible" = "online";
+
+ @Column({ nullable: true })
+ stream_notifications_enabled: boolean = false;
+
+ @Column({ nullable: true })
+ theme: "dark" | "light" = "dark"; // dark
+
+ @Column({ nullable: true })
+ timezone_offset: number = 0; // e.g -60
}
interface CustomStatus {
- emoji_id?: string;
- emoji_name?: string;
- expires_at?: number;
- text?: string;
+ emoji_id?: string;
+ emoji_name?: string;
+ expires_at?: number;
+ text?: string;
}
interface GuildFolder {
- color: number;
- guild_ids: string[];
- id: number;
- name: string;
+ color: number;
+ guild_ids: string[];
+ id: number;
+ name: string;
}
-interface FriendSourceFlags {
- all: boolean
-}
\ No newline at end of file
+interface FriendSourceFlags {
+ all: boolean;
+}
diff --git a/src/util/entities/ValidRegistrationTokens.ts b/src/util/entities/ValidRegistrationTokens.ts
index 00839324..7db66c1d 100644
--- a/src/util/entities/ValidRegistrationTokens.ts
+++ b/src/util/entities/ValidRegistrationTokens.ts
@@ -4,10 +4,10 @@ import { BaseEntity, Column, Entity, PrimaryColumn } from "typeorm";
export class ValidRegistrationToken extends BaseEntity {
@PrimaryColumn()
token: string;
-
+
@Column()
created_at: Date = new Date();
@Column()
expires_at: Date;
-}
\ No newline at end of file
+}
diff --git a/src/util/entities/index.ts b/src/util/entities/index.ts
index dc509250..3e64965c 100644
--- a/src/util/entities/index.ts
+++ b/src/util/entities/index.ts
@@ -33,4 +33,4 @@ export * from "./User";
export * from "./UserSettings";
export * from "./ValidRegistrationTokens";
export * from "./VoiceState";
-export * from "./Webhook";
\ No newline at end of file
+export * from "./Webhook";
diff --git a/src/util/index.ts b/src/util/index.ts
index 7b4dc936..957fb393 100644
--- a/src/util/index.ts
+++ b/src/util/index.ts
@@ -6,4 +6,4 @@ export * from "./entities/index";
export * from "./dtos/index";
export * from "./schemas";
export * from "./imports";
-export * from "./config"
\ No newline at end of file
+export * from "./config";
diff --git a/src/util/interfaces/Event.ts b/src/util/interfaces/Event.ts
index f5bccb2f..b772c3e4 100644
--- a/src/util/interfaces/Event.ts
+++ b/src/util/interfaces/Event.ts
@@ -81,9 +81,9 @@ export interface ReadyEventData {
number,
null,
number,
- [[number, { e: number; s: number; }[]]],
+ [[number, { e: number; s: number }[]]],
[number, [[number, [number, number]]]],
- { b: number; k: bigint[]; }[],
+ { b: number; k: bigint[] }[],
][];
guild_join_requests?: any[]; // ? what is this? this is new
shard?: [number, number];
@@ -481,7 +481,7 @@ export interface SessionsReplace extends Event {
export interface GuildMemberListUpdate extends Event {
event: "GUILD_MEMBER_LIST_UPDATE";
data: {
- groups: { id: string; count: number; }[];
+ groups: { id: string; count: number }[];
guild_id: string;
id: string;
member_count: number;
@@ -489,8 +489,8 @@ export interface GuildMemberListUpdate extends Event {
ops: {
index: number;
item: {
- member?: PublicMember & { presence: Presence; };
- group?: { id: string; count: number; }[];
+ member?: PublicMember & { presence: Presence };
+ group?: { id: string; count: number }[];
};
}[];
};
diff --git a/src/util/schemas/ApplicationAuthorizeSchema.ts b/src/util/schemas/ApplicationAuthorizeSchema.ts
index 1a0aae0f..add26c74 100644
--- a/src/util/schemas/ApplicationAuthorizeSchema.ts
+++ b/src/util/schemas/ApplicationAuthorizeSchema.ts
@@ -3,5 +3,5 @@ export interface ApplicationAuthorizeSchema {
guild_id: string;
permissions: string;
captcha_key?: string;
- code?: string; // 2fa code
-}
\ No newline at end of file
+ code?: string; // 2fa code
+}
diff --git a/src/util/schemas/ApplicationCreateSchema.ts b/src/util/schemas/ApplicationCreateSchema.ts
index 6a021b46..0801a6c5 100644
--- a/src/util/schemas/ApplicationCreateSchema.ts
+++ b/src/util/schemas/ApplicationCreateSchema.ts
@@ -1,4 +1,4 @@
export interface ApplicationCreateSchema {
name: string;
team_id?: string | number;
-}
\ No newline at end of file
+}
diff --git a/src/util/schemas/ApplicationModifySchema.ts b/src/util/schemas/ApplicationModifySchema.ts
index ab23d57e..5f5bbe1d 100644
--- a/src/util/schemas/ApplicationModifySchema.ts
+++ b/src/util/schemas/ApplicationModifySchema.ts
@@ -11,4 +11,4 @@ export interface ApplicationModifySchema {
bot_public?: boolean;
bot_require_code_grant?: boolean;
flags?: number;
-}
\ No newline at end of file
+}
diff --git a/src/util/schemas/BotModifySchema.ts b/src/util/schemas/BotModifySchema.ts
index b801ab27..19a5c54e 100644
--- a/src/util/schemas/BotModifySchema.ts
+++ b/src/util/schemas/BotModifySchema.ts
@@ -1,4 +1,4 @@
export interface BotModifySchema {
avatar?: string;
username?: string;
-}
\ No newline at end of file
+}
diff --git a/src/util/schemas/ChannelPermissionOverwriteSchema.ts b/src/util/schemas/ChannelPermissionOverwriteSchema.ts
index 6d6d6c34..4f5c9712 100644
--- a/src/util/schemas/ChannelPermissionOverwriteSchema.ts
+++ b/src/util/schemas/ChannelPermissionOverwriteSchema.ts
@@ -1,4 +1,4 @@
import { ChannelPermissionOverwrite } from "@fosscord/util";
export interface ChannelPermissionOverwriteSchema
- extends ChannelPermissionOverwrite {}
\ No newline at end of file
+ extends ChannelPermissionOverwrite {}
diff --git a/src/util/schemas/ChannelReorderSchema.ts b/src/util/schemas/ChannelReorderSchema.ts
index 6eb4cdd5..c6e59ebd 100644
--- a/src/util/schemas/ChannelReorderSchema.ts
+++ b/src/util/schemas/ChannelReorderSchema.ts
@@ -3,4 +3,4 @@ export type ChannelReorderSchema = {
position?: number;
lock_permissions?: boolean;
parent_id?: string;
-}[];
\ No newline at end of file
+}[];
diff --git a/src/util/schemas/GatewayPayloadSchema.ts b/src/util/schemas/GatewayPayloadSchema.ts
index 324ad1eb..ce27f0dc 100644
--- a/src/util/schemas/GatewayPayloadSchema.ts
+++ b/src/util/schemas/GatewayPayloadSchema.ts
@@ -5,4 +5,4 @@ export const PayloadSchema = {
$d: new Tuple(Object, Number), // or number for heartbeat sequence
$s: Number,
$t: String,
-};
\ No newline at end of file
+};
diff --git a/src/util/schemas/GuildUpdateSchema.ts b/src/util/schemas/GuildUpdateSchema.ts
index e858a7a2..4e8daacf 100644
--- a/src/util/schemas/GuildUpdateSchema.ts
+++ b/src/util/schemas/GuildUpdateSchema.ts
@@ -1,6 +1,7 @@
import { GuildCreateSchema } from "@fosscord/util";
-export interface GuildUpdateSchema extends Omit<GuildCreateSchema, "channels" | "name"> {
+export interface GuildUpdateSchema
+ extends Omit<GuildCreateSchema, "channels" | "name"> {
name?: string;
banner?: string | null;
splash?: string | null;
diff --git a/src/util/schemas/MemberChangeProfileSchema.ts b/src/util/schemas/MemberChangeProfileSchema.ts
index 73c852f3..3c16c359 100644
--- a/src/util/schemas/MemberChangeProfileSchema.ts
+++ b/src/util/schemas/MemberChangeProfileSchema.ts
@@ -5,7 +5,7 @@ export interface MemberChangeProfileSchema {
pronouns?: string;
/*
- * @items.type integer
- */
+ * @items.type integer
+ */
theme_colors?: [number, number];
}
diff --git a/src/util/schemas/RolePositionUpdateSchema.ts b/src/util/schemas/RolePositionUpdateSchema.ts
index 1019d504..993d1ae0 100644
--- a/src/util/schemas/RolePositionUpdateSchema.ts
+++ b/src/util/schemas/RolePositionUpdateSchema.ts
@@ -1,4 +1,4 @@
export type RolePositionUpdateSchema = {
id: string;
position: number;
-}[];
\ No newline at end of file
+}[];
diff --git a/src/util/schemas/UserGuildSettingsSchema.ts b/src/util/schemas/UserGuildSettingsSchema.ts
index e78bbf7c..b9efdbfa 100644
--- a/src/util/schemas/UserGuildSettingsSchema.ts
+++ b/src/util/schemas/UserGuildSettingsSchema.ts
@@ -6,4 +6,4 @@ export interface UserGuildSettingsSchema
channel_overrides?: {
[channel_id: string]: Partial<ChannelOverride>;
};
-}
\ No newline at end of file
+}
diff --git a/src/util/schemas/UserProfileModifySchema.ts b/src/util/schemas/UserProfileModifySchema.ts
index 1e53d9e4..840e9c3e 100644
--- a/src/util/schemas/UserProfileModifySchema.ts
+++ b/src/util/schemas/UserProfileModifySchema.ts
@@ -5,7 +5,7 @@ export interface UserProfileModifySchema {
pronouns?: string;
/*
- * @items.type integer
- */
- theme_colors?: [number, number]
+ * @items.type integer
+ */
+ theme_colors?: [number, number];
}
diff --git a/src/util/schemas/UserSettingsSchema.ts b/src/util/schemas/UserSettingsSchema.ts
index db015457..eb9b316d 100644
--- a/src/util/schemas/UserSettingsSchema.ts
+++ b/src/util/schemas/UserSettingsSchema.ts
@@ -1,3 +1,3 @@
import { UserSettings } from "@fosscord/util";
-export interface UserSettingsSchema extends Partial<UserSettings> {}
\ No newline at end of file
+export interface UserSettingsSchema extends Partial<UserSettings> {}
diff --git a/src/util/schemas/index.ts b/src/util/schemas/index.ts
index be4be0c7..e4f565c9 100644
--- a/src/util/schemas/index.ts
+++ b/src/util/schemas/index.ts
@@ -59,4 +59,4 @@ export * from "./UserSettingsSchema";
export * from "./BotModifySchema";
export * from "./ApplicationModifySchema";
export * from "./ApplicationCreateSchema";
-export * from "./ApplicationAuthorizeSchema";
\ No newline at end of file
+export * from "./ApplicationAuthorizeSchema";
diff --git a/src/util/util/BitField.ts b/src/util/util/BitField.ts
index e2f4e2a5..413112ca 100644
--- a/src/util/util/BitField.ts
+++ b/src/util/util/BitField.ts
@@ -138,10 +138,8 @@ export class BitField {
const FLAGS = this.FLAGS || this.constructor?.FLAGS;
if (typeof bit === "string") {
- if (typeof FLAGS[bit] !== "undefined")
- return FLAGS[bit];
- else
- bit = BigInt(bit);
+ if (typeof FLAGS[bit] !== "undefined") return FLAGS[bit];
+ else bit = BigInt(bit);
}
if (
diff --git a/src/util/util/Config.ts b/src/util/util/Config.ts
index e3ac4177..5d98f5bc 100644
--- a/src/util/util/Config.ts
+++ b/src/util/util/Config.ts
@@ -14,7 +14,7 @@ var pairs: ConfigEntity[];
export const Config = {
init: async function init() {
if (config) return config;
- console.log('[Config] Loading configuration...');
+ console.log("[Config] Loading configuration...");
pairs = await ConfigEntity.find();
config = pairsToConfig(pairs);
// TODO: this overwrites existing config values with defaults.
@@ -26,16 +26,19 @@ export const Config = {
if (Object.keys(config).length == 0) config = new ConfigValue();
if (process.env.CONFIG_PATH) {
- console.log(`[Config] Using config path from environment rather than database.`);
+ console.log(
+ `[Config] Using config path from environment rather than database.`,
+ );
try {
- const overrideConfig = JSON.parse(fs.readFileSync(overridePath, { encoding: "utf8" }));
+ const overrideConfig = JSON.parse(
+ fs.readFileSync(overridePath, { encoding: "utf8" }),
+ );
config = overrideConfig.merge(config);
} catch (error) {
fs.writeFileSync(overridePath, JSON.stringify(config, null, 4));
}
}
-
return this.set(config);
},
get: function get() {
diff --git a/src/util/util/Constants.ts b/src/util/util/Constants.ts
index b84a8178..d4431209 100644
--- a/src/util/util/Constants.ts
+++ b/src/util/util/Constants.ts
@@ -1043,7 +1043,7 @@ export const FosscordApiErrors = {
45006,
501,
),
- FEATURE_IS_IMMUTABLE : new ApiError(
+ FEATURE_IS_IMMUTABLE: new ApiError(
"The feature ({}) cannot be edited.",
45007,
403,
diff --git a/src/util/util/Database.ts b/src/util/util/Database.ts
index da0909ab..2089d453 100644
--- a/src/util/util/Database.ts
+++ b/src/util/util/Database.ts
@@ -37,7 +37,6 @@ const DataSourceOptions = new DataSource({
migrations: [path.join(__dirname, "..", "migration", DatabaseType, "*.js")],
});
-
// Gets the existing database connection
export function getDatabase(): DataSource | null {
// if (!dbConnection) throw new Error("Tried to get database before it was initialised");
@@ -60,8 +59,13 @@ export async function initDatabase(): Promise<DataSource> {
if (!process.env.DB_SYNC) {
const supported = ["mysql", "mariadb", "postgres", "sqlite"];
if (!supported.includes(DatabaseType)) {
- console.log("[Database]" + red(` We don't have migrations for DB type '${DatabaseType}'` +
- ` To ignore, set DB_SYNC=true in your env. https://docs.fosscord.com/setup/server/configuration/env/`));
+ console.log(
+ "[Database]" +
+ red(
+ ` We don't have migrations for DB type '${DatabaseType}'` +
+ ` To ignore, set DB_SYNC=true in your env. https://docs.fosscord.com/setup/server/configuration/env/`,
+ ),
+ );
process.exit();
}
}
@@ -71,12 +75,20 @@ export async function initDatabase(): Promise<DataSource> {
dbConnection = await DataSourceOptions.initialize();
// Crude way of detecting if the migrations table exists.
- const dbExists = async () => { try { await ConfigEntity.count(); return true; } catch (e) { return false; } };
- if (!await dbExists()) {
- console.log("[Database] This appears to be a fresh database. Synchronising.");
+ const dbExists = async () => {
+ try {
+ await ConfigEntity.count();
+ return true;
+ } catch (e) {
+ return false;
+ }
+ };
+ if (!(await dbExists())) {
+ console.log(
+ "[Database] This appears to be a fresh database. Synchronising.",
+ );
await dbConnection.synchronize();
- }
- else {
+ } else {
await dbConnection.runMigrations();
}
diff --git a/src/util/util/InvisibleCharacters.ts b/src/util/util/InvisibleCharacters.ts
index 82031f53..c45915f4 100644
--- a/src/util/util/InvisibleCharacters.ts
+++ b/src/util/util/InvisibleCharacters.ts
@@ -1,7 +1,7 @@
// List from https://invisible-characters.com/
export const InvisibleCharacters = [
"\u{9}", //Tab
- '\u{c}', //Form feed
+ "\u{c}", //Form feed
//'\u{20}', //Space //categories can have spaces in them
"\u{ad}", //Soft hyphen
//"\u{34f}", //Combining grapheme joiner
diff --git a/src/util/util/Rights.ts b/src/util/util/Rights.ts
index 8e54a04f..68a7c840 100644
--- a/src/util/util/Rights.ts
+++ b/src/util/util/Rights.ts
@@ -32,7 +32,7 @@ export class Rights extends BitField {
static FLAGS = {
OPERATOR: BitFlag(0), // has all rights
MANAGE_APPLICATIONS: BitFlag(1),
- MANAGE_GUILDS: BitFlag(2), // Manage all guilds instance-wide
+ MANAGE_GUILDS: BitFlag(2), // Manage all guilds instance-wide
MANAGE_MESSAGES: BitFlag(3), // Can't see other messages but delete/edit them in channels that they can see
MANAGE_RATE_LIMITS: BitFlag(4),
MANAGE_ROUTING: BitFlag(5), // can create custom message routes to any channel/guild
@@ -81,7 +81,7 @@ export class Rights extends BitField {
SELF_EDIT_FLAGS: BitFlag(45), // can modify own flags
EDIT_FLAGS: BitFlag(46), // can set others' flags
MANAGE_GROUPS: BitFlag(47), // can manage others' groups
- VIEW_SERVER_STATS: BitFlag(48) // added per @chrischrome's request — can view server stats)
+ VIEW_SERVER_STATS: BitFlag(48), // added per @chrischrome's request — can view server stats)
};
any(permission: RightResolvable, checkOperator = true) {
diff --git a/src/util/util/index.ts b/src/util/util/index.ts
index f7a273cb..01ef4eae 100644
--- a/src/util/util/index.ts
+++ b/src/util/util/index.ts
@@ -19,4 +19,4 @@ export * from "./Snowflake";
export * from "./String";
export * from "./Array";
export * from "./TraverseDirectory";
-export * from "./InvisibleCharacters";
\ No newline at end of file
+export * from "./InvisibleCharacters";
|