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() {