diff --git a/src/Server.ts b/src/Server.ts
index 19a0fc5f..c7c52c1f 100644
--- a/src/Server.ts
+++ b/src/Server.ts
@@ -4,7 +4,7 @@ import { Connection } from "mongoose";
import { Server, ServerOptions } from "lambert-server";
import { Authentication, GlobalRateLimit } from "./middlewares/";
import Config from "./util/Config";
-import { db } from "fosscord-server-util";
+import { db } from "@fosscord/server-util";
import i18next from "i18next";
import i18nextMiddleware, { I18next } from "i18next-http-middleware";
import i18nextBackend from "i18next-node-fs-backend";
@@ -13,21 +13,21 @@ import { BodyParser } from "./middlewares/BodyParser";
import { Router } from "express";
import fetch from "node-fetch";
-export interface DiscordServerOptions extends ServerOptions {}
+export interface FosscordServerOptions extends ServerOptions {}
declare global {
namespace Express {
interface Request {
// @ts-ignore
- server: DiscordServer;
+ server: FosscordServer;
}
}
}
-export class DiscordServer extends Server {
- public options: DiscordServerOptions;
+export class FosscordServer extends Server {
+ public options: FosscordServerOptions;
- constructor(opts?: Partial<DiscordServerOptions>) {
+ constructor(opts?: Partial<FosscordServerOptions>) {
// @ts-ignore
super({ ...opts, errorHandler: false, jsonBody: false });
}
diff --git a/src/index.ts b/src/index.ts
index 6a0fabc4..c6417126 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,17 +1,19 @@
-process.on("uncaughtException", console.error);
-process.on("unhandledRejection", console.error);
-
-import "missing-native-js-functions";
-import { config } from "dotenv";
-config();
-import { DiscordServer } from "./Server";
-
-var port = Number(process.env.PORT);
-if (isNaN(port)) port = 1000;
-
-const server = new DiscordServer({ port });
-server.start().catch(console.error);
-
-// @ts-ignore
-global.server = server;
-export default server;
+export * from "./Server";
+export * from "./middlewares/";
+export * from "./schema/Ban";
+export * from "./schema/Channel";
+export * from "./schema/Guild";
+export * from "./schema/Invite";
+export * from "./schema/Message";
+export * from "./util/Captcha";
+export * from "./util/Config";
+export * from "./util/Constants";
+export * from "./util/Event";
+export * from "./util/instanceOf";
+export * from "./util/Event";
+export * from "./util/instanceOf";
+export * from "./util/Member";
+export * from "./util/RandomInviteID";
+export * from "./util/String";
+export * from "./util/User";
+export { check as checkPassword } from "./util/passwordStrength";
diff --git a/src/middlewares/Authentication.ts b/src/middlewares/Authentication.ts
index 30445815..0ecc1bc0 100644
--- a/src/middlewares/Authentication.ts
+++ b/src/middlewares/Authentication.ts
@@ -1,6 +1,6 @@
import { NextFunction, Request, Response } from "express";
import { HTTPError } from "lambert-server";
-import { checkToken } from "fosscord-server-util";
+import { checkToken } from "@fosscord/server-util";
export const NO_AUTHORIZATION_ROUTES = [
"/api/v8/auth/login",
diff --git a/src/middlewares/index.ts b/src/middlewares/index.ts
index e3332f07..6a2993a7 100644
--- a/src/middlewares/index.ts
+++ b/src/middlewares/index.ts
@@ -1,4 +1,6 @@
-import { Authentication } from "./Authentication";
-import { GlobalRateLimit } from "./GlobalRateLimit";
-
-export { Authentication, GlobalRateLimit };
+export * from "./GlobalRateLimit";
+export * from "./Authentication";
+export * from "./BodyParser";
+export * from "./CORS";
+export * from "./ErrorHandler";
+export * from "./RateLimit";
diff --git a/src/routes/auth/login.ts b/src/routes/auth/login.ts
index cc2b6202..247ee018 100644
--- a/src/routes/auth/login.ts
+++ b/src/routes/auth/login.ts
@@ -2,7 +2,7 @@ import { Request, Response, Router } from "express";
import { check, FieldErrors, Length } from "../../util/instanceOf";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
-import { User, UserModel } from "fosscord-server-util";
+import { UserModel } from "@fosscord/server-util";
import Config from "../../util/Config";
import { adjustEmail } from "./register";
diff --git a/src/routes/auth/register.ts b/src/routes/auth/register.ts
index 5501203d..1a026670 100644
--- a/src/routes/auth/register.ts
+++ b/src/routes/auth/register.ts
@@ -1,6 +1,6 @@
import { Request, Response, Router } from "express";
import Config from "../../util/Config";
-import { trimSpecial, User, Snowflake, UserModel } from "fosscord-server-util";
+import { trimSpecial, User, Snowflake, UserModel } from "@fosscord/server-util";
import bcrypt from "bcrypt";
import { check, Email, EMAIL_REGEX, FieldErrors, Length } from "../../util/instanceOf";
import "missing-native-js-functions";
diff --git a/src/routes/channels/#channel_id/followers.ts b/src/routes/channels/#channel_id/followers.ts
index 9a4e81fa..c06db61b 100644
--- a/src/routes/channels/#channel_id/followers.ts
+++ b/src/routes/channels/#channel_id/followers.ts
@@ -1,4 +1,14 @@
import { Router } from "express";
const router: Router = Router();
+// TODO:
export default router;
+
+/**
+ *
+ * @param {"webhook_channel_id":"754001514330062952"}
+ *
+ * Creates a WebHook in the channel and returns the id of it
+ *
+ * @returns {"channel_id": "816382962056560690", "webhook_id": "834910735095037962"}
+ */
diff --git a/src/routes/channels/#channel_id/index.ts b/src/routes/channels/#channel_id/index.ts
index 9a4e81fa..f6970df3 100644
--- a/src/routes/channels/#channel_id/index.ts
+++ b/src/routes/channels/#channel_id/index.ts
@@ -1,4 +1,30 @@
+import { ChannelModel, getPermission, toObject } from "@fosscord/server-util";
import { Router } from "express";
+import { HTTPError } from "lambert-server";
const router: Router = Router();
+// TODO: delete channel
+// TODO: Get channel
+
+router.delete("/", async(req,res)=>{
+ const {channel_id} = req.params
+
+ const channel = await ChannelModel.findOne({ id: channel_id }, { guild_id: true, type: true, permission_overwrites: true }).exec();
+ if (!channel) throw new HTTPError("Channel not found", 404);
+ if (channel.guild_id) {
+ const permission = await getPermission(req.user_id, channel.guild_id)
+ permission.hasThrow("MANAGE_CHANNELS")
+
+ // TODO Channel Update Gateway event will fire for each of them
+ await ChannelModel.updateMany({parent_id: channel_id}, {$set: {channel_id: null}}).exec()
+
+ await ChannelModel.deleteOne({id: channel_id})
+ }
+
+ // TODO: Dm channel "close" not delete
+
+ const data = toObject(channel);
+ //TODO: Reload channel list if request successful
+ res.send(data)
+})
export default router;
diff --git a/src/routes/channels/#channel_id/invites.ts b/src/routes/channels/#channel_id/invites.ts
index da802800..10d6ae3f 100644
--- a/src/routes/channels/#channel_id/invites.ts
+++ b/src/routes/channels/#channel_id/invites.ts
@@ -7,7 +7,7 @@ import { emitEvent } from "../../../util/Event";
import { InviteCreateSchema } from "../../../schema/Invite";
-import { getPermission, ChannelModel, InviteModel, InviteCreateEvent, toObject } from "fosscord-server-util";
+import { getPermission, ChannelModel, InviteModel, InviteCreateEvent, toObject } from "@fosscord/server-util";
const router: Router = Router();
@@ -22,10 +22,7 @@ router.post("/", check(InviteCreateSchema), async (req: Request, res: Response)
const { guild_id } = channel;
const permission = await getPermission(user_id, guild_id);
-
- if (!permission.has("CREATE_INSTANT_INVITE")) {
- throw new HTTPError("You aren't authorised to access this endpoint", 401);
- }
+ permission.hasThrow("CREATE_INSTANT_INVITE");
const invite = {
code: random(),
@@ -55,10 +52,7 @@ router.get("/", async (req: Request, res: Response) => {
}
const { guild_id } = channel;
const permission = await getPermission(user_id, guild_id);
-
- if (!permission.has("MANAGE_CHANNELS")) {
- throw new HTTPError("You aren't authorised to access this endpoint", 401);
- }
+ permission.hasThrow("MANAGE_CHANNELS");
const invites = await InviteModel.find({ guild_id }).exec();
diff --git a/src/routes/channels/#channel_id/messages/#message_id/crosspost.ts b/src/routes/channels/#channel_id/messages/#message_id/crosspost.ts
new file mode 100644
index 00000000..17f36396
--- /dev/null
+++ b/src/routes/channels/#channel_id/messages/#message_id/crosspost.ts
@@ -0,0 +1,8 @@
+import { Router } from "express";
+
+const router = Router();
+
+// TODO:
+// router.post("/", (req, res) => {});
+
+export default router;
diff --git a/src/routes/channels/#channel_id/messages/#message_id/index.ts b/src/routes/channels/#channel_id/messages/#message_id/index.ts
new file mode 100644
index 00000000..014daee7
--- /dev/null
+++ b/src/routes/channels/#channel_id/messages/#message_id/index.ts
@@ -0,0 +1,6 @@
+import { Router } from "express";
+
+const router = Router();
+// TODO:
+
+export default router;
diff --git a/src/routes/channels/#channel_id/messages/#message_id/reactions.ts b/src/routes/channels/#channel_id/messages/#message_id/reactions.ts
new file mode 100644
index 00000000..014daee7
--- /dev/null
+++ b/src/routes/channels/#channel_id/messages/#message_id/reactions.ts
@@ -0,0 +1,6 @@
+import { Router } from "express";
+
+const router = Router();
+// TODO:
+
+export default router;
diff --git a/src/routes/channels/#channel_id/messages/bulk-delete.ts b/src/routes/channels/#channel_id/messages/bulk-delete.ts
index 89e9d720..ff1324d7 100644
--- a/src/routes/channels/#channel_id/messages/bulk-delete.ts
+++ b/src/routes/channels/#channel_id/messages/bulk-delete.ts
@@ -1,5 +1,5 @@
import { Router } from "express";
-import { ChannelModel, getPermission, MessageDeleteBulkEvent, MessageModel } from "fosscord-server-util";
+import { ChannelModel, getPermission, MessageDeleteBulkEvent, MessageModel } from "@fosscord/server-util";
import { HTTPError } from "lambert-server";
import Config from "../../../../util/Config";
import { emitEvent } from "../../../../util/Event";
@@ -13,12 +13,12 @@ export default router;
// TODO: should this request fail, if you provide messages older than 14 days/invalid ids?
// https://discord.com/developers/docs/resources/channel#bulk-delete-messages
router.post("/", check({ messages: [String] }), async (req, res) => {
- const channel_id = req.params.channel_id
+ const channel_id = req.params.channel_id;
const channel = await ChannelModel.findOne({ id: channel_id }, { permission_overwrites: true, guild_id: true }).exec();
if (!channel?.guild_id) throw new HTTPError("Can't bulk delete dm channel messages", 400);
const permission = await getPermission(req.user_id, channel?.guild_id, channel_id, { channel });
- if (!permission.has("MANAGE_MESSAGES")) throw new HTTPError("You are missing the MANAGE_MESSAGES permissions");
+ permission.hasThrow("MANAGE_MESSAGES");
const { maxBulkDelete } = Config.get().limits.message;
diff --git a/src/routes/channels/#channel_id/messages/index.ts b/src/routes/channels/#channel_id/messages/index.ts
index c3ea3da9..a5151d9b 100644
--- a/src/routes/channels/#channel_id/messages/index.ts
+++ b/src/routes/channels/#channel_id/messages/index.ts
@@ -9,7 +9,7 @@ import {
MessageModel,
Snowflake,
toObject,
-} from "fosscord-server-util";
+} from "@fosscord/server-util";
import { HTTPError } from "lambert-server";
import { MessageCreateSchema } from "../../../../schema/Message";
import { check, instanceOf, Length } from "../../../../util/instanceOf";
@@ -22,7 +22,7 @@ const router: Router = Router();
export default router;
-function isTextChannel(type: ChannelType): boolean {
+export function isTextChannel(type: ChannelType): boolean {
switch (type) {
case ChannelType.GUILD_VOICE:
case ChannelType.GUILD_CATEGORY:
@@ -62,7 +62,8 @@ router.get("/", async (req, res) => {
if (channel.guild_id) {
const permissions = await getPermission(req.user_id, channel.guild_id, channel_id, { channel });
- if (!permissions.has("VIEW_CHANNEL")) throw new HTTPError("You don't have permission to view this channel", 401);
+ permissions.hasThrow("VIEW_CHANNEL");
+
if (!permissions.has("READ_MESSAGE_HISTORY")) return res.json([]);
} else if (channel.recipients) {
// group/dm channel
@@ -106,11 +107,10 @@ router.post("/", check(MessageCreateSchema), async (req, res) => {
if (channel.guild_id) {
const permissions = await getPermission(req.user_id, channel.guild_id, channel_id, { channel });
- if (!permissions.has("SEND_MESSAGES")) throw new HTTPError("You don't have the SEND_MESSAGES permission");
- if (body.tts && !permissions.has("SEND_TTS_MESSAGES")) throw new HTTPError("You are missing the SEND_TTS_MESSAGES permission");
+ permissions.hasThrow("SEND_MESSAGES");
+ if (body.tts) permissions.hasThrow("SEND_TTS_MESSAGES");
if (body.message_reference) {
- if (!permissions.has("READ_MESSAGE_HISTORY"))
- throw new HTTPError("You are missing the READ_MESSAGE_HISTORY permission to reply");
+ permissions.hasThrow("READ_MESSAGE_HISTORY");
if (body.message_reference.guild_id !== channel.guild_id)
throw new HTTPError("You can only reference messages from this guild");
}
diff --git a/src/routes/channels/#channel_id/permissions.ts b/src/routes/channels/#channel_id/permissions.ts
index 9a4e81fa..93c33ea5 100644
--- a/src/routes/channels/#channel_id/permissions.ts
+++ b/src/routes/channels/#channel_id/permissions.ts
@@ -1,4 +1,5 @@
import { Router } from "express";
const router: Router = Router();
+// TODO:
export default router;
diff --git a/src/routes/channels/#channel_id/pins.ts b/src/routes/channels/#channel_id/pins.ts
index 9a4e81fa..93c33ea5 100644
--- a/src/routes/channels/#channel_id/pins.ts
+++ b/src/routes/channels/#channel_id/pins.ts
@@ -1,4 +1,5 @@
import { Router } from "express";
const router: Router = Router();
+// TODO:
export default router;
diff --git a/src/routes/channels/#channel_id/recipients.ts b/src/routes/channels/#channel_id/recipients.ts
index 9a4e81fa..93c33ea5 100644
--- a/src/routes/channels/#channel_id/recipients.ts
+++ b/src/routes/channels/#channel_id/recipients.ts
@@ -1,4 +1,5 @@
import { Router } from "express";
const router: Router = Router();
+// TODO:
export default router;
diff --git a/src/routes/channels/#channel_id/typing.ts b/src/routes/channels/#channel_id/typing.ts
index 9a4e81fa..93c33ea5 100644
--- a/src/routes/channels/#channel_id/typing.ts
+++ b/src/routes/channels/#channel_id/typing.ts
@@ -1,4 +1,5 @@
import { Router } from "express";
const router: Router = Router();
+// TODO:
export default router;
diff --git a/src/routes/channels/#channel_id/webhooks.ts b/src/routes/channels/#channel_id/webhooks.ts
index 9a4e81fa..a56365b8 100644
--- a/src/routes/channels/#channel_id/webhooks.ts
+++ b/src/routes/channels/#channel_id/webhooks.ts
@@ -1,4 +1,27 @@
import { Router } from "express";
+import { check, Length } from "../../../util/instanceOf";
+import { ChannelModel, getPermission, trimSpecial } from "@fosscord/server-util";
+import { HTTPError } from "lambert-server";
+import { isTextChannel } from "./messages/index";
+
const router: Router = Router();
+// TODO:
+
+// TODO: use Image Data Type for avatar instead of String
+router.post("/", check({ name: new Length(String, 1, 80), $avatar: String }), async (req, res) => {
+ const channel_id = req.params.channel_id;
+ const channel = await ChannelModel.findOne({ id: channel_id }, { guild_id: true, type: true }).exec();
+ if (!channel) throw new HTTPError("Channel not found", 404);
+
+ isTextChannel(channel.type);
+ if (!channel.guild_id) throw new HTTPError("Not a guild channel", 400);
+
+ const permission = await getPermission(req.user_id, channel.guild_id);
+ permission.hasThrow("MANAGE_WEBHOOKS");
+
+ var { avatar, name } = req.body as { name: string; avatar?: string };
+ name = trimSpecial(name);
+ if (name === "clyde") throw new HTTPError("Invalid name", 400);
+});
export default router;
diff --git a/src/routes/guilds/#guild_id/bans.ts b/src/routes/guilds/#guild_id/bans.ts
index 3de80a32..f84950f9 100644
--- a/src/routes/guilds/#guild_id/bans.ts
+++ b/src/routes/guilds/#guild_id/bans.ts
@@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
-import { BanModel, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, GuildModel, toObject } from "fosscord-server-util";
+import { BanModel, getPermission, GuildBanAddEvent, GuildBanRemoveEvent, GuildModel, toObject } from "@fosscord/server-util";
import { HTTPError } from "lambert-server";
import { getIpAdress } from "../../../middlewares/GlobalRateLimit";
import { BanCreateSchema } from "../../../schema/Ban";
@@ -35,7 +35,7 @@ router.post("/:user_id", check(BanCreateSchema), async (req: Request, res: Respo
const banned_user = await getPublicUser(banned_user_id);
const perms = await getPermission(req.user_id, guild_id);
- if (!perms.has("BAN_MEMBERS")) throw new HTTPError("You don't have the permission to ban members", 403);
+ perms.hasThrow("BAN_MEMBERS");
if (req.user_id === banned_user_id) throw new HTTPError("You can't ban yourself", 400);
await removeMember(banned_user_id, guild_id);
@@ -69,9 +69,7 @@ router.delete("/:user_id", async (req: Request, res: Response) => {
if (!guild) throw new HTTPError("Guild not found", 404);
const perms = await getPermission(req.user_id, guild_id);
- if (!perms.has("BAN_MEMBERS")) {
- throw new HTTPError("No permissions", 403);
- }
+ perms.hasThrow("BAN_MEMBERS");
await BanModel.deleteOne({
user_id: banned_user_id,
diff --git a/src/routes/guilds/#guild_id/channels.ts b/src/routes/guilds/#guild_id/channels.ts
index e0d8f3ac..d42ba481 100644
--- a/src/routes/guilds/#guild_id/channels.ts
+++ b/src/routes/guilds/#guild_id/channels.ts
@@ -1,5 +1,5 @@
import { Router } from "express";
-import { ChannelCreateEvent, ChannelModel, ChannelType, GuildModel, Snowflake, toObject } from "fosscord-server-util";
+import { ChannelCreateEvent, ChannelModel, ChannelType, GuildModel, Snowflake, toObject } from "@fosscord/server-util";
import { HTTPError } from "lambert-server";
import { ChannelModifySchema } from "../../../schema/Channel";
import { emitEvent } from "../../../util/Event";
diff --git a/src/routes/guilds/#guild_id/index.ts b/src/routes/guilds/#guild_id/index.ts
index 7e5f49d3..2a7d9b38 100644
--- a/src/routes/guilds/#guild_id/index.ts
+++ b/src/routes/guilds/#guild_id/index.ts
@@ -12,7 +12,7 @@ import {
RoleModel,
toObject,
UserModel,
-} from "fosscord-server-util";
+} from "@fosscord/server-util";
import { HTTPError } from "lambert-server";
import { GuildUpdateSchema } from "../../../schema/Guild";
import { emitEvent } from "../../../util/Event";
@@ -41,7 +41,7 @@ router.patch("/", check(GuildUpdateSchema), async (req: Request, res: Response)
// TODO: guild update check image
const perms = await getPermission(req.user_id, guild_id);
- if (!perms.has("MANAGE_GUILD")) throw new HTTPError("You do not have the MANAGE_GUILD permission", 401);
+ perms.hasThrow("MANAGE_GUILD");
const guild = await GuildModel.findOneAndUpdate({ id: guild_id }, body)
.populate({ path: "joined_at", match: { id: req.user_id } })
diff --git a/src/routes/guilds/#guild_id/members.ts b/src/routes/guilds/#guild_id/members.ts
index f4e6d4e8..61493485 100644
--- a/src/routes/guilds/#guild_id/members.ts
+++ b/src/routes/guilds/#guild_id/members.ts
@@ -1,5 +1,5 @@
import { Request, Response, Router } from "express";
-import { GuildModel, MemberModel, toObject } from "fosscord-server-util";
+import { GuildModel, MemberModel, toObject } from "@fosscord/server-util";
import { HTTPError } from "lambert-server";
import { instanceOf, Length } from "../../../util/instanceOf";
import { PublicMemberProjection } from "../../../util/Member";
diff --git a/src/routes/guilds/index.ts b/src/routes/guilds/index.ts
index 57d7ddc4..bd491e86 100644
--- a/src/routes/guilds/index.ts
+++ b/src/routes/guilds/index.ts
@@ -1,5 +1,5 @@
import { Router, Request, Response } from "express";
-import { RoleModel, GuildModel, Snowflake, Guild } from "fosscord-server-util";
+import { RoleModel, GuildModel, Snowflake, Guild } from "@fosscord/server-util";
import { HTTPError } from "lambert-server";
import { check } from "./../../util/instanceOf";
import { GuildCreateSchema } from "../../schema/Guild";
@@ -9,6 +9,8 @@ import { addMember } from "../../util/Member";
const router: Router = Router();
+//TODO: create default channel
+
router.post("/", check(GuildCreateSchema), async (req: Request, res: Response) => {
const body = req.body as GuildCreateSchema;
diff --git a/src/routes/invites/index.ts b/src/routes/invites/index.ts
index df74e216..7f4ff59b 100644
--- a/src/routes/invites/index.ts
+++ b/src/routes/invites/index.ts
@@ -1,5 +1,5 @@
import { Router, Request, Response } from "express";
-import { getPermission, InviteModel, toObject } from "fosscord-server-util";
+import { getPermission, InviteModel, toObject } from "@fosscord/server-util";
import { HTTPError } from "lambert-server";
const router: Router = Router();
@@ -21,7 +21,8 @@ router.delete("/:invite_code", async (req: Request, res: Response) => {
const { guild_id, channel_id } = invite;
const perms = await getPermission(req.user_id, guild_id, channel_id);
- if (!perms.has("MANAGE_GUILD") || !perms.has("MANAGE_CHANNELS")) throw new HTTPError("You aren't allow", 401);
+ if (!perms.has("MANAGE_GUILD") && !perms.has("MANAGE_CHANNELS"))
+ throw new HTTPError("You missing the MANAGE_GUILD or MANAGE_CHANNELS permission", 401);
await InviteModel.deleteOne({ code }).exec();
diff --git a/src/routes/users/#id/index.ts b/src/routes/users/#id/index.ts
new file mode 100644
index 00000000..d5f3b788
--- /dev/null
+++ b/src/routes/users/#id/index.ts
@@ -0,0 +1,19 @@
+import { Router, Request, Response } from "express";
+import { UserModel, toObject } from "@fosscord/server-util";
+import { getPublicUser } from "../../../util/User";
+import { HTTPError } from "lambert-server";
+import { UserUpdateSchema } from "../../../schema/User";
+import { check } from "../../../util/instanceOf";
+
+const router: Router = Router();
+
+router.get("/", async (req: Request, res: Response) => {
+ const { id } = req.params;
+ const user = await getPublicUser(id);
+ if (!user) throw new HTTPError("User not found", 404);
+
+ res.json(user);
+});
+
+
+export default router;
diff --git a/src/routes/users/@me/channels.ts b/src/routes/users/@me/channels.ts
new file mode 100644
index 00000000..45371b34
--- /dev/null
+++ b/src/routes/users/@me/channels.ts
@@ -0,0 +1,69 @@
+import {
+ Router,
+ Request,
+ Response
+} from "express";
+import {
+ ChannelModel,
+ ChannelCreateEvent,
+ DMChannel,
+ UserModel,
+ toObject,
+ ChannelType,
+ Snowflake
+} from "@fosscord/server-util";
+import {
+ HTTPError
+} from "lambert-server";
+import {
+ emitEvent
+} from "../../../util/Event";
+import {
+ getPublicUser
+} from "../../../util/User";
+import {
+ DmChannelCreateSchema
+} from "../../../schema/Channel";
+import {
+ check
+} from "../../../util/instanceOf";
+
+const router: Router = Router();
+
+router.get("/", async (req: Request, res: Response) => {
+ const user = await UserModel.findOne({
+ id: req.user_id
+ }, {
+ guilds: true
+ }).exec();
+ if (!user) throw new HTTPError("User not found", 404);
+
+ var testID = "829044530203328513"; //FOR TEST
+
+ var channels = await ChannelModel.find({
+ recipients: req.user_id,
+ type: 1
+ }).exec();
+
+ res.json(toObject(channels));
+});
+
+router.post("/", check(DmChannelCreateSchema), async (req, res) => {
+ const body = req.body as DmChannelCreateSchema;
+
+ const channel = {
+ ...body,
+ owner_id: req.user_id,
+ id: Snowflake.generate(),
+ type: ChannelType.DM,
+ created_at: new Date(),
+ };
+ await new ChannelModel(channel).save();
+
+ /*Event({ event: "CHANNEL_CREATE", data: channel } as ChannelCreateEvent);*/
+
+
+ res.json(channel);
+});
+
+export default router;
\ No newline at end of file
diff --git a/src/routes/users/@me/guilds.ts b/src/routes/users/@me/guilds.ts
index d0fbaa3e..5042c17c 100644
--- a/src/routes/users/@me/guilds.ts
+++ b/src/routes/users/@me/guilds.ts
@@ -1,5 +1,5 @@
import { Router, Request, Response } from "express";
-import { GuildModel, MemberModel, UserModel, GuildDeleteEvent, GuildMemberRemoveEvent, toObject } from "fosscord-server-util";
+import { GuildModel, MemberModel, UserModel, GuildDeleteEvent, GuildMemberRemoveEvent, toObject } from "@fosscord/server-util";
import { HTTPError } from "lambert-server";
import { emitEvent } from "../../../util/Event";
import { getPublicUser } from "../../../util/User";
diff --git a/src/routes/users/@me/index.ts b/src/routes/users/@me/index.ts
index 32877dcc..22d4cf3b 100644
--- a/src/routes/users/@me/index.ts
+++ b/src/routes/users/@me/index.ts
@@ -1,5 +1,5 @@
import { Router, Request, Response } from "express";
-import { UserModel } from "fosscord-server-util";
+import { UserModel } from "@fosscord/server-util";
import { HTTPError } from "lambert-server";
const router: Router = Router();
diff --git a/src/schema/Channel.ts b/src/schema/Channel.ts
index 0fafc54d..3a22872a 100644
--- a/src/schema/Channel.ts
+++ b/src/schema/Channel.ts
@@ -1,3 +1,4 @@
+import { ChannelType } from "@fosscord/server-util";
import { Length } from "../util/instanceOf";
export const ChannelModifySchema = {
@@ -20,6 +21,24 @@ export const ChannelModifySchema = {
$nsfw: Boolean,
};
+export const DmChannelCreateSchema = {
+ owner_id: String,
+ $id: String,
+ $created_at: Date,
+ name: String,
+ type: Number,
+ recipients: [String]
+}
+
+export interface DmChannelCreateSchema {
+ owner_id: String;
+ id?: String;
+ created_at?: Date;
+ name: String;
+ type: Number;
+ recipients: String[];
+}
+
export interface ChannelModifySchema {
name: string;
type: number;
diff --git a/src/schema/Guild.ts b/src/schema/Guild.ts
index 6527f35d..2b792db0 100644
--- a/src/schema/Guild.ts
+++ b/src/schema/Guild.ts
@@ -1,4 +1,4 @@
-import { ChannelSchema, GuildChannel } from "fosscord-server-util";
+import { ChannelSchema, GuildChannel } from "@fosscord/server-util";
import { Length } from "../util/instanceOf";
export const GuildCreateSchema = {
diff --git a/src/schema/Message.ts b/src/schema/Message.ts
index c0e2315a..9b62edcf 100644
--- a/src/schema/Message.ts
+++ b/src/schema/Message.ts
@@ -1,4 +1,4 @@
-import { Embed, EmbedImage } from "fosscord-server-util";
+import { Embed, EmbedImage } from "@fosscord/server-util";
import { Length } from "../util/instanceOf";
export const MessageCreateSchema = {
diff --git a/src/schema/User.ts b/src/schema/User.ts
new file mode 100644
index 00000000..2b74a433
--- /dev/null
+++ b/src/schema/User.ts
@@ -0,0 +1,43 @@
+export const UserUpdateSchema = {
+ id: String,
+ username: String,
+ discriminator: String,
+ avatar: String || null,
+ $phone: String,
+ desktop: Boolean,
+ mobile: Boolean,
+ premium: Boolean,
+ premium_type: Number,
+ bot: Boolean,
+ system: Boolean,
+ nsfw_allowed: Boolean,
+ mfa_enabled: Boolean,
+ created_at: Date,
+ verified: Boolean,
+ $email: String,
+ flags: BigInt,
+ public_flags: BigInt,
+ $guilds: [String],
+};
+
+export interface UserUpdateSchema {
+ id: string;
+ username: string;
+ discriminator: string;
+ avatar: string | null;
+ phone?: string;
+ desktop: boolean;
+ mobile: boolean;
+ premium: boolean;
+ premium_type: number;
+ bot: boolean;
+ system: boolean;
+ nsfw_allowed: boolean;
+ mfa_enabled: boolean;
+ created_at: Date;
+ verified: boolean;
+ email?: string;
+ flags: bigint;
+ public_flags: bigint;
+ guilds: string[];
+}
diff --git a/src/start.ts b/src/start.ts
new file mode 100644
index 00000000..11e15941
--- /dev/null
+++ b/src/start.ts
@@ -0,0 +1,33 @@
+process.on("uncaughtException", console.error);
+process.on("unhandledRejection", console.error);
+
+import "missing-native-js-functions";
+import { config } from "dotenv";
+config();
+import { FosscordServer } from "./Server";
+import cluster from "cluster";
+import os from "os";
+const cores = os.cpus().length;
+
+if (cluster.isMaster && process.env.production == "true") {
+ console.log(`Primary ${process.pid} is running`);
+
+ // Fork workers.
+ for (let i = 0; i < cores; i++) {
+ cluster.fork();
+ }
+
+ cluster.on("exit", (worker, code, signal) => {
+ console.log(`worker ${worker.process.pid} died, restart worker`);
+ cluster.fork();
+ });
+} else {
+ var port = Number(process.env.PORT);
+ if (isNaN(port)) port = 1000;
+
+ const server = new FosscordServer({ port });
+ server.start().catch(console.error);
+
+ // @ts-ignore
+ global.server = server;
+}
diff --git a/src/test/rethink_test.ts b/src/test/rethink_test.ts.disabled
index d1470515..d1470515 100644
--- a/src/test/rethink_test.ts
+++ b/src/test/rethink_test.ts.disabled
diff --git a/src/test/test.ts b/src/test/test.ts
index eb0cb8b3..b7d877b3 100644
--- a/src/test/test.ts
+++ b/src/test/test.ts
@@ -1,4 +1,4 @@
-import { getPermission } from "fosscord-server-util";
+import { getPermission } from "@fosscord/server-util";
async function main() {
const t = await getPermission("811642917432066048", "812327318532915201");
diff --git a/src/util/Captcha.ts b/src/util/Captcha.ts
index e69de29b..cb0ff5c3 100644
--- a/src/util/Captcha.ts
+++ b/src/util/Captcha.ts
@@ -0,0 +1 @@
+export {};
diff --git a/src/util/Config.ts b/src/util/Config.ts
index 60d83e1a..e500197f 100644
--- a/src/util/Config.ts
+++ b/src/util/Config.ts
@@ -1,4 +1,4 @@
-import { Config, Snowflake } from "fosscord-server-util";
+import { Config, Snowflake } from "@fosscord/server-util";
import crypto from "crypto";
import fs from "fs";
@@ -16,7 +16,7 @@ export default {
setAll: Config.setAll,
};
-export interface RateLimit {
+export interface RateLimitOptions {
count: number;
timespan: number;
}
@@ -62,8 +62,8 @@ export interface DefaultOptions {
};
routes: {
auth?: {
- login?: RateLimit;
- register?: RateLimit;
+ login?: RateLimitOptions;
+ register?: RateLimitOptions;
};
channel?: {};
// TODO: rate limit configuration for all routes
diff --git a/src/util/Event.ts b/src/util/Event.ts
index 8a24e4bb..5ff027e5 100644
--- a/src/util/Event.ts
+++ b/src/util/Event.ts
@@ -1,4 +1,4 @@
-import { Event, EventModel } from "fosscord-server-util";
+import { Event, EventModel } from "@fosscord/server-util";
export async function emitEvent(payload: Omit<Event, "created_at">) {
const obj = {
diff --git a/src/util/Member.ts b/src/util/Member.ts
index 4d1b8ac5..2be9686e 100644
--- a/src/util/Member.ts
+++ b/src/util/Member.ts
@@ -7,7 +7,7 @@ import {
GuildModel,
MemberModel,
UserModel,
-} from "fosscord-server-util";
+} from "@fosscord/server-util";
import { HTTPError } from "lambert-server";
import Config from "./Config";
import { emitEvent } from "./Event";
diff --git a/src/util/User.ts b/src/util/User.ts
index 05213642..0f3768cc 100644
--- a/src/util/User.ts
+++ b/src/util/User.ts
@@ -1,4 +1,4 @@
-import { toObject, UserModel } from "fosscord-server-util";
+import { toObject, UserModel } from "@fosscord/server-util";
import { HTTPError } from "lambert-server";
export const PublicUserProjection = {
diff --git a/src/util/instanceOf.ts b/src/util/instanceOf.ts
index b4a231ba..e4e58092 100644
--- a/src/util/instanceOf.ts
+++ b/src/util/instanceOf.ts
@@ -34,6 +34,9 @@ export function FieldErrors(fields: Record<string, { code?: string; message: str
);
}
+// TODO: implement Image data type: Data URI scheme that supports JPG, GIF, and PNG formats. An example Data URI format is: data:image/jpeg;base64,BASE64_ENCODED_JPEG_IMAGE_DATA
+// Ensure you use the proper content type (image/jpeg, image/png, image/gif) that matches the image data being provided.
+
export class FieldError extends Error {
constructor(public code: string | number, public message: string, public errors?: any) {
super(message);
|