Merge branch 'Sterben/communityrelations-master' into master

merge-requests/17/head
Hiroyuki 2021-02-28 12:48:56 -04:00
commit ab841a792c
No known key found for this signature in database
GPG Key ID: C15AC26538975A24
4 changed files with 472 additions and 166 deletions

View File

@ -1,5 +1,6 @@
import { TextChannel } from 'eris'; import { TextChannel } from 'eris';
import { v4 as genUUID } from 'uuid'; import { v4 as genUUID } from 'uuid';
import { Request, Response } from 'express';
import { RichEmbed, Route, Server } from '../../../class'; import { RichEmbed, Route, Server } from '../../../class';
export default class Root extends Route { export default class Root extends Route {
@ -125,6 +126,72 @@ export default class Root extends Route {
}); });
}); });
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 = <TextChannel>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) => { this.router.post('/resolution', async (req, res) => {
if (!req.body.pin) { if (!req.body.pin) {
return res.status(401).json({ return res.status(401).json({
@ -288,6 +355,42 @@ export default class Root extends Route {
res.status(200).json({ message: `Resolution with ID ${req.params.id} deleted.` }); 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) => { this.router.get('/eo/:id', async (req, res) => {
if (!req.params.id) { if (!req.params.id) {
return res.status(400).json({ return res.status(400).json({
@ -365,6 +468,60 @@ export default class Root extends Route {
}); });
}); });
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) => { this.router.patch('/eo/:id', async (req, res) => {
if (!req.body.pin) { if (!req.body.pin) {
return res.status(401).json({ return res.status(401).json({
@ -457,6 +614,117 @@ export default class Root extends Route {
res.status(200).json({ message: `Updated Motion with ID ${motion.oID}.` }); 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.Resolution.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).json({ motions });
});
this.router.get('/proc', async (_req: Request, res: Response) => {
const proclamations = await this.server.client.db.Proclamation.find().lean();
res.status(200).send({ proclamations });
});
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) => { this.router.patch('/resolution/:id', async (req, res) => {
if (!req.body.pin) { if (!req.body.pin) {
return res.status(401).json({ return res.status(401).json({
@ -522,5 +790,11 @@ export default class Root extends Route {
res.status(200).json({ resolutions }); res.status(200).json({ resolutions });
}); });
this.router.get('/resolution', async (_req, res) => {
const resolutions = await this.server.client.db.Resolution.find().lean();
res.status(200).json({ resolutions });
});
} }
} }

View File

@ -16,6 +16,7 @@ import {
NNTrainingData, NNTrainingDataInterface, NNTrainingData, NNTrainingDataInterface,
Note, NoteInterface, Note, NoteInterface,
PagerNumber, PagerNumberInterface, PagerNumber, PagerNumberInterface,
Proclamation, ProclamationInterface,
Promo, PromoInterface, Promo, PromoInterface,
Rank, RankInterface, Rank, RankInterface,
Redirect, RedirectInterface, Redirect, RedirectInterface,
@ -58,6 +59,7 @@ export default class Client extends eris.Client {
NNTrainingData: mongoose.Model<NNTrainingDataInterface>, NNTrainingData: mongoose.Model<NNTrainingDataInterface>,
Note: mongoose.Model<NoteInterface>, Note: mongoose.Model<NoteInterface>,
PagerNumber: mongoose.Model<PagerNumberInterface>, PagerNumber: mongoose.Model<PagerNumberInterface>,
Proclamation: mongoose.Model<ProclamationInterface>,
Promo: mongoose.Model<PromoInterface>, Promo: mongoose.Model<PromoInterface>,
Rank: mongoose.Model<RankInterface>, Rank: mongoose.Model<RankInterface>,
Redirect: mongoose.Model<RedirectInterface>, Redirect: mongoose.Model<RedirectInterface>,
@ -75,7 +77,7 @@ export default class Client extends eris.Client {
this.events = new Collection<Event>(); this.events = new Collection<Event>();
this.intervals = new Collection<NodeJS.Timeout>(); this.intervals = new Collection<NodeJS.Timeout>();
this.queue = new Queue(this); 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() { public async loadDatabase() {

View File

@ -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<ProclamationInterface>('Proclamations', Proclamation);

View File

@ -9,6 +9,7 @@ export { default as Motion, MotionInterface } from './Motion';
export { default as NNTrainingData, NNTrainingDataInterface } from './NNTrainingData'; export { default as NNTrainingData, NNTrainingDataInterface } from './NNTrainingData';
export { default as Note, NoteInterface } from './Note'; export { default as Note, NoteInterface } from './Note';
export { default as PagerNumber, PagerNumberInterface, PagerNumberRaw } from './PagerNumber'; 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 Promo, PromoInterface } from './Promo';
export { default as Rank, RankInterface } from './Rank'; export { default as Rank, RankInterface } from './Rank';
export { default as Redirect, RedirectInterface, RedirectRaw } from './Redirect'; export { default as Redirect, RedirectInterface, RedirectRaw } from './Redirect';