diff options
author | Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> | 2021-04-14 15:01:27 +0200 |
---|---|---|
committer | Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> | 2021-04-14 15:01:27 +0200 |
commit | 9c62b43664f9808497cdaf5142ef071c4e01275d (patch) | |
tree | a2a8b0b0b72d2182229e332b158fd9310a1cb809 /src/util | |
parent | :zap: export regex (diff) | |
parent | :bug: fix Activity model (diff) | |
download | server-9c62b43664f9808497cdaf5142ef071c4e01275d.tar.xz |
Merge branch 'main' of https://github.com/discord-open-source/discord-server-util into main
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/Database.ts | 87 | ||||
-rw-r--r-- | src/util/MongoBigInt.ts | 2 | ||||
-rw-r--r-- | src/util/Permissions.ts | 32 | ||||
-rw-r--r-- | src/util/Snowflake.ts | 2 | ||||
-rw-r--r-- | src/util/checkToken.ts | 2 | ||||
-rw-r--r-- | src/util/index.ts | 8 | ||||
-rw-r--r-- | src/util/toBigInt.ts | 3 |
7 files changed, 94 insertions, 42 deletions
diff --git a/src/util/Database.ts b/src/util/Database.ts index 2304378c..339ac65b 100644 --- a/src/util/Database.ts +++ b/src/util/Database.ts @@ -1,13 +1,31 @@ import "./MongoBigInt"; -import mongoose, { Collection, Connection } from "mongoose"; +import mongoose, { Collection, Connection, LeanDocument } from "mongoose"; import { ChangeStream, ChangeEvent, Long } from "mongodb"; import EventEmitter from "events"; +import { Document } from "mongoose"; const uri = process.env.MONGO_URL || "mongodb://localhost:27017/fosscord?readPreference=secondaryPreferred"; -const connection = mongoose.createConnection(uri, { autoIndex: true }); +console.log(`[DB] connect: ${uri}`); + +const connection = mongoose.createConnection(uri, { + autoIndex: true, + useNewUrlParser: true, + useUnifiedTopology: true, + useFindAndModify: false, +}); export default <Connection>connection; +function transform<T>(document: T) { + // @ts-ignore + return document.toObject({ virtuals: true }); +} + +export function toObject<T>(document: T): LeanDocument<T> { + // @ts-ignore + return Array.isArray(document) ? document.map((x) => transform<T>(x)) : transform(document); +} + export interface MongooseCache { on(event: "delete", listener: (id: string) => void): this; on(event: "change", listener: (data: any) => void): this; @@ -29,7 +47,8 @@ export class MongooseCache extends EventEmitter { super(); } - async init() { + init = async () => { + // @ts-ignore this.stream = this.collection.watch(this.pipeline, { fullDocument: "updateLookup" }); this.stream.on("change", this.change); @@ -40,9 +59,15 @@ export class MongooseCache extends EventEmitter { const arr = await this.collection.aggregate(this.pipeline).toArray(); this.data = arr.length ? arr[0] : arr; } - } + }; - convertResult(obj: any) { + changeStream = (pipeline: any) => { + this.pipeline = pipeline; + this.destroy(); + this.init(); + }; + + convertResult = (obj: any) => { if (obj instanceof Long) return BigInt(obj.toString()); if (typeof obj === "object") { Object.keys(obj).forEach((key) => { @@ -51,40 +76,44 @@ export class MongooseCache extends EventEmitter { } return obj; - } + }; change = (doc: ChangeEvent) => { - // @ts-ignore - if (doc.fullDocument) { + try { // @ts-ignore - if (!this.opts.onlyEvents) this.data = doc.fullDocument; - } + if (doc.fullDocument) { + // @ts-ignore + if (!this.opts.onlyEvents) this.data = doc.fullDocument; + } - switch (doc.operationType) { - case "dropDatabase": - return this.destroy(); - case "drop": - return this.destroy(); - case "delete": - return this.emit("delete", doc.documentKey._id.toHexString()); - case "insert": - return this.emit("insert", doc.fullDocument); - case "update": - case "replace": - return this.emit("change", doc.fullDocument); - case "invalidate": - return this.destroy(); - default: - return; + switch (doc.operationType) { + case "dropDatabase": + return this.destroy(); + case "drop": + return this.destroy(); + case "delete": + return this.emit("delete", doc.documentKey._id.toHexString()); + case "insert": + return this.emit("insert", doc.fullDocument); + case "update": + case "replace": + return this.emit("change", doc.fullDocument); + case "invalidate": + return this.destroy(); + default: + return; + } + } catch (error) { + this.emit("error", error); } }; - destroy() { - this.stream.off("change", this.change); + destroy = () => { + this.stream?.off("change", this.change); this.emit("close"); if (this.stream.isClosed()) return; return this.stream.close(); - } + }; } diff --git a/src/util/MongoBigInt.ts b/src/util/MongoBigInt.ts index c4e5f623..fc451925 100644 --- a/src/util/MongoBigInt.ts +++ b/src/util/MongoBigInt.ts @@ -44,7 +44,7 @@ class LongSchema extends mongoose.SchemaType { if (val instanceof Number || "number" == typeof val) return BigInt(val); if (!Array.isArray(val) && val.toString) return BigInt(val.toString()); - // @ts-ignore + //@ts-ignore throw new SchemaType.CastError("Long", val); } diff --git a/src/util/Permissions.ts b/src/util/Permissions.ts index ae21e138..c7a41594 100644 --- a/src/util/Permissions.ts +++ b/src/util/Permissions.ts @@ -97,6 +97,16 @@ export class Permissions extends BitField { return (checkAdmin && super.has(Permissions.FLAGS.ADMINISTRATOR)) || super.has(permission); } + /** + * Checks whether the bitfield has a permission, or multiple permissions, but throws an Error if user fails to match auth criteria. + */ + hasThrow(permission: PermissionResolvable, checkAdmin = true) { + if ((checkAdmin && super.has(Permissions.FLAGS.ADMINISTRATOR)) || super.has(permission)) { + return true; + } + throw new Error(`User doesn't fulfill the following permission criteria: ${permission}`); + } + static channelPermission(overwrites: ChannelPermissionOverwrite[], init?: bigint) { // TODO: do not deny any permissions if admin return overwrites.reduce((permission, overwrite) => { @@ -121,7 +131,7 @@ export class Permissions extends BitField { guild, channel, }: { - user: { id: bigint; roles: bigint[] }; + user: { id: string; roles: string[] }; guild: { roles: Role[] }; channel?: { overwrites?: ChannelPermissionOverwrite[]; @@ -144,22 +154,24 @@ export class Permissions extends BitField { } export async function getPermission( - user_id: bigint, - guild_id: bigint, - channel_id?: bigint, - cache?: { channel?: ChannelDocument | null; member?: MemberDocument | null } + user_id: string, + guild_id: string, + channel_id?: string, + cache?: { channel?: ChannelDocument | null; member?: MemberDocument | null; guild?: GuildDocument | null } ) { - var { channel, member } = cache || {}; + var { channel, member, guild } = cache || {}; - const guild = await GuildModel.findOne({ id: guild_id }, { owner_id: true }).exec(); + if (!guild) guild = await GuildModel.findOne({ id: guild_id }, { owner_id: true }).exec(); if (!guild) throw new Error("Guild not found"); if (guild.owner_id === user_id) return new Permissions(Permissions.FLAGS.ADMINISTRATOR); - member = await MemberModel.findOne({ guild_id, id: user_id }, "roles").exec(); + if (!member) member = await MemberModel.findOne({ guild_id, id: user_id }, "roles").exec(); if (!member) throw new Error("Member not found"); - var roles = await RoleModel.find({ guild_id, id: { $in: member.roles } }).exec(); - if (channel_id) { + var roles = await RoleModel.find({ guild_id, id: { $in: member.roles } }) + .lean() + .exec(); + if (channel_id && !channel) { channel = await ChannelModel.findOne({ id: channel_id }, "permission_overwrites").exec(); } diff --git a/src/util/Snowflake.ts b/src/util/Snowflake.ts index 9e94bbd9..1ccae43c 100644 --- a/src/util/Snowflake.ts +++ b/src/util/Snowflake.ts @@ -87,7 +87,7 @@ export class Snowflake { var worker = Snowflake.workerId << 17n; var process = Snowflake.processId << 12n; var increment = Snowflake.INCREMENT++; - return time | worker | process | increment; + return (time | worker | process | increment).toString(); } /** diff --git a/src/util/checkToken.ts b/src/util/checkToken.ts index b4635126..d5a128b4 100644 --- a/src/util/checkToken.ts +++ b/src/util/checkToken.ts @@ -4,7 +4,7 @@ import Config from "./Config"; export function checkToken(token: string): Promise<any> { return new Promise((res, rej) => { - jwt.verify(token, Config.getAll().api.security.jwtSecret, JWTOptions, (err, decoded: any) => { + jwt.verify(token, Config.getAll()?.api?.security?.jwtSecret, JWTOptions, (err, decoded: any) => { if (err || !decoded) return rej("Invalid Token"); return res(decoded); diff --git a/src/util/index.ts b/src/util/index.ts new file mode 100644 index 00000000..7e8bca20 --- /dev/null +++ b/src/util/index.ts @@ -0,0 +1,8 @@ +export * from "./String"; +export * from "./BitField"; +export * from "./Intents"; +export * from "./MessageFlags"; +export * from "./Permissions"; +export * from "./Snowflake"; +export * from "./UserFlags"; +export * from "./toBigInt" \ No newline at end of file diff --git a/src/util/toBigInt.ts b/src/util/toBigInt.ts new file mode 100644 index 00000000..d57c4568 --- /dev/null +++ b/src/util/toBigInt.ts @@ -0,0 +1,3 @@ +export default function toBigInt(string: String): BigInt { + return BigInt(string); +} |