diff --git a/api/src/routes/channels/#channel_id/invites.ts b/api/src/routes/channels/#channel_id/invites.ts
index 6d2c625d..9c361164 100644
--- a/api/src/routes/channels/#channel_id/invites.ts
+++ b/api/src/routes/channels/#channel_id/invites.ts
@@ -19,7 +19,8 @@ export interface InviteCreateSchema {
target_user_type?: number;
}
-router.post("/", route({ body: "InviteCreateSchema", permission: "CREATE_INSTANT_INVITE" }), async (req: Request, res: Response) => {
+router.post("/", route({ body: "InviteCreateSchema", permission: "CREATE_INSTANT_INVITE", right: "CREATE_INVITES" }),
+ async (req: Request, res: Response) => {
const { user_id } = req;
const { channel_id } = req.params;
const channel = await Channel.findOneOrFail({ where: { id: channel_id }, select: ["id", "name", "type", "guild_id"] });
diff --git a/api/src/routes/channels/#channel_id/messages/#message_id/index.ts b/api/src/routes/channels/#channel_id/messages/#message_id/index.ts
index 7f7de264..58dfb1cc 100644
--- a/api/src/routes/channels/#channel_id/messages/#message_id/index.ts
+++ b/api/src/routes/channels/#channel_id/messages/#message_id/index.ts
@@ -1,4 +1,4 @@
-import { Channel, emitEvent, getPermission, MessageDeleteEvent, Message, MessageUpdateEvent } from "@fosscord/util";
+import { Channel, emitEvent, getPermission, getRights, MessageDeleteEvent, Message, MessageUpdateEvent } from "@fosscord/util";
import { Router, Response, Request } from "express";
import { route } from "@fosscord/api";
import { handleMessage, postHandleMessage } from "@fosscord/api";
@@ -7,18 +7,23 @@ import { MessageCreateSchema } from "../index";
const router = Router();
// TODO: message content/embed string length limit
-router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGES" }), async (req: Request, res: Response) => {
+router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGES", right: "SEND_MESSAGES" }), async (req: Request, res: Response) => {
const { message_id, channel_id } = req.params;
var body = req.body as MessageCreateSchema;
const message = await Message.findOneOrFail({ where: { id: message_id, channel_id }, relations: ["attachments"] });
const permissions = await getPermission(req.user_id, undefined, channel_id);
-
- if (req.user_id !== message.author_id) {
- permissions.hasThrow("MANAGE_MESSAGES");
- body = { flags: body.flags }; // admins can only suppress embeds of other messages
- }
+
+ const rights = await getRights(req.user_id);
+
+ if ((req.user_id !== message.author_id)) {
+ if (!rights.has("MANAGE_MESSAGES")) {
+ permissions.hasThrow("MANAGE_MESSAGES");
+ body = { flags: body.flags };
+// guild admins can only suppress embeds of other messages, no such restriction imposed to instance-wide admins
+ }
+ } else rights.hasThrow("SELF_EDIT_MESSAGES");
const new_message = await handleMessage({
...message,
@@ -46,17 +51,20 @@ router.patch("/", route({ body: "MessageCreateSchema", permission: "SEND_MESSAGE
return res.json(message);
});
-// permission check only if deletes messagr from other user
router.delete("/", route({}), async (req: Request, res: Response) => {
const { message_id, channel_id } = req.params;
const channel = await Channel.findOneOrFail({ id: channel_id });
const message = await Message.findOneOrFail({ id: message_id });
+
+ const rights = await getRights(req.user_id);
- if (message.author_id !== req.user_id) {
- const permission = await getPermission(req.user_id, channel.guild_id, channel_id);
- permission.hasThrow("MANAGE_MESSAGES");
- }
+ if ((message.author_id !== req.user_id)) {
+ if (!rights.has("MANAGE_MESSAGES")) {
+ const permission = await getPermission(req.user_id, channel.guild_id, channel_id);
+ permission.hasThrow("MANAGE_MESSAGES");
+ }
+ } else rights.hasThrow("SELF_DELETE_MESSAGES");
await Message.delete({ id: message_id });
diff --git a/api/src/routes/guilds/#guild_id/index.ts b/api/src/routes/guilds/#guild_id/index.ts
index 991c3f93..4ec3df72 100644
--- a/api/src/routes/guilds/#guild_id/index.ts
+++ b/api/src/routes/guilds/#guild_id/index.ts
@@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
-import { emitEvent, getPermission, Guild, GuildUpdateEvent, handleFile, Member } from "@fosscord/util";
+import { DiscordApiErrors, emitEvent, getPermission, getRights, Guild, GuildUpdateEvent, handleFile, Member } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { route } from "@fosscord/api";
import "missing-native-js-functions";
@@ -37,9 +37,17 @@ router.get("/", route({}), async (req: Request, res: Response) => {
return res.send(guild);
});
-router.patch("/", route({ body: "GuildUpdateSchema", permission: "MANAGE_GUILD" }), async (req: Request, res: Response) => {
+router.patch("/", route({ body: "GuildUpdateSchema"}), async (req: Request, res: Response) => {
const body = req.body as GuildUpdateSchema;
const { guild_id } = req.params;
+
+
+ const rights = await getRights(req.user_id);
+ const permission = await getPermission(req.user_id, guild_id);
+
+ if (!rights.has("MANAGE_GUILDS")||!permission.has("MANAGE_GUILD"))
+ throw DiscordApiErrors.MISSING_PERMISSIONS.withParams("MANAGE_GUILD");
+
// TODO: guild update check image
if (body.icon) body.icon = await handleFile(`/icons/${guild_id}`, body.icon);
diff --git a/api/src/routes/guilds/index.ts b/api/src/routes/guilds/index.ts
index 7b676211..10721413 100644
--- a/api/src/routes/guilds/index.ts
+++ b/api/src/routes/guilds/index.ts
@@ -1,5 +1,5 @@
import { Router, Request, Response } from "express";
-import { Role, Guild, Snowflake, Config, Member, Channel, DiscordApiErrors, handleFile } from "@fosscord/util";
+import { Role, Guild, Snowflake, Config, getRights, Member, Channel, DiscordApiErrors, handleFile } from "@fosscord/util";
import { route } from "@fosscord/api";
import { ChannelModifySchema } from "../channels/#channel_id";
@@ -20,12 +20,13 @@ export interface GuildCreateSchema {
//TODO: create default channel
-router.post("/", route({ body: "GuildCreateSchema" }), async (req: Request, res: Response) => {
+router.post("/", route({ body: "GuildCreateSchema", right: "CREATE_GUILDS" }), async (req: Request, res: Response) => {
const body = req.body as GuildCreateSchema;
const { maxGuilds } = Config.get().limits.user;
const guild_count = await Member.count({ id: req.user_id });
- if (guild_count >= maxGuilds) {
+ const rights = await getRights(req.user_id);
+ if ((guild_count >= maxGuilds)&&!rights.has("MANAGE_GUILDS")) {
throw DiscordApiErrors.MAXIMUM_GUILDS.withParams(maxGuilds);
}
diff --git a/api/src/routes/invites/index.ts b/api/src/routes/invites/index.ts
index 37e9e05a..21da2d18 100644
--- a/api/src/routes/invites/index.ts
+++ b/api/src/routes/invites/index.ts
@@ -13,7 +13,7 @@ router.get("/:code", route({}), async (req: Request, res: Response) => {
res.status(200).send(invite);
});
-router.post("/:code", route({}), async (req: Request, res: Response) => {
+router.post("/:code", route({right: "JOIN_GUILDS"}), async (req: Request, res: Response) => {
const { code } = req.params;
const { guild_id } = await Invite.findOneOrFail({ code })
const { features } = await Guild.findOneOrFail({ id: guild_id});
diff --git a/api/src/routes/scheduled-maintenances/upcoming_json.ts b/api/src/routes/scheduled-maintenances/upcoming_json.ts
new file mode 100644
index 00000000..83092e44
--- /dev/null
+++ b/api/src/routes/scheduled-maintenances/upcoming_json.ts
@@ -0,0 +1,12 @@
+import { Router, Request, Response } from "express";
+import { route } from "@fosscord/api";
+const router = Router();
+
+router.get("/scheduled-maintenances/upcoming.json",route({}), async (req: Request, res: Response) => {
+ res.json({
+ "page": {},
+ "scheduled_maintenances": {}
+ });
+});
+
+export default router;
diff --git a/api/src/routes/users/@me/notes.ts b/api/src/routes/users/@me/notes.ts
index 96067bf5..4887b191 100644
--- a/api/src/routes/users/@me/notes.ts
+++ b/api/src/routes/users/@me/notes.ts
@@ -1,14 +1,39 @@
import { Request, Response, Router } from "express";
import { route } from "@fosscord/api";
+import { User, emitEvent } from "@fosscord/util";
const router: Router = Router();
+router.get("/:id", route({}), async (req: Request, res: Response) => {
+ const { id } = req.params;
+ const user = await User.findOneOrFail({ where: { id: req.user_id }, select: ["notes"] });
+
+ const note = user.notes[id];
+ return res.json({
+ note: note,
+ note_user_id: id,
+ user_id: user.id,
+ });
+});
+
router.put("/:id", route({}), async (req: Request, res: Response) => {
- //TODO
- res.json({
- message: "Unknown User",
- code: 10013
- }).status(404);
+ const { id } = req.params;
+ const user = await User.findOneOrFail({ where: { id: req.user_id } });
+ const noteUser = await User.findOneOrFail({ where: { id: id }}); //if noted user does not exist throw
+ const { note } = req.body;
+
+ await User.update({ id: req.user_id }, { notes: { ...user.notes, [noteUser.id]: note } });
+
+ await emitEvent({
+ event: "USER_NOTE_UPDATE",
+ data: {
+ note: note,
+ id: noteUser.id
+ },
+ user_id: user.id,
+ })
+
+ return res.status(204);
});
export default router;
|