diff --git a/api/src/routes/channels/#channel_id/pins.ts b/api/src/routes/channels/#channel_id/pins.ts
index 96a3fdbf..fafb789f 100644
--- a/api/src/routes/channels/#channel_id/pins.ts
+++ b/api/src/routes/channels/#channel_id/pins.ts
@@ -1,6 +1,7 @@
import { Channel, ChannelPinsUpdateEvent, Config, emitEvent, getPermission, Message, MessageUpdateEvent } from "@fosscord/util";
import { Router, Request, Response } from "express";
import { HTTPError } from "lambert-server";
+import { DiscordApiErrors } from "../../../util/Constants";
const router: Router = Router();
@@ -16,7 +17,7 @@ router.put("/:message_id", async (req: Request, res: Response) => {
const pinned_count = await Message.count({ channel: { id: channel_id }, pinned: true });
const { maxPins } = Config.get().limits.channel;
- if (pinned_count >= maxPins) throw new HTTPError("Max pin count reached: " + maxPins);
+ if (pinned_count >= maxPins) throw DiscordApiErrors.MAXIMUM_PINS.withParams(maxPins);
await Promise.all([
Message.update({ id: message_id }, { pinned: true }),
diff --git a/api/src/routes/channels/#channel_id/webhooks.ts b/api/src/routes/channels/#channel_id/webhooks.ts
index 775053ba..d2a4b9a0 100644
--- a/api/src/routes/channels/#channel_id/webhooks.ts
+++ b/api/src/routes/channels/#channel_id/webhooks.ts
@@ -1,11 +1,12 @@
import { Router, Response, Request } from "express";
import { check, Length } from "../../../util/instanceOf";
-import { Channel, getPermission, trimSpecial } from "@fosscord/util";
+import { Channel, Config, getPermission, trimSpecial, Webhook } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { isTextChannel } from "./messages/index";
+import { DiscordApiErrors } from "../../../util/Constants";
const router: Router = Router();
-// TODO:
+// TODO: webhooks
// TODO: use Image Data Type for avatar instead of String
router.post("/", check({ name: new Length(String, 1, 80), $avatar: String }), async (req: Request, res: Response) => {
@@ -15,6 +16,10 @@ router.post("/", check({ name: new Length(String, 1, 80), $avatar: String }), as
isTextChannel(channel.type);
if (!channel.guild_id) throw new HTTPError("Not a guild channel", 400);
+ const webhook_count = await Webhook.count({ channel_id });
+ const { maxWebhooks } = Config.get().limits.channel;
+ if (webhook_count > maxWebhooks) throw DiscordApiErrors.MAXIMUM_WEBHOOKS.withParams(maxWebhooks);
+
const permission = await getPermission(req.user_id, channel.guild_id);
permission.hasThrow("MANAGE_WEBHOOKS");
diff --git a/api/src/routes/guilds/#guild_id/roles.ts b/api/src/routes/guilds/#guild_id/roles.ts
index f6ac8caa..c3dd92dc 100644
--- a/api/src/routes/guilds/#guild_id/roles.ts
+++ b/api/src/routes/guilds/#guild_id/roles.ts
@@ -7,12 +7,14 @@ import {
GuildRoleCreateEvent,
GuildRoleUpdateEvent,
GuildRoleDeleteEvent,
- emitEvent
+ emitEvent,
+ Config
} from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { check } from "../../../util/instanceOf";
import { RoleModifySchema } from "../../../schema/Roles";
+import { DiscordApiErrors } from "../../../util/Constants";
const router: Router = Router();
@@ -33,24 +35,34 @@ router.post("/", check(RoleModifySchema), async (req: Request, res: Response) =>
const perms = await getPermission(req.user_id, guild_id);
perms.hasThrow("MANAGE_ROLES");
- const role = await new Role({
+ const role_count = await Role.count({ guild_id });
+ const { maxRoles } = Config.get().limits.guild;
+
+ if (role_count > maxRoles) throw DiscordApiErrors.MAXIMUM_ROLES.withParams(maxRoles);
+
+ const role = {
+ position: 0,
+ hoist: false,
+ color: 0, // default value
...body,
id: Snowflake.generate(),
guild_id: guild_id,
managed: false,
- position: 0,
- tags: null,
- permissions: String(perms.bitfield & (body.permissions || 0n))
- }).save();
-
- await emitEvent({
- event: "GUILD_ROLE_CREATE",
- guild_id,
- data: {
+ permissions: String(perms.bitfield & (body.permissions || 0n)),
+ tags: undefined
+ };
+
+ await Promise.all([
+ Role.insert(role),
+ emitEvent({
+ event: "GUILD_ROLE_CREATE",
guild_id,
- role: role
- }
- } as GuildRoleCreateEvent);
+ data: {
+ guild_id,
+ role: role
+ }
+ } as GuildRoleCreateEvent)
+ ]);
res.json(role);
});
@@ -84,14 +96,13 @@ router.delete("/:role_id", async (req: Request, res: Response) => {
// TODO: check role hierarchy
router.patch("/:role_id", check(RoleModifySchema), async (req: Request, res: Response) => {
- const guild_id = req.params.guild_id;
- const { role_id } = req.params;
+ const { role_id, guild_id } = req.params;
const body = req.body as RoleModifySchema;
const perms = await getPermission(req.user_id, guild_id);
perms.hasThrow("MANAGE_ROLES");
- const role = new Role({ ...body, id: role_id, guild_id, permissions: perms.bitfield & (body.permissions || 0n) });
+ const role = new Role({ ...body, id: role_id, guild_id, permissions: String(perms.bitfield & (body.permissions || 0n)) });
await Promise.all([
role.save(),
diff --git a/api/src/routes/guilds/index.ts b/api/src/routes/guilds/index.ts
index e4157384..a54b83ba 100644
--- a/api/src/routes/guilds/index.ts
+++ b/api/src/routes/guilds/index.ts
@@ -3,6 +3,7 @@ import { Role, Guild, Snowflake, Config, User, Member, Channel } from "@fosscord
import { HTTPError } from "lambert-server";
import { check } from "./../../util/instanceOf";
import { GuildCreateSchema } from "../../schema/Guild";
+import { DiscordApiErrors } from "../../util/Constants";
const router: Router = Router();
@@ -14,7 +15,7 @@ router.post("/", check(GuildCreateSchema), async (req: Request, res: Response) =
const { maxGuilds } = Config.get().limits.user;
const guild_count = await Member.count({ id: req.user_id });
if (guild_count >= maxGuilds) {
- throw new HTTPError(`Maximum number of guilds reached ${maxGuilds}`, 403);
+ throw DiscordApiErrors.MAXIMUM_GUILDS.withParams(maxGuilds);
}
const guild_id = Snowflake.generate();
diff --git a/api/src/routes/guilds/templates/index.ts b/api/src/routes/guilds/templates/index.ts
index 7a8ac886..3a619278 100644
--- a/api/src/routes/guilds/templates/index.ts
+++ b/api/src/routes/guilds/templates/index.ts
@@ -4,6 +4,7 @@ import { Template, Guild, Role, Snowflake, Config, User, Member } from "@fosscor
import { HTTPError } from "lambert-server";
import { GuildTemplateCreateSchema } from "../../../schema/Guild";
import { check } from "../../../util/instanceOf";
+import { DiscordApiErrors } from "../../../util/Constants";
router.get("/:code", async (req: Request, res: Response) => {
const { code } = req.params;
@@ -21,7 +22,7 @@ router.post("/:code", check(GuildTemplateCreateSchema), async (req: Request, res
const guild_count = await Member.count({ id: req.user_id });
if (guild_count >= maxGuilds) {
- throw new HTTPError(`Maximum number of guilds reached ${maxGuilds}`, 403);
+ throw DiscordApiErrors.MAXIMUM_GUILDS.withParams(maxGuilds);
}
const template = await Template.findOneOrFail({ code: code });
diff --git a/api/src/routes/users/@me/relationships.ts b/api/src/routes/users/@me/relationships.ts
index 0b864d88..2bd9c819 100644
--- a/api/src/routes/users/@me/relationships.ts
+++ b/api/src/routes/users/@me/relationships.ts
@@ -5,10 +5,12 @@ import {
RelationshipType,
RelationshipRemoveEvent,
emitEvent,
- Relationship
+ Relationship,
+ Config
} from "@fosscord/util";
import { Router, Response, Request } from "express";
import { HTTPError } from "lambert-server";
+import { DiscordApiErrors } from "../../../util/Constants";
import { check, Length } from "../../../util/instanceOf";
@@ -31,6 +33,7 @@ async function updateRelationship(req: Request, res: Response, friend: User, typ
var relationship = user.relationships.find((x) => x.id === id);
const friendRequest = friend.relationships.find((x) => x.id === req.user_id);
+ // TODO: you can add infinitely many blocked users (should this be prevented?)
if (type === RelationshipType.blocked) {
if (relationship) {
if (relationship.type === RelationshipType.blocked) throw new HTTPError("You already blocked the user");
@@ -67,6 +70,9 @@ async function updateRelationship(req: Request, res: Response, friend: User, typ
return res.sendStatus(204);
}
+ const { maxFriends } = Config.get().limits.user;
+ if (user.relationships.length >= maxFriends) throw DiscordApiErrors.MAXIMUM_FRIENDS.withParams(maxFriends);
+
var incoming_relationship = new Relationship({ nickname: undefined, type: RelationshipType.incoming, id: req.user_id });
var outgoing_relationship = new Relationship({ nickname: undefined, type: RelationshipType.outgoing, id });
|