diff --git a/api/src/routes/channels/#channel_id/messages/index.ts b/api/src/routes/channels/#channel_id/messages/index.ts
index d3c0a409..1ae9d676 100644
--- a/api/src/routes/channels/#channel_id/messages/index.ts
+++ b/api/src/routes/channels/#channel_id/messages/index.ts
@@ -37,7 +37,11 @@ export function isTextChannel(type: ChannelType): boolean {
case ChannelType.GUILD_PUBLIC_THREAD:
case ChannelType.GUILD_PRIVATE_THREAD:
case ChannelType.GUILD_TEXT:
+ case ChannelType.ENCRYPTED:
+ case ChannelType.ENCRYPTED_THREAD:
return true;
+ default:
+ throw new HTTPError("unimplemented", 400);
}
}
@@ -87,7 +91,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: { id: "DESC" },
take: limit,
where: { channel_id },
@@ -107,7 +111,7 @@ router.get("/", async (req: Request, res: Response) => {
const endpoint = Config.get().cdn.endpointPublic;
return res.json(
- messages.map((x) => {
+ messages.map((x: any) => {
(x.reactions || []).forEach((x: any) => {
// @ts-ignore
if ((x.user_ids || []).includes(req.user_id)) x.me = true;
@@ -116,10 +120,10 @@ router.get("/", async (req: Request, res: Response) => {
});
// @ts-ignore
if (!x.author) x.author = { discriminator: "0000", username: "Deleted User", public_flags: "0", avatar: null };
- x.attachments?.forEach((x) => {
+ x.attachments?.forEach((y: any) => {
// dynamically set attachment proxy_url in case the endpoint changed
- const uri = x.proxy_url.startsWith("http") ? x.proxy_url : `https://example.org${x.proxy_url}`;
- x.proxy_url = `${endpoint == null ? "" : endpoint}${new URL(uri).pathname}`;
+ 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}`;
});
return x;
@@ -172,7 +176,7 @@ router.post(
}
const channel = await Channel.findOneOrFail({ where: { id: channel_id }, relations: ["recipients", "recipients.user"] });
- const embeds = [];
+ const embeds = body.embeds || [];
if (body.embed) embeds.push(body.embed);
let message = await handleMessage({
...body,
@@ -216,7 +220,7 @@ router.post(
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/api/src/routes/channels/#channel_id/webhooks.ts b/api/src/routes/channels/#channel_id/webhooks.ts
index 7b894455..92895da6 100644
--- a/api/src/routes/channels/#channel_id/webhooks.ts
+++ b/api/src/routes/channels/#channel_id/webhooks.ts
@@ -14,6 +14,10 @@ export interface WebhookCreateSchema {
name: string;
avatar: string;
}
+//TODO: implement webhooks
+router.get("/", route({}), async (req: Request, res: Response) => {
+ res.json([]);
+});
// TODO: use Image Data Type for avatar instead of String
router.post("/", route({ body: "WebhookCreateSchema", permission: "MANAGE_WEBHOOKS" }), async (req: Request, res: Response) => {
diff --git a/api/src/routes/guilds/#guild_id/audit-logs.ts b/api/src/routes/guilds/#guild_id/audit-logs.ts
new file mode 100644
index 00000000..a4f2f800
--- /dev/null
+++ b/api/src/routes/guilds/#guild_id/audit-logs.ts
@@ -0,0 +1,20 @@
+import { Router, Response, Request } from "express";
+import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util";
+import { HTTPError } from "lambert-server";
+import { route } from "@fosscord/api";
+import { ChannelModifySchema } from "../../channels/#channel_id";
+const router = Router();
+
+//TODO: implement audit logs
+router.get("/", route({}), async (req: Request, res: Response) => {
+ res.json({
+ audit_log_entries: [],
+ users: [],
+ integrations: [],
+ webhooks: [],
+ guild_scheduled_events: [],
+ threads: [],
+ application_commands: []
+ });
+});
+export default router;
diff --git a/api/src/routes/guilds/#guild_id/bans.ts b/api/src/routes/guilds/#guild_id/bans.ts
index e7d46898..1e09a38d 100644
--- a/api/src/routes/guilds/#guild_id/bans.ts
+++ b/api/src/routes/guilds/#guild_id/bans.ts
@@ -6,13 +6,32 @@ import { getIpAdress, route } from "@fosscord/api";
export interface BanCreateSchema {
delete_message_days?: string;
reason?: string;
-}
+};
+
+export interface BanRegistrySchema {
+ id: string;
+ user_id: string;
+ guild_id: string;
+ executor_id: string;
+ ip?: string;
+ reason?: string | undefined;
+};
const router: Router = Router();
+
+/* TODO: Deleting the secrets is just a temporary go-around. Views should be implemented for both safety and better handling. */
+
router.get("/", route({ permission: "BAN_MEMBERS" }), async (req: Request, res: Response) => {
const { guild_id } = req.params;
- var bans = await Ban.find({ guild_id: guild_id });
+ let bans = await Ban.find({ guild_id: guild_id });
+
+ /* Filter secret from database registry.*/
+
+ bans.forEach((registry: BanRegistrySchema) => {
+ delete registry.ip;
+ });
+
return res.json(bans);
});
@@ -20,7 +39,12 @@ router.get("/:user", route({ permission: "BAN_MEMBERS" }), async (req: Request,
const { guild_id } = req.params;
const user_id = req.params.ban;
- var ban = await Ban.findOneOrFail({ guild_id: guild_id, user_id: user_id });
+ let ban = await Ban.findOneOrFail({ guild_id: guild_id, user_id: user_id }) as BanRegistrySchema;
+
+ /* Filter secret from registry. */
+
+ delete ban.ip
+
return res.json(ban);
});
diff --git a/api/src/routes/guilds/#guild_id/integrations.ts b/api/src/routes/guilds/#guild_id/integrations.ts
new file mode 100644
index 00000000..abf997c9
--- /dev/null
+++ b/api/src/routes/guilds/#guild_id/integrations.ts
@@ -0,0 +1,12 @@
+import { Router, Response, Request } from "express";
+import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util";
+import { HTTPError } from "lambert-server";
+import { route } from "@fosscord/api";
+import { ChannelModifySchema } from "../../channels/#channel_id";
+const router = Router();
+
+//TODO: implement integrations list
+router.get("/", route({}), async (req: Request, res: Response) => {
+ res.json([]);
+});
+export default router;
diff --git a/api/src/routes/guilds/#guild_id/roles.ts b/api/src/routes/guilds/#guild_id/roles.ts
index b1875598..b6894e3f 100644
--- a/api/src/routes/guilds/#guild_id/roles.ts
+++ b/api/src/routes/guilds/#guild_id/roles.ts
@@ -8,7 +8,8 @@ import {
GuildRoleDeleteEvent,
emitEvent,
Config,
- DiscordApiErrors
+ DiscordApiErrors,
+ handleFile
} from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { route } from "@fosscord/api";
@@ -22,6 +23,8 @@ export interface RoleModifySchema {
hoist?: boolean; // whether the role should be displayed separately in the sidebar
mentionable?: boolean; // whether the role should be mentionable
position?: number;
+ icon?: string;
+ unicode_emoji?: string;
}
export type RolePositionUpdateSchema = {
@@ -58,7 +61,9 @@ router.post("/", route({ body: "RoleModifySchema", permission: "MANAGE_ROLES" })
guild_id: guild_id,
managed: false,
permissions: String(req.permission!.bitfield & BigInt(body.permissions || "0")),
- tags: undefined
+ tags: undefined,
+ icon: null,
+ unicode_emoji: null
});
await Promise.all([
@@ -105,6 +110,8 @@ router.patch("/:role_id", route({ body: "RoleModifySchema", permission: "MANAGE_
const { role_id, guild_id } = req.params;
const body = req.body as RoleModifySchema;
+ if (body.icon) body.icon = await handleFile(`/role-icons/${role_id}`, body.icon as string);
+
const role = new Role({
...body,
id: role_id,
diff --git a/api/src/routes/guilds/#guild_id/webhooks.ts b/api/src/routes/guilds/#guild_id/webhooks.ts
new file mode 100644
index 00000000..8b2febea
--- /dev/null
+++ b/api/src/routes/guilds/#guild_id/webhooks.ts
@@ -0,0 +1,12 @@
+import { Router, Response, Request } from "express";
+import { Channel, ChannelUpdateEvent, getPermission, emitEvent } from "@fosscord/util";
+import { HTTPError } from "lambert-server";
+import { route } from "@fosscord/api";
+import { ChannelModifySchema } from "../../channels/#channel_id";
+const router = Router();
+
+//TODO: implement webhooks
+router.get("/", route({}), async (req: Request, res: Response) => {
+ res.json([]);
+});
+export default router;
diff --git a/api/src/routes/invites/index.ts b/api/src/routes/invites/index.ts
index a2cf4cb5..37e9e05a 100644
--- a/api/src/routes/invites/index.ts
+++ b/api/src/routes/invites/index.ts
@@ -19,7 +19,8 @@ router.post("/:code", route({}), async (req: Request, res: Response) => {
const { features } = await Guild.findOneOrFail({ id: guild_id});
const { public_flags } = await User.findOneOrFail({ id: req.user_id });
- if(features.includes("INTERNAL_EMPLOYEE_ONLY") && (public_flags & 1) !== 1) throw new HTTPError("You are not allowed to join this guild.", 401)
+ if(features.includes("INTERNAL_EMPLOYEE_ONLY") && (public_flags & 1) !== 1) throw new HTTPError("Only intended for the staff of this server.", 401);
+ if(features.includes("INVITES_CLOSED")) throw new HTTPError("Sorry, this guild has joins closed.", 403);
const invite = await Invite.joinGuild(req.user_id, code);
diff --git a/api/src/routes/stop.ts b/api/src/routes/stop.ts
new file mode 100644
index 00000000..7f8b78ba
--- /dev/null
+++ b/api/src/routes/stop.ts
@@ -0,0 +1,26 @@
+import { Router, Request, Response } from "express";
+import { route } from "@fosscord/api";
+import { User } from "@fosscord/util";
+
+const router: Router = Router();
+
+router.post("/", route({}), async (req: Request, res: Response) => {
+ //EXPERIMENTAL: have an "OPERATOR" platform permission implemented for this API route
+ const user = await User.findOneOrFail({ where: { id: req.user_id }, select: ["rights"] });
+ if((Number(user.rights) << Number(0))%Number(2)==Number(1)) {
+ console.log("user that POSTed to the API was ALLOWED");
+ console.log(user.rights);
+ res.sendStatus(200)
+ process.kill(process.pid, 'SIGTERM')
+ }
+ else {
+ console.log("operation failed");
+ console.log(user.rights);
+ res.sendStatus(403)
+ }
+});
+
+export default router;
+
+//THIS API CAN ONLY BE USED BY USERS WITH THE 'OPERATOR' RIGHT (which is the value of 1) ONLY IF ANY OTHER RIGHTS ARE ADDED OR IF THE USER DOESNT HAVE PERMISSION,
+//THE REQUEST WILL RETURN 403 'FORBIDDEN'
|