From 829405378d154412e56f8dd7e6e296b7790d3ac4 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 24 Oct 2020 02:54:01 -0400 Subject: [PATCH] add past hard inquiry data --- .../comm.libraryofcode.org/routes/report.ts | 9 +- src/api/loc.sh/routes/internal.ts | 154 +----------------- src/commands/index.ts | 1 + src/commands/pulldata.ts | 107 ++++++++++++ src/commands/score.ts | 9 +- src/commands/whois.ts | 2 +- src/models/Score.ts | 46 +++++- 7 files changed, 170 insertions(+), 158 deletions(-) create mode 100644 src/commands/pulldata.ts diff --git a/src/api/comm.libraryofcode.org/routes/report.ts b/src/api/comm.libraryofcode.org/routes/report.ts index ce3b35a..b42f2c1 100644 --- a/src/api/comm.libraryofcode.org/routes/report.ts +++ b/src/api/comm.libraryofcode.org/routes/report.ts @@ -1,6 +1,7 @@ /* eslint-disable no-bitwise */ /* eslint-disable no-continue */ import jwt from 'jsonwebtoken'; +import { v4 as uuid } from 'uuid'; import { TextChannel } from 'eris'; import { LocalStorage, Route, Server, RichEmbed } from '../../../class'; @@ -96,11 +97,11 @@ export default class Report extends Route { else if (member.cloudServices > 10) cloudServicesScore = 10; else cloudServicesScore = Math.round(member.cloudServices); - const inquiries: [{ name: string, date: Date }?] = []; + const inquiries: [{ id?: string, name: string, date: Date }?] = []; if (member.inquiries?.length > 0) { for (const inq of member.inquiries) { const testDate = (new Date(new Date(inq.date).setHours(2190))); - if (testDate > new Date()) inquiries.push({ name: inq.name, date: inq.date }); + if (testDate > new Date()) inquiries.push({ id: inq.id, name: inq.name, date: inq.date }); } } @@ -114,9 +115,11 @@ export default class Report extends Route { } await this.server.client.db.Merchant.updateOne({ key: req.headers.authorization }, { $addToSet: { pulls: { type: 0, reason: req.body.reason, date: new Date() } } }); - await this.server.client.db.Score.updateOne({ userID: member.userID }, { $addToSet: { inquiries: { name: merchant.name, reason: req.body.reason, date: new Date() } } }); + const reportID = uuid(); + await this.server.client.db.Score.updateOne({ userID: member.userID }, { $addToSet: { inquiries: { id: reportID, name: merchant.name, reason: req.body.reason, date: new Date(), report: member } } }); const embed = new RichEmbed(); embed.setTitle('Inquiry Notification'); + embed.setDescription(reportID); embed.setColor('#800080'); embed.addField('Member', `${mem.user.username}#${mem.user.discriminator} | <@${member.userID}>`, true); embed.addField('Type', 'HARD', true); diff --git a/src/api/loc.sh/routes/internal.ts b/src/api/loc.sh/routes/internal.ts index 9e76a85..e143399 100644 --- a/src/api/loc.sh/routes/internal.ts +++ b/src/api/loc.sh/routes/internal.ts @@ -38,163 +38,17 @@ export default class Internal extends Route { } }); - this.router.get('/offer', async (req, res) => { + this.router.get('/offer', async (_req, res) => { try { - res.setHeader('Access-Control-Allow-Origin', '*'); - if (!req.query.code) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED }); - if (await this.acceptedOffers.get(req.query.code.toString())) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED }); - let offer: { - userID?: string, - staffID?: string, - channelID?: string, - messageID?: string, - pin?: string, - name?: string, - department?: string, - date?: Date, - }; - - try { - offer = <{ - userID?: string, - staffID?: string, - channelID?: string, - messageID?: string, - pin?: string, - name?: string, - department?: string, - date?: Date, - }> jwt.verify(req.query.code.toString(), this.server.client.config.internalKey); - } catch { - return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED }); - } - const chan = this.server.client.guilds.get(this.constants.discord.SERVER_ID).channels.get(offer.channelID); - await chan.createMessage(`__**PRE-APPROVED OFFER ACCEPTED**__\n<@${offer.staffID}>`); - const message = await chan.getMessage(offer.messageID); - const args = []; - args.push(offer.userID, 'hard'); - `${offer.department}:${offer.name}`.split(' ').forEach((item) => args.push(item)); - await this.server.client.commands.get('score').run(message, args); - await this.acceptedOffers.set(req.query.code.toString(), true); - return res.sendStatus(200); + return res.status(410).json({ code: this.constants.codes.DEPRECATED, message: this.constants.codes.DEPRECATED }); } catch (err) { return this.handleError(err, res); } }); - this.router.get('/score', async (req, res) => { + this.router.get('/score', async (_req, res) => { try { - res.setHeader('Access-Control-Allow-Origin', 'report.libraryofcode.org'); - if (this.timeout.has(req.ip)) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED }); - if (!req.query.pin) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED }); - const args = req.query.pin.toString(); - this.timeout.add(req.ip); - setTimeout(() => this.timeout.delete(req.ip), 1800000); - let score = await this.server.client.db.Score.findOne({ pin: [Number(args.split('-')[0]), Number(args.split('-')[1]), Number(args.split('-')[2])] }).lean().exec(); - if (!score) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED }); - const member = await this.server.client.getRESTGuildMember(this.constants.discord.SERVER_ID, score.userID); - if (!member) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED }); - let updated = false; - if (req.query.staff) { - const args = req.query.staff.toString(); - const staffScore = await this.server.client.db.Score.findOne({ pin: [Number(args.split('-')[0]), Number(args.split('-')[1]), Number(args.split('-')[2])] }).lean().exec(); - if (!staffScore) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED }); - if (!staffScore.staff) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED }); - this.timeout.delete(req.ip); - if (staffScore.userID === score.userID) { - updated = true; - await this.server.client.db.Score.updateOne({ userID: score.userID }, { $addToSet: { softInquiries: { name: `${member.username} via report.libraryofcode.org @ IP ${req.ip}`, date: new Date() } } }); - const embed = new RichEmbed(); - embed.setTitle('Inquiry Notification'); - embed.setColor('#00FFFF'); - embed.addField('Member', `${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`, true); - embed.addField('Type', 'SOFT', true); - embed.addField('Department/Service', `${member.username} via report.libraryofcode.org @ IP ${req.ip}`.toUpperCase(), true); - embed.setTimestamp(); - embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL); - const chan = this.server.client.guilds.get(this.server.client.config.guildID).channels.get('611584771356622849'); - chan.createMessage({ embed }).catch(() => {}); - } else { - await this.server.client.db.Score.updateOne({ userID: score.userID }, { $addToSet: { softInquiries: { name: 'Library of Code sp-us | Staff Team via report.libraryofcode.org', date: new Date() } } }); - const embed = new RichEmbed(); - embed.setTitle('Inquiry Notification'); - embed.setColor('#00FFFF'); - embed.addField('Member', `${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`, true); - embed.addField('Type', 'SOFT', true); - embed.addField('Department/Service', 'Library of Code sp-us | Staff Team via report.libraryofcode.org'.toUpperCase(), true); - embed.setTimestamp(); - embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL); - const chan = this.server.client.guilds.get(this.server.client.config.guildID).channels.get('611584771356622849'); - chan.createMessage({ embed }).catch(() => {}); - } - } else if (!updated) { - await this.server.client.db.Score.updateOne({ userID: score.userID }, { $addToSet: { softInquiries: { name: `${member.username} via report.libraryofcode.org @ IP ${req.ip}`, date: new Date() } } }); - const embed = new RichEmbed(); - embed.setTitle('Inquiry Notification'); - embed.setColor('#00FFFF'); - embed.addField('Member', `${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`, true); - embed.addField('Type', 'SOFT', true); - embed.addField('Department/Service', `${member.username} via report.libraryofcode.org @ IP ${req.ip}`.toUpperCase(), true); - embed.setTimestamp(); - embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL); - const chan = this.server.client.guilds.get(this.server.client.config.guildID).channels.get('611584771356622849'); - chan.createMessage({ embed }).catch(() => {}); - } - score = await this.server.client.db.Score.findOne({ pin: [Number(args.split('-')[0]), Number(args.split('-')[1]), Number(args.split('-')[2])] }).lean().exec(); - - let totalScore = '0'; - let activityScore = '0'; - let moderationScore = '0'; - let roleScore = '0'; - let cloudServicesScore = '0'; - let otherScore = '0'; - let miscScore = '0'; - - if (score.total < 200) totalScore = '---'; - else if (score.total > 800) totalScore = '800'; - else totalScore = `${score.total}`; - - if (score.activity < 10) activityScore = '---'; - else if (score.activity > Math.floor((Math.log1p(3000 + 300 + 200 + 100) * 12))) activityScore = String(Math.floor((Math.log1p(3000 + 300 + 200 + 100) * 12))); - else activityScore = `${score.activity}`; - - if (score.roles <= 0) roleScore = '---'; - else if (score.roles > 54) roleScore = '54'; - else roleScore = `${score.roles}`; - - moderationScore = `${score.moderation}`; - - if (score.other === 0) otherScore = '---'; - else otherScore = `${score.other}`; - - if (score.staff <= 0) miscScore = '---'; - else miscScore = `${score.staff}`; - - if (score.cloudServices === 0) cloudServicesScore = '---'; - else if (score.cloudServices > 10) cloudServicesScore = '10'; - else cloudServicesScore = `${score.cloudServices}`; - - const moderations = await this.server.client.db.Moderation.find({ userID: score.userID }); - - - return res.status(200).json({ - name: `${member.username}#${member.discriminator}`, - userID: score.userID, - pin: score.pin?.join('-'), - score: totalScore, - activityScore, - cloudServicesScore, - moderationScore, - roleScore, - otherScore, - miscScore, - notify: score.notify, - locked: !!score.locked, - totalModerations: moderations?.length > 0 ? moderations.length : 0, - inquiries: score.inquiries?.length > 0 ? score.inquiries : [], - softInquiries: score.softInquiries?.length > 0 ? score.softInquiries : [], - lastUpdated: score.lastUpdate, - }); + return res.status(410).json({ code: this.constants.codes.DEPRECATED, message: this.constants.codes.DEPRECATED }); } catch (err) { return this.handleError(err, res); } diff --git a/src/commands/index.ts b/src/commands/index.ts index 21bf384..59c802a 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -24,6 +24,7 @@ export { default as npm } from './npm'; export { default as offer } from './offer'; export { default as page } from './page'; export { default as ping } from './ping'; +export { default as pulldata } from './pulldata'; export { default as rank } from './rank'; export { default as roleinfo } from './roleinfo'; export { default as score } from './score'; diff --git a/src/commands/pulldata.ts b/src/commands/pulldata.ts new file mode 100644 index 0000000..094d1c0 --- /dev/null +++ b/src/commands/pulldata.ts @@ -0,0 +1,107 @@ +/* eslint-disable no-continue */ +/* eslint-disable default-case */ +import { Message, TextChannel } from 'eris'; +import { Client, Command, RichEmbed } from '../class'; + +export default class Score extends Command { + constructor(client: Client) { + super(client); + this.name = 'pulldata'; + this.description = 'Retrieves information about a hard inquiry that was performed on a member.'; + this.usage = `${this.client.config.prefix}pulldata `; + this.aliases = ['inq']; + this.permissions = 5; + this.guildOnly = true; + this.enabled = true; + } + + public async run(message: Message, args: string[]) { + try { + if (!args[1]) return this.client.commands.get('help').run(message, [this.name]); + + const member = this.client.util.resolveMember(args[0], this.mainGuild); + if (!member) return this.error(message.channel, 'Could not locate member.'); + const score = await this.client.db.Score.findOne({ userID: member.id }); + if (!score) return this.error(message.channel, 'Could not find Community Report for this user.'); + const report = score.inquiries.find((inq) => inq.id === args[1]); + if (!report) return this.error(message.channel, 'Could not find inquiry information.'); + + await this.client.db.Score.updateOne({ userID: member.id }, { $addToSet: { softInquiries: { name: 'Library of Code sp-us | Bureau of Community Reports', date: new Date() } } }); + const embed2 = new RichEmbed(); + embed2.setTitle('Inquiry Notification'); + embed2.setColor('#00FFFF'); + const mem = this.client.util.resolveMember(score.userID, this.client.guilds.get(this.client.config.guildID)); + embed2.addField('Member', `${mem.user.username}#${mem.user.discriminator} | <@${score.userID}>`, true); + embed2.addField('Type', 'SOFT', true); + embed2.addField('Department/Service', 'Library of Code sp-us | Bureau of Community Reports'.toUpperCase(), true); + embed2.setTimestamp(); + embed2.setFooter(this.client.user.username, this.client.user.avatarURL); + const log = this.client.guilds.get(this.client.config.guildID).channels.get('611584771356622849'); + log.createMessage({ embed: embed2 }).catch(() => {}); + + const embed = new RichEmbed(); + embed.setTitle(`Hard Inquiry Information - ${report.id}`); + embed.setAuthor(member.username, member.user.avatarURL); + let currentScore = '0'; + if (score.total < 200) currentScore = '---'; + else if (score.total > 800) currentScore = '800'; + else currentScore = `${score.total}`; + embed.setDescription(`**Current Community Score:** ${currentScore}\n\n**Department/Service:** ${report.name || 'N/A'}\n**Reason:** ${report.reason || 'N/A'}`); + + let totalScore = '0'; + let activityScore = '0'; + let moderationScore = '0'; + let roleScore = '0'; + let cloudServicesScore = '0'; + let otherScore = '0'; + let miscScore = '0'; + + if (score.total < 200) totalScore = '---'; + else if (score.total > 800) totalScore = '800'; + else totalScore = `${score.total}`; + + if (score.activity < 10) activityScore = '---'; + else if (score.activity > Math.floor((Math.log1p(3000 + 300 + 200 + 100) * 12))) activityScore = String(Math.floor((Math.log1p(3000 + 300 + 200 + 100) * 12))); + else activityScore = `${score.activity}`; + + if (score.roles <= 0) roleScore = '---'; + else if (score.roles > 54) roleScore = '54'; + else roleScore = `${score.roles}`; + + moderationScore = `${score.moderation}`; + + if (score.other === 0) otherScore = '---'; + else otherScore = `${score.other}`; + + if (score.staff <= 0) miscScore = '---'; + else miscScore = `${score.staff}`; + + if (score.cloudServices === 0) cloudServicesScore = '---'; + else if (score.cloudServices > 10) cloudServicesScore = '10'; + else cloudServicesScore = `${score.cloudServices}`; + + let color = '🔴'; + let additionalText = 'POOR'; + embed.setColor('FF0000'); + if (score.total >= 550) { color = '🟠'; additionalText = 'FAIR'; embed.setColor('FFA500'); } + if (score.total >= 630) { color = '🟡'; additionalText = 'GOOD'; embed.setColor('FFFF00'); } + if (score.total >= 700) { color = '🟢'; additionalText = 'EXCELLENT'; embed.setColor('66FF66'); } + if (score.total >= 770) { color = '✨'; additionalText = 'EXCEPTIONAL'; embed.setColor('#99FFFF'); } + embed.addField('Total | 200 to 800', score ? `${color} ${totalScore} | ${additionalText}` : 'N/C', true); + embed.addField(`Activity | 10 to ${Math.floor(Math.log1p(3000 + 300 + 200 + 100) * 12)}`, activityScore || 'N/C', true); + embed.addField('Roles | 1 to N/A', roleScore || 'N/C', true); + embed.addField('Moderation | N/A to 2' || 'N/C', moderationScore, true); + embed.addField('Cloud Services | N/A to 10+', cloudServicesScore || 'N/C', true); + embed.addField('Other', otherScore || 'N/C', true); + embed.addField('Misc', miscScore || 'N/C', true); + if (score.pin?.length > 0) { + embed.addField('PIN', score.pin.join('-'), true); + } + embed.setTimestamp(report.date); + embed.setFooter('Inquiry performed on', this.client.user.avatarURL); + return message.channel.createMessage({ embed }); + } catch (err) { + return this.client.util.handleError(err, message, this); + } + } +} diff --git a/src/commands/score.ts b/src/commands/score.ts index 4c87fcd..cf0c566 100644 --- a/src/commands/score.ts +++ b/src/commands/score.ts @@ -1,5 +1,6 @@ /* eslint-disable no-continue */ /* eslint-disable default-case */ +import { v4 as uuid } from 'uuid'; import { Message, User, TextChannel } from 'eris'; import { Client, Command, RichEmbed } from '../class'; @@ -67,7 +68,7 @@ export default class Score extends Command { log.createMessage({ embed }).catch(() => {}); check = true; } else { - user = this.client.util.resolveMember(args[0], this.mainGuild).user; + user = this.client.util.resolveMember(args[0], this.mainGuild)?.user; if (!user) { const sc = await this.client.db.Score.findOne({ pin: [Number(args[0].split('-')[0]), Number(args[0].split('-')[1]), Number(args[0].split('-')[2])] }); user = this.client.util.resolveMember(sc.userID, this.mainGuild).user; @@ -81,9 +82,11 @@ export default class Score extends Command { const score = await this.client.db.Score.findOne({ userID: user.id }); if (!score) return this.error(message.channel, 'Score not calculated yet.'); if (score.locked) return this.error(message.channel, 'The score report you have requested has been locked.'); - await this.client.db.Score.updateOne({ userID: user.id }, { $addToSet: { inquiries: { name, reason, date: new Date() } } }); + const reportID = uuid(); + await this.client.db.Score.updateOne({ userID: user.id }, { $addToSet: { inquiries: { id: reportID, name, reason, date: new Date(), report: score.toObject() } } }); const embed = new RichEmbed(); embed.setTitle('Inquiry Notification'); + embed.setDescription(reportID); embed.setColor('#800080'); const mem = this.client.util.resolveMember(score.userID, this.client.guilds.get(this.client.config.guildID)); embed.addField('Member', `${mem.user.username}#${mem.user.discriminator} | <@${score.userID}>`, true); @@ -161,7 +164,7 @@ export default class Score extends Command { score.inquiries.forEach((inq) => { const testDate = (new Date(new Date(inq.date).setHours(2190))); // eslint-disable-next-line no-useless-escape - if (testDate > new Date()) desc += `**Department/Service:** ${inq.name.replace(/\*/gmi, '')}\n**Reason:** ${inq.reason}\n**Date:** ${inq.date.toLocaleString('en-us')} ET\n\n`; + if (testDate > new Date()) desc += `${inq.id ? `__[${inq.id}]__\n` : ''}**Department/Service:** ${inq.name.replace(/\*/gmi, '')}\n**Reason:** ${inq.reason}\n**Date:** ${inq.date.toLocaleString('en-us')} ET\n\n`; }); embed.setDescription(desc); } diff --git a/src/commands/whois.ts b/src/commands/whois.ts index 1b94565..a16eadc 100644 --- a/src/commands/whois.ts +++ b/src/commands/whois.ts @@ -86,7 +86,7 @@ export default class Whois extends Command { embed.addField(`Roles [${member.roles.length}]`, member.roles.map((r) => this.mainGuild.roles.get(r)).sort((a, b) => b.position - a.position).map((r) => `<@&${r.id}>`).join(', ')); } - const flags = []; + const flags: string[] = []; if (member.user.publicFlags) { if ((member.user.publicFlags & (1 << 12)) === 1 << 12) flags.push('<:System:768370601265201152>'); if ((member.user.publicFlags & (1 << 0)) === 1 << 0) flags.push('<:DiscordStaff:768370601882025985>'); diff --git a/src/models/Score.ts b/src/models/Score.ts index 602a465..f7e0bc6 100644 --- a/src/models/Score.ts +++ b/src/models/Score.ts @@ -2,6 +2,50 @@ import { Document, Schema, model } from 'mongoose'; +export interface Inquiry { + id?: string, + name: string, + reason: string, + date: Date, + report: ScoreInterfaceRaw, +} + +export interface ScoreInterfaceRaw { + userID: string + /** + * total will be between 800-200 - 0 signfies "No Score", too little information is available or other variable are too low + * - CALCULATION: `(COMBINED SUBSCORES x 5) * 5.13; Math.floor()` + */ + total: number, + /** + * 10 - 55 + */ + activity: number, + /** + * 0 - 54 + */ + roles: number, + /** + * -50 - 2 + * all users start out with 2 moderation points, the number of points decreases for each moderation. + */ + moderation: number, + /** + * -20 - 50 + * processed by CSD + */ + cloudServices: number, + // 0 or 20, 20 points are added if the user is a staff member + staff: number, + other: number, + notify: boolean, + locked: boolean, + inquiries: [ Inquiry ], + softInquiries: [{ name: string, date: Date }], + lastUpdate: Date, + pin: number[], +} + export interface ScoreInterface extends Document { userID: string @@ -33,7 +77,7 @@ export interface ScoreInterface extends Document { other: number, notify: boolean, locked: boolean, - inquiries: [{ name: string, reason: string, date: Date }], + inquiries: [ Inquiry ], softInquiries: [{ name: string, date: Date }], lastUpdate: Date, pin: number[],