Merge branch 'eirk/cloudservices-master'
commit
b40b39ca12
|
@ -1,10 +1,57 @@
|
|||
node_modules
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# macOS files
|
||||
.DS_Store
|
||||
*.DS_Store
|
||||
|
||||
# Database files
|
||||
*.sqlite
|
||||
|
||||
# IDE and text editor configuration files
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# other files
|
||||
dist/
|
||||
src/config.json
|
||||
package-lock.json
|
||||
htmlEmail_templates
|
||||
yarn-error.log
|
||||
src/keys.json
|
||||
dist
|
||||
htmlEmail_templates
|
||||
securesign_genrsa.ts
|
||||
.idea
|
||||
.vscode
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"eslint.enable": true,
|
||||
"eslint.validate": [
|
||||
{
|
||||
"language": "typescript",
|
||||
"autoFix": true
|
||||
}
|
||||
],
|
||||
"editor.tabSize": 2
|
||||
}
|
57
package.json
57
package.json
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "cloudservices-rewrite",
|
||||
"version": "1.2.0",
|
||||
"description": "The official LOC Cloud Services system, this is a rewrite of the original version. ",
|
||||
"version": "2.0",
|
||||
"description": "The official LOC Cloud Services system, this is a rewrite the original version, using discord.js.",
|
||||
"main": "dist/Client.js",
|
||||
"scripts": {
|
||||
"lint": "eslint ./ --ext ts --fix",
|
||||
|
@ -12,40 +12,37 @@
|
|||
"license": "AGPL-3.0-only",
|
||||
"private": false,
|
||||
"dependencies": {
|
||||
"axios": "^0.19.0",
|
||||
"axios": "^0.21.1",
|
||||
"body-parser": "^1.19.0",
|
||||
"eris": "bsian03/eris#dev",
|
||||
"eris-pagination": "git+https://github.com/bsian03/eris-pagination#c0f77b118e98309e89e6522ef545f9d121601f21",
|
||||
"discord.js": "^13.0.0",
|
||||
"express": "^4.17.1",
|
||||
"fs-extra": "^8.1.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"hastebin-gen": "^2.0.5",
|
||||
"helmet": "^3.21.2",
|
||||
"ioredis": "^4.14.1",
|
||||
"helmet": "^4.6.0",
|
||||
"ioredis": "^4.27.7",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"moment": "^2.27.0",
|
||||
"moment-precise-range-plugin": "^1.3.0",
|
||||
"mongoose": "^5.7.4",
|
||||
"nodemailer": "^6.3.1",
|
||||
"moment": "^2.29.1",
|
||||
"mongoose": "^5.13.5",
|
||||
"nodemailer": "^6.6.3",
|
||||
"signale": "^1.4.0",
|
||||
"uuid": "^3.3.3"
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/express-serve-static-core": "^4.17.5",
|
||||
"@types/fs-extra": "^8.0.0",
|
||||
"@types/helmet": "^0.0.45",
|
||||
"@types/ioredis": "^4.0.18",
|
||||
"@types/jsonwebtoken": "^8.5.0",
|
||||
"@types/mongoose": "^5.7.14",
|
||||
"@types/nodemailer": "^6.2.1",
|
||||
"@types/signale": "^1.2.1",
|
||||
"@types/uuid": "^3.4.5",
|
||||
"@typescript-eslint/eslint-plugin": "2.31.0",
|
||||
"@typescript-eslint/parser": "2.31.0",
|
||||
"eslint": "^6.5.1",
|
||||
"eslint-config-airbnb-base": "^14.0.0",
|
||||
"eslint-plugin-import": "^2.18.2",
|
||||
"madge": "^3.9.2",
|
||||
"typescript": "^3.6.4"
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/express-serve-static-core": "^4.17.24",
|
||||
"@types/fs-extra": "^9.0.12",
|
||||
"@types/ioredis": "^4.26.7",
|
||||
"@types/jsonwebtoken": "^8.5.4",
|
||||
"@types/node": "^16.4.13",
|
||||
"@types/nodemailer": "^6.4.4",
|
||||
"@types/signale": "^1.4.2",
|
||||
"@types/uuid": "^8.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "^4.29.0",
|
||||
"@typescript-eslint/parser": "^4.29.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-airbnb-base": "^14.2.1",
|
||||
"eslint-plugin-import": "^2.23.4",
|
||||
"madge": "^5.0.1",
|
||||
"typescript": "^4.3.5"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import os from 'os';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { TextChannel } from 'eris';
|
||||
import { TextChannel, MessageEmbed } from 'discord.js';
|
||||
import { Server } from '..';
|
||||
import { RichEmbed, Route } from '../../class';
|
||||
import { Route } from '../../class';
|
||||
|
||||
export default class Root extends Route {
|
||||
constructor(server: Server) {
|
||||
|
@ -59,18 +59,18 @@ export default class Root extends Route {
|
|||
const token = <any> jwt.verify(req.query.t.toString(), this.server.client.config.keyPair.privateKey);
|
||||
const check = await this.server.storage.get<boolean>(req.query.t.toString());
|
||||
if (check) return res.sendStatus(401);
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Referral Authorization');
|
||||
embed.setDescription(req.query.t.toString());
|
||||
embed.addField('Referred User', `${token.referredUserAndDiscrim} | ${token.referredUserID}`, true);
|
||||
embed.addField('Referrer User', token.referrerUsername, true);
|
||||
embed.addField('Referral Code', token.referralCode, true);
|
||||
embed.setTimestamp();
|
||||
embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL);
|
||||
const channel = <TextChannel> this.server.client.guilds.get('446067825673633794').channels.get('580950455581147146');
|
||||
embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL());
|
||||
const channel = this.server.client.guilds.cache.get('446067825673633794').channels.cache.get('580950455581147146') as TextChannel;
|
||||
res.sendStatus(200);
|
||||
await this.server.storage.set(req.query.t.toString(), true);
|
||||
return channel.createMessage({ content: `<@${token.staffUserID}>`, embed });
|
||||
return channel.send({ content: `<@${token.staffUserID}>`, embeds: [embed] });
|
||||
} catch {
|
||||
return res.sendStatus(401);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* eslint-disable no-continue */
|
||||
import { TextChannel } from 'eris';
|
||||
import { TextChannel, MessageEmbed, TextBasedChannel } from 'discord.js';
|
||||
import { Server } from '..';
|
||||
import { Route, RichEmbed } from '../../class';
|
||||
import { Route } from '../../class';
|
||||
|
||||
export default class Webhook extends Route {
|
||||
constructor(server: Server) {
|
||||
|
@ -12,7 +12,7 @@ export default class Webhook extends Route {
|
|||
this.router.post('/s1', async (req, res) => {
|
||||
try {
|
||||
if (req.headers.authorization !== this.server.security.keys.iv.toString('base64')) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.codes.UNAUTHORIZED });
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Service Request');
|
||||
embed.setDescription(`https://staff.libraryofcode.org/browse/${req.body.key}\n${req.body.url}`);
|
||||
embed.setColor('#FF00FF');
|
||||
|
@ -20,10 +20,10 @@ export default class Webhook extends Route {
|
|||
embed.addField('Reporter', req.body.reporter, true);
|
||||
embed.addField('Status', req.body.status, true);
|
||||
embed.addField('Summary', req.body.summary);
|
||||
embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL);
|
||||
embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
const chan = <TextChannel> this.server.client.getChannel('780513128240382002');
|
||||
chan.createMessage({ content: '<@&741797822940315650>', embed });
|
||||
const channel = this.server.client.channels.cache.get('780513128240382002') as TextChannel;
|
||||
channel.send({ content: '<@&741797822940315650>', embeds: [embed] });
|
||||
return res.status(200).json({ code: this.constants.codes.SUCCESS, message: this.constants.codes.SUCCESS });
|
||||
} catch (err) {
|
||||
return this.handleError(err, res);
|
||||
|
@ -47,17 +47,18 @@ export default class Webhook extends Route {
|
|||
} else {
|
||||
await account.updateOne({ $set: { tier: 3 } });
|
||||
}
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Cloud Account | Tier Change');
|
||||
embed.setColor('#0099ff');
|
||||
embed.addField('User', `${account.username} | <@${account.userID}>`, true);
|
||||
embed.addField('Technician', 'SYSTEM', true);
|
||||
embed.addField('Old Tier -> New Tier', `${account.tier} -> 3`, true);
|
||||
embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL);
|
||||
embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
await this.server.client.util.sendMessageToUserTerminal(account.username, 'A technician has changed your tier to 3').catch(() => { });
|
||||
this.server.client.createMessage('580950455581147146', { embed });
|
||||
this.server.client.getDMChannel(account.userID).then((channel) => channel.createMessage({ embed })).catch();
|
||||
const channel = this.server.client.channels.cache.get('580950455581147146') as TextChannel;
|
||||
channel.send({ embeds: [embed] });
|
||||
this.server.client.users.cache.get(account.userID).send({ embeds: [embed] });
|
||||
return res.sendStatus(200);
|
||||
});
|
||||
|
||||
|
@ -74,17 +75,18 @@ export default class Webhook extends Route {
|
|||
} else {
|
||||
await account.updateOne({ $set: { tier: 1 } });
|
||||
}
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Cloud Account | Tier Change');
|
||||
embed.setColor('#0099ff');
|
||||
embed.addField('User', `${account.username} | <@${account.userID}>`, true);
|
||||
embed.addField('Technician', 'SYSTEM', true);
|
||||
embed.addField('Old Tier -> New Tier', `${account.tier} -> 1`, true);
|
||||
embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL);
|
||||
embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
await this.server.client.util.sendMessageToUserTerminal(account.username, 'A technician has changed your tier.').catch(() => { });
|
||||
this.server.client.createMessage('580950455581147146', { embed });
|
||||
this.server.client.getDMChannel(account.userID).then((channel) => channel.createMessage({ embed })).catch();
|
||||
const ch = this.server.client.channels.cache.get('580950455581147146') as TextChannel;
|
||||
ch.send({ embeds: [embed] });
|
||||
this.server.client.users.cache.get(account.userID).send({ embeds: [embed] });
|
||||
return res.sendStatus(200);
|
||||
});
|
||||
|
||||
|
@ -105,17 +107,18 @@ export default class Webhook extends Route {
|
|||
} else {
|
||||
await account.updateOne({ $set: { tier: 2 } });
|
||||
}
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Cloud Account | Tier Change');
|
||||
embed.setColor('#0099ff');
|
||||
embed.addField('User', `${account.username} | <@${account.userID}>`, true);
|
||||
embed.addField('Technician', 'SYSTEM', true);
|
||||
embed.addField('Old Tier -> New Tier', `${account.tier} -> 2`, true);
|
||||
embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL);
|
||||
embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
await this.server.client.util.sendMessageToUserTerminal(account.username, 'A technician has changed your tier to 2').catch(() => { });
|
||||
this.server.client.createMessage('580950455581147146', { embed });
|
||||
this.server.client.getDMChannel(account.userID).then((channel) => channel.createMessage({ embed })).catch();
|
||||
const ch = this.server.client.channels.cache.get('580950455581147146') as TextChannel;
|
||||
ch.send({ embeds: [embed] });
|
||||
this.server.client.users.cache.get(account.userID).send({ embeds: [embed] });
|
||||
return res.sendStatus(200);
|
||||
});
|
||||
|
||||
|
@ -132,17 +135,18 @@ export default class Webhook extends Route {
|
|||
} else {
|
||||
await account.updateOne({ $set: { tier: 1 } });
|
||||
}
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Cloud Account | Tier Change');
|
||||
embed.setColor('#0099ff');
|
||||
embed.addField('User', `${account.username} | <@${account.userID}>`, true);
|
||||
embed.addField('Technician', 'SYSTEM', true);
|
||||
embed.addField('Old Tier -> New Tier', `${account.tier} -> 1`, true);
|
||||
embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL);
|
||||
embed.setFooter(this.server.client.user.username, this.server.client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
await this.server.client.util.sendMessageToUserTerminal(account.username, 'A technician has changed your tier.').catch(() => { });
|
||||
this.server.client.createMessage('580950455581147146', { embed });
|
||||
this.server.client.getDMChannel(account.userID).then((channel) => channel.createMessage({ embed })).catch();
|
||||
const ch = this.server.client.channels.cache.get('580950455581147146') as TextChannel;
|
||||
ch.send({ embeds: [embed] });
|
||||
this.server.client.users.cache.get(account.userID).send({ embeds: [embed] });
|
||||
return res.sendStatus(200);
|
||||
});
|
||||
|
||||
|
|
|
@ -20,15 +20,15 @@ export default class AccountUtil {
|
|||
* @param moderator The Discord user ID for the Staff member that created the account.
|
||||
*/
|
||||
public async createAccount(data: { userID: string, username: string, emailAddress: string }, moderator: string): Promise<{ account: AccountInterface, tempPass: string }> {
|
||||
const moderatorMember = this.client.guilds.get('446067825673633794').members.get(moderator);
|
||||
const moderatorMember = this.client.guilds.cache.get('446067825673633794').members.cache.get(moderator);
|
||||
const tempPass = this.client.util.randomPassword();
|
||||
let passHash = await this.client.util.createHash(tempPass); passHash = passHash.replace(/[$]/g, '\\$').replace('\n', '');
|
||||
const acctName = this.client.users.get(data.userID).username.replace(/[!@#$%^&*(),.?":{}|<>]/g, '-').replace(/\s/g, '-');
|
||||
const passHash = (await this.client.util.createHash(tempPass)).replace(/[$]/g, '\\$').replace('\n', '');
|
||||
const acctName = this.client.users.cache.get(data.userID).username.replace(/[!@#$%^&*(),.?":{}|<>]/g, '-').replace(/\s/g, '-');
|
||||
const etcPasswd = `${acctName},${data.userID},,`;
|
||||
const code = randomBytes(3).toString('hex').toUpperCase();
|
||||
|
||||
const accountInterface = await this.client.util.createAccount(passHash, etcPasswd, data.username, data.userID, data.emailAddress, moderator, code);
|
||||
await this.client.util.createModerationLog(data.userID, moderatorMember, 0);
|
||||
await this.client.util.createModerationLog(data.userID, moderatorMember.user, 0);
|
||||
const req = await axios.get('https://loc.sh/int/directory');
|
||||
const find = req.data.find((mem) => mem.userID === moderator);
|
||||
|
||||
|
@ -70,10 +70,11 @@ export default class AccountUtil {
|
|||
</body>
|
||||
`,
|
||||
});
|
||||
|
||||
this.client.guilds.get('446067825673633794').members.get(data.userID).addRole('546457886440685578');
|
||||
const dmChannel = await this.client.getDMChannel(data.userID).catch();
|
||||
dmChannel.createMessage('<:loc:607695848612167700> **Thank you for creating an account with us!** <:loc:607695848612167700>\n'
|
||||
const guild = this.client.guilds.cache.get('446067825673633794');
|
||||
const member = guild.members.cache.get(data.userID);
|
||||
await member.roles.add('546457886440685578');
|
||||
const user = this.client.users.cache.get(data.userID);
|
||||
user.send('<:loc:607695848612167700> **Thank you for creating an account with us!** <:loc:607695848612167700>\n'
|
||||
+ `Please log into your account by running \`ssh ${data.username}@cloud.libraryofcode.org\` in your terminal, then use the password \`${tempPass}\` to log in.\n`
|
||||
+ `You will be asked to change your password, \`(current) UNIX password\` is \`${tempPass}\`, then create a password that is at least 12 characters long, with at least one number, special character, and an uppercase letter\n`
|
||||
+ 'Bear in mind that when you enter your password, it will be blank, so be careful not to type in your password incorrectly.\n\n'
|
||||
|
@ -90,7 +91,7 @@ export default class AccountUtil {
|
|||
await this.client.util.exec(`lock ${account.username}`);
|
||||
await account.updateOne({ locked: true });
|
||||
|
||||
await this.client.util.createModerationLog(account.userID, this.client.users.get(moderatorID), 2, data?.reason, data?.time);
|
||||
await this.client.util.createModerationLog(account.userID, this.client.users.cache.get(moderatorID), 2, data?.reason, data?.time);
|
||||
|
||||
this.client.util.transport.sendMail({
|
||||
to: account.emailAddress,
|
||||
|
@ -101,7 +102,7 @@ export default class AccountUtil {
|
|||
<h1>Library of Code | Cloud Services</h1>
|
||||
<p>Your Cloud Account has been locked until ${data?.time ? moment(data?.time).calendar() : 'indefinitely'} under the EULA.</p>
|
||||
<p><b>Reason:</b> ${data?.reason ? data.reason : 'none provided'}</p>
|
||||
<p><b>Technician:</b> ${moderatorID !== this.client.user.id ? this.client.users.get(moderatorID).username : 'SYSTEM'}</p>
|
||||
<p><b>Technician:</b> ${moderatorID !== this.client.user.id ? (this.client.users.cache.get(moderatorID).username) : 'SYSTEM'}</p>
|
||||
<p><b>Expiration:</b> ${data?.time ? moment(data?.time).format('dddd, MMMM Do YYYY, h:mm:ss A') : 'N/A'}</p>
|
||||
|
||||
<b><i>Library of Code sp-us | Support Team</i></b>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Eris from 'eris';
|
||||
import { Client as DiscordClient, Intents } from 'discord.js';
|
||||
import Redis from 'ioredis';
|
||||
import mongoose from 'mongoose';
|
||||
import signale from 'signale';
|
||||
|
@ -8,8 +8,7 @@ import { Account, AccountInterface, Moderation, ModerationInterface, Domain, Dom
|
|||
import { emojis } from '../stores';
|
||||
import { Command, CSCLI, Util, Collection, Server, Event } from '.';
|
||||
|
||||
|
||||
export default class Client extends Eris.Client {
|
||||
export default class Client extends DiscordClient {
|
||||
public config: { 'token': string; 'cloudflare': string; 'prefix': string; 'emailPass': string; 'mongoURL': string; 'port': number; 'keyPair': { 'publicKey': string; 'privateKey': string; }; vendorKey: string; internalKey: string; };
|
||||
|
||||
public util: Util;
|
||||
|
@ -35,7 +34,36 @@ export default class Client extends Eris.Client {
|
|||
public buildError: boolean
|
||||
|
||||
constructor() {
|
||||
super(config.token, { getAllUsers: true, restMode: true, defaultImageFormat: 'png', intents: ['guildBans', 'guildEmojis', 'guildInvites', 'guildMembers', 'guildMessageReactions', 'guildMessages', 'guildPresences', 'guildWebhooks', 'guilds', 'directMessages'] });
|
||||
super({
|
||||
shards: 'auto',
|
||||
intents: [
|
||||
Intents.FLAGS.GUILDS,
|
||||
Intents.FLAGS.GUILD_MEMBERS,
|
||||
Intents.FLAGS.GUILD_BANS,
|
||||
Intents.FLAGS.GUILD_EMOJIS_AND_STICKERS,
|
||||
Intents.FLAGS.GUILD_WEBHOOKS,
|
||||
Intents.FLAGS.GUILD_INVITES,
|
||||
Intents.FLAGS.GUILD_INTEGRATIONS,
|
||||
Intents.FLAGS.GUILD_PRESENCES,
|
||||
Intents.FLAGS.GUILD_MESSAGES,
|
||||
Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
|
||||
Intents.FLAGS.DIRECT_MESSAGES,
|
||||
],
|
||||
partials: [
|
||||
'USER',
|
||||
'CHANNEL',
|
||||
'GUILD_MEMBER',
|
||||
'MESSAGE',
|
||||
'REACTION',
|
||||
],
|
||||
allowedMentions: {
|
||||
parse: [
|
||||
'users',
|
||||
'roles',
|
||||
],
|
||||
repliedUser: false,
|
||||
},
|
||||
});
|
||||
|
||||
process.title = 'cloudservices';
|
||||
this.config = config;
|
||||
|
@ -74,7 +102,7 @@ export default class Client extends Eris.Client {
|
|||
const funcRequire: Function = require(`${__dirname}/../functions/${func}`).default;
|
||||
this.functions.set(func.split('.')[0], funcRequire);
|
||||
} catch (error) {
|
||||
this.signale.error(`Error occured loading ${func}`);
|
||||
this.signale.error(`Error occurred loading ${func}`);
|
||||
await this.util.handleError(error);
|
||||
}
|
||||
});
|
||||
|
@ -83,7 +111,6 @@ export default class Client extends Eris.Client {
|
|||
public loadCommand(CommandFile: any) {
|
||||
// eslint-disable-next-line no-useless-catch
|
||||
try {
|
||||
// eslint-disable-next-line
|
||||
const command: Command = new CommandFile(this);
|
||||
if (command.subcmds.length) {
|
||||
command.subcmds.forEach((C) => {
|
||||
|
@ -126,19 +153,17 @@ export default class Client extends Eris.Client {
|
|||
|
||||
public async init() {
|
||||
await mongoose.connect(config.mongoURL, { useNewUrlParser: true, useUnifiedTopology: true });
|
||||
await this.connect();
|
||||
await this.login(config.token);
|
||||
this.on('ready', () => {
|
||||
this.signale.info(`Connected to Discord as ${this.user.username}#${this.user.discriminator}`);
|
||||
});
|
||||
const intervals = await fs.readdir(`${__dirname}/../intervals`);
|
||||
intervals.forEach((interval) => {
|
||||
// eslint-disable-next-line
|
||||
if (interval === 'index.js') return;
|
||||
require(`${__dirname}/../intervals/${interval}`).default(this);
|
||||
this.signale.complete(`Loaded interval ${interval.split('.')[0]}`);
|
||||
});
|
||||
this.server = new Server(this, { port: this.config.port });
|
||||
// eslint-disable-next-line no-new
|
||||
|
||||
const corepath = '/opt/CloudServices/dist';
|
||||
const cmdFiles = await fs.readdir('/opt/CloudServices/dist/commands');
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message, TextableChannel } from 'eris';
|
||||
import { Message, TextBasedChannels } from 'discord.js';
|
||||
import { Client, Collection } from '.';
|
||||
|
||||
export default class Command {
|
||||
|
@ -39,15 +39,15 @@ export default class Command {
|
|||
this.permissions = {};
|
||||
}
|
||||
|
||||
public success(channel: TextableChannel, txt: string) {
|
||||
return channel.createMessage(`***${this.client.stores.emojis.success} ${txt}***`);
|
||||
public success(channel: TextBasedChannels, txt: string) {
|
||||
return channel.send(`***${this.client.stores.emojis.success} ${txt}***`);
|
||||
}
|
||||
|
||||
public loading(channel: TextableChannel, txt: string) {
|
||||
return channel.createMessage(`***${this.client.stores.emojis.loading} ${txt}***`);
|
||||
public loading(channel: TextBasedChannels, txt: string) {
|
||||
return channel.send(`***${this.client.stores.emojis.loading} ${txt}***`);
|
||||
}
|
||||
|
||||
public error(channel: TextableChannel, txt: string) {
|
||||
return channel.createMessage(`***${this.client.stores.emojis.error} ${txt}***`);
|
||||
public error(channel: TextBasedChannels, txt: string) {
|
||||
return channel.send(`***${this.client.stores.emojis.error} ${txt}***`);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,8 @@ import { gzip, gzipSync, unzip } from 'zlib';
|
|||
|
||||
type JSONData = [{key: string, value: any}?];
|
||||
|
||||
|
||||
/**
|
||||
* Persistant local JSON-based storage.
|
||||
* Persistent local JSON-based storage.
|
||||
* - auto-locking system to prevent corrupted data
|
||||
* - uses gzip compression to keep DB storage space utilization low
|
||||
* @author Matthew <matthew@staff.libraryofcode.org>
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
import { Message, MessageEmbed, EmojiResolvable, User, MessageReaction } from 'discord.js';
|
||||
|
||||
export default async function PaginationEmbed(message: Message, pages: MessageEmbed[], options?: {leftArrow?: EmojiResolvable, rightArrow?: EmojiResolvable, timeout?: number }) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options = {
|
||||
leftArrow: options?.leftArrow ?? '⬅️',
|
||||
rightArrow: options?.rightArrow ?? '➡️',
|
||||
timeout: options?.timeout ?? 120000,
|
||||
};
|
||||
|
||||
let pageNumber: number = 0;
|
||||
|
||||
const paginationMessage = await message.channel.send({ content: `Page ${pageNumber + 1} of ${pages.length}`, embeds: [pages[pageNumber]] });
|
||||
|
||||
await paginationMessage.react(options.leftArrow);
|
||||
await paginationMessage.react(options.rightArrow);
|
||||
|
||||
const filter = (reaction: MessageReaction, user: User) => {
|
||||
if ([options.leftArrow, options.rightArrow].includes(reaction.emoji.name)
|
||||
&& !user.bot
|
||||
&& user.id === message.author.id) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const reactionCollector = paginationMessage.createReactionCollector({
|
||||
filter,
|
||||
time: options.timeout,
|
||||
dispose: true,
|
||||
});
|
||||
|
||||
reactionCollector.on('collect', (reaction, user) => {
|
||||
reaction.users.remove(user);
|
||||
if (reaction.emoji.name === options.leftArrow) {
|
||||
if (pageNumber > 0) {
|
||||
pageNumber -= 1;
|
||||
} else {
|
||||
pageNumber = pages.length - 1;
|
||||
}
|
||||
} else if (reaction.emoji.name === options.rightArrow) {
|
||||
if (pageNumber + 1 < pages.length) {
|
||||
pageNumber += 1;
|
||||
} else {
|
||||
pageNumber = 0;
|
||||
}
|
||||
}
|
||||
paginationMessage.edit({ content: `Page ${pageNumber + 1} / ${pages.length}`, embeds: [pages[pageNumber]] });
|
||||
});
|
||||
|
||||
reactionCollector.on('end', () => {
|
||||
if (!paginationMessage.deleted) {
|
||||
paginationMessage.reactions.removeAll();
|
||||
}
|
||||
});
|
||||
return paginationMessage;
|
||||
}
|
|
@ -104,7 +104,7 @@ export default class Report {
|
|||
* @param pin The last 4 digits of the member's PIN number.
|
||||
* @param reason A reason for the hard inquiry.
|
||||
* ```ts
|
||||
* Report.hard('253600545972027394', 1102, 'Verification and Elibility for Personal Account');
|
||||
* Report.hard('253600545972027394', 1102, 'Verification and Eligibility for Personal Account');
|
||||
* ```
|
||||
*/
|
||||
public static async hard(userID: string, pin: number, reason: string, auth: string): Promise<HardReport> {
|
||||
|
|
|
@ -1,176 +0,0 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
|
||||
export default class RichEmbed {
|
||||
title?: string
|
||||
|
||||
type?: string
|
||||
|
||||
description?: string
|
||||
|
||||
url?: string
|
||||
|
||||
timestamp?: Date
|
||||
|
||||
color?: number
|
||||
|
||||
footer?: { text: string, icon_url?: string, proxy_icon_url?: string}
|
||||
|
||||
image?: { url: string, proxy_url?: string, height?: number, width?: number }
|
||||
|
||||
thumbnail?: { url?: string, proxy_url?: string, height?: number, width?: number }
|
||||
|
||||
video?: { url: string, height?: number, width?: number }
|
||||
|
||||
provider?: { name: string, url?: string}
|
||||
|
||||
author?: { name: string, url?: string, proxy_icon_url?: string, icon_url?: string}
|
||||
|
||||
fields?: {name: string, value: string, inline?: boolean}[]
|
||||
|
||||
constructor(data: {
|
||||
title?: string, type?: string, description?: string, url?: string, timestamp?: Date, color?: number, fields?: {name: string, value: string, inline?: boolean}[]
|
||||
footer?: { text: string, icon_url?: string, proxy_icon_url?: string}, image?: { url: string, proxy_url?: string, height?: number, width?: number },
|
||||
thumbnail?: { url: string, proxy_url?: string, height?: number, width?: number }, video?: { url: string, height?: number, width?: number },
|
||||
provider?: { name: string, url?: string}, author?: { name: string, url?: string, proxy_icon_url?: string, icon_url?: string},
|
||||
} = {}) {
|
||||
/*
|
||||
let types: {
|
||||
title?: string, type?: string, description?: string, url?: string, timestamp?: Date, color?: number, fields?: {name: string, value: string, inline?: boolean}[]
|
||||
footer?: { text: string, icon_url?: string, proxy_icon_url?: string}, image?: { url?: string, proxy_url?: string, height?: number, width?: number },
|
||||
thumbnail?: { url?: string, proxy_url?: string, height?: number, width?: number }, video?: { url?: string, height?: number, width?: number },
|
||||
provider?: { name?: string, url?: string}, author?: { name?: string, url?: string, proxy_icon_url?: string, icon_url?: string}
|
||||
};
|
||||
*/
|
||||
this.title = data.title;
|
||||
this.description = data.description;
|
||||
this.url = data.url;
|
||||
this.color = data.color;
|
||||
this.author = data.author;
|
||||
this.timestamp = data.timestamp;
|
||||
this.fields = data.fields || [];
|
||||
this.thumbnail = data.thumbnail;
|
||||
this.image = data.image;
|
||||
this.footer = data.footer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title of this embed.
|
||||
*/
|
||||
setTitle(title: string) {
|
||||
if (typeof title !== 'string') throw new TypeError('RichEmbed titles must be a string.');
|
||||
if (title.length > 256) throw new RangeError('RichEmbed titles may not exceed 256 characters.');
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the description of this embed.
|
||||
*/
|
||||
setDescription(description: string) {
|
||||
if (typeof description !== 'string') throw new TypeError('RichEmbed descriptions must be a string.');
|
||||
if (description.length > 2048) throw new RangeError('RichEmbed descriptions may not exceed 2048 characters.');
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the URL of this embed.
|
||||
*/
|
||||
setURL(url: string) {
|
||||
if (typeof url !== 'string') throw new TypeError('RichEmbed URLs must be a string.');
|
||||
if (!url.startsWith('http://') || !url.startsWith('https://')) url = `https://${url}`;
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color of this embed.
|
||||
*/
|
||||
setColor(color: string | number) {
|
||||
if (typeof color === 'string' || typeof color === 'number') {
|
||||
if (typeof color === 'string') {
|
||||
const regex = /[^a-f0-9]/gi;
|
||||
color = color.replace(/#/g, '');
|
||||
if (regex.test(color)) throw new RangeError('Hexadecimal colours must not contain characters other than 0-9 and a-f.');
|
||||
color = parseInt(color, 16);
|
||||
} else if (color < 0 || color > 16777215) throw new RangeError('Base 10 colours must not be less than 0 or greater than 16777215.');
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
throw new TypeError('RichEmbed colours must be hexadecimal as string or number.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the author of this embed.
|
||||
*/
|
||||
setAuthor(name: string, icon_url?: string, url?: string) {
|
||||
if (typeof name !== 'string') throw new TypeError('RichEmbed Author names must be a string.');
|
||||
if (url && typeof url !== 'string') throw new TypeError('RichEmbed Author URLs must be a string.');
|
||||
if (icon_url && typeof icon_url !== 'string') throw new TypeError('RichEmbed Author icons must be a string.');
|
||||
this.author = { name, icon_url, url };
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the timestamp of this embed.
|
||||
*/
|
||||
setTimestamp(timestamp = new Date()) {
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
if (isNaN(timestamp.getTime())) throw new TypeError('Expecting ISO8601 (Date constructor)');
|
||||
this.timestamp = timestamp;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a field to the embed (max 25).
|
||||
*/
|
||||
addField(name: string, value: string, inline = false) {
|
||||
if (typeof name !== 'string') throw new TypeError('RichEmbed Field names must be a string.');
|
||||
if (typeof value !== 'string') throw new TypeError('RichEmbed Field values must be a string.');
|
||||
if (typeof inline !== 'boolean') throw new TypeError('RichEmbed Field inlines must be a boolean.');
|
||||
if (this.fields.length >= 25) throw new RangeError('RichEmbeds may not exceed 25 fields.');
|
||||
if (name.length > 256) throw new RangeError('RichEmbed field names may not exceed 256 characters.');
|
||||
if (!/\S/.test(name)) throw new RangeError('RichEmbed field names may not be empty.');
|
||||
if (value.length > 1024) throw new RangeError('RichEmbed field values may not exceed 1024 characters.');
|
||||
if (!/\S/.test(value)) throw new RangeError('RichEmbed field values may not be empty.');
|
||||
this.fields.push({ name, value, inline });
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function for `<RichEmbed>.addField('\u200B', '\u200B', inline)`.
|
||||
*/
|
||||
addBlankField(inline = false) {
|
||||
return this.addField('\u200B', '\u200B', inline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the thumbnail of this embed.
|
||||
*/
|
||||
setThumbnail(url: string) {
|
||||
if (typeof url !== 'string') throw new TypeError('RichEmbed Thumbnail URLs must be a string.');
|
||||
this.thumbnail = { url };
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the image of this embed.
|
||||
*/
|
||||
setImage(url: string) {
|
||||
if (typeof url !== 'string') throw new TypeError('RichEmbed Image URLs must be a string.');
|
||||
if (!url.startsWith('http://') || !url.startsWith('https://')) url = `https://${url}`;
|
||||
this.image = { url };
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the footer of this embed.
|
||||
*/
|
||||
setFooter(text: string, icon_url?: string) {
|
||||
if (typeof text !== 'string') throw new TypeError('RichEmbed Footers must be a string.');
|
||||
if (icon_url && typeof icon_url !== 'string') throw new TypeError('RichEmbed Footer icon URLs must be a string.');
|
||||
if (text.length > 2048) throw new RangeError('RichEmbed footer text may not exceed 2048 characters.');
|
||||
this.footer = { text, icon_url };
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ export default class Route {
|
|||
|
||||
public init(): void {
|
||||
this.router.all('*', (req, res, next) => {
|
||||
// this.server.client.signale.log(`'${req.method}' request from '${req.ip}' to '${req.hostname}${req.path}'.`);
|
||||
this.server.client.signale.log(`'${req.method}' request from '${req.ip}' to '${req.hostname}${req.path}'.`);
|
||||
if (this.conf.maintenance === true) res.status(503).json({ code: this.constants.codes.MAINTENANCE_OR_UNAVAILABLE, message: this.constants.messages.MAINTENANCE_OR_UNAVAILABLE });
|
||||
else if (this.conf.deprecated === true) res.status(501).json({ code: this.constants.codes.DEPRECATED, message: this.constants.messages.DEPRECATED });
|
||||
else next();
|
||||
|
@ -44,7 +44,7 @@ export default class Route {
|
|||
}
|
||||
|
||||
/**
|
||||
* This function checks for the presense of a Bearer token with Security.extractBearer(),
|
||||
* This function checks for the presence of a Bearer token with Security.extractBearer(),
|
||||
* then it will attempt to validate it with Security.checkBearer().
|
||||
* If it can authenticate the request, it'll add a custom property on Request called
|
||||
* `account`, which will hold an the bearer token's account owner. The account is of the
|
||||
|
|
|
@ -6,7 +6,6 @@ import fs from 'fs-extra';
|
|||
import { Client, Collection, LocalStorage, Route } from '.';
|
||||
import { Security } from '../api';
|
||||
|
||||
|
||||
export default class Server {
|
||||
public routes: Collection<Route>
|
||||
|
||||
|
|
|
@ -5,14 +5,14 @@ import axios from 'axios';
|
|||
import { randomBytes } from 'crypto';
|
||||
import childProcess from 'child_process';
|
||||
import nodemailer from 'nodemailer';
|
||||
import { Message, PrivateChannel, GroupChannel, Member, User } from 'eris';
|
||||
import uuid from 'uuid/v4';
|
||||
import { Message, DMChannel, User, MessageEmbed, ColorResolvable, TextChannel } from 'discord.js';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import moment from 'moment';
|
||||
import fs from 'fs';
|
||||
import hastebin from 'hastebin-gen';
|
||||
import { getUserByUid } from '../functions';
|
||||
import { AccountUtil, Client, Command, RichEmbed } from '.';
|
||||
import { ModerationInterface, AccountInterface, Account } from '../models';
|
||||
import { AccountUtil, Client, Command, PaginationEmbed } from '.';
|
||||
import { ModerationInterface, AccountInterface } from '../models';
|
||||
import { Certificate } from '../../types/x509';
|
||||
|
||||
export default class Util {
|
||||
|
@ -96,7 +96,6 @@ export default class Util {
|
|||
return returnArray;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resolves a command
|
||||
* @param query Command input
|
||||
|
@ -131,29 +130,32 @@ export default class Util {
|
|||
this.client.signale.error(error);
|
||||
const info = { content: `\`\`\`js\n${error.stack}\n\`\`\``, embed: null };
|
||||
if (message) {
|
||||
const embed = new RichEmbed();
|
||||
embed.setColor('FF0000');
|
||||
embed.setAuthor(`Error caused by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL);
|
||||
const embed = new MessageEmbed();
|
||||
embed.setColor('#FF0000');
|
||||
embed.setAuthor(`Error caused by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL());
|
||||
embed.setTitle('Message content');
|
||||
embed.setDescription(message.content);
|
||||
embed.addField('User', `${message.author.mention} (\`${message.author.id}\`)`, true);
|
||||
embed.addField('Channel', message.channel.mention, true);
|
||||
embed.addField('User', `${message.author.toString()} (\`${message.author.id}\`)`, true);
|
||||
embed.addField('Channel', `<#${message.channel.id}>`, true);
|
||||
let guild: string;
|
||||
if (message.channel instanceof PrivateChannel || message.channel instanceof GroupChannel) guild = '@me';
|
||||
else guild = message.channel.guild.id;
|
||||
if (message.channel instanceof DMChannel) guild = '@me';
|
||||
else guild = message.guild.id;
|
||||
embed.addField('Message link', `[Click here](https://discordapp.com/channels/${guild}/${message.channel.id}/${message.id})`, true);
|
||||
embed.setTimestamp(new Date(message.timestamp));
|
||||
embed.setTimestamp(new Date(message.createdTimestamp));
|
||||
info.embed = embed;
|
||||
}
|
||||
await this.client.createMessage('595788220764127272', info);
|
||||
const ch = this.client.channels.cache.get('595788220764127272') as TextChannel;
|
||||
await ch.send(info);
|
||||
const msg = message.content.slice(this.client.config.prefix.length).trim().split(/ +/g);
|
||||
if (command) this.resolveCommand(msg).then((c) => { c.cmd.enabled = false; });
|
||||
if (message) message.channel.createMessage(`***${this.client.stores.emojis.error} An unexpected error has occured - please contact a member of the Engineering Team.${command ? ' This command has been disabled.' : ''}***`);
|
||||
if (message) message.channel.send(`***${this.client.stores.emojis.error} An unexpected error has occurred - please contact a member of the Engineering Team.${command ? ' This command has been disabled.' : ''}***`);
|
||||
} catch (err) {
|
||||
this.client.signale.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
public createPaginationEmbed = PaginationEmbed;
|
||||
|
||||
public splitFields(fields: { name: string, value: string, inline?: boolean }[]): { name: string, value: string, inline?: boolean }[][] {
|
||||
let index = 0;
|
||||
const array: {name: string, value: string, inline?: boolean}[][] = [[]];
|
||||
|
@ -181,7 +183,6 @@ export default class Util {
|
|||
return arrayString;
|
||||
}
|
||||
|
||||
|
||||
public async createHash(password: string): Promise<string> {
|
||||
const hashed = await this.exec(`mkpasswd -m sha-512 "${password}"`);
|
||||
return hashed;
|
||||
|
@ -220,13 +221,15 @@ export default class Util {
|
|||
this.exec(`deluser ${username} --remove-home --backup-to /management/Archives && rm -rf -R ${account.homepath}`),
|
||||
this.client.db.Account.deleteOne({ username }),
|
||||
];
|
||||
this.client.removeGuildMemberRole('446067825673633794', account.userID, '546457886440685578', 'Cloud Account Deleted').catch();
|
||||
const guild = this.client.guilds.cache.get('446067825673633794');
|
||||
const member = await guild.members.fetch(account.userID);
|
||||
await member.roles.remove('546457886440685578', 'Cloud Account Deleted');
|
||||
// @ts-ignore
|
||||
await Promise.all(tasks);
|
||||
}
|
||||
|
||||
public async messageCollector(message: Message, question: string, timeout: number, shouldDelete = false, choices: string[] = null, filter = (msg: Message): boolean|void => {}): Promise<Message> {
|
||||
const msg = await message.channel.createMessage(question);
|
||||
const msg = await message.channel.send(question);
|
||||
return new Promise((res, rej) => {
|
||||
const func = (Msg: Message) => {
|
||||
if (filter(Msg) === false) return;
|
||||
|
@ -253,7 +256,7 @@ export default class Util {
|
|||
*
|
||||
* `4` - Delete
|
||||
*/
|
||||
public async createModerationLog(user: string, moderator: Member|User, type: number, reason?: string, duration?: number): Promise<ModerationInterface> {
|
||||
public async createModerationLog(user: string, moderator: User, type: number, reason?: string, duration?: number): Promise<ModerationInterface> {
|
||||
const moderatorID = moderator.id;
|
||||
const account = await this.client.db.Account.findOne({ $or: [{ username: user }, { userID: user }] });
|
||||
if (!account) return Promise.reject(new Error(`Account ${user} not found`));
|
||||
|
@ -280,28 +283,30 @@ export default class Util {
|
|||
await log.save();
|
||||
|
||||
let embedTitle: string;
|
||||
let color: string;
|
||||
let color: ColorResolvable;
|
||||
let archType: string;
|
||||
switch (type) {
|
||||
default: archType = 'Staff'; embedTitle = 'Cloud Account | Generic'; color = '0892e1'; break;
|
||||
case 0: archType = 'Technician'; embedTitle = 'Cloud Account | Create'; color = '00ff00'; break;
|
||||
case 1: archType = 'Technician'; embedTitle = 'Account Warning | Warn'; color = 'ffff00'; break;
|
||||
case 2: archType = 'Technician'; embedTitle = 'Account Infraction | Lock'; color = 'ff6600'; break;
|
||||
case 3: archType = 'Technician'; embedTitle = 'Account Reclaim | Unlock'; color = '0099ff'; break;
|
||||
case 4: archType = 'Director'; embedTitle = 'Cloud Account | Delete'; color = 'ff0000'; break;
|
||||
default: archType = 'Staff'; embedTitle = 'Cloud Account | Generic'; color = '#0892e1'; break;
|
||||
case 0: archType = 'Technician'; embedTitle = 'Cloud Account | Create'; color = '#00ff00'; break;
|
||||
case 1: archType = 'Technician'; embedTitle = 'Account Warning | Warn'; color = '#ffff00'; break;
|
||||
case 2: archType = 'Technician'; embedTitle = 'Account Infraction | Lock'; color = '#ff6600'; break;
|
||||
case 3: archType = 'Technician'; embedTitle = 'Account Reclaim | Unlock'; color = '#0099ff'; break;
|
||||
case 4: archType = 'Director'; embedTitle = 'Cloud Account | Delete'; color = '#ff0000'; break;
|
||||
}
|
||||
const req = await axios.get('https://loc.sh/int/directory');
|
||||
const find = req.data.find((mem) => mem.userID === moderator.id);
|
||||
const embed = new RichEmbed()
|
||||
const embed = new MessageEmbed()
|
||||
.setTitle(embedTitle)
|
||||
.setColor(color)
|
||||
.addField('User', `${username} | <@${userID}>`, true)
|
||||
.addField(archType, moderatorID === this.client.user.id ? 'SYSTEM' : `${moderator.username}, ${find.pn.join(', ')} (<@${moderatorID}>)`, true)
|
||||
.setFooter(this.client.user.username, this.client.user.avatarURL)
|
||||
.setFooter(this.client.user.username, this.client.user.avatarURL())
|
||||
.setTimestamp();
|
||||
if (reason) embed.addField('Reason', reason || 'Not specified');
|
||||
if (type === 2) embed.addField('Lock Expiration', `${date ? moment(date).format('dddd, MMMM Do YYYY, h:mm:ss A') : 'Indefinitely'}`);
|
||||
this.client.createMessage('580950455581147146', { embed }); this.client.getDMChannel(userID).then((channel) => channel.createMessage({ embed })).catch();
|
||||
const ch = this.client.channels.cache.get('580950455581147146') as TextChannel;
|
||||
ch.send({ embeds: [embed] });
|
||||
this.client.users.fetch(userID).then((channel) => channel.send({ embeds: [embed] })).catch();
|
||||
|
||||
return Promise.resolve(log);
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ export { default as Event } from './Event';
|
|||
export { default as Handler } from './Handler';
|
||||
export { default as LocalStorage } from './LocalStorage';
|
||||
export { default as Report } from './Report';
|
||||
export { default as RichEmbed } from './RichEmbed';
|
||||
export { default as Route } from './Route';
|
||||
export { default as Security } from './Security';
|
||||
export { default as Server } from './Server';
|
||||
export { default as Util } from './Util';
|
||||
export { default as PaginationEmbed } from './PaginationEmbed';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message, TextChannel } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class AddReferral extends Command {
|
||||
|
@ -19,10 +19,10 @@ export default class AddReferral extends Command {
|
|||
if (!account) return this.error(message.channel, 'Cannot find user.');
|
||||
|
||||
await account.updateOne({ $inc: { totalReferrals: 1 } });
|
||||
this.client.getDMChannel(account.userID).then((chan) => {
|
||||
chan.createMessage('__**Referral - Application Approval**__\nAn applicant who used your referral code during the application process has been approved. Your referral count has been increased.');
|
||||
this.client.users.fetch(account.userID).then((chan) => {
|
||||
chan.send('__**Referral - Application Approval**__\nAn applicant who used your referral code during the application process has been approved. Your referral count has been increased.');
|
||||
}).catch(() => {});
|
||||
return this.success(message.channel, `Added referral value to account.\nReferrer: \`${account.username}\` | <@${account.userID}>`);
|
||||
return this.success(message.channel as TextChannel, `Added referral value to account.\nReferrer: \`${account.username}\` | <@${account.userID}>`);
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Announce extends Command {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable no-useless-escape */
|
||||
import { Message } from 'eris';
|
||||
import { Client, Command, Report, RichEmbed } from '../class';
|
||||
import { Message, MessageEmbed, TextChannel } from 'discord.js';
|
||||
import { Client, Command, Report } from '../class';
|
||||
|
||||
export default class ApplyT2 extends Command {
|
||||
constructor(client: Client) {
|
||||
|
@ -24,7 +24,7 @@ export default class ApplyT2 extends Command {
|
|||
const decision = await Report.tier2(account.userID, this.client.config.internalKey);
|
||||
if (decision.status === 'SUCCESS') {
|
||||
await loading.delete();
|
||||
message.channel.createMessage(`__**Decision**__\n\n**Status:** ${decision.decision}\n**Processed by:** EDS (A\*01)`);
|
||||
message.channel.send(`__**Decision**__\n\n**Status:** ${decision.decision}\n**Processed by:** EDS (A\*01)`);
|
||||
|
||||
if (decision.decision === 'APPROVED') {
|
||||
const tier = await this.client.db.Tier.findOne({ id: 2 });
|
||||
|
@ -33,21 +33,23 @@ export default class ApplyT2 extends Command {
|
|||
} else {
|
||||
await account.updateOne({ $set: { tier: 2 } });
|
||||
}
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Cloud Account | Tier Change');
|
||||
embed.setColor('#0099ff');
|
||||
embed.addField('User', `${account.username} | <@${account.userID}>`, true);
|
||||
embed.addField('Technician', 'SYSTEM', true);
|
||||
embed.addField('Old Tier -> New Tier', `${account.tier} -> 2`, true);
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
await this.client.util.sendMessageToUserTerminal(account.username, 'A technician has changed your tier to 2').catch(() => { });
|
||||
this.client.createMessage('580950455581147146', { embed }); return this.client.getDMChannel(account.userID).then((channel) => channel.createMessage({ embed })).catch();
|
||||
const ch = this.client.channels.cache.get('580950455581147146') as TextChannel;
|
||||
ch.send({ embeds: [embed] });
|
||||
return this.client.users.fetch(account.userID).then((channel) => channel.send({ embeds: [embed] })).catch();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
await loading.delete();
|
||||
return message.channel.createMessage(`__**Decision**__\n\n**Status:** ${decision.decision}\n**Processed by:** EDS (A*01)\n\n\n*Pre-Declines will not result in a hard pull, and they may be due to a server issue or insufficient information. You may want to contact a Staff member for further information.*`);
|
||||
return message.channel.send(`__**Decision**__\n\n**Status:** ${decision.decision}\n**Processed by:** EDS (A*01)\n\n\n*Pre-Declines will not result in a hard pull, and they may be due to a server issue or insufficient information. You may want to contact a Staff member for further information.*`);
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import jwt from 'jsonwebtoken';
|
||||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class AuthReferral extends Command {
|
||||
|
@ -18,13 +18,23 @@ export default class AuthReferral extends Command {
|
|||
if (!args.length) return this.client.commands.get('help').run(message, [this.name]);
|
||||
const referrer = await this.client.db.Account.findOne({ $or: [{ username: args[0] }, { referralCode: args[0] }, { userID: args[0].replace(/[<@!>]/gi, '') }] });
|
||||
if (!referrer) return this.error(message.channel, 'Cannot find referrer.');
|
||||
const referred = await this.client.getRESTGuildMember('446067825673633794', args[1]);
|
||||
const referred = await message.guild.members.fetch(args[1]);
|
||||
if (!referred) return this.error(message.channel, 'Cannot find referred member.');
|
||||
|
||||
const token = jwt.sign({ staffUserID: message.author.id, referralCode: referrer.referralCode, referrerUserID: referrer.userID, referrerUsername: referrer.username, referredUserID: referred.id, referredUserAndDiscrim: `${referred.username}#${referred.discriminator}` }, this.client.config.keyPair.privateKey, { expiresIn: '24 hours', issuer: 'Library of Code sp-us | Cloud Services Daemon' });
|
||||
this.client.getDMChannel(referrer.userID).then(async (chan) => {
|
||||
await chan.createMessage(`__**Referral Request Authorization**__\nYour referral code has been used in an application recently submitted to us. We need to authorize this request, please visit https://loc.sh/rv and enter the authorization token below. This token expires in 24 hours. If you did not authorize this request, please contact us immediately by DMing Ramirez or opening a ticket at https://loc.sh/cs-help.\n**Referred User:** ${referred.username}#${referred.discriminator} | <@${referred.user.id}>`);
|
||||
await chan.createMessage(`\`${token}\``);
|
||||
const token = jwt.sign(
|
||||
{ staffUserID: message.author.id,
|
||||
referralCode: referrer.referralCode,
|
||||
referrerUserID: referrer.userID,
|
||||
referrerUsername: referrer.username,
|
||||
referredUserID: referred.id,
|
||||
referredUserAndDiscrim: `${referred.user.username}#${referred.user.discriminator}` },
|
||||
this.client.config.keyPair.privateKey, { expiresIn: '24 hours', issuer: 'Library of Code sp-us | Cloud Services Daemon' },
|
||||
);
|
||||
this.client.users.fetch(referrer.userID).then(async (user) => {
|
||||
await user.send('__**Referral Request Authorization**__\n'
|
||||
+ 'Your referral code has been used in an application recently submitted to us. We need to authorize this request, please visit https://loc.sh/rv and enter the authorization token below. This token expires in 24 hours. If you did not authorize this request, please contact us immediately by DMing Ramirez or opening a ticket at https://loc.sh/cs-help.\n'
|
||||
+ `**Referred User:** ${referred.user.username}#${referred.user.discriminator} | ${referred.user.toString()}`);
|
||||
await user.send(`\`${token}\``);
|
||||
}).catch(() => {
|
||||
this.error(message.channel, 'Could not DM referrer.');
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
import Bearer_Revoke from './bearer_revoke';
|
||||
|
||||
|
@ -19,8 +19,8 @@ export default class Bearer extends Command {
|
|||
if (!account) return this.error(message.channel, 'Account not found.');
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
const bearer = await this.client.server.security.createBearer(account._id);
|
||||
const dm = await this.client.getDMChannel(message.author.id);
|
||||
const msg = await dm.createMessage(`__**Library of Code sp-us | Cloud Services [API]**__\n*This message will automatically be deleted in 60 seconds, copy the token and save it. You cannot recover it.*\n\n${bearer}`);
|
||||
const dm = await this.client.users.fetch(message.author.id);
|
||||
const msg = await dm.send(`__**Library of Code sp-us | Cloud Services [API]**__\n*This message will automatically be deleted in 60 seconds, copy the token and save it. You cannot recover it.*\n\n${bearer}`);
|
||||
this.success(message.channel, 'Bearer token sent to direct messages.');
|
||||
return setTimeout(() => {
|
||||
msg.delete();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Bearer_Revoke extends Command {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import axios from 'axios';
|
||||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Cloudflare extends Command {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message, PrivateChannel, GroupChannel } from 'eris';
|
||||
import { GuildMember, Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class CreateAccount extends Command {
|
||||
|
@ -20,10 +20,10 @@ export default class CreateAccount extends Command {
|
|||
|
||||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (message.channel instanceof PrivateChannel || message.channel instanceof GroupChannel) return message; // Stop TS being gay
|
||||
if (!args[2]) return this.client.commands.get('help').run(message, [this.name]);
|
||||
if (!message.channel.guild.members.has(args[0])) return this.error(message.channel, 'User not found.');
|
||||
if (message.channel.guild.members.get(args[0]).bot) return this.error(message.channel, 'I cannot create accounts for bots.');
|
||||
const member: GuildMember = await message.guild.members.fetch(args[0]);
|
||||
if (!member) return this.error(message.channel, 'User not found.');
|
||||
if (member.user.bot) return this.error(message.channel, 'I cannot create accounts for bots.');
|
||||
const checkUser = await this.client.db.Account.findOne({ userID: args[0] });
|
||||
if (checkUser) return this.error(message.channel, `<@${args[0]}> already has an account.`);
|
||||
const checkEmail = await this.client.db.Account.findOne({ emailAddress: args[1] });
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
import Create from './cwg_create';
|
||||
import Data from './cwg_data';
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import fs, { writeFile, unlink } from 'fs-extra';
|
||||
import axios from 'axios';
|
||||
import { randomBytes } from 'crypto';
|
||||
import { Message } from 'eris';
|
||||
import { Message, MessageEmbed, TextChannel } from 'discord.js';
|
||||
import { AccountInterface } from '../models';
|
||||
import { Client, Command, RichEmbed } from '../class';
|
||||
import { Client, Command } from '../class';
|
||||
import { parseCertificate } from '../functions';
|
||||
|
||||
export default class CWG_Create extends Command {
|
||||
|
@ -45,7 +45,7 @@ export default class CWG_Create extends Command {
|
|||
try {
|
||||
answer = await this.client.util.messageCollector(
|
||||
message,
|
||||
`***${this.client.stores.emojis.error} This port is already binded to a domain. Do you wish to continue? (y/n)***`,
|
||||
`***${this.client.stores.emojis.error} This port is already bound to a domain. Do you wish to continue? (y/n)***`,
|
||||
30000, true, ['y', 'n'], (msg) => msg.author.id === message.author.id && msg.channel.id === message.channel.id,
|
||||
);
|
||||
} catch (error) {
|
||||
|
@ -80,12 +80,12 @@ export default class CWG_Create extends Command {
|
|||
// @ts-ignore
|
||||
await Promise.all(tasks);
|
||||
|
||||
const embed = new RichEmbed()
|
||||
const embed = new MessageEmbed()
|
||||
.setTitle('Domain Creation')
|
||||
.setColor(3066993)
|
||||
.addField('Account Username', `${account.username} | <@${account.userID}>`, true)
|
||||
.addField('Account ID', account.id, true)
|
||||
.addField('Technician', `<@${message.author.id}>`, true)
|
||||
.addField('Technician', message.author.toString(), true)
|
||||
.addField('Domain', domain.domain, true)
|
||||
.addField('Port', String(domain.port), true);
|
||||
|
||||
|
@ -95,20 +95,20 @@ export default class CWG_Create extends Command {
|
|||
|
||||
embed.addField('Certificate Issuer', cert.issuer.organizationName, true)
|
||||
.addField('Certificate Subject', cert.subject.commonName, true)
|
||||
.setFooter(this.client.user.username, this.client.user.avatarURL)
|
||||
.setTimestamp(new Date(message.timestamp));
|
||||
.setFooter(this.client.user.username, this.client.user.avatarURL())
|
||||
.setTimestamp(new Date(message.createdTimestamp));
|
||||
|
||||
const completed = [
|
||||
edit.edit(`***${this.client.stores.emojis.success} Successfully binded ${domain.domain} to port ${domain.port} for ${account.username}.***`),
|
||||
this.client.createMessage('580950455581147146', { embed }),
|
||||
this.client.getDMChannel(account.userID).then((r) => r.createMessage({ embed })),
|
||||
edit.edit(`***${this.client.stores.emojis.success} Successfully bound ${domain.domain} to port ${domain.port} for ${account.username}.***`),
|
||||
(this.client.channels.cache.get('580950455581147146') as TextChannel).send({ embeds: [embed] }),
|
||||
this.client.users.fetch(account.userID).then((r) => r.send({ embeds: [embed] })),
|
||||
this.client.util.transport.sendMail({
|
||||
to: account.emailAddress,
|
||||
from: 'Library of Code sp-us | Support Team <help@libraryofcode.org>',
|
||||
subject: 'Your domain has been binded',
|
||||
subject: 'Your domain has been bound',
|
||||
html: `
|
||||
<h1>Library of Code sp-us | Cloud Services</h1>
|
||||
<p>Hello, this is an email informing you that a new domain under your account has been binded.
|
||||
<p>Hello, this is an email informing you that a new domain under your account has been bound.
|
||||
Information is below.</p>
|
||||
<b>Domain:</b> ${domain.domain}<br>
|
||||
<b>Port:</b> ${domain.port}<br>
|
||||
|
@ -124,8 +124,8 @@ export default class CWG_Create extends Command {
|
|||
];
|
||||
|
||||
if (!domain.domain.includes('cloud.libraryofcode.org')) {
|
||||
const content = `__**DNS Record Setup**__\nYou recently a binded a custom domain to your Library of Code sp-us Account. You'll have to update your DNS records. We've provided the records below.\n\n\`${domain.domain} IN CNAME cloud.libraryofcode.org AUTO/500\`\nThis basically means you need to make a CNAME record with the key/host of ${domain.domain} and the value/point to cloud.libraryofcode.org. If you have any questions, don't hesitate to ask us.`;
|
||||
completed.push(this.client.getDMChannel(account.userID).then((r) => r.createMessage(content)));
|
||||
const content = `__**DNS Record Setup**__\nYou recently a bound a custom domain to your Library of Code sp-us Account. You'll have to update your DNS records. We've provided the records below.\n\n\`${domain.domain} IN CNAME cloud.libraryofcode.org AUTO/500\`\nThis basically means you need to make a CNAME record with the key/host of ${domain.domain} and the value/point to cloud.libraryofcode.org. If you have any questions, don't hesitate to ask us.`;
|
||||
completed.push(this.client.users.fetch(account.userID).then((r) => r.send(content)));
|
||||
}
|
||||
|
||||
return Promise.all(completed);
|
||||
|
@ -194,23 +194,23 @@ export default class CWG_Create extends Command {
|
|||
return { cert: `/etc/ssl/certs/cwg/${domain}.chain.crt`, key: `/etc/ssl/private/cwg/${domain}.key.pem` };
|
||||
}
|
||||
|
||||
public checkOccurance(text: string, query: string) {
|
||||
public checkOccurrence(text: string, query: string) {
|
||||
return (text.match(new RegExp(query, 'g')) || []).length;
|
||||
}
|
||||
|
||||
public isValidCertificateChain(cert: string) {
|
||||
if (!cert.replace(/^\s+|\s+$/g, '').startsWith('-----BEGIN CERTIFICATE-----')) return false;
|
||||
if (!cert.replace(/^\s+|\s+$/g, '').endsWith('-----END CERTIFICATE-----')) return false;
|
||||
if (this.checkOccurance(cert.replace(/^\s+|\s+$/g, ''), '-----BEGIN CERTIFICATE-----') !== 2) return false;
|
||||
if (this.checkOccurance(cert.replace(/^\s+|\s+$/g, ''), '-----END CERTIFICATE-----') !== 2) return false;
|
||||
if (this.checkOccurrence(cert.replace(/^\s+|\s+$/g, ''), '-----BEGIN CERTIFICATE-----') !== 2) return false;
|
||||
if (this.checkOccurrence(cert.replace(/^\s+|\s+$/g, ''), '-----END CERTIFICATE-----') !== 2) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public isValidPrivateKey(key: string) {
|
||||
if (!key.replace(/^\s+|\s+$/g, '').startsWith('-----BEGIN PRIVATE KEY-----') && !key.replace(/^\s+|\s+$/g, '').startsWith('-----BEGIN RSA PRIVATE KEY-----') && !key.replace(/^\s+|\s+$/g, '').startsWith('-----BEGIN ECC PRIVATE KEY-----')) return false;
|
||||
if (!key.replace(/^\s+|\s+$/g, '').endsWith('-----END PRIVATE KEY-----') && !key.replace(/^\s+|\s+$/g, '').endsWith('-----END RSA PRIVATE KEY-----') && !key.replace(/^\s+|\s+$/g, '').endsWith('-----END ECC PRIVATE KEY-----')) return false;
|
||||
if ((this.checkOccurance(key.replace(/^\s+|\s+$/g, ''), '-----BEGIN PRIVATE KEY-----') !== 1) && (this.checkOccurance(key.replace(/^\s+|\s+$/g, ''), '-----BEGIN RSA PRIVATE KEY-----') !== 1) && (this.checkOccurance(key.replace(/^\s+|\s+$/g, ''), '-----BEGIN ECC PRIVATE KEY-----') !== 1)) return false;
|
||||
if ((this.checkOccurance(key.replace(/^\s+|\s+$/g, ''), '-----END PRIVATE KEY-----') !== 1) && (this.checkOccurance(key.replace(/^\s+|\s+$/g, ''), '-----END RSA PRIVATE KEY-----') !== 1) && (this.checkOccurance(key.replace(/^\s+|\s+$/g, ''), '-----END ECC PRIVATE KEY-----') !== 1)) return false;
|
||||
if ((this.checkOccurrence(key.replace(/^\s+|\s+$/g, ''), '-----BEGIN PRIVATE KEY-----') !== 1) && (this.checkOccurrence(key.replace(/^\s+|\s+$/g, ''), '-----BEGIN RSA PRIVATE KEY-----') !== 1) && (this.checkOccurrence(key.replace(/^\s+|\s+$/g, ''), '-----BEGIN ECC PRIVATE KEY-----') !== 1)) return false;
|
||||
if ((this.checkOccurrence(key.replace(/^\s+|\s+$/g, ''), '-----END PRIVATE KEY-----') !== 1) && (this.checkOccurrence(key.replace(/^\s+|\s+$/g, ''), '-----END RSA PRIVATE KEY-----') !== 1) && (this.checkOccurrence(key.replace(/^\s+|\s+$/g, ''), '-----END ECC PRIVATE KEY-----') !== 1)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import fs from 'fs';
|
||||
import moment from 'moment';
|
||||
import { createPaginationEmbed } from 'eris-pagination';
|
||||
import { Message } from 'eris';
|
||||
import { Client, Command, RichEmbed } from '../class';
|
||||
import { Message, MessageEmbed } from 'discord.js';
|
||||
import { Client, Command, PaginationEmbed } from '../class';
|
||||
|
||||
export default class CWG_Data extends Command {
|
||||
constructor(client: Client) {
|
||||
|
@ -32,7 +31,7 @@ export default class CWG_Data extends Command {
|
|||
const embeds = await Promise.all(dom.map(async (domain) => {
|
||||
const pem = fs.readFileSync(domain.x509.cert, { encoding: 'utf8' });
|
||||
const cert = await this.client.util.parseCertificate(pem);
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Domain Information');
|
||||
embed.addField('Account Username', domain.account.username, true);
|
||||
embed.addField('Account ID', domain.account.userID, true);
|
||||
|
@ -41,13 +40,13 @@ export default class CWG_Data extends Command {
|
|||
embed.addField('Certificate Issuer', cert.data.issuer.organization[0], true);
|
||||
embed.addField('Certificate Subject', cert.data.issuer.commonName, true);
|
||||
embed.addField('Certificate Expiration Date', moment(cert.data.notAfter).format('dddd, MMMM Do YYYY, h:mm:ss A'), true);
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
return embed;
|
||||
}));
|
||||
this.client.signale.log(embeds);
|
||||
if (embeds.length === 1) return message.channel.createMessage({ embed: embeds[0] });
|
||||
return createPaginationEmbed(message, embeds);
|
||||
if (embeds.length === 1) return message.channel.send({ embeds: [embeds[0]] });
|
||||
return this.client.util.createPaginationEmbed(message, embeds);
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import fs from 'fs-extra';
|
||||
import axios from 'axios';
|
||||
import { Message } from 'eris';
|
||||
import { Client, Command, RichEmbed } from '../class';
|
||||
import { Message, MessageEmbed, TextChannel } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class CWG_Delete extends Command {
|
||||
constructor(client: Client) {
|
||||
|
@ -20,13 +20,13 @@ export default class CWG_Delete extends Command {
|
|||
const domain = await this.client.db.Domain.findOne({ $or: [{ domain: args[0] }, { port: Number(args[0]) || 0 }] });
|
||||
if (!domain) return this.error(message.channel, 'The domain or port you provided could not be found.');
|
||||
const edit = await this.loading(message.channel, 'Deleting domain...');
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Domain Deletion');
|
||||
embed.addField('Account Username', `${domain.account.username} | <@${domain.account.userID}>`, true);
|
||||
embed.addField('Account ID', domain.account.userID, true);
|
||||
embed.addField('Domain', domain.domain, true);
|
||||
embed.addField('Port', String(domain.port), true);
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
if (domain.domain.includes('cloud.libraryofcode.org')) {
|
||||
const resultID = await axios({
|
||||
|
@ -51,8 +51,9 @@ export default class CWG_Delete extends Command {
|
|||
await this.client.db.Domain.deleteOne({ domain: domain.domain });
|
||||
await this.client.util.exec('systemctl reload nginx');
|
||||
edit.edit(`***${this.client.stores.emojis.success} Domain ${domain.domain} with port ${domain.port} has been successfully deleted.***`);
|
||||
this.client.createMessage('580950455581147146', { embed });
|
||||
return this.client.getDMChannel(domain.account.userID).then((channel) => channel.createMessage({ embed })).catch(() => {});
|
||||
const ch = this.client.channels.cache.get('580950455581147146') as TextChannel;
|
||||
ch.send({ embeds: [embed] });
|
||||
return this.client.users.fetch(domain.account.userID).then((u) => u.send({ embeds: [embed] })).catch(() => {});
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { writeFile, unlink } from 'fs-extra';
|
||||
import axios from 'axios';
|
||||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class CWG_UpdateCert extends Command {
|
||||
|
@ -49,23 +49,23 @@ export default class CWG_UpdateCert extends Command {
|
|||
}
|
||||
}
|
||||
|
||||
public checkOccurance(text: string, query: string) {
|
||||
public checkOccurrence(text: string, query: string) {
|
||||
return (text.match(new RegExp(query, 'g')) || []).length;
|
||||
}
|
||||
|
||||
public isValidCertificateChain(cert: string) {
|
||||
if (!cert.replace(/^\s+|\s+$/g, '').startsWith('-----BEGIN CERTIFICATE-----')) return false;
|
||||
if (!cert.replace(/^\s+|\s+$/g, '').endsWith('-----END CERTIFICATE-----')) return false;
|
||||
if (this.checkOccurance(cert.replace(/^\s+|\s+$/g, ''), '-----BEGIN CERTIFICATE-----') !== 2) return false;
|
||||
if (this.checkOccurance(cert.replace(/^\s+|\s+$/g, ''), '-----END CERTIFICATE-----') !== 2) return false;
|
||||
if (this.checkOccurrence(cert.replace(/^\s+|\s+$/g, ''), '-----BEGIN CERTIFICATE-----') !== 2) return false;
|
||||
if (this.checkOccurrence(cert.replace(/^\s+|\s+$/g, ''), '-----END CERTIFICATE-----') !== 2) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public isValidPrivateKey(key: string) {
|
||||
if (!key.replace(/^\s+|\s+$/g, '').startsWith('-----BEGIN PRIVATE KEY-----')) return false;
|
||||
if (!key.replace(/^\s+|\s+$/g, '').endsWith('-----END PRIVATE KEY-----')) return false;
|
||||
if (this.checkOccurance(key.replace(/^\s+|\s+$/g, ''), '-----BEGIN PRIVATE KEY-----') !== 1) return false;
|
||||
if (this.checkOccurance(key.replace(/^\s+|\s+$/g, ''), '-----END PRIVATE KEY-----') !== 1) return false;
|
||||
if (this.checkOccurrence(key.replace(/^\s+|\s+$/g, ''), '-----BEGIN PRIVATE KEY-----') !== 1) return false;
|
||||
if (this.checkOccurrence(key.replace(/^\s+|\s+$/g, ''), '-----END PRIVATE KEY-----') !== 1) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Message, PrivateChannel } from 'eris';
|
||||
import uuid from 'uuid/v4';
|
||||
import { Message } from 'discord.js';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class DeleteAccount extends Command {
|
||||
|
@ -18,9 +18,9 @@ export default class DeleteAccount extends Command {
|
|||
try {
|
||||
if (!args[1]) return this.client.commands.get('help').run(message, [this.name]);
|
||||
const account = await this.client.db.Account.findOne({ $or: [{ username: args[0] }, { userID: args[0] }, { emailAddress: args[0] }] });
|
||||
if (!account) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Account not found.***`);
|
||||
if (!account) return message.channel.send(`${this.client.stores.emojis.error} ***Account not found.***`);
|
||||
const { root, username, userID, emailAddress, homepath } = account;
|
||||
if (root) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Permission denied.***`);
|
||||
if (root) return message.channel.send(`${this.client.stores.emojis.error} ***Permission denied.***`);
|
||||
|
||||
const pad = (number: number, amount: number): string => '0'.repeat(amount - number.toString().length) + number;
|
||||
const randomNumber = Math.floor(Math.random() * 9999);
|
||||
|
@ -28,17 +28,17 @@ export default class DeleteAccount extends Command {
|
|||
try {
|
||||
await this.client.util.messageCollector(message,
|
||||
`***Please confirm that you are permanently deleting ${username}'s account by entering ${verify}. This action cannot be reversed.***`,
|
||||
15000, true, [verify], (msg) => !(message.channel instanceof PrivateChannel && msg.author.id === message.author.id));
|
||||
15000, true, [verify], (msg) => !(msg.author.id === message.author.id));
|
||||
} catch (error) {
|
||||
if (error.message.includes('Did not supply')) return message;
|
||||
throw error;
|
||||
}
|
||||
|
||||
const deleting = await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Deleting account, please wait...***`);
|
||||
const deleting = await message.channel.send(`${this.client.stores.emojis.loading} ***Deleting account, please wait...***`);
|
||||
const reason = args.slice(1).join(' ');
|
||||
const logInput = { username, userID, logID: uuid(), moderatorID: message.author.id, type: 4, date: new Date(), reason: null };
|
||||
if (reason) logInput.reason = reason;
|
||||
await this.client.util.createModerationLog(args[0], message.member, 4, reason);
|
||||
await this.client.util.createModerationLog(args[0], message.author, 4, reason);
|
||||
await this.client.util.deleteAccount(username);
|
||||
message.delete().catch(() => {});
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { randomBytes } from 'crypto';
|
||||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class EmailCode extends Command {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable no-eval */
|
||||
import axios from 'axios';
|
||||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { inspect } from 'util';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
|
@ -45,22 +45,21 @@ export default class Eval extends Command {
|
|||
evaled = error.stack;
|
||||
}
|
||||
|
||||
evaled = evaled.replace(new RegExp(this.client.config.token, 'gi'), 'juul');
|
||||
evaled = evaled.replace(new RegExp(this.client.config.emailPass, 'gi'), 'juul');
|
||||
evaled = evaled.replace(new RegExp(this.client.config.cloudflare, 'gi'), 'juul');
|
||||
|
||||
evaled = evaled.replace(new RegExp(this.client.config.token, 'gi'), 'token');
|
||||
evaled = evaled.replace(new RegExp(this.client.config.emailPass, 'gi'), 'emailPass');
|
||||
evaled = evaled.replace(new RegExp(this.client.config.cloudflare, 'gi'), 'cloudflare');
|
||||
|
||||
const display = this.client.util.splitString(evaled, 1975);
|
||||
if (display[5]) {
|
||||
try {
|
||||
const { data } = await axios.post('https://snippets.cloud.libraryofcode.org/documents', display.join(''));
|
||||
return message.channel.createMessage(`${this.client.stores.emojis.success} Your evaluation evaled can be found on https://snippets.cloud.libraryofcode.org/${data.key}`);
|
||||
return message.channel.send(`${this.client.stores.emojis.success} Your evaluation evaled can be found on https://snippets.cloud.libraryofcode.org/${data.key}`);
|
||||
} catch (error) {
|
||||
return message.channel.createMessage(`${this.client.stores.emojis.error} ${error}`);
|
||||
return message.channel.send(`${this.client.stores.emojis.error} ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
return display.forEach((m) => message.channel.createMessage(`\`\`\`js\n${m}\n\`\`\``));
|
||||
return display.forEach((m) => message.channel.send(`\`\`\`js\n${m}\n\`\`\``));
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import axios from 'axios';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
|
@ -38,7 +38,7 @@ export default class Exec extends Command {
|
|||
}
|
||||
|
||||
await response.delete();
|
||||
return splitResult.forEach((m) => message.channel.createMessage(`\`\`\`bash\n${m}\n\`\`\``));
|
||||
return splitResult.forEach((m) => message.channel.send(`\`\`\`bash\n${m}\n\`\`\``));
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class GetReferral extends Command {
|
||||
|
@ -16,8 +16,8 @@ export default class GetReferral extends Command {
|
|||
const account = await this.client.db.Account.findOne({ userID: message.author.id });
|
||||
if (!account) return this.error(message.channel, 'You do not have a Cloud Services account.');
|
||||
|
||||
return this.client.getDMChannel(message.author.id).then((chan) => {
|
||||
chan.createMessage(`__**CS Account Referral Code**__\n*Referral codes are considered to be somewhat private information. Applicants with referral codes have a greater chance of approval, don't refer someone you don't trust :).*\nYour referral code: \`${account.referralCode}\`\nReferrals Granted: \`${account.totalReferrals ? account.totalReferrals : '0'}\``);
|
||||
return this.client.users.fetch(message.author.id).then((u) => {
|
||||
u.send(`__**CS Account Referral Code**__\n*Referral codes are considered to be somewhat private information. Applicants with referral codes have a greater chance of approval, don't refer someone you don't trust :).*\nYour referral code: \`${account.referralCode}\`\nReferrals Granted: \`${account.totalReferrals ? account.totalReferrals : '0'}\``);
|
||||
}).catch(() => this.error(message.channel, 'Could not send you a DM.'));
|
||||
} catch (err) {
|
||||
return this.client.util.handleError(err, message, this);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { Message } from 'eris';
|
||||
import { createPaginationEmbed } from 'eris-pagination';
|
||||
import { Client, Command, RichEmbed } from '../class';
|
||||
import { Message, MessageEmbed } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Help extends Command {
|
||||
constructor(client: Client) {
|
||||
|
@ -21,44 +20,45 @@ export default class Help extends Command {
|
|||
const commands = this.client.commands.map((c) => {
|
||||
const aliases = c.aliases.map((alias) => `${this.client.config.prefix}${alias}`).join(', ');
|
||||
const perms: string[] = [];
|
||||
let allowedRoles = c.permissions && c.permissions.roles && c.permissions.roles.map((r) => `<@&${r}>`).join(', ');
|
||||
let allowedRoles = c.permissions && c.permissions.roles && c.permissions.roles.map((r) => r.toString()).join(', ');
|
||||
if (allowedRoles) { allowedRoles = `**Roles:** ${allowedRoles}`; perms.push(allowedRoles); }
|
||||
let allowedUsers = c.permissions && c.permissions.users && c.permissions.users.map((u) => `<@${u}>`).join(', ');
|
||||
let allowedUsers = c.permissions && c.permissions.users && c.permissions.users.map((u) => u.toString()).join(', ');
|
||||
if (allowedUsers) { allowedUsers = `**Users:** ${allowedUsers}`; perms.push(allowedUsers); }
|
||||
const displayedPerms = perms.length ? `**Permissions:**\n${perms.join('\n')}` : '';
|
||||
return { name: `${this.client.config.prefix}${c.name}`, value: `**Description:** ${c.description}\n**Aliases:** ${aliases}\n**Usage:** ${c.usage}\n${displayedPerms}`, inline: false };
|
||||
});
|
||||
|
||||
const splitCommands = this.client.util.splitFields(commands);
|
||||
const cmdPages: RichEmbed[] = [];
|
||||
const cmdPages: MessageEmbed[] = [];
|
||||
splitCommands.forEach((splitCmd) => {
|
||||
const embed = new RichEmbed();
|
||||
embed.setTimestamp(); embed.setFooter(`Requested by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL);
|
||||
embed.setAuthor(`${this.client.user.username}#${this.client.user.discriminator}`, this.client.user.avatarURL);
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTimestamp();
|
||||
embed.setFooter(`Requested by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL());
|
||||
embed.setAuthor(`${this.client.user.username}#${this.client.user.discriminator}`, this.client.user.avatarURL());
|
||||
embed.setDescription(`Command list for ${this.client.user.username}`);
|
||||
splitCmd.forEach((c) => embed.addField(c.name, c.value, c.inline));
|
||||
return cmdPages.push(embed);
|
||||
});
|
||||
if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
|
||||
return createPaginationEmbed(message, cmdPages);
|
||||
if (cmdPages.length === 1) return message.channel.send({ embeds: [cmdPages[0]] });
|
||||
return this.client.util.createPaginationEmbed(message, cmdPages);
|
||||
}
|
||||
const resolved = await this.client.util.resolveCommand(args, message);
|
||||
if (!resolved) return message.channel.createMessage(`${this.client.stores.emojis.error} **Command not found!**`);
|
||||
if (!resolved) return message.channel.send(`${this.client.stores.emojis.error} **Command not found!**`);
|
||||
const { cmd } = resolved;
|
||||
const perms: string[] = [];
|
||||
let allowedRoles = cmd.permissions && cmd.permissions.roles && cmd.permissions.roles.map((r) => `<@&${r}>`).join(', ');
|
||||
let allowedRoles = cmd.permissions && cmd.permissions.roles && cmd.permissions.roles.map((r) => r.toString()).join(', ');
|
||||
if (allowedRoles) { allowedRoles = `**Roles:** ${allowedRoles}`; perms.push(allowedRoles); }
|
||||
let allowedUsers = cmd.permissions && cmd.permissions.users && cmd.permissions.users.map((u) => `<@${u}>`).join(', ');
|
||||
let allowedUsers = cmd.permissions && cmd.permissions.users && cmd.permissions.users.map((u) => u.toString()).join(', ');
|
||||
if (allowedUsers) { allowedUsers = `**Users:** ${allowedUsers}`; perms.push(allowedUsers); }
|
||||
const displayedPerms = perms.length ? `\n**Permissions:**\n${perms.join('\n')}` : '';
|
||||
const aliases = cmd.aliases.length ? `\n**Aliases:** ${cmd.aliases.map((alias) => `${this.client.config.prefix}${cmd.parentName ? `${cmd.parentName} ` : ''}${alias}`).join(', ')}` : '';
|
||||
const subcommands = cmd.subcommands.size ? `\n**Subcommands:** ${cmd.subcommands.map((s) => `${cmd.name} ${s.name}`).join(', ')}` : '';
|
||||
const embed = new RichEmbed();
|
||||
embed.setTimestamp(); embed.setFooter(`Requested by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL);
|
||||
embed.setTitle(`${this.client.config.prefix}${cmd.parentName ? `${cmd.parentName}${cmd.name}` : cmd.name}`); embed.setAuthor(`${this.client.user.username}#${this.client.user.discriminator}`, this.client.user.avatarURL);
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTimestamp(); embed.setFooter(`Requested by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL());
|
||||
embed.setTitle(`${this.client.config.prefix}${cmd.parentName ? `${cmd.parentName}${cmd.name}` : cmd.name}`); embed.setAuthor(`${this.client.user.username}#${this.client.user.discriminator}`, this.client.user.avatarURL());
|
||||
const description = `**Description**: ${cmd.description}\n**Usage:** ${cmd.usage}${aliases}${displayedPerms}${subcommands}`;
|
||||
embed.setDescription(description);
|
||||
message.channel.createMessage({ embed });
|
||||
message.channel.send({ embeds: [embed] });
|
||||
} catch (error) {
|
||||
this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message, MessageEmbed } from 'discord.js';
|
||||
import { totalmem } from 'os';
|
||||
import { Client, Command, RichEmbed } from '../class';
|
||||
import { version as erisVersion } from '../../node_modules/eris/package.json';
|
||||
import { Client, Command } from '../class';
|
||||
import { version as discordjsVersion } from '../../node_modules/discord.js/package.json';
|
||||
import { version as expressVersion } from '../../node_modules/express/package.json';
|
||||
import { version as mongooseVersion } from '../../node_modules/mongoose/package.json';
|
||||
import { version as ioredisVersion } from '../../node_modules/ioredis/package.json';
|
||||
|
@ -18,20 +18,20 @@ export default class Info extends Command {
|
|||
|
||||
public async run(message: Message) {
|
||||
try {
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Information');
|
||||
embed.setThumbnail(this.client.user.avatarURL);
|
||||
embed.setThumbnail(this.client.user.avatarURL());
|
||||
embed.addField('Language(s)', '<:ts:604565354554982401> TypeScript, <:Go:703449475405971466> Go', true);
|
||||
embed.addField('Runtime', `Node (${process.version})`, true);
|
||||
embed.addField('Compilers/Transpilers', `TypeScript [tsc] (${tscVersion}) | Go [gc] (${await this.client.util.exec('go version')})`, true);
|
||||
embed.addField('Process Manager', `SystemD (${(await this.client.util.exec('systemd --version')).split('\n')[0]})`, true);
|
||||
embed.addField('Discord Library', `Eris (${erisVersion})`, true);
|
||||
embed.addField('Discord Library', `Discord.js (${discordjsVersion})`, true);
|
||||
embed.addField('HTTP Server Library', `Express (${expressVersion})`, true);
|
||||
embed.addField('Database Library', `MongoDB w/ Mongoose ODM (${mongooseVersion})`, true);
|
||||
embed.addField('Cache Library', `Redis w/ IORedis (${ioredisVersion})`, true);
|
||||
embed.addField('Memory Usage', `${Math.round(process.memoryUsage().rss / 1024 / 1024)} MB / ${Math.round(totalmem() / 1024 / 1024 / 1024)} GB`, true);
|
||||
embed.addField('Repository', 'https://loc.sh/csdgit | Licensed under GNU Affero General Public License V3', true);
|
||||
return message.channel.createMessage({ embed });
|
||||
return message.channel.send({ embeds: [embed] });
|
||||
} catch (err) {
|
||||
return this.client.util.handleError(err, message, this);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Message } from 'eris';
|
||||
import { Client, Command, RichEmbed } from '../class';
|
||||
import { Message, MessageEmbed } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
import { dataConversion } from '../functions';
|
||||
import setRamNotification from './limits_setramnotification';
|
||||
|
||||
|
@ -16,7 +16,7 @@ export default class Limits extends Command {
|
|||
public async run(message: Message) {
|
||||
try {
|
||||
const tiers = await this.client.db.Tier.find();
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Resource Limit Information');
|
||||
const account = await this.client.db.Account.findOne({ userID: message.author.id });
|
||||
if (account) {
|
||||
|
@ -29,12 +29,12 @@ export default class Limits extends Command {
|
|||
}
|
||||
embed.setDescription(`Your resource limit is ${dataConversion(tier.resourceLimits?.ram * 1024 * 1024) ?? '0 B'}.\n${msg}`);
|
||||
}
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
for (const tier of tiers.sort((a, b) => a.id - b.id)) {
|
||||
embed.addField(`Tier ${tier.id}`, `**RAM:** ${dataConversion(tier.resourceLimits?.ram * 1024 * 1024) ?? '0 B'}\n**Storage:** ${dataConversion(tier.resourceLimits?.storage * 1024 * 1024) ?? '0 B'}`);
|
||||
}
|
||||
return message.channel.createMessage({ embed });
|
||||
return message.channel.send({ embeds: [embed] });
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message, TextChannel } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Limits_SetRAMNotification extends Command {
|
||||
constructor(client: Client) {
|
||||
super(client);
|
||||
this.name = 'set-ram-notification';
|
||||
this.description = 'Sets your personal perference for receiving RAM resource limit notifications. Set the limit to "-1" to disable notifications.';
|
||||
this.description = 'Sets your personal preference for receiving RAM resource limit notifications. Set the limit to "-1" to disable notifications.';
|
||||
this.usage = `${this.client.config.prefix}limits set-ram-notification <limit in mb>`;
|
||||
this.enabled = true;
|
||||
}
|
||||
|
@ -13,16 +13,16 @@ export default class Limits_SetRAMNotification extends Command {
|
|||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
const account = await this.client.db.Account.findOne({ userID: message.author.id });
|
||||
if (!account) return this.error(message.channel, 'You do not appear to have an account.');
|
||||
if (!account) return this.error(message.channel as TextChannel, 'You do not appear to have an account.');
|
||||
const tier = await this.client.db.Tier.findOne({ id: account.tier });
|
||||
if (Number(args[0]) >= tier.resourceLimits.ram) return this.error(message.channel, 'You cannot set your notification limit to be set to or above your hard limit.');
|
||||
if (Number(args[0]) < 0) return this.error(message.channel, 'You cannot set your notification limit to a negative number.');
|
||||
if (Number(args[0]) >= tier.resourceLimits.ram) return this.error(message.channel as TextChannel, 'You cannot set your notification limit to be set to or above your hard limit.');
|
||||
if (Number(args[0]) < 0) return this.error(message.channel as TextChannel, 'You cannot set your notification limit to a negative number.');
|
||||
if (Number(args[0]) === 0) {
|
||||
await account.updateOne({ $set: { ramLimitNotification: 0 } });
|
||||
return this.success(message.channel, 'You have disabled notifications.');
|
||||
return this.success(message.channel as TextChannel, 'You have disabled notifications.');
|
||||
}
|
||||
await account.updateOne({ $set: { ramLimitNotification: Number(args[0]) } });
|
||||
return this.success(message.channel, `You will now receive notifications when you go above ${Number(args[0])} MB.`);
|
||||
return this.success(message.channel as TextChannel, `You will now receive notifications when you go above ${Number(args[0])} MB.`);
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Load extends Command {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import moment, { unitOfTime } from 'moment';
|
||||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Lock extends Command {
|
||||
|
@ -29,7 +29,7 @@ export default class Lock extends Command {
|
|||
const momentMilliseconds = moment.duration(Number(length), unit as unitOfTime.Base).asMilliseconds();
|
||||
const reason = momentMilliseconds ? args.slice(2).join(' ') : args.slice(1).join(' ');
|
||||
|
||||
await this.client.util.createModerationLog(account.userID, message.member, 2, reason, momentMilliseconds);
|
||||
await this.client.util.createModerationLog(account.userID, message.author, 2, reason, momentMilliseconds);
|
||||
edit.edit(`***${this.client.stores.emojis.success} Account ${account.username} has been locked by Technician ${message.author.username}#${message.author.discriminator}.***`);
|
||||
message.delete();
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { Message } from 'eris';
|
||||
import { createPaginationEmbed } from 'eris-pagination';
|
||||
import { Client, Command, RichEmbed } from '../class';
|
||||
import { Message, MessageEmbed } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Modlogs extends Command {
|
||||
constructor(client: Client) {
|
||||
|
@ -35,16 +34,16 @@ export default class Modlogs extends Command {
|
|||
const inline = true;
|
||||
return { name, value, inline };
|
||||
}));
|
||||
const users = [...new Set(query.map((log) => log.userID))].map((u) => `<@${u}>`);
|
||||
const users = [...new Set(query.map((log) => log.userID))].map((u) => u.toString());
|
||||
|
||||
const logs = this.client.util.splitFields(formatted);
|
||||
|
||||
const embeds = logs.map((l) => {
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setDescription(`List of Cloud moderation logs for ${users.join(', ')}`);
|
||||
embed.setAuthor('Library of Code | Cloud Services', this.client.user.avatarURL, 'https://libraryofcode.org/');
|
||||
embed.setAuthor('Library of Code | Cloud Services', this.client.user.avatarURL(), 'https://libraryofcode.org/');
|
||||
embed.setTitle('Cloud Modlogs/Infractions');
|
||||
embed.setFooter(`Requested by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL);
|
||||
embed.setFooter(`Requested by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL());
|
||||
l.forEach((f) => embed.addField(f.name, f.value, f.inline));
|
||||
embed.setTimestamp();
|
||||
embed.setColor(3447003);
|
||||
|
@ -52,9 +51,9 @@ export default class Modlogs extends Command {
|
|||
});
|
||||
|
||||
if (embeds.length === 1) {
|
||||
msg.edit({ content: '', embed: embeds[0] });
|
||||
msg.edit({ content: '', embeds: [embeds[0]] });
|
||||
} else {
|
||||
createPaginationEmbed(message, embeds, {});
|
||||
this.client.util.createPaginationEmbed(message, embeds);
|
||||
}
|
||||
return msg;
|
||||
} catch (error) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Message } from 'eris';
|
||||
import { Client, Command, RichEmbed } from '../class';
|
||||
import { Message, MessageEmbed, TextChannel } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Notify extends Command {
|
||||
constructor(client: Client) {
|
||||
|
@ -17,17 +17,18 @@ export default class Notify extends Command {
|
|||
const edit = await this.loading(message.channel, 'Sending notification...');
|
||||
const account = await this.client.db.Account.findOne({ $or: [{ username: args[0] }, { userID: args[0].replace(/[<@!>]/gi, '') }] });
|
||||
if (!account) return edit.edit(`***${this.client.stores.emojis.error} Cannot find user.***`);
|
||||
const embed = new RichEmbed()
|
||||
const embed = new MessageEmbed()
|
||||
.setTitle('Cloud Account | Notification')
|
||||
.setDescription(args.slice(1).join(' '))
|
||||
.addField('Technician', `<@${message.author.id}>`, true)
|
||||
.setFooter(this.client.user.username, this.client.user.avatarURL)
|
||||
.addField('Technician', message.author.toString(), true)
|
||||
.setFooter(this.client.user.username, this.client.user.avatarURL())
|
||||
.setTimestamp();
|
||||
this.client.getDMChannel(account.userID).then((channel) => {
|
||||
channel.createMessage({ embed });
|
||||
this.client.users.fetch(account.userID).then((u) => {
|
||||
u.send({ embeds: [embed] });
|
||||
});
|
||||
embed.addField('User', `${account.username} | <@${account.userID}>`, true);
|
||||
this.client.createMessage('580950455581147146', { embed });
|
||||
const ch = this.client.channels.cache.get('580950455581147146') as TextChannel;
|
||||
ch.send({ embeds: [embed] });
|
||||
this.client.util.transport.sendMail({
|
||||
to: account.emailAddress,
|
||||
from: 'Library of Code sp-us | Cloud Services <help@libraryofcode.org>',
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Ping extends Command {
|
||||
|
@ -12,8 +12,8 @@ export default class Ping extends Command {
|
|||
public async run(message: Message) {
|
||||
try {
|
||||
const clientStart: number = Date.now();
|
||||
const msg: Message = await message.channel.createMessage('🏓 Pong!');
|
||||
msg.edit(`🏓 Pong!\nClient: \`${Date.now() - clientStart}ms\`\nResponse: \`${msg.createdAt - message.createdAt}ms\``);
|
||||
const msg: Message = await message.channel.send('🏓 Pong!');
|
||||
msg.edit(`🏓 Pong!\nClient: \`${Date.now() - clientStart}ms\`\nResponse: \`${msg.createdTimestamp - message.createdTimestamp}ms\``);
|
||||
} catch (error) {
|
||||
this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import axios from 'axios';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
|
@ -41,7 +41,6 @@ export default class Pull extends Command {
|
|||
+ `***${this.client.stores.emojis.loading} Reinstalling dependencies...***`);
|
||||
const passedPull = await updateMessage.edit(continueMessage);
|
||||
|
||||
|
||||
let install: string;
|
||||
try {
|
||||
install = await this.client.util.exec('yarn install', { cwd: '/opt/CloudServices' });
|
||||
|
@ -76,7 +75,7 @@ export default class Pull extends Command {
|
|||
updatedMessage += `${this.client.stores.emojis.error} Could not upload error: ${e}`;
|
||||
}
|
||||
} else {
|
||||
split.forEach((m) => message.channel.createMessage(`\`\`\`bash\n${m}\n\`\`\``));
|
||||
split.forEach((m) => message.channel.send(`\`\`\`bash\n${m}\n\`\`\``));
|
||||
}
|
||||
}
|
||||
this.client.buildError = true;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class ResetPassword extends Command {
|
||||
|
@ -25,9 +25,9 @@ export default class ResetPassword extends Command {
|
|||
await this.client.util.exec(`echo '${account.username}:${tempPass}@' | chpasswd && chage -d0 ${account.username}`);
|
||||
|
||||
let completeMessage = `${this.client.stores.emojis.success} ***Password for ${account.username} reset to \`${tempPass}@\`***`;
|
||||
const dmChannel = await this.client.getDMChannel(account.userID);
|
||||
const dmChannel = await this.client.users.fetch(account.userID);
|
||||
try {
|
||||
await dmChannel.createMessage(`We received a password reset request from you, your new password is \`${tempPass}@\`.\n`
|
||||
await dmChannel.send(`We received a password reset request from you, your new password is \`${tempPass}@\`.\n`
|
||||
+ `You will be asked to change your password when you log back in, \`(current) UNIX password\` is \`${tempPass}@\`, then create a password that is at least 12 characters long, with at least one number, special character, and an uppercase letter.\n`
|
||||
+ 'Bear in mind that when you enter your password, it will be blank, so be careful not to type in your password incorrectly.');
|
||||
} catch (error) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Restart extends Command {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
import SetLimit_RAM from './setlimit_ram';
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class SetLimit_RAM extends Command {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import moment from 'moment';
|
||||
import { Message } from 'eris';
|
||||
import os, { totalmem } from 'os';
|
||||
import { Client, Command, RichEmbed } from '../class';
|
||||
import { Message, MessageEmbed } from 'discord.js';
|
||||
import os from 'os';
|
||||
import { Client, Command } from '../class';
|
||||
import { dataConversion } from '../functions';
|
||||
|
||||
export default class SysInfo extends Command {
|
||||
|
@ -14,21 +14,21 @@ export default class SysInfo extends Command {
|
|||
|
||||
public async run(message: Message) {
|
||||
const availableMemory: string = await this.client.util.exec('free -b');
|
||||
const usedMemory = dataConversion(totalmem() - Number(availableMemory.split('\n')[1].split(' ').slice(-1)[0]));
|
||||
const usedMemory = dataConversion(os.totalmem() - Number(availableMemory.split('\n')[1].split(' ').slice(-1)[0]));
|
||||
const date = new Date();
|
||||
date.setMilliseconds(-(moment.duration(os.uptime(), 's').asMilliseconds()));
|
||||
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('System Information & Statistics');
|
||||
embed.addField('Hostname', os.hostname(), true);
|
||||
embed.addField('Uptime', `${moment.duration(os.uptime(), 's').humanize()} | Last restart was on ${moment(date).format('dddd, MMMM Do YYYY, h:mm:ss A')} EST`, true);
|
||||
embed.addField('CPU', `${os.cpus()[0].model} ${os.cpus()[0].speed / 1000}GHz | ${os.cpus().length} Cores | ${os.arch()}`, true);
|
||||
embed.addField('Load Average (last 15 minutes)', os.loadavg()[2].toFixed(3), true);
|
||||
embed.addField('Memory/RAM', `${usedMemory} / ${dataConversion(totalmem())}`, true);
|
||||
embed.addField('Memory/RAM', `${usedMemory} / ${dataConversion(os.totalmem())}`, true);
|
||||
embed.addField('Network Interfaces (IPv4)', os.networkInterfaces().enp0s3.filter((r) => r.family === 'IPv4')[0].address, true);
|
||||
// embed.addField('Network Interfaces (IPv6)', os.networkInterfaces().enp0s3.filter((r) => r.family === 'IPv6')[0].address.replace(/:/gi, '\:'), true); // eslint-disable-line
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
message.channel.createMessage({ embed });
|
||||
message.channel.send({ embeds: [embed] });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
import SystemD_Linger from './systemd_linger';
|
||||
import SystemD_Status from './systemd_status';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable consistent-return */
|
||||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class SystemdD_Linger extends Command {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class SystemD_Restart extends Command {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class SystemD_Start extends Command {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Message } from 'eris';
|
||||
import { Client, Command, RichEmbed } from '../class';
|
||||
import { Message, MessageEmbed } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class SystemD_Status extends Command {
|
||||
constructor(client: Client) {
|
||||
|
@ -22,12 +22,12 @@ export default class SystemD_Status extends Command {
|
|||
if (err.toString().includes('could not be found')) return this.error(message.channel, 'The service name you provided doesn\'t exist.');
|
||||
return this.error(message.channel, err.toString());
|
||||
}
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle(`SystemD Status | ${args[0]}`);
|
||||
embed.setDescription(`\`\`\`sh\n${cmd}\n\`\`\``);
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
return message.channel.createMessage({ embed });
|
||||
return message.channel.send({ embeds: [embed] });
|
||||
} catch (err) {
|
||||
return this.client.util.handleError(err, message, this);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class SystemD_Stop extends Command {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Message } from 'eris';
|
||||
import { Client, Command, RichEmbed } from '../class';
|
||||
import { Message, MessageEmbed, TextChannel } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Tier extends Command {
|
||||
constructor(client: Client) {
|
||||
|
@ -28,16 +28,18 @@ export default class Tier extends Command {
|
|||
await account.updateOne({ $set: { tier: Number(args[1]) } });
|
||||
}
|
||||
edit.edit(`***${this.client.stores.emojis.success} Tier for ${account.username} has been changed to ${args[1]}.***`);
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Cloud Account | Tier Change');
|
||||
embed.setColor('#0099ff');
|
||||
embed.addField('User', `${account.username} | <@${account.userID}>`, true);
|
||||
embed.addField('Technician', `<@${message.author.id}>`, true);
|
||||
embed.addField('Technician', message.author.toString(), true);
|
||||
embed.addField('Old Tier -> New Tier', `${account.tier} -> ${args[1]}`, true);
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
await this.client.util.sendMessageToUserTerminal(account.username, `A technician has changed your tier to ${args[1]}`).catch(() => { });
|
||||
this.client.createMessage('580950455581147146', { embed }); return this.client.getDMChannel(account.userID).then((channel) => channel.createMessage({ embed })).catch();
|
||||
const ch = this.client.channels.cache.get('580950455581147146') as TextChannel;
|
||||
ch.send({ embeds: [embed] });
|
||||
return this.client.users.fetch(account.userID).then((u) => u.send({ embeds: [embed] })).catch();
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Unban extends Command {
|
||||
|
@ -16,7 +16,7 @@ export default class Unban extends Command {
|
|||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (!args[1]) return this.client.commands.get('help').run(message, [this.name]);
|
||||
const msg = await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Unbanning IP...***`);
|
||||
const msg = await message.channel.send(`${this.client.stores.emojis.loading} ***Unbanning IP...***`);
|
||||
try {
|
||||
await this.client.util.exec(`sudo fail2ban-client set ${args[0]} unbanip ${args[1]}`);
|
||||
} catch (error) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Unlock extends Command {
|
||||
|
@ -21,7 +21,7 @@ export default class Unlock extends Command {
|
|||
await this.client.util.exec(`unlock ${account.username}`);
|
||||
await account.updateOne({ locked: false });
|
||||
|
||||
await this.client.util.createModerationLog(account.userID, message.member, 3, args.slice(1).join(' '));
|
||||
await this.client.util.createModerationLog(account.userID, message.author, 3, args.slice(1).join(' '));
|
||||
message.delete();
|
||||
edit.edit(`***${this.client.stores.emojis.success} Account ${account.username} has been unlocked by Technician ${message.author.username}#${message.author.discriminator}.***`);
|
||||
} catch (error) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* eslint-disable no-await-in-loop */
|
||||
import { Message } from 'eris';
|
||||
import { createPaginationEmbed } from 'eris-pagination';
|
||||
import { Client, Command, RichEmbed } from '../class';
|
||||
import { Message, MessageEmbed } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Users extends Command {
|
||||
constructor(client: Client) {
|
||||
|
@ -47,10 +46,10 @@ export default class Users extends Command {
|
|||
const data = this.client.util.splitFields(embedFields);
|
||||
|
||||
const embeds = data.map((l) => {
|
||||
const embed = new RichEmbed();
|
||||
embed.setAuthor('Library of Code | Cloud Services', this.client.user.avatarURL, 'https://libraryofcode.org/');
|
||||
const embed = new MessageEmbed();
|
||||
embed.setAuthor('Library of Code | Cloud Services', this.client.user.avatarURL(), 'https://libraryofcode.org/');
|
||||
embed.setTitle('Cloud Accounts');
|
||||
embed.setFooter(`Requested by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL);
|
||||
embed.setFooter(`Requested by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL());
|
||||
l.forEach((f) => embed.addField(f.name, f.value, true));
|
||||
embed.setTimestamp();
|
||||
embed.setColor(3447003);
|
||||
|
@ -58,10 +57,10 @@ export default class Users extends Command {
|
|||
});
|
||||
|
||||
if (embeds.length === 1) {
|
||||
msg.edit({ content: '', embed: embeds[0] });
|
||||
msg.edit({ content: '', embeds: [embeds[0]] });
|
||||
} else {
|
||||
msg.delete();
|
||||
createPaginationEmbed(message, embeds, {});
|
||||
this.client.util.createPaginationEmbed(message, embeds);
|
||||
}
|
||||
return msg;
|
||||
} catch (error) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from 'eris';
|
||||
import { Message } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Warn extends Command {
|
||||
|
@ -18,7 +18,7 @@ export default class Warn extends Command {
|
|||
const account = await this.client.db.Account.findOne({ $or: [{ username: args[0] }, { userID: args[0].replace(/[<@!>]/gi, '') }] });
|
||||
if (!account) return edit.edit(`***${this.client.stores.emojis.error} Cannot find user.***`);
|
||||
if (account.root) return edit.edit(`***${this.client.stores.emojis.error} Permission denied.***`);
|
||||
await this.client.util.createModerationLog(account.userID, message.member, 1, args.slice(1).join(' '));
|
||||
await this.client.util.createModerationLog(account.userID, message.author, 1, args.slice(1).join(' '));
|
||||
message.delete();
|
||||
edit.edit(`***${this.client.stores.emojis.success} Account ${account.username} has been warned by Technician ${message.author.username}#${message.author.discriminator}.***`);
|
||||
await this.client.util.sendMessageToUserTerminal(account.username, `WARNING FROM TECHNICIAN: ${args.slice(1).join(' ')}`).catch(() => { });
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import moment from 'moment';
|
||||
import { Message, GuildTextableChannel, Member, Role } from 'eris';
|
||||
import { Client, Command, Report, RichEmbed } from '../class';
|
||||
import { Message, TextChannel, Role, MessageEmbed, GuildMember } from 'discord.js';
|
||||
import { Client, Command } from '../class';
|
||||
import { dataConversion } from '../functions';
|
||||
import { AccountInterface } from '../models';
|
||||
|
||||
|
@ -16,22 +16,26 @@ export default class Whois extends Command {
|
|||
|
||||
public fullRoles = ['662163685439045632', '701454780828221450'];
|
||||
|
||||
public IP_REGEX = /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/g
|
||||
public IP_REGEX = /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/g;
|
||||
|
||||
public async run(message: Message<GuildTextableChannel>, args: string[]) {
|
||||
public IP_V4_REGEX = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/
|
||||
|
||||
public IP_V6_REGEX = /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/
|
||||
|
||||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
let full = false;
|
||||
let account: AccountInterface;
|
||||
if (args[1] === '--full' && this.fullRoles.some((r) => message.member.roles.includes(r) || message.author.id === '554168666938277889')) full = true;
|
||||
if (args[1] === '--full' && this.fullRoles.some((r) => message.member.roles.cache.has(r) || message.author.id === '554168666938277889')) full = true;
|
||||
|
||||
const user = args[0] || message.author.id;
|
||||
if (full) account = await this.client.db.Account.findOne({ $or: [{ username: user }, { userID: user }, { emailAddress: user }, { supportKey: user.toUpperCase() }, { referralCode: args[0] }] });
|
||||
else account = await this.client.db.Account.findOne({ $or: [{ username: user }, { userID: user }] });
|
||||
if (!account) return this.error(message.channel, 'Account not found.');
|
||||
if (!account) return this.error(message.channel as TextChannel, 'Account not found.');
|
||||
|
||||
const thumbnail = this.client.users.get(account.userID)?.avatarURL || message.channel.guild.iconURL;
|
||||
const thumbnail = (await this.client.users.fetch(account.userID))?.avatarURL() || message.guild.iconURL();
|
||||
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Account Information');
|
||||
embed.setThumbnail(thumbnail);
|
||||
if (full) await this.full(account, embed, message.member);
|
||||
|
@ -43,18 +47,18 @@ export default class Whois extends Command {
|
|||
switch (true) {
|
||||
case account.permissions.director:
|
||||
details += 'This account belongs to a Director.\n';
|
||||
role = message.member.guild.roles.get('662163685439045632');
|
||||
role = await message.member.guild.roles.fetch('662163685439045632');
|
||||
break;
|
||||
case account.permissions.technician:
|
||||
details += 'This account belongs to a Technician.\n';
|
||||
role = message.member.guild.roles.get('701454780828221450');
|
||||
role = await message.member.guild.roles.fetch('701454780828221450');
|
||||
break;
|
||||
case account.permissions.staff:
|
||||
details += 'This account belongs to a Staff member.\n';
|
||||
role = message.member.guild.roles.get('453689940140883988');
|
||||
role = await message.member.guild.roles.fetch('453689940140883988');
|
||||
break;
|
||||
default:
|
||||
role = message.member.guild.roles.get(message.member.guild.id);
|
||||
role = await message.member.guild.roles.fetch(message.member.guild.id);
|
||||
break;
|
||||
}
|
||||
if (account.root) details += '**This account has root/administrative privileges.**\n';
|
||||
|
@ -62,13 +66,13 @@ export default class Whois extends Command {
|
|||
if (details) embed.addField('Additional Details', details, true);
|
||||
|
||||
embed.setTimestamp();
|
||||
return message.channel.createMessage({ embed });
|
||||
return message.channel.send({ embeds: [embed] });
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
}
|
||||
|
||||
public async full(account: AccountInterface, embed: RichEmbed, member: Member) {
|
||||
public async full(account: AccountInterface, embed: MessageEmbed, member: GuildMember) {
|
||||
const [cpuUsage, data, fingerInformation, chage, memory] = await Promise.all([
|
||||
this.client.util.exec(`top -b -n 1 -u ${account.username} | awk 'NR>7 { sum += $9; } END { print sum; }'`),
|
||||
this.client.redis.get(`storage-${account.username}`),
|
||||
|
@ -76,7 +80,7 @@ export default class Whois extends Command {
|
|||
this.client.util.exec(`chage -l ${account.username}`),
|
||||
this.client.util.exec(`memory ${account.username}`),
|
||||
]);
|
||||
const finger = !member.roles.includes('662163685439045632') ? fingerInformation.replace(this.IP_REGEX, '[MASKED IP ADDRRESS]') : fingerInformation;
|
||||
const finger = !member.roles.cache.has('662163685439045632') ? fingerInformation.replace(this.IP_REGEX, '[MASKED IP ADDRESS]') : fingerInformation;
|
||||
|
||||
embed.setDescription(`${finger}\n${chage}`);
|
||||
embed.addField('Username', `${account.username} | <@${account.userID}>`, true);
|
||||
|
@ -85,14 +89,16 @@ export default class Whois extends Command {
|
|||
embed.addField('Tier', String(account.tier), true);
|
||||
embed.addField('Support Key', account.supportKey, true);
|
||||
embed.addField('Referral Code & Total', `${account.referralCode} | ${account.totalReferrals}`, true);
|
||||
embed.addField('Created By', this.client.users.get(account.createdBy) ? `<@${this.client.users.get(account.createdBy).id}>` : 'SYSTEM', true);
|
||||
embed.addField('Created By', await this.client.users.fetch(account.createdBy)
|
||||
? (await this.client.users.fetch(account.createdBy)).toString()
|
||||
: 'SYSTEM', true);
|
||||
embed.addField('Created At', moment(account.createdAt).format('dddd, MMMM Do YYYY, h:mm:ss A'), true);
|
||||
embed.addField('CPU Usage', `${cpuUsage.split('\n')[0] || '0'}%`, true);
|
||||
embed.addField('Memory', dataConversion(Number(memory) * 1000), true);
|
||||
embed.addField('Storage', data ? dataConversion(Number(data)) : 'N/A', true);
|
||||
}
|
||||
|
||||
public async default(account: AccountInterface, embed: RichEmbed) {
|
||||
public async default(account: AccountInterface, embed: MessageEmbed) {
|
||||
const [cpuUsage, data, memory] = await Promise.all([
|
||||
this.client.util.exec(`top -b -n 1 -u ${account.username} | awk 'NR>7 { sum += $9; } END { print sum; }'`),
|
||||
this.client.redis.get(`storage-${account.username}`),
|
||||
|
@ -102,7 +108,9 @@ export default class Whois extends Command {
|
|||
embed.addField('Username', `${account.username} | <@${account.userID}>`, true);
|
||||
embed.addField('ID', account.userID, true);
|
||||
embed.addField('Tier', String(account.tier), true);
|
||||
embed.addField('Created By', this.client.users.get(account.createdBy) ? `<@${this.client.users.get(account.createdBy).id}>` : 'SYSTEM', true);
|
||||
embed.addField('Created By', await this.client.users.fetch(account.createdBy)
|
||||
? (await this.client.users.fetch(account.createdBy)).toString()
|
||||
: 'SYSTEM', true);
|
||||
embed.addField('Created At', moment(account.createdAt).format('dddd, MMMM Do YYYY, h:mm:ss A'), true);
|
||||
embed.addField('CPU Usage', `${cpuUsage.split('\n')[0] || '0'}%`, true);
|
||||
embed.addField('Memory', dataConversion(Number(memory) * 1000), true);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Message, TextChannel } from 'eris';
|
||||
import { Client, Event, RichEmbed } from '../class';
|
||||
import { Message, TextChannel, MessageEmbed } from 'discord.js';
|
||||
import { Client, Event } from '../class';
|
||||
|
||||
export default class extends Event {
|
||||
public client: Client
|
||||
|
@ -10,9 +10,6 @@ export default class extends Event {
|
|||
this.event = 'messageCreate';
|
||||
}
|
||||
|
||||
public info(message: Message) {
|
||||
}
|
||||
|
||||
public async run(message: Message) {
|
||||
try {
|
||||
if (message.author.bot && message.author.id !== '554168666938277889') return;
|
||||
|
@ -28,8 +25,9 @@ export default class extends Event {
|
|||
let hasRolePerms: boolean = false;
|
||||
if (resolved.cmd.permissions.roles) {
|
||||
for (const role of resolved.cmd.permissions.roles) {
|
||||
if (message.member && message.member.roles.includes(role)) {
|
||||
hasRolePerms = true; break;
|
||||
if (message.member && message.member.roles.cache.has(role)) {
|
||||
hasRolePerms = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,9 +35,15 @@ export default class extends Event {
|
|||
hasUserPerms = true;
|
||||
hasRolePerms = true;
|
||||
}
|
||||
if (message.author.id === '554168666938277889') { hasUserPerms = true; hasRolePerms = true; }
|
||||
if (message.author.id === '554168666938277889') {
|
||||
hasUserPerms = true;
|
||||
hasRolePerms = true;
|
||||
}
|
||||
if (!hasRolePerms && !hasUserPerms) return;
|
||||
if (!resolved.cmd.enabled) { message.channel.createMessage(`***${this.client.stores.emojis.error} This command has been disabled***`); return; }
|
||||
if (!resolved.cmd.enabled) {
|
||||
message.channel.send(`***${this.client.stores.emojis.error} This command has been disabled***`);
|
||||
return;
|
||||
}
|
||||
await resolved.cmd.run(message, resolved.args);
|
||||
} catch (error) {
|
||||
this.client.util.handleError(error, message);
|
||||
|
|
|
@ -1,60 +1,62 @@
|
|||
/* eslint-disable no-await-in-loop */
|
||||
import { Client, RichEmbed } from '../class';
|
||||
import { MessageEmbed, TextChannel } from 'discord.js';
|
||||
import { Client } from '../class';
|
||||
|
||||
export default function checkStaffStatus(client: Client) {
|
||||
setInterval(async () => {
|
||||
const accounts = await client.db.Account.find();
|
||||
for (const acc of accounts) {
|
||||
const tier3 = await client.db.Tier.findOne({ id: 3 });
|
||||
|
||||
let user = client.guilds.get('446067825673633794').members.get(acc.userID);
|
||||
let user = client.guilds.cache.get('446067825673633794').members.cache.get(acc.userID);
|
||||
try {
|
||||
if (!user) user = await client.guilds.get('446067825673633794').getRESTMember(acc.userID);
|
||||
if (!user) user = await client.guilds.cache.get('446067825673633794').members.fetch(acc.userID);
|
||||
} catch (error) {
|
||||
continue; // eslint-disable-line no-continue
|
||||
}
|
||||
if (!acc.permissions.director && user.roles.includes('662163685439045632')) {
|
||||
|
||||
if (!acc.permissions.director && user.roles.cache.has('662163685439045632')) {
|
||||
await client.db.Account.updateOne({ username: acc.username }, { $set: { 'permissions.director': true } });
|
||||
if (acc.ramLimitNotification !== -1) {
|
||||
await client.db.Account.updateOne({ username: acc.username }, { $set: { ramLimitNotification: tier3.resourceLimits.ram - 20 } });
|
||||
}
|
||||
}
|
||||
if (!acc.permissions.technician && user.roles.includes('701454780828221450')) {
|
||||
if (!acc.permissions.technician && user.roles.cache.has('701454780828221450')) {
|
||||
await client.db.Account.updateOne({ username: acc.username }, { $set: { 'permissions.technician': true } });
|
||||
if (acc.ramLimitNotification !== -1) {
|
||||
await client.db.Account.updateOne({ username: acc.username }, { $set: { ramLimitNotification: tier3.resourceLimits.ram - 20 } });
|
||||
}
|
||||
}
|
||||
if (!acc.permissions.staff && user.roles.includes('446104438969466890')) {
|
||||
if (!acc.permissions.staff && user.roles.cache.has('446104438969466890')) {
|
||||
await client.db.Account.updateOne({ username: acc.username }, { $set: { 'permissions.staff': true } });
|
||||
if (acc.ramLimitNotification !== -1) {
|
||||
await client.db.Account.updateOne({ username: acc.username }, { $set: { ramLimitNotification: tier3.resourceLimits.ram - 20 } });
|
||||
}
|
||||
}
|
||||
|
||||
if (acc.permissions.director && !user.roles.includes('662163685439045632')) {
|
||||
if (acc.permissions.director && !user.roles.cache.has('662163685439045632')) {
|
||||
await client.db.Account.updateOne({ username: acc.username }, { $set: { 'permissions.director': false } });
|
||||
}
|
||||
if (acc.permissions.technician && !user.roles.includes('701454780828221450')) {
|
||||
if (acc.permissions.technician && !user.roles.cache.has('701454780828221450')) {
|
||||
await client.db.Account.updateOne({ username: acc.username }, { $set: { 'permissions.technician': false } });
|
||||
}
|
||||
if (acc.permissions.staff && !user.roles.includes('446104438969466890')) {
|
||||
if (acc.permissions.staff && !user.roles.cache.has('446104438969466890')) {
|
||||
await client.db.Account.updateOne({ username: acc.username }, { $set: { 'permissions.staff': false } });
|
||||
}
|
||||
|
||||
if (acc.permissions.staff && acc.tier < 3) {
|
||||
await client.db.Account.updateOne({ username: acc.username }, { $set: { tier: 3 } });
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Cloud Account | Tier Change');
|
||||
embed.setColor('#0099ff');
|
||||
embed.addField('User', `${acc.username} | <@${acc.userID}>`, true);
|
||||
embed.addField('Moderator', `<@${client.user.id}>`, true);
|
||||
embed.addField('Moderator', client.user.toString(), true);
|
||||
embed.addField('Old Tier -> New Tier', `${acc.tier} -> 3`, true);
|
||||
embed.setFooter(client.user.username, client.user.avatarURL);
|
||||
embed.setFooter(client.user.username, client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
client.createMessage('580950455581147146', { embed });
|
||||
client.getDMChannel(acc.userID).then((chan) => {
|
||||
chan.createMessage('***Your account has automatically been upgraded to Tier 3 since you are a Staff member.***');
|
||||
const ch = await client.channels.fetch('580950455581147146') as TextChannel;
|
||||
ch.send({ embeds: [embed] });
|
||||
client.users.fetch(acc.userID).then((chan) => {
|
||||
chan.send('***Your account has automatically been upgraded to Tier 3 since you are a Staff member.***');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
/* eslint-disable no-useless-escape */
|
||||
/* eslint-disable no-continue */
|
||||
/* eslint-disable no-await-in-loop */
|
||||
import { Client, RichEmbed } from '../class';
|
||||
import { MessageEmbed, TextChannel } from 'discord.js';
|
||||
import { Client } from '../class';
|
||||
import { Tiers } from '../models';
|
||||
|
||||
const channelID = '691824484230889546';
|
||||
|
@ -32,15 +33,16 @@ export default function memory(client: Client) {
|
|||
client.signale.info(`RAM Hard Limit Reached | ${acc.username} | ${memoryConversion}/${userLimits.hard} MB`);
|
||||
await client.util.sendMessageToUserTerminal(acc.username, 'REACHED RAM LIMIT; SENDING KILL SIGNAL');
|
||||
client.util.exec(`killall -9 -u ${acc.username}`);
|
||||
const embed = new RichEmbed();
|
||||
const embed = new MessageEmbed();
|
||||
embed.setTitle('Resource Enforcement Notification');
|
||||
embed.setDescription('Someone has reached the (hard) resource limit for their tier on RAM. The system has automatically killed all of their processes.');
|
||||
embed.addField('User', `${acc.username} | <@${acc.userID}> | ${acc.userID}`, true);
|
||||
embed.addField('Tier', String(acc.tier), true);
|
||||
embed.addField('Memory Usage', `${String(memoryConversion)} MB`, true);
|
||||
embed.addField('Memory Limit', `${String(userLimits.hard)} MB`, true);
|
||||
client.createMessage(channelID, { embed });
|
||||
client.util.createModerationLog(acc.userID, client.guilds.get('446067825673633794').members.get(client.user.id), 1, `You have exceeded your resource limit of '${String(userLimits.hard)} MB'. Any process running on your user account has been sent a STOP/KILL signal. If you have any questions, please contact a Technician.`);
|
||||
const ch = client.channels.cache.get(channelID) as TextChannel;
|
||||
ch.send({ embeds: [embed] });
|
||||
client.util.createModerationLog(acc.userID, (await (await client.guilds.fetch('446067825673633794')).members.fetch(client.user.id)).user, 1, `You have exceeded your resource limit of '${String(userLimits.hard)} MB'. Any process running on your user account has been sent a STOP/KILL signal. If you have any questions, please contact a Technician.`);
|
||||
client.util.transport.sendMail({
|
||||
to: acc.emailAddress,
|
||||
from: 'Library of Code sp-us | Cloud Services <help@libraryofcode.org>',
|
||||
|
@ -54,34 +56,36 @@ export default function memory(client: Client) {
|
|||
<b><i>Library of Code sp-us | Support Team</i></b>
|
||||
`,
|
||||
});
|
||||
client.createMessage(channelID, { embed });
|
||||
ch.send({ embeds: [embed] });
|
||||
set.delete(acc.username);
|
||||
} else if ((memoryConversion >= userLimits.soft) && !set.has(acc.username)) {
|
||||
client.signale.info(`RAM Soft Limit Reached | ${acc.username} | ${memoryConversion}/${userLimits.soft} MB`);
|
||||
const embed = new RichEmbed();
|
||||
if (client.users.get(acc.userID)) embed.setThumbnail(client.users.get(acc.userID).avatarURL);
|
||||
const embed = new MessageEmbed();
|
||||
const user = await client.users.fetch(acc.userID);
|
||||
if (user) embed.setThumbnail(user.avatarURL());
|
||||
embed.setTitle('Resource Limit Notification');
|
||||
embed.setDescription('Someone has reached the (soft) resource limit for their tier on RAM.');
|
||||
embed.addField('User', `${acc.username} | <@${acc.userID}> | ${acc.userID}`, true);
|
||||
embed.addField('Tier', String(acc.tier), true);
|
||||
embed.addField('Memory Usage', `${String(memoryConversion)} MB`, true);
|
||||
embed.addField('Memory Limit', `${String(userLimits.hard)} MB`, true);
|
||||
embed.setFooter(client.user.username, client.user.avatarURL);
|
||||
embed.setFooter(client.user.username, client.user.avatarURL());
|
||||
embed.setTimestamp();
|
||||
if (acc.ramLimitNotification !== 0) {
|
||||
await client.createMessage(channelID, { embed });
|
||||
const ch = client.channels.cache.get(channelID) as TextChannel;
|
||||
await ch.send({ embeds: [embed] });
|
||||
}
|
||||
if ((memoryConversion >= acc.ramLimitNotification) && (acc.ramLimitNotification !== 0)) {
|
||||
const notifyEmbed = new RichEmbed()
|
||||
const notifyEmbed = new MessageEmbed()
|
||||
.setTitle('Cloud Account | Notification')
|
||||
.setDescription(`You are about to reach your RAM resource limits, you are currently using '${String(Math.round(memoryConversion))} MB' and your limit is '${String(userLimits.hard)} MB'. Please correct your usage to avoid further action.`)
|
||||
.addField('User', `${acc.username} | <@${acc.userID}>`, true)
|
||||
.addField('Technician', 'SYSTEM', true)
|
||||
.addField('Additional Information', 'This notification was sent by the system. You can set your notification preferences by running \`=limits set-ram-notification <preferred ram threshold in MB>\`, you can disable these notifications by running \`=limits set-ram-notification -1\`.')
|
||||
.setFooter(client.user.username, client.user.avatarURL)
|
||||
.setFooter(client.user.username, client.user.avatarURL())
|
||||
.setTimestamp();
|
||||
client.getDMChannel(acc.userID).then((channel) => {
|
||||
channel.createMessage({ embed: notifyEmbed });
|
||||
client.users.fetch(acc.userID).then((u) => {
|
||||
u.send({ embeds: [notifyEmbed] });
|
||||
});
|
||||
await client.util.sendMessageToUserTerminal(acc.username, `You are about to reach your RAM resource limits, you are currently using '${String(Math.round(memoryConversion))} MB' and your limit is '${String(userLimits.hard)} MB'. Please correct your usage to avoid further action.`).catch(() => { });
|
||||
client.util.transport.sendMail({
|
||||
|
@ -96,7 +100,8 @@ export default function memory(client: Client) {
|
|||
<b><i>Library of Code sp-us | Support Team</i></b>
|
||||
`,
|
||||
});
|
||||
client.createMessage('580950455581147146', { embed: notifyEmbed });
|
||||
const channel = client.channels.cache.get('580950455581147146') as TextChannel;
|
||||
channel.send({ embeds: [notifyEmbed] });
|
||||
}
|
||||
set.add(acc.username);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* eslint-disable no-await-in-loop */
|
||||
/* eslint-disable no-unreachable */
|
||||
// import fs from 'fs-extra';
|
||||
import { spawn } from 'child_process';
|
||||
import { Client } from '../class';
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
/* Basic Options */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"target": "ES2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
|
||||
"target": "ES2019", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
|
||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
||||
"lib": ["ES2019.Object", "ES2020.Promise"], /* Specify library files to be included in the compilation. */
|
||||
"lib": [
|
||||
"ES2019.Object",
|
||||
"ES2020.Promise"
|
||||
], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
|
@ -21,43 +23,37 @@
|
|||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": false, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
"skipLibCheck": true,
|
||||
"noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
"strictNullChecks": false, /* Enable strict null checks. */
|
||||
"strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
"strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||
"strictPropertyInitialization": false, /* Enable strict checking of property initialization in classes. */
|
||||
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
|
||||
/* Module Resolution Options */
|
||||
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
"resolveJsonModule": true,
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
"typeRoots": ["./types"], /* List of folders to include type definitions from. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
"skipLibCheck": true, /* Skips type-checking the installed libraries in node_modules. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
"preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
import { EmbedOptions } from 'eris';
|
||||
import RichEmbed from '../src/class/RichEmbed';
|
||||
|
||||
declare global {
|
||||
namespace Eris {
|
||||
type MessageContent = string | { content?: string; tts?: boolean; disableEveryone?: boolean; embed?: EmbedOptions | RichEmbed; flags?: number };
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue