From d5eb391ec62b2add8da179d5829430a5933163b1 Mon Sep 17 00:00:00 2001 From: Sterben Date: Sun, 14 Feb 2021 19:10:25 -0500 Subject: [PATCH 1/8] Add new file --- src/models/proclamation | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/models/proclamation diff --git a/src/models/proclamation b/src/models/proclamation new file mode 100644 index 0000000..fa0b9fb --- /dev/null +++ b/src/models/proclamation @@ -0,0 +1,29 @@ +import { Document, model, Schema } from 'mongoose'; + +export interface ProclamationInterface extends Document { + issuedBy: string; + subject: string; + body: string; + at: Date; + oID: string; + voteResults: { + yea: number; + nay: number; + }; + acceptedAt: number; +} + +const Proclamation = new Schema({ + issuedBy: { type: String, required: true }, + subject: { type: String, required: true }, + body: { type: String, required: true }, + at: { type: Date, required: true }, + oID: { type: String, required: true, unique: true }, + voteResults: { + yea: Number, + Nay: Number, + }, + acceptedAt: Number, +}); + +export default model('Proclamations', Proclamation); From 0ae20add1b3e78ca1c90b1b0f0e69cad7fd29d41 Mon Sep 17 00:00:00 2001 From: Sterben Date: Sun, 14 Feb 2021 19:10:46 -0500 Subject: [PATCH 2/8] Update proclamation --- src/models/proclamation | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/proclamation b/src/models/proclamation index fa0b9fb..df3cc6b 100644 --- a/src/models/proclamation +++ b/src/models/proclamation @@ -21,7 +21,7 @@ const Proclamation = new Schema({ oID: { type: String, required: true, unique: true }, voteResults: { yea: Number, - Nay: Number, + nay: Number, }, acceptedAt: Number, }); From 9bc5c90cdeafd1dd7da71d56a4740b12bec00a18 Mon Sep 17 00:00:00 2001 From: Sterben Date: Sun, 14 Feb 2021 19:10:56 -0500 Subject: [PATCH 3/8] Update proclamation --- src/models/{proclamation => proclamation.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/models/{proclamation => proclamation.ts} (100%) diff --git a/src/models/proclamation b/src/models/proclamation.ts similarity index 100% rename from src/models/proclamation rename to src/models/proclamation.ts From 32b5a462e2140acd6d0e2a48f4bd0ed5e7283697 Mon Sep 17 00:00:00 2001 From: Sterben Date: Sun, 14 Feb 2021 19:11:19 -0500 Subject: [PATCH 4/8] Update proclamation.ts --- src/models/{proclamation.ts => Proclamation.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/models/{proclamation.ts => Proclamation.ts} (100%) diff --git a/src/models/proclamation.ts b/src/models/Proclamation.ts similarity index 100% rename from src/models/proclamation.ts rename to src/models/Proclamation.ts From 7fe1516ef8e008c3b97f0c6d16c53e10250636da Mon Sep 17 00:00:00 2001 From: Sterben Date: Sun, 14 Feb 2021 19:12:09 -0500 Subject: [PATCH 5/8] Update index.ts --- src/models/index.ts | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/models/index.ts b/src/models/index.ts index 568c71f..0626279 100644 --- a/src/models/index.ts +++ b/src/models/index.ts @@ -1,19 +1,20 @@ -export { default as Customer, CustomerInterface } from './Customer'; -export { default as CustomerPortal, CustomerPortalInterface } from './CustomerPortal'; -export { default as ExecutiveOrder, ExecutiveOrderInterface } from './ExecutiveOrder'; -export { default as File, FileInterface } from './File'; -export { default as Member, MemberInterface } from './Member'; -export { default as Merchant, MerchantInterface } from './Merchant'; -export { default as Moderation, ModerationInterface } from './Moderation'; -export { default as Motion, MotionInterface } from './Motion'; -export { default as NNTrainingData, NNTrainingDataInterface } from './NNTrainingData'; -export { default as Note, NoteInterface } from './Note'; -export { default as PagerNumber, PagerNumberInterface, PagerNumberRaw } from './PagerNumber'; -export { default as Promo, PromoInterface } from './Promo'; -export { default as Rank, RankInterface } from './Rank'; -export { default as Redirect, RedirectInterface, RedirectRaw } from './Redirect'; -export { default as Resolution, ResolutionInterface } from './Resolution'; -export { default as Score, ScoreInterface, ScoreInterfaceRaw } from './Score'; -export { default as ScoreHistorical, ScoreHistoricalInterface } from './ScoreHistorical'; -export { default as Staff, StaffInterface } from './Staff'; -export { default as Stat, StatInterface } from './Stat'; +export { default as Customer, CustomerInterface } from './Customer'; +export { default as CustomerPortal, CustomerPortalInterface } from './CustomerPortal'; +export { default as ExecutiveOrder, ExecutiveOrderInterface } from './ExecutiveOrder'; +export { default as File, FileInterface } from './File'; +export { default as Member, MemberInterface } from './Member'; +export { default as Merchant, MerchantInterface } from './Merchant'; +export { default as Moderation, ModerationInterface } from './Moderation'; +export { default as Motion, MotionInterface } from './Motion'; +export { default as NNTrainingData, NNTrainingDataInterface } from './NNTrainingData'; +export { default as Note, NoteInterface } from './Note'; +export { default as PagerNumber, PagerNumberInterface, PagerNumberRaw } from './PagerNumber'; +export { default as Proclamation, ProclamationInterface } from './Proclamation' +export { default as Promo, PromoInterface } from './Promo'; +export { default as Rank, RankInterface } from './Rank'; +export { default as Redirect, RedirectInterface, RedirectRaw } from './Redirect'; +export { default as Resolution, ResolutionInterface } from './Resolution'; +export { default as Score, ScoreInterface, ScoreInterfaceRaw } from './Score'; +export { default as ScoreHistorical, ScoreHistoricalInterface } from './ScoreHistorical'; +export { default as Staff, StaffInterface } from './Staff'; +export { default as Stat, StatInterface } from './Stat'; From 6a3bf66f2851bca33705f82f3664e060f7a293e2 Mon Sep 17 00:00:00 2001 From: Sterben Date: Sun, 14 Feb 2021 19:13:35 -0500 Subject: [PATCH 6/8] procs --- src/class/Client.ts | 295 ++++++++++++++++++++++---------------------- 1 file changed, 148 insertions(+), 147 deletions(-) diff --git a/src/class/Client.ts b/src/class/Client.ts index 18c70de..48a5562 100644 --- a/src/class/Client.ts +++ b/src/class/Client.ts @@ -1,147 +1,148 @@ -import Stripe from 'stripe'; -import eris from 'eris'; -import pluris from 'pluris'; -import mongoose from 'mongoose'; -import { promises as fs } from 'fs'; -import { Collection, Command, LocalStorage, Queue, Util, ServerManagement, Event } from '.'; -import { - Customer, CustomerInterface, - CustomerPortal, CustomerPortalInterface, - ExecutiveOrder, ExecutiveOrderInterface, - File, FileInterface, - Member, MemberInterface, - Merchant, MerchantInterface, - Moderation, ModerationInterface, - Motion, MotionInterface, - NNTrainingData, NNTrainingDataInterface, - Note, NoteInterface, - PagerNumber, PagerNumberInterface, - Promo, PromoInterface, - Rank, RankInterface, - Redirect, RedirectInterface, - Resolution, ResolutionInterface, - Score, ScoreInterface, - ScoreHistorical, ScoreHistoricalInterface, - Staff, StaffInterface, - Stat, StatInterface, -} from '../models'; -import { Config } from '../../types'; // eslint-disable-line - -pluris(eris); - -export default class Client extends eris.Client { - public config: Config; - - public commands: Collection; - - public events: Collection; - - public intervals: Collection; - - public util: Util; - - public serverManagement: ServerManagement; - - public queue: Queue; - - public stripe: Stripe; - - public db: { - Customer: mongoose.Model, - CustomerPortal: mongoose.Model, - ExecutiveOrder: mongoose.Model, - File: mongoose.Model, - Member: mongoose.Model, - Merchant: mongoose.Model, - Moderation: mongoose.Model, - Motion: mongoose.Model, - NNTrainingData: mongoose.Model, - Note: mongoose.Model, - PagerNumber: mongoose.Model, - Promo: mongoose.Model, - Rank: mongoose.Model, - Redirect: mongoose.Model, - Resolution: mongoose.Model, - Score: mongoose.Model, - ScoreHistorical: mongoose.Model, - Staff: mongoose.Model, - Stat: mongoose.Model, - local: { muted: LocalStorage } - }; - - constructor(token: string, options?: eris.ClientOptions) { - super(token, options); - this.commands = new Collection(); - this.events = new Collection(); - this.intervals = new Collection(); - this.queue = new Queue(this); - this.db = { Customer, CustomerPortal, ExecutiveOrder, File, Member, Merchant, Moderation, Motion, NNTrainingData, Note, PagerNumber, Promo, Rank, Redirect, Resolution, Score, ScoreHistorical, Staff, Stat, local: { muted: new LocalStorage('muted') } }; - } - - public async loadDatabase() { - await mongoose.connect(this.config.mongoDB, { useNewUrlParser: true, useUnifiedTopology: true, poolSize: 50 }); - - const statMessages = await this.db.Stat.findOne({ name: 'messages' }); - const statCommands = await this.db.Stat.findOne({ name: 'commands' }); - const statPages = await this.db.Stat.findOne({ name: 'pages' }); - const statRequests = await this.db.Stat.findOne({ name: 'requests' }); - - if (!statMessages) { - await (new this.db.Stat({ name: 'messages', value: 0 }).save()); - } - if (!statCommands) { - await (new this.db.Stat({ name: 'commands', value: 0 }).save()); - } - if (!statPages) { - await (new this.db.Stat({ name: 'pages', value: 0 }).save()); - } - if (!statRequests) { - await (new this.db.Stat({ name: 'requests', value: 0 }).save()); - } - } - - public loadPlugins() { - this.util = new Util(this); - this.serverManagement = new ServerManagement(this); - this.stripe = new Stripe(this.config.stripeKey, { apiVersion: null, typescript: true }); - } - - public async loadIntervals() { - const intervalFiles = await fs.readdir(`${__dirname}/../intervals`); - intervalFiles.forEach((file) => { - const intervalName = file.split('.')[0]; - if (file === 'index.js') return; - const interval: NodeJS.Timeout = (require(`${__dirname}/../intervals/${file}`).default)(this); - this.intervals.add(intervalName, interval); - this.util.signale.success(`Successfully loaded interval: ${intervalName}`); - }); - } - - public async loadEvents(eventFiles: { [s: string]: typeof Event; } | ArrayLike) { - const evtFiles = Object.entries(eventFiles); - for (const [name, Ev] of evtFiles) { - const event = new Ev(this); - this.events.add(event.event, event); - this.on(event.event, event.run); - this.util.signale.success(`Successfully loaded event: ${name}`); - delete require.cache[require.resolve(`${__dirname}/../events/${name}`)]; - } - } - - public async loadCommands(commandFiles: { [s: string]: typeof Command; } | ArrayLike) { - const cmdFiles = Object.values(commandFiles); - for (const Cmd of cmdFiles) { - const command = new Cmd(this); - if (command.subcmds.length) { - command.subcmds.forEach((C) => { - const cmd: Command = new C(this); - command.subcommands.add(cmd.name, cmd); - this.util.signale.success(`Successfully loaded subcommand ${cmd.name} under ${command.name}`); - }); - } - delete command.subcmds; - this.commands.add(command.name, command); - this.util.signale.success(`Successfully loaded command: ${command.name}`); - } - } -} +import Stripe from 'stripe'; +import eris from 'eris'; +import pluris from 'pluris'; +import mongoose from 'mongoose'; +import { promises as fs } from 'fs'; +import { Collection, Command, LocalStorage, Queue, Util, ServerManagement, Event } from '.'; +import { + Customer, CustomerInterface, + CustomerPortal, CustomerPortalInterface, + ExecutiveOrder, ExecutiveOrderInterface, + File, FileInterface, + Member, MemberInterface, + Merchant, MerchantInterface, + Moderation, ModerationInterface, + Motion, MotionInterface, + NNTrainingData, NNTrainingDataInterface, + Note, NoteInterface, + PagerNumber, PagerNumberInterface, + Proclamation, ProclamationInterface, + Promo, PromoInterface, + Rank, RankInterface, + Redirect, RedirectInterface, + Resolution, ResolutionInterface, + Score, ScoreInterface, + ScoreHistorical, ScoreHistoricalInterface, + Staff, StaffInterface, + Stat, StatInterface, +} from '../models'; +import { Config } from '../../types'; // eslint-disable-line + +pluris(eris); + +export default class Client extends eris.Client { + public config: Config; + + public commands: Collection; + + public events: Collection; + + public intervals: Collection; + + public util: Util; + + public serverManagement: ServerManagement; + + public queue: Queue; + + public stripe: Stripe; + + public db: { + Customer: mongoose.Model, + CustomerPortal: mongoose.Model, + ExecutiveOrder: mongoose.Model, + File: mongoose.Model, + Member: mongoose.Model, + Merchant: mongoose.Model, + Moderation: mongoose.Model, + Motion: mongoose.Model, + NNTrainingData: mongoose.Model, + Note: mongoose.Model, + PagerNumber: mongoose.Model, + Promo: mongoose.Model, + Rank: mongoose.Model, + Redirect: mongoose.Model, + Resolution: mongoose.Model, + Score: mongoose.Model, + ScoreHistorical: mongoose.Model, + Staff: mongoose.Model, + Stat: mongoose.Model, + local: { muted: LocalStorage } + }; + + constructor(token: string, options?: eris.ClientOptions) { + super(token, options); + this.commands = new Collection(); + this.events = new Collection(); + this.intervals = new Collection(); + this.queue = new Queue(this); + this.db = { Customer, CustomerPortal, ExecutiveOrder, File, Member, Merchant, Moderation, Motion, NNTrainingData, Note, PagerNumber, Promo, Rank, Redirect, Resolution, Score, ScoreHistorical, Staff, Stat, local: { muted: new LocalStorage('muted') } }; + } + + public async loadDatabase() { + await mongoose.connect(this.config.mongoDB, { useNewUrlParser: true, useUnifiedTopology: true, poolSize: 50 }); + + const statMessages = await this.db.Stat.findOne({ name: 'messages' }); + const statCommands = await this.db.Stat.findOne({ name: 'commands' }); + const statPages = await this.db.Stat.findOne({ name: 'pages' }); + const statRequests = await this.db.Stat.findOne({ name: 'requests' }); + + if (!statMessages) { + await (new this.db.Stat({ name: 'messages', value: 0 }).save()); + } + if (!statCommands) { + await (new this.db.Stat({ name: 'commands', value: 0 }).save()); + } + if (!statPages) { + await (new this.db.Stat({ name: 'pages', value: 0 }).save()); + } + if (!statRequests) { + await (new this.db.Stat({ name: 'requests', value: 0 }).save()); + } + } + + public loadPlugins() { + this.util = new Util(this); + this.serverManagement = new ServerManagement(this); + this.stripe = new Stripe(this.config.stripeKey, { apiVersion: null, typescript: true }); + } + + public async loadIntervals() { + const intervalFiles = await fs.readdir(`${__dirname}/../intervals`); + intervalFiles.forEach((file) => { + const intervalName = file.split('.')[0]; + if (file === 'index.js') return; + const interval: NodeJS.Timeout = (require(`${__dirname}/../intervals/${file}`).default)(this); + this.intervals.add(intervalName, interval); + this.util.signale.success(`Successfully loaded interval: ${intervalName}`); + }); + } + + public async loadEvents(eventFiles: { [s: string]: typeof Event; } | ArrayLike) { + const evtFiles = Object.entries(eventFiles); + for (const [name, Ev] of evtFiles) { + const event = new Ev(this); + this.events.add(event.event, event); + this.on(event.event, event.run); + this.util.signale.success(`Successfully loaded event: ${name}`); + delete require.cache[require.resolve(`${__dirname}/../events/${name}`)]; + } + } + + public async loadCommands(commandFiles: { [s: string]: typeof Command; } | ArrayLike) { + const cmdFiles = Object.values(commandFiles); + for (const Cmd of cmdFiles) { + const command = new Cmd(this); + if (command.subcmds.length) { + command.subcmds.forEach((C) => { + const cmd: Command = new C(this); + command.subcommands.add(cmd.name, cmd); + this.util.signale.success(`Successfully loaded subcommand ${cmd.name} under ${command.name}`); + }); + } + delete command.subcmds; + this.commands.add(command.name, command); + this.util.signale.success(`Successfully loaded command: ${command.name}`); + } + } +} From 5127e93795d1b7985d39d36f00b8c1c2ff97bf6e Mon Sep 17 00:00:00 2001 From: Sterben Date: Sat, 20 Feb 2021 01:23:10 -0500 Subject: [PATCH 7/8] added get proclamations endpoint --- src/api/board.ins/routes/root.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/api/board.ins/routes/root.ts b/src/api/board.ins/routes/root.ts index 93b1cbe..67a4241 100644 --- a/src/api/board.ins/routes/root.ts +++ b/src/api/board.ins/routes/root.ts @@ -155,6 +155,14 @@ export default class Root extends Route { }); }); + this.router.get('/proclamations', async (_req, res) => { + const proclamations = await this.server.client.db.Proclamation.find().lean(); + + res.status(200).send({ + proclamations, + }); + }); + this.router.get('/executive-orders', async (_req, res) => { const executiveOrders = await this.server.client.db.ExecutiveOrder.find().lean(); From a116404ef592664c340fe5fb1455f7fadb8309d6 Mon Sep 17 00:00:00 2001 From: Sterben Date: Sun, 28 Feb 2021 00:06:13 -0600 Subject: [PATCH 8/8] all endpoints updated & added --- .eslintrc.json | 3 +- src/api/board.ins/routes/root.ts | 574 +++++++++++++++++++++++++++++-- src/class/Client.ts | 3 +- 3 files changed, 556 insertions(+), 24 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 8e5b667..7cfeb4b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -39,7 +39,8 @@ "no-param-reassign": "off", "no-underscore-dangle": "off", "keyword-spacing": "off", - "no-multiple-empty-lines": "off" + "no-multiple-empty-lines": "off", + "consistent-return": "off" }, "ignorePatterns": "**/*.js" } diff --git a/src/api/board.ins/routes/root.ts b/src/api/board.ins/routes/root.ts index 67a4241..2594fe0 100644 --- a/src/api/board.ins/routes/root.ts +++ b/src/api/board.ins/routes/root.ts @@ -1,5 +1,6 @@ import { TextChannel } from 'eris'; import { v4 as genUUID } from 'uuid'; +import { Request, Response } from 'express'; import { RichEmbed, Route, Server } from '../../../class'; export default class Root extends Route { @@ -11,7 +12,7 @@ export default class Root extends Route { } public bind() { - this.router.post('/executive-orders', async (req, res) => { + this.router.post('/eo', async (req: Request, res: Response) => { if (!req.body.pin) { return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, @@ -66,13 +67,13 @@ export default class Root extends Route { const channel = this.server.client.getChannel('807444198969835550'); await channel.createMessage({ embed }); - return res.status(200).json({ + res.status(200).json({ code: this.constants.codes.SUCCESS, message: `Created new Executive Order with ID ${executiveOrder.oID} by ${staffDiscord.username}#${staffDiscord.discriminator}, ${staffInformation.pn.join(', ')}.`, }); }); - this.router.post('/motions', async (req, res) => { + this.router.post('/motion', async (req: Request, res: Response) => { if (!req.body.pin) { return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, @@ -133,29 +134,560 @@ export default class Root extends Route { processed: false, }); - return res.status(200).json({ + res.status(200).json({ code: this.constants.codes.SUCCESS, message: `Created new Motion with ID ${motion.oID} by ${staffDiscord.username}#${staffDiscord.discriminator}, ${staffInformation.pn.join(', ')}.`, }); }); - this.router.get('/motions', async (_req, res) => { + this.router.post('/proc', async (req: Request, res: Response) => { + if (!req.body.pin) { + return res.status(401).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + const director = await this.server.client.db.Score.findOne({ pin: req.body.pin }); + const staffGuild = this.server.client.guilds.get('446067825673633794') || await this.server.client.getRESTGuild('446067825673633794'); + + if (!director || !staffGuild.members.get(director.userID)?.roles?.includes('662163685439045632')) { + return res.status(401).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + if (!req.body.subject) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + + if (!req.body.body) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + + const proclamationID = genUUID(); + + const staffDiscord = this.server.client.users.get(director.userID) || await this.server.client.getRESTUser(director.userID); + const staffInformation = await this.server.client.db.Staff.findOne({ userID: director.userID }); + + const embed = new RichEmbed(); + embed.setTitle('Proclamation'); + embed.setAuthor(`${staffDiscord.username}#${staffDiscord.discriminator}, ${staffInformation.pn.join(', ')}`, staffDiscord.avatarURL); + embed.setColor('#66e1ff'); + embed.addField('Subject', req.body.subject); + embed.addField('Body', req.body.body); + embed.addField('ID', proclamationID); + embed.setTimestamp(new Date()); + + const channel = this.server.client.getChannel('807444198969835550'); + const motionMessage = await channel.createMessage({ embed }); + await motionMessage.addReaction(this.server.client.util.emojis.SUCCESS); + await motionMessage.addReaction(this.server.client.util.emojis.ERROR); + + const motion = await this.server.client.db.Proclamation.create({ + issuedBy: director.userID, + subject: req.body.subject, + body: req.body.body, + at: new Date(), + oID: proclamationID, + processed: false, + }); + + res.status(200).json({ + code: this.constants.codes.SUCCESS, + message: `Created new Proclamation with ID ${motion.oID} by ${staffDiscord.username}#${staffDiscord.discriminator}, ${staffInformation.pn.join(', ')}.`, + }); + }); + + this.router.post('/resolution', async (req, res) => { + if (!req.body.pin) { + return res.status(401).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + const director = await this.server.client.db.Score.findOne({ pin: req.body.pin }); + const staffGuild = this.server.client.guilds.get('446067825673633794') || await this.server.client.getRESTGuild('446067825673633794'); + + if (!director || !staffGuild.members.get(director.userID)?.roles?.includes('662163685439045632')) { + return res.status(403).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + if (!req.body.subject || !req.body.body) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + + const resolutionID = genUUID(); + + const staffDiscord = this.server.client.users.get(director.userID) || await this.server.client.getRESTUser(director.userID); + const staffInformation = await this.server.client.db.Staff.findOne({ userID: director.userID }); + + const embed = new RichEmbed(); + embed.setTitle('Resolution'); + embed.setAuthor(`${staffDiscord.username}#${staffDiscord.discriminator}, ${staffInformation.pn.join(', ')}`, staffDiscord.avatarURL); + embed.setColor('#29be74'); + embed.addField('Subject', req.body.subject); + embed.addField('Body', req.body.body); + embed.setDescription(resolutionID); + embed.setTimestamp(new Date()); + + const resolution = await this.server.client.db.Resolution.create({ + issuedBy: director.userID, + subject: req.body.subject, + body: req.body.body, + at: new Date(), + oID: resolutionID, + processed: false, + }); + + res.status(200).json({ + code: this.constants.codes.SUCCESS, + message: `Created new Resolution with ID ${resolution.oID} by ${staffDiscord.username}#${staffDiscord.discriminator}, ${staffInformation.pn.join(', ')}.`, + }); + }); + + this.router.delete('/eo/:id', async (req, res) => { + if (!req.body.pin) { + return res.status(401).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + const director = await this.server.client.db.Score.findOne({ pin: req.body.pin }); + const staffGuild = this.server.client.guilds.get('446067825673633794') || await this.server.client.getRESTGuild('446067825673633794'); + + if (!director || !staffGuild.members.get(director.userID)?.roles?.includes('662163685439045632')) { + return res.status(403).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + if (!req.params.id) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + + if (!(await this.server.client.db.ExecutiveOrder.exists({ oID: req.params.id }))) { + return res.status(404).json({ + code: this.constants.codes.NOT_FOUND, + message: this.constants.messages.NOT_FOUND, + }); + } + + await this.server.client.db.ExecutiveOrder.deleteOne({ oID: req.params.id }); + + res.status(200).json({ message: `Executive Order with ID ${req.params.id} deleted.` }); + }); + + this.router.delete('/motion/:id', async (req, res) => { + if (!req.body.pin) { + return res.status(401).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + const director = await this.server.client.db.Score.findOne({ pin: req.body.pin }); + const staffGuild = this.server.client.guilds.get('446067825673633794') || await this.server.client.getRESTGuild('446067825673633794'); + + if (!director || !staffGuild.members.get(director.userID)?.roles?.includes('662163685439045632')) { + return res.status(403).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + if (!req.params.id) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + if (!(await this.server.client.db.Resolution.exists({ oID: req.params.id }))) { + return res.status(404).json({ + code: this.constants.codes.NOT_FOUND, + message: this.constants.messages.NOT_FOUND, + }); + } + + await this.server.client.db.Motion.deleteOne({ oID: req.params.id }); + + res.status(200).json({ message: `Motion with ID ${req.params.id} deleted.` }); + }); + + this.router.delete('/resolution/:id', async (req, res) => { + if (!req.body.pin) { + return res.status(401).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + const director = await this.server.client.db.Score.findOne({ pin: req.body.pin }); + const staffGuild = this.server.client.guilds.get('446067825673633794') || await this.server.client.getRESTGuild('446067825673633794'); + + if (!director || !staffGuild.members.get(director.userID)?.roles?.includes('662163685439045632')) { + return res.status(403).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + if (!req.params.id) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + if (!(await this.server.client.db.Resolution.exists({ oID: req.params.id }))) { + return res.status(404).json({ + code: this.constants.codes.NOT_FOUND, + message: this.constants.messages.NOT_FOUND, + }); + } + + await this.server.client.db.Resolution.deleteOne({ oID: req.params.id }); + + res.status(200).json({ message: `Resolution with ID ${req.params.id} deleted.` }); + }); + + this.router.delete('/proc/:id', async (req, res) => { + if (!req.body.pin) { + return res.status(401).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + const director = await this.server.client.db.Score.findOne({ pin: req.body.pin }); + const staffGuild = this.server.client.guilds.get('446067825673633794') || await this.server.client.getRESTGuild('446067825673633794'); + + if (!director || !staffGuild.members.get(director.userID)?.roles?.includes('662163685439045632')) { + return res.status(403).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + if (!req.params.id) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + if (!(await this.server.client.db.Proclamation.exists({ oID: req.params.id }))) { + return res.status(404).json({ + code: this.constants.codes.NOT_FOUND, + message: this.constants.messages.NOT_FOUND, + }); + } + + await this.server.client.db.Proclamation.deleteOne({ oID: req.params.id }); + + res.status(200).json({ message: `Proclamation with ID ${req.params.id} deleted.` }); + }); + + this.router.get('/eo/:id', async (req, res) => { + if (!req.params.id) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + if (!(await this.server.client.db.ExecutiveOrder.exists({ oID: req.params.id }))) { + return res.status(404).json({ + code: this.constants.codes.NOT_FOUND, + message: this.constants.messages.NOT_FOUND, + }); + } + + const executiveOrder = await this.server.client.db.ExecutiveOrder.findOne({ oID: req.params.id }); + + res.status(200).json({ + issuedBy: executiveOrder.issuedBy, + id: executiveOrder.oID, + subject: executiveOrder.subject, + body: executiveOrder.body, + at: new Date(executiveOrder.at), + }); + }); + + this.router.get('/motion/:id', async (req, res) => { + if (!req.params.id) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + if (!(await this.server.client.db.Motion.exists({ oID: req.params.id }))) { + return res.status(404).json({ + code: this.constants.codes.NOT_FOUND, + message: this.constants.messages.NOT_FOUND, + }); + } + + const motion = await this.server.client.db.Motion.findOne({ oID: req.params.id }); + + res.status(200).json({ + issuedBy: motion.issuedBy, + id: motion.oID, + subject: motion.subject, + body: motion.body, + at: new Date(motion.at), + }); + }); + + this.router.get('/resolution/:id', async (req, res) => { + if (!req.params.id) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + if (!(await this.server.client.db.Resolution.exists({ oID: req.params.id }))) { + return res.status(404).json({ + code: this.constants.codes.NOT_FOUND, + message: this.constants.messages.NOT_FOUND, + }); + } + + const resolution = await this.server.client.db.Resolution.findOne({ oID: req.params.id }); + + res.status(200).json({ + issuedBy: resolution.issuedBy, + id: resolution.oID, + subject: resolution.subject, + body: resolution.body, + at: new Date(resolution.at), + approvedAt: resolution.acceptedAt || null, + voteResults: resolution.voteResults || null, + }); + }); + + this.router.get('/proc/:id', async (req: Request, res: Response) => { + const proclamation = await this.server.client.db.Proclamation.findOne({ oID: req.params.id }).lean(); + + res.status(200).send({ + proclamation, + }); + }); + + this.router.patch('/proc/:id', async (req, res) => { + if (!req.body.pin) { + return res.status(401).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + const director = await this.server.client.db.Score.findOne({ pin: req.body.pin }); + const staffGuild = this.server.client.guilds.get('446067825673633794') || await this.server.client.getRESTGuild('446067825673633794'); + + if (!director || !staffGuild.members.get(director.userID)?.roles?.includes('662163685439045632')) { + return res.status(403).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + if (!req.params.id) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + if (!(await this.server.client.db.Proclamation.exists({ oID: req.params.id }))) { + return res.status(404).json({ + code: this.constants.codes.NOT_FOUND, + message: this.constants.messages.NOT_FOUND, + }); + } + if (!req.body.subject && !req.body.body) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + + const proclamation = await this.server.client.db.Proclamation.findOne({ oID: req.params.id }); + await proclamation.updateOne({ + subject: req.body.subject || proclamation.subject, + body: req.body.body || proclamation.body, + }); + + res.status(200).json({ message: `Updated Proclamation with ID ${proclamation.oID}.` }); + }); + + this.router.patch('/eo/:id', async (req, res) => { + if (!req.body.pin) { + return res.status(401).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + const director = await this.server.client.db.Score.findOne({ pin: req.body.pin }); + const staffGuild = this.server.client.guilds.get('446067825673633794') || await this.server.client.getRESTGuild('446067825673633794'); + + if (!director || !staffGuild.members.get(director.userID)?.roles?.includes('662163685439045632')) { + return res.status(403).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + if (!req.params.id) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + if (!(await this.server.client.db.ExecutiveOrder.exists({ oID: req.params.id }))) { + return res.status(404).json({ + code: this.constants.codes.NOT_FOUND, + message: this.constants.messages.NOT_FOUND, + }); + } + if (!req.body.subject && !req.body.body) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + + const executiveOrder = await this.server.client.db.ExecutiveOrder.findOne({ oID: req.params.id }); + await executiveOrder.updateOne({ + subject: req.body.subject || executiveOrder.subject, + body: req.body.body || executiveOrder.body, + }); + + res.status(200).json({ message: `Updated Executive Order with ID ${executiveOrder.oID}.` }); + }); + + this.router.patch('/motion/:id', async (req, res) => { + if (!req.body.pin) { + return res.status(401).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + const director = await this.server.client.db.Score.findOne({ pin: req.body.pin }); + const staffGuild = this.server.client.guilds.get('446067825673633794') || await this.server.client.getRESTGuild('446067825673633794'); + + if (!director || !staffGuild.members.get(director.userID)?.roles?.includes('662163685439045632')) { + return res.status(403).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + if (!req.params.id) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + if (!(await this.server.client.db.Motion.exists({ oID: req.params.id }))) { + return res.status(404).json({ + code: this.constants.codes.NOT_FOUND, + message: this.constants.messages.NOT_FOUND, + }); + } + if (!req.body.subject && !req.body.body) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + + const motion = await this.server.client.db.Motion.findOne({ oID: req.params.id }); + await motion.updateOne({ + subject: req.body.subject || motion.subject, + body: req.body.body || motion.body, + }); + + res.status(200).json({ message: `Updated Motion with ID ${motion.oID}.` }); + }); + + this.router.patch('/resolution/:id', async (req, res) => { + if (!req.body.pin) { + return res.status(401).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + const director = await this.server.client.db.Score.findOne({ pin: req.body.pin }); + const staffGuild = this.server.client.guilds.get('446067825673633794') || await this.server.client.getRESTGuild('446067825673633794'); + + if (!director || !staffGuild.members.get(director.userID)?.roles?.includes('662163685439045632')) { + return res.status(403).json({ + code: this.constants.codes.UNAUTHORIZED, + message: this.constants.messages.UNAUTHORIZED, + }); + } + + if (!req.params.id) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + if (!(await this.server.client.db.Motion.exists({ oID: req.params.id }))) { + return res.status(404).json({ + code: this.constants.codes.NOT_FOUND, + message: this.constants.messages.NOT_FOUND, + }); + } + if (!req.body.subject && !req.body.body) { + return res.status(400).json({ + code: this.constants.codes.CLIENT_ERROR, + message: this.constants.messages.CLIENT_ERROR, + }); + } + + const resolution = await this.server.client.db.Resolution.findOne({ oID: req.params.id }); + await resolution.updateOne({ + subject: req.body.subject || resolution.subject, + body: req.body.body || resolution.body, + }); + + res.status(200).json({ message: `Updated Resolution with ID ${resolution.oID}.` }); + }); + + this.router.get('/eo', async (_req, res) => { + const executiveOrders = await this.server.client.db.ExecutiveOrder.find().lean(); + + + res.status(200).json({ executiveOrders }); + }); + + this.router.get('/motion', async (_req, res) => { const motions = await this.server.client.db.Motion.find().lean(); - res.status(200).send({ - motions, - }); + res.status(200).json({ motions }); }); - this.router.get('/resolutions', async (_req, res) => { - const resolutions = await this.server.client.db.Resolution.find().lean(); - - res.status(200).send({ - resolutions, - }); - }); - - this.router.get('/proclamations', async (_req, res) => { + this.router.get('/proc', async (req: Request, res: Response) => { const proclamations = await this.server.client.db.Proclamation.find().lean(); res.status(200).send({ @@ -163,12 +695,10 @@ export default class Root extends Route { }); }); - this.router.get('/executive-orders', async (_req, res) => { - const executiveOrders = await this.server.client.db.ExecutiveOrder.find().lean(); + this.router.get('/resolution', async (_req, res) => { + const resolutions = await this.server.client.db.Resolution.find().lean(); - res.status(200).send({ - executiveOrders, - }); + res.status(200).json({ resolutions }); }); } } diff --git a/src/class/Client.ts b/src/class/Client.ts index 48a5562..c2d042a 100644 --- a/src/class/Client.ts +++ b/src/class/Client.ts @@ -59,6 +59,7 @@ export default class Client extends eris.Client { NNTrainingData: mongoose.Model, Note: mongoose.Model, PagerNumber: mongoose.Model, + Proclamation: mongoose.Model, Promo: mongoose.Model, Rank: mongoose.Model, Redirect: mongoose.Model, @@ -76,7 +77,7 @@ export default class Client extends eris.Client { this.events = new Collection(); this.intervals = new Collection(); this.queue = new Queue(this); - this.db = { Customer, CustomerPortal, ExecutiveOrder, File, Member, Merchant, Moderation, Motion, NNTrainingData, Note, PagerNumber, Promo, Rank, Redirect, Resolution, Score, ScoreHistorical, Staff, Stat, local: { muted: new LocalStorage('muted') } }; + this.db = { Customer, CustomerPortal, ExecutiveOrder, File, Member, Merchant, Moderation, Motion, NNTrainingData, Note, PagerNumber, Proclamation, Promo, Rank, Redirect, Resolution, Score, ScoreHistorical, Staff, Stat, local: { muted: new LocalStorage('muted') } }; } public async loadDatabase() {