summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Server.ts15
-rw-r--r--src/middlewares/GlobalRateLimit.ts2
-rw-r--r--src/middlewares/RateLimit.ts3
-rw-r--r--src/routes/api/v8/auth/login.ts12
-rw-r--r--src/routes/api/v8/auth/register.ts14
-rw-r--r--src/routes/api/v8/guilds/index.ts88
-rw-r--r--src/test/mongo_test.ts34
-rw-r--r--src/util/Event.ts24
8 files changed, 97 insertions, 95 deletions
diff --git a/src/Server.ts b/src/Server.ts

index b561f94e..fa4111db 100644 --- a/src/Server.ts +++ b/src/Server.ts
@@ -1,5 +1,6 @@ import "missing-native-js-functions"; import fs from "fs/promises"; +import { Connection } from "mongoose"; import { Server, ServerOptions } from "lambert-server"; import { Authentication, GlobalRateLimit } from "./middlewares/"; import Config from "./util/Config"; @@ -29,8 +30,20 @@ export class DiscordServer extends Server { super({ ...opts, errorHandler: false, jsonBody: false }); } + async setupSchema() { + await db.collection("users").createIndex({ id: 1 }, { unique: true }); + await db.collection("messages").createIndex({ id: 1 }, { unique: true }); + await db.collection("channels").createIndex({ id: 1 }, { unique: true }); + await db.collection("guilds").createIndex({ id: 1 }, { unique: true }); + await db.collection("members").createIndex({ id: 1 }, { unique: true }); + await db.collection("roles").createIndex({ id: 1 }, { unique: true }); + await db.collection("emojis").createIndex({ id: 1 }, { unique: true }); + } + async start() { - await db.init(); + // @ts-ignore + await (db as Promise<Connection>); + await this.setupSchema(); console.log("[DB] connected"); await Promise.all([Config.init()]); diff --git a/src/middlewares/GlobalRateLimit.ts b/src/middlewares/GlobalRateLimit.ts
index c729987a..33dc5e0f 100644 --- a/src/middlewares/GlobalRateLimit.ts +++ b/src/middlewares/GlobalRateLimit.ts
@@ -6,6 +6,8 @@ import { db } from "fosscord-server-util"; // TODO: increment count on serverside export async function GlobalRateLimit(req: Request, res: Response, next: NextFunction) { + return next(); + // TODO: use new db mongoose models if (!Config.get().limits.rate.ip.enabled) return next(); const ip = getIpAdress(req); diff --git a/src/middlewares/RateLimit.ts b/src/middlewares/RateLimit.ts
index c42d773c..b015c7e0 100644 --- a/src/middlewares/RateLimit.ts +++ b/src/middlewares/RateLimit.ts
@@ -5,6 +5,9 @@ import { getIpAdress } from "./GlobalRateLimit"; export function RateLimit({ count = 10, timespan = 1000 * 5, name = "/" }) { return async (req: Request, res: Response, next: NextFunction) => { + return next(); + // TODO: use new db mongoose models + let id = req.userid || getIpAdress(req); const limit: { count: number; start: number } = (await db.data.ratelimit.routes[name][id].get()) || { diff --git a/src/routes/api/v8/auth/login.ts b/src/routes/api/v8/auth/login.ts
index ac9775df..acdac1ce 100644 --- a/src/routes/api/v8/auth/login.ts +++ b/src/routes/api/v8/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 { db, User } from "fosscord-server-util"; +import { User, UserModel } from "fosscord-server-util"; import Config from "../../../../util/Config"; import { adjustEmail } from "./register"; @@ -23,10 +23,12 @@ router.post( const { login, password } = req.body; // * MongoDB Specific query for user with same email or phone number - const userquery = { $or: [{ email: adjustEmail(login) }, { phone: login }] }; - const user: User = await db.data - .users(userquery) - .get({ hash: true, id: true, user_settings: { locale: true, theme: true } }); + const user = await UserModel.findOne( + { + $or: [{ email: adjustEmail(login) }, { phone: login }], + }, + `hash id user_settings.locale user_settings.theme` + ).exec(); if (!user) { throw FieldErrors({ diff --git a/src/routes/api/v8/auth/register.ts b/src/routes/api/v8/auth/register.ts
index 1250b689..1205c462 100644 --- a/src/routes/api/v8/auth/register.ts +++ b/src/routes/api/v8/auth/register.ts
@@ -1,6 +1,6 @@ import { Request, Response, Router } from "express"; import Config from "../../../../util/Config"; -import { db, trimSpecial, User, Snowflake } 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"; @@ -80,7 +80,8 @@ router.post( adjusted_email = adjustEmail(email); // check if there is already an account with this email - const exists = await db.data.users({ email: adjusted_email }).get(); + const exists = await UserModel.findOne({ email: adjusted_email }).exec(); + if (exists) { throw FieldErrors({ email: { @@ -116,7 +117,8 @@ router.post( if (!register.allowMultipleAccounts) { // TODO: check if fingerprint was eligible generated - const exists = await db.data.users({ fingerprint }).get(); + const exists = await UserModel.findOne({ fingerprints: fingerprint }).exec(); + if (exists) { throw FieldErrors({ email: { @@ -150,7 +152,7 @@ router.post( // TODO: is there any better way to generate a random discriminator only once, without checking if it already exists in the mongodb database? for (let tries = 0; tries < 5; tries++) { discriminator = Math.randomIntBetween(1, 9999).toString().padStart(4, "0"); - exists = await db.data.users({ discriminator, username: adjusted_username }).get({ id: true }); + exists = await UserModel.findOne({ discriminator, username: adjusted_username }, "id").exec(); if (!exists) break; } @@ -164,6 +166,8 @@ router.post( } // constructing final user object + // TODO fix: + // @ts-ignore const user: User = { id: Snowflake.generate(), created_at: Date.now(), @@ -220,7 +224,7 @@ router.post( }; // insert user into database - await db.data.users.push(user); + await new UserModel(user).save({}); return res.json({ token: await generateToken(user.id) }); } diff --git a/src/routes/api/v8/guilds/index.ts b/src/routes/api/v8/guilds/index.ts
index 2d7e081a..46372a68 100644 --- a/src/routes/api/v8/guilds/index.ts +++ b/src/routes/api/v8/guilds/index.ts
@@ -1,19 +1,20 @@ import { Router, Request, Response } from "express"; -import { db, Guild, Snowflake } from "fosscord-server-util"; +import { GuildDeleteEvent, GuildModel, MemberModel, Snowflake } from "fosscord-server-util"; import { HTTPError } from "lambert-server"; import { check } from "./../../../../util/instanceOf"; -import { GuildCreateSchema, GuildGetSchema, GuildUpdateSchema } from "../../../../schema/Guild"; +import { GuildCreateSchema, GuildUpdateSchema } from "../../../../schema/Guild"; +import { emitEvent } from "../../../../util/Event"; const router: Router = Router(); router.get("/:id", async (req: Request, res: Response) => { - const member = await db.data.guilds({ id: req.params.id }).members({ id: req.userid }).get({ id: true }); + const guild = await GuildModel.findOne({ id: BigInt(req.params.id) }).exec(); + if (!guild) throw new HTTPError("Guild doesn't exist"); - if (!member) { - throw new HTTPError("you arent a member of the guild you are trying to access", 401); - } + const member = await MemberModel.findOne({ guild_id: req.params.id, id: req.userid }, "id").exec(); + + if (!member) throw new HTTPError("you arent a member of the guild you are trying to access", 401); - const guild = await db.data.guilds({ id: req.params.id }).get(GuildGetSchema); return res.json(guild); }); @@ -21,7 +22,7 @@ router.patch("/:id", check(GuildUpdateSchema), async (req: Request, res: Respons // TODO: check permission of member const body = req.body as GuildUpdateSchema; - const guild = await db.data.guilds({ id: req.params.id }).get({ id: true }); + const guild = await GuildModel.findOne({ id: BigInt(req.params.id) }).exec(); if (!guild) throw new HTTPError("This guild doesnt exist", 404); throw "not finished"; @@ -30,70 +31,40 @@ router.patch("/:id", check(GuildUpdateSchema), async (req: Request, res: Respons // // TODO: finish POST route router.post("/", check(GuildCreateSchema), async (req: Request, res: Response) => { const body = req.body as GuildCreateSchema; + // TODO: check if user is in more than 100 (config max guilds) const guildID = Snowflake.generate(); - const guild: Guild = { - // name: undefined, - // owner: undefined, - ...body, // ! contains name & icon values + const guild = { + name: body.name, + region: body.region || "en-US", owner_id: req.userid, + icon: undefined, afk_channel_id: undefined, afk_timeout: 300, application_id: undefined, banner: undefined, - channels: [], default_message_notifications: undefined, description: undefined, splash: undefined, discovery_splash: undefined, - emojis: [], explicit_content_filter: undefined, features: [], - // icon: undefined, id: guildID, - // joined_at: undefined, large: undefined, max_members: 250000, - max_presences: undefined, + max_presences: 250000, max_video_channel_users: 25, - member_count: 0, presence_count: 0, - members: [ - { - id: req.userid, - roles: [], // @everyone role is not explicitly set, the client and server automatically assumes it - joined_at: Date.now(), - nick: undefined, - premium_since: undefined, - deaf: false, - mute: false, - pending: false, - permissions: 8n, // value will be computed if a role is changed - }, - ], + member_count: 0, mfa_level: 0, preferred_locale: "en-US", premium_subscription_count: 0, premium_tier: 0, - presences: [], public_updates_channel_id: undefined, - region: undefined, - roles: [ - { - color: 0, - hoist: false, - name: "@everyone", - permissions: 0n, - id: guildID, - managed: true, // ? discord set this to true, - mentionable: false, - position: 0, - }, - ], rules_channel_id: undefined, system_channel_flags: undefined, system_channel_id: undefined, - unavailable: undefined, + unavailable: false, vanity_url_code: undefined, verification_level: undefined, voice_states: [], @@ -103,7 +74,9 @@ router.post("/", check(GuildCreateSchema), async (req: Request, res: Response) = }; try { - await db.data.guilds.push(guild); + await new GuildModel(guild).save(); + // TODO: insert default everyone role + // TODO: automatically add user to guild } catch (error) { throw new HTTPError("Couldnt create Guild", 500); } @@ -111,16 +84,29 @@ router.post("/", check(GuildCreateSchema), async (req: Request, res: Response) = }); router.delete("/:id", async (req: Request, res: Response) => { - const { id: guildID } = req.params; - - const guild = await db.data.guilds({ id: guildID }).get({ owner_id: true }); + try { + var guildID = BigInt(req.params.id); + } catch (error) { + throw new HTTPError("Invalid id format", 400); + } + const guild = await GuildModel.findOne({ id: BigInt(req.params.id) }, "owner_id").exec(); if (!guild) throw new HTTPError("This guild doesnt exist", 404); if (guild.owner_id !== req.userid) throw new HTTPError("You arent the owner of this guild", 401); - await db.data.guilds({ id: guildID }).delete(); + await emitEvent({ + event: "GUILD_DELETE", + data: { + id: guildID, + }, + guild_id: guildID, + } as GuildDeleteEvent); + + await GuildModel.deleteOne({ id: guildID }).exec(); return res.status(204); }); export default router; + +export async function addMember(guild: bigint, user: bigint) {} diff --git a/src/test/mongo_test.ts b/src/test/mongo_test.ts
index b2cc2bce..5c973429 100644 --- a/src/test/mongo_test.ts +++ b/src/test/mongo_test.ts
@@ -1,20 +1,28 @@ -import mongoose from "mongoose"; -import { Long } from "mongodb"; -import { Snowflake } from "fosscord-server-util"; +import mongoose, { Schema, Types } from "mongoose"; +import { Long as MongoTypeLong } from "mongodb"; +require("mongoose-long")(mongoose); + +const partSchema = new Schema({ + long: { + type: mongoose.Types.Long, + }, +}); + +const Part = mongoose.model("Part", partSchema, "test"); async function main() { - const conn = await mongoose.createConnection( - "mongodb://localhost:27017/lambert?readPreference=secondaryPreferred", - { - useNewUrlParser: true, - useUnifiedTopology: false, - } - ); + const conn = await mongoose.connect("mongodb://localhost:27017/lambert?readPreference=secondaryPreferred", { + useNewUrlParser: true, + useUnifiedTopology: false, + }); console.log("connected"); - const result = await conn.collection("users").insertOne({ test: Long.fromString(Snowflake.generate().toString()) }); - // .project(undefined) - console.log(result); + const part = new Part({ long: 390810485244821505n }); + + // await part.save(); + console.log("saved"); + const test = await Part.find({}); + console.log(test); } main(); diff --git a/src/util/Event.ts b/src/util/Event.ts
index 53c08e2b..c75c909f 100644 --- a/src/util/Event.ts +++ b/src/util/Event.ts
@@ -1,26 +1,10 @@ -import { db } from "fosscord-server-util"; +import { Event, EventModel } from "fosscord-server-util"; -export async function emitEvent({ - guild, - user, - channel, - event, - data, -}: { - guild?: bigint; - channel?: bigint; - user?: bigint; - event: string; - data: any; -}) { +export async function emitEvent(payload: Omit<Event, "created_at">) { const emitEvent = { created_at: Math.floor(Date.now() / 1000), // in seconds - guild_id: guild, - user_id: user, - channel_id: channel, - data, - event, + ...payload, }; - return await db.data.events.push(emitEvent); + return await new EventModel(emitEvent).save(); }