From c0a96a5f67f2d4f01720cea2999245a34b25d41c Mon Sep 17 00:00:00 2001 From: Hiroyuki Date: Fri, 5 Mar 2021 00:04:47 -0400 Subject: [PATCH] Updated endpoints and typechecking --- src/api/board.ins/routes/root.ts | 145 ++++++++++++++----------------- src/events/messageReactionAdd.ts | 2 +- src/models/Resolution.ts | 8 +- 3 files changed, 69 insertions(+), 86 deletions(-) diff --git a/src/api/board.ins/routes/root.ts b/src/api/board.ins/routes/root.ts index ee29a43..e8e18df 100644 --- a/src/api/board.ins/routes/root.ts +++ b/src/api/board.ins/routes/root.ts @@ -30,7 +30,7 @@ export default class Root extends Route { }); } - if (!req.body.subject || !req.body.body) { + if (typeof req.body.subject !== 'string' || typeof req.body.body !== 'string' || req.body.subject.length > 1024 || req.body.body.length > 1024) { return res.status(400).json({ code: this.constants.codes.CLIENT_ERROR, message: this.constants.messages.CLIENT_ERROR, @@ -48,6 +48,7 @@ export default class Root extends Route { embed.setColor('#dd3acd'); embed.addField('Subject', req.body.subject); embed.addField('Body', req.body.body); + embed.addField('Director', directorDiscord.mention); embed.setDescription(eoID); embed.setTimestamp(new Date()); @@ -69,64 +70,6 @@ export default class Root extends Route { }); }); - this.router.post('/motion', 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(this.server.client.config.guildID) || await this.server.client.getRESTGuild(this.server.client.config.guildID); - - 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 motionID = genUUID(); - - const directorDiscord = this.server.client.users.get(director.userID) || await this.server.client.getRESTUser(director.userID); - const directorInformation = await this.server.client.db.Staff.findOne({ userID: director.userID }); - - const embed = new RichEmbed(); - embed.setTitle('Motion'); - embed.setAuthor(`${directorDiscord.username}#${directorDiscord.discriminator}, ${directorInformation.pn.join(', ')}`, directorDiscord.avatarURL); - embed.setColor('#66e1ff'); - embed.addField('Subject', req.body.subject); - embed.addField('Body', req.body.body); - embed.setDescription(motionID); - embed.setTimestamp(new Date()); - - const channel = this.server.client.getChannel('807444198969835550'); - const msg = await channel.createMessage({ embed }); - - const motion = await this.server.client.db.Motion.create({ - issuer: director.userID, - subject: req.body.subject, - body: req.body.body, - at: new Date(), - oID: motionID, - processed: false, - msg: msg.id, - }); - - res.status(200).json({ - code: this.constants.codes.SUCCESS, - message: `Created new Motion with ID ${motion.oID} by ${directorDiscord.username}#${directorDiscord.discriminator}, ${directorInformation.pn.join(', ')}.`, - }); - }); - this.router.post('/proc', async (req: Request, res: Response) => { if (!req.body.pin) { return res.status(401).json({ @@ -145,14 +88,7 @@ export default class Root extends Route { }); } - 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) { + if (typeof req.body.subject !== 'string' || typeof req.body.body !== 'string' || req.body.subject.length > 1024 || req.body.body.length > 1024) { return res.status(400).json({ code: this.constants.codes.CLIENT_ERROR, message: this.constants.messages.CLIENT_ERROR, @@ -171,6 +107,7 @@ export default class Root extends Route { embed.addField('Subject', req.body.subject); embed.addField('Body', req.body.body); embed.addField('ID', proclamationID); + embed.addField('Director', directorDiscord.mention); embed.setTimestamp(new Date()); const channel = this.server.client.getChannel('807444198969835550'); @@ -439,7 +376,7 @@ export default class Root extends Route { message: this.constants.messages.NOT_FOUND, }); } - if (!req.body.subject && !req.body.body) { + if (typeof req.body.subject !== 'string' || typeof req.body.body !== 'string' || req.body.subject.length > 1024 || req.body.body.length > 1024) { return res.status(400).json({ code: this.constants.codes.CLIENT_ERROR, message: this.constants.messages.CLIENT_ERROR, @@ -469,6 +406,7 @@ export default class Root extends Route { embed.setColor('#66e1ff'); embed.addField('Subject', req.body.subject || executiveOrder.subject); embed.addField('Body', req.body.body || executiveOrder.body); + embed.addField('Director', `<@!${executiveOrder.issuer}>`); embed.setDescription(req.params.id); embed.setTimestamp(new Date()); @@ -511,7 +449,7 @@ export default class Root extends Route { message: this.constants.messages.NOT_FOUND, }); } - if (!req.body.subject && !req.body.body) { + if (typeof req.body.subject !== 'string' || typeof req.body.body !== 'string' || req.body.subject.length > 1024 || req.body.body.length > 1024) { return res.status(400).json({ code: this.constants.codes.CLIENT_ERROR, message: this.constants.messages.CLIENT_ERROR, @@ -541,6 +479,7 @@ export default class Root extends Route { embed.setColor('#66e1ff'); embed.addField('Subject', req.body.subject || motion.subject); embed.addField('Body', req.body.body || motion.body); + embed.addField('Director', `<@!${motion.issuer}>`); embed.setDescription(req.params.id); embed.setTimestamp(new Date()); @@ -583,7 +522,7 @@ export default class Root extends Route { message: this.constants.messages.NOT_FOUND, }); } - if (!req.body.subject && !req.body.body) { + if (typeof req.body.subject !== 'string' || typeof req.body.body !== 'string' || req.body.subject.length > 1024 || req.body.body.length > 1024) { return res.status(400).json({ code: this.constants.codes.CLIENT_ERROR, message: this.constants.messages.CLIENT_ERROR, @@ -613,6 +552,7 @@ export default class Root extends Route { embed.setColor('#66e1ff'); embed.addField('Subject', req.body.subject || proclamation.subject); embed.addField('Body', req.body.body || proclamation.body); + embed.addField('Director', `<@!${proclamation.issuer}>`); embed.setDescription(req.params.id); embed.setTimestamp(new Date()); @@ -655,7 +595,7 @@ export default class Root extends Route { message: this.constants.messages.NOT_FOUND, }); } - if (!req.body.subject && !req.body.body) { + if (typeof req.body.subject !== 'string' || typeof req.body.body !== 'string' || req.body.subject.length > 1024 || req.body.body.length > 1024) { return res.status(400).json({ code: this.constants.codes.CLIENT_ERROR, message: this.constants.messages.CLIENT_ERROR, @@ -678,19 +618,24 @@ export default class Root extends Route { if (resolution.subject !== req.body.subject || resolution.body !== req.body.body) { const directorStaffProfile = await this.server.client.db.Staff.findOne({ userID: directorDiscord.id }); + const motion = await this.server.client.db.Motion.findOne({ oID: resolution.oID }); const embed = new RichEmbed(); embed.setTitle('Resolution'); embed.setAuthor(`${directorDiscord.username}#${directorDiscord.discriminator}, ${directorStaffProfile.pn.join(', ')}`, directorDiscord.avatarURL); - embed.setColor('#66e1ff'); + embed.setColor('#75b0ff'); embed.addField('Subject', req.body.subject || resolution.subject); embed.addField('Body', req.body.body || resolution.body); + embed.addField('Director', `<@!${motion.issuer}>`); embed.setDescription(req.params.id); embed.setTimestamp(new Date()); const channel = this.server.client.getChannel('807444198969835550'); const resMessage = await channel.getMessage(resolution.msg); - await resMessage.edit({ embed }); + await resMessage.edit({ + content: `<@!${resolution.issuer}>`, + embed, + }); } res.status(200).json({ message: `Updated Resolution with ID ${resolution.oID}.` }); @@ -752,7 +697,13 @@ export default class Root extends Route { message: this.constants.messages.NOT_FOUND, }); } - if (Number.isNaN(Number(req.body.yea)) || Number.isNaN(Number(req.body.nay)) || Number.isNaN(Number(req.body.present)) || Number.isNaN(Number(req.body.absent))) { + + const yea = Number(req.body.yea); + const nay = Number(req.body.nay); + const present = Number(req.body.present); + const absent = Number(req.body.absent); + + if (Number.isNaN(yea) || Number.isNaN(nay) || Number.isNaN(present) || Number.isNaN(absent)) { return res.status(400).json({ code: this.constants.codes.CLIENT_ERROR, message: this.constants.messages.CLIENT_ERROR, @@ -763,10 +714,10 @@ export default class Root extends Route { await motion.updateOne({ processed: true, results: { - yea: Number(req.body.yea), - nay: Number(req.body.nay), - present: Number(req.body.present), - absent: Number(req.body.absent), + yea, + nay, + present, + absent, }, }); @@ -778,14 +729,48 @@ export default class Root extends Route { embed.setTitle('Motion Confirmed'); embed.setAuthor(`${directorDiscord.username}#${directorDiscord.discriminator}, ${directorStaffProfile.pn.join(', ')}`, directorDiscord.avatarURL); embed.setColor('#27b17a'); - embed.addField('Subject', req.body.subject); - embed.addField('Body', req.body.body); + embed.addField('Subject', motion.subject); + embed.addField('Body', motion.body); + embed.addField('Director', `<@!${motion.issuer}>`); embed.setDescription(motion.oID); embed.setFooter(motion.oID, directorDiscord.avatarURL); embed.setTimestamp(new Date()); await channel.createMessage({ embed }); + const excludingYea = nay + present + absent; + if (yea > excludingYea) { + const resolutionEmbed = new RichEmbed(); + resolutionEmbed.setTitle('Resolution'); + resolutionEmbed.setAuthor(`${directorDiscord.username}#${directorDiscord.discriminator}, ${directorStaffProfile.pn.join(', ')}`, directorDiscord.avatarURL); + resolutionEmbed.setColor('#75b0ff'); + resolutionEmbed.addField('Subject', motion.subject); + resolutionEmbed.addField('Body', motion.body); + resolutionEmbed.addField('Director', `<@!${motion.issuer}>`); + resolutionEmbed.setDescription(motion.oID); + resolutionEmbed.setTimestamp(new Date()); + + const resMsg = await channel.createMessage({ + content: `<@!${motion.issuer}>`, + embed: resolutionEmbed, + }); + + await this.server.client.db.Resolution.create({ + issuer: motion.issuer, + subject: motion.subject, + body: motion.body, + at: Date.now(), + oID: motion.oID, + results: { + yea, + nay, + present, + absent, + }, + msg: resMsg.id, + }); + } + res.status(200).json({ message: `Confirmed results of motion with ID ${motion.oID}.` }); }); } diff --git a/src/events/messageReactionAdd.ts b/src/events/messageReactionAdd.ts index 478209a..3284f0f 100644 --- a/src/events/messageReactionAdd.ts +++ b/src/events/messageReactionAdd.ts @@ -9,7 +9,7 @@ export default class MessageReactionAdd extends Event { this.event = 'messageReactionAdd'; } - public async run(message: Message, emoji: Emoji, reactor: Member) { + public async run(message: Message, _emoji: Emoji, reactor: Member) { if (message.channel.id !== '807444198969835550') return; if (message.author.id !== this.client.user.id) return; diff --git a/src/models/Resolution.ts b/src/models/Resolution.ts index 302c617..b9f472c 100644 --- a/src/models/Resolution.ts +++ b/src/models/Resolution.ts @@ -4,7 +4,7 @@ export interface ResolutionInterface extends Document { issuer: string; subject: string; body: string; - at: Date; + at: number; oID: string; results: { yea: number; @@ -12,7 +12,6 @@ export interface ResolutionInterface extends Document { present: number; absent: number; }; - acceptedAt: number; msg: string; } @@ -20,7 +19,7 @@ const Resolution = new Schema({ issuer: { type: String, required: true }, subject: { type: String, required: true }, body: { type: String, required: true }, - at: { type: Date, required: true }, + at: { type: Number, required: true }, oID: { type: String, required: true, unique: true }, results: { yea: Number, @@ -28,8 +27,7 @@ const Resolution = new Schema({ present: Number, absent: Number, }, - acceptedAt: Number, - msg: { required: true, unique: true, type: String }, + msg: { type: String, required: true, unique: true }, }); export default model('Resolutions', Resolution);