forked from engineering/cloudservices
rewrite all commands
parent
9d38a8bec7
commit
af7fbffe6b
|
@ -16,7 +16,7 @@ export default class Announce extends Command {
|
|||
public async run(message: Message, args?: string[]) {
|
||||
try {
|
||||
if (!args.length) return this.client.commands.get('help').run(message, [this.name]);
|
||||
const notification = await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Sending announcement, please wait...***`);
|
||||
const notification = await this.loading(message.channel, 'Sending announcement, please wait...');
|
||||
if (args[0] === '-e') await this.client.util.exec(`echo "\n\n**************************************************************************\nEMERGENCY SYSTEM BROADCAST MESSAGE | Library of Code sp-us (root enforced)\n--------------------------------------------------------------------------\n\n\n${args.slice(1).join(' ').trim()}\n\n\n\n\n\n\n\n\n\n\n\n\n" | wall -n`);
|
||||
else await this.client.util.exec(`echo "\nSYSTEM BROADCAST MESSAGE | Library of Code sp-us (root enforced)\n\n\n${args.join(' ').trim()}" | wall -n`);
|
||||
message.delete();
|
||||
|
|
|
@ -15,12 +15,12 @@ export default class Bearer extends Command {
|
|||
public async run(message: Message) {
|
||||
try {
|
||||
const account = await this.client.db.Account.findOne({ userID: message.author.id });
|
||||
if (!account) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Account not found***`);
|
||||
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}`);
|
||||
message.channel.createMessage(`***${this.client.stores.emojis.success} Bearer token sent to direct messages.***`);
|
||||
this.error(message.channel, 'Bearer token sent to direct messages.');
|
||||
return setTimeout(() => {
|
||||
msg.delete();
|
||||
}, 60000);
|
||||
|
|
|
@ -18,13 +18,13 @@ export default class Cloudflare extends Command {
|
|||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (!args.length) return this.client.commands.get('help').run(message, ['cloudflare']);
|
||||
const msg = await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Locating entry...***`);
|
||||
const msg = await this.loading(message.channel, 'Locating entry...');
|
||||
const { data } = await axios({
|
||||
method: 'get',
|
||||
url: `https://api.cloudflare.com/client/v4/zones/5e82fc3111ed4fbf9f58caa34f7553a7/dns_records?name=${args[0]}`,
|
||||
headers: { Authorization: `Bearer ${this.client.config.cloudflare}` },
|
||||
});
|
||||
if (!data.result.length) return msg.edit(`${this.client.stores.emojis.error} ***Entry not found***`);
|
||||
if (!data.result.length) return msg.edit(`${this.client.stores.emojis.error} ***Entry not found.***`);
|
||||
msg.edit(`${this.client.stores.emojis.success} ***Located entry***\n${this.client.stores.emojis.loading} ***Deleting entry...***`);
|
||||
const { id }: { id: string } = data.result[0];
|
||||
await axios({
|
||||
|
|
|
@ -23,19 +23,19 @@ export default class CreateAccount extends Command {
|
|||
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 message.channel.createMessage(`${this.client.stores.emojis.error} ***User not found.***`);
|
||||
if (message.channel.guild.members.get(args[0]).bot) return message.channel.createMessage(`${this.client.stores.emojis.error} ***I cannot create accounts for bots.***`);
|
||||
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 checkUser = await this.client.db.Account.findOne({ userID: args[0] });
|
||||
if (checkUser) return message.channel.createMessage(`${this.client.stores.emojis.error} ***<@${args[0]}> already has an account.***`);
|
||||
if (checkUser) return this.error(message.channel, `<@${args[0]}> already has an account.`);
|
||||
const checkEmail = await this.client.db.Account.findOne({ emailAddress: args[1] });
|
||||
if (checkEmail) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Account already exists with this email address.***`);
|
||||
if (checkEmail) return this.error(message.channel, 'Account already exists with this email address.');
|
||||
const checkAccount = await this.client.db.Account.findOne({ username: args[2] });
|
||||
if (checkAccount) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Account already exists with this username.***`);
|
||||
if (checkAccount) return this.error(message.channel, 'Account already exists with this username.');
|
||||
|
||||
if (!this.client.util.isValidEmail(args[1])) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid email address supplied.***`);
|
||||
if (!/^[a-z][-a-z0-9]*$/.test(args[2])) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid username supplied.***`);
|
||||
if (!this.client.util.isValidEmail(args[1])) return this.error(message.channel, 'Invalid email address supplied.');
|
||||
if (!/^[a-z][-a-z0-9]*$/.test(args[2])) return this.error(message.channel, 'Invalid username supplied.');
|
||||
|
||||
const confirmation = await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Creating account...***`);
|
||||
const confirmation = await this.loading(message.channel, 'Creating account...');
|
||||
const data = await this.client.util.accounts.createAccount({ userID: args[0], username: args[2], emailAddress: args[1] }, message.author.id);
|
||||
message.delete();
|
||||
|
||||
|
|
|
@ -32,14 +32,14 @@ export default class CWG_Create extends Command {
|
|||
try {
|
||||
if (!args[2]) return this.client.commands.get('help').run(message, ['cwg', this.name]);
|
||||
|
||||
if (!this.urlRegex.test(args[1])) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid URL***`);
|
||||
if (Number(args[2]) <= 1024 || Number(args[2]) >= 65535) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Port must be greater than 1024 and less than 65535***`);
|
||||
if (!args[1].endsWith('.cloud.libraryofcode.org') && !args[4]) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Certificate Chain and Private Key are required for custom domains***`);
|
||||
if (!this.urlRegex.test(args[1])) return this.error(message.channel, 'Invalid URL supplied.');
|
||||
if (Number(args[2]) <= 1024 || Number(args[2]) >= 65535) return this.error(message.channel, 'Port must be greater than 1024 and less than 65535.');
|
||||
if (!args[1].endsWith('.cloud.libraryofcode.org') && !args[4]) return this.error(message.channel, 'Certificate Chain and Private Key are required for custom domains.');
|
||||
|
||||
const account = await this.client.db.Account.findOne({ $or: [{ username: args[0] }, { userID: args[0] }] });
|
||||
if (!account) return message.channel.createMessage(`${this.client.stores.emojis.error} Cannot locate account, please try again.`);
|
||||
if (!account) return this.error(message.channel, 'Cannot locate account.');
|
||||
|
||||
if (await this.client.db.Domain.exists({ domain: args[1] })) return message.channel.createMessage(`${this.client.stores.emojis.error} ***This domain already exists***`);
|
||||
if (await this.client.db.Domain.exists({ domain: args[1] })) return this.error(message.channel, 'This domain already exists.');
|
||||
|
||||
if (await this.client.db.Domain.exists({ port: Number(args[2]) })) {
|
||||
let answer: Message;
|
||||
|
@ -50,24 +50,24 @@ export default class CWG_Create extends Command {
|
|||
30000, true, ['y', 'n'], (msg) => msg.author.id === message.author.id && msg.channel.id === message.channel.id,
|
||||
);
|
||||
} catch (error) {
|
||||
return message.channel.createMessage(`${this.client.stores.emojis.error} ***Bind request cancelled***`);
|
||||
return this.error(message.channel, 'Bind request cancelled.');
|
||||
}
|
||||
if (answer.content === 'n') return message.channel.createMessage(`${this.client.stores.emojis.error} ***Bind request cancelled***`);
|
||||
if (answer.content === 'n') return this.error(message.channel, 'Bind request cancelled.');
|
||||
}
|
||||
|
||||
const edit = await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Binding domain...***`);
|
||||
const edit = await this.loading(message.channel, 'Binding domain...');
|
||||
|
||||
let certs: { cert?: string, key?: string } = {};
|
||||
if (!args[1].endsWith('.cloud.libraryofcode.org')) {
|
||||
const urls = args.slice(3, 5);
|
||||
if (urls.some((l) => !l.includes('snippets.cloud.libraryofcode.org/raw/'))) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid snippets URL***`);
|
||||
if (urls.some((l) => !l.includes('snippets.cloud.libraryofcode.org/raw/'))) return this.error(message.channel, 'Invalid snippets URL. Make sure to use https://snippets.libraryofcode.org/raw/*.');
|
||||
|
||||
const tasks = urls.map((l) => axios({ method: 'GET', url: l }));
|
||||
const response = await Promise.all(tasks);
|
||||
const certAndPrivateKey: string[] = response.map((r) => r.data);
|
||||
|
||||
if (!this.isValidCertificateChain(certAndPrivateKey[0])) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid Certificate Chain***`);
|
||||
if (!this.isValidPrivateKey(certAndPrivateKey[1])) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid Private Key***`);
|
||||
if (!this.isValidCertificateChain(certAndPrivateKey[0])) return this.error(message.channel, 'The certificate chain provided is invalid.');
|
||||
if (!this.isValidPrivateKey(certAndPrivateKey[1])) return this.error(message.channel, 'The private key provided is invalid.');
|
||||
|
||||
certs = { cert: certAndPrivateKey[0], key: certAndPrivateKey[1] };
|
||||
} else {
|
||||
|
|
|
@ -24,12 +24,12 @@ export default class CWG_Data extends Command {
|
|||
if (!Number.isNaN(Number(args[0]))) {
|
||||
try {
|
||||
await this.client.util.exec(`fuser ${args[0]}/tcp`);
|
||||
return message.channel.createMessage(`***${this.client.stores.emojis.error} The port you provided is being used by a system process.***`);
|
||||
return this.error(message.channel, 'The port you provided is being used by a system process.');
|
||||
} catch (error) {
|
||||
return message.channel.createMessage(`***${this.client.stores.emojis.error} The domain or port you provided could not be found.***`);
|
||||
return this.error(message.channel, 'The domain or port you provided could not be found.');
|
||||
}
|
||||
}
|
||||
return message.channel.createMessage(`***${this.client.stores.emojis.error} The domain or port you provided could not be found.***`);
|
||||
return this.error(message.channel, 'The domain or port you provided could not be found.');
|
||||
}
|
||||
const embeds = dom.map((domain) => {
|
||||
const cert = fs.readFileSync(domain.x509.cert, { encoding: 'utf8' });
|
||||
|
|
|
@ -19,8 +19,8 @@ export default class CWG_Delete extends Command {
|
|||
try {
|
||||
if (!args[0]) return this.client.commands.get('help').run(message, ['cwg', this.name]);
|
||||
const domain = await this.client.db.Domain.findOne({ $or: [{ domain: args[0] }, { port: Number(args[0]) || 0 }] });
|
||||
if (!domain) return message.channel.createMessage(`***${this.client.stores.emojis.error} The domain or port you provided could not be found.***`);
|
||||
const edit = await message.channel.createMessage(`***${this.client.stores.emojis.loading} Deleting domain...***`);
|
||||
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();
|
||||
embed.setTitle('Domain Deletion');
|
||||
embed.addField('Account Username', domain.account.username, true);
|
||||
|
|
|
@ -19,18 +19,18 @@ export default class CWG_UpdateCert extends Command {
|
|||
try {
|
||||
if (!args[2]) return this.client.commands.get('help').run(message, ['cwg', this.name]);
|
||||
const dom = await this.client.db.Domain.findOne({ $or: [{ domain: args[0] }, { port: Number(args[0]) || 0 }] });
|
||||
if (!dom) return message.channel.createMessage(`***${this.client.stores.emojis.error} The domain or port you provided could not be found.***`);
|
||||
if (!dom) return this.error(message.channel, 'The domain or port you provided could not be found.');
|
||||
const { domain, port, x509, account } = dom;
|
||||
const { cert, key } = x509;
|
||||
|
||||
const urls = args.slice(1, 3); // eslint-disable-line
|
||||
if (urls.some((l) => !l.includes('snippets.cloud.libraryofcode.org/raw/'))) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid snippets URL***`);
|
||||
if (urls.some((l) => !l.includes('snippets.cloud.libraryofcode.org/raw/'))) return this.error(message.channel, 'Invalid snippets URL.');
|
||||
const tasks = urls.map((l) => axios({ method: 'GET', url: l }));
|
||||
const response = await Promise.all(tasks);
|
||||
const certAndPrivateKey: string[] = response.map((r) => r.data);
|
||||
|
||||
if (!this.isValidCertificateChain(certAndPrivateKey[0])) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid Certificate Chain***`);
|
||||
if (!this.isValidPrivateKey(certAndPrivateKey[1])) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid Private Key***`);
|
||||
if (!this.isValidCertificateChain(certAndPrivateKey[0])) return this.error(message.channel, 'The certificate chain provided is invalid.');
|
||||
if (!this.isValidPrivateKey(certAndPrivateKey[1])) return this.error(message.channel, 'The private key provided is invalid.');
|
||||
|
||||
const path = `/opt/CloudServices/temp/${account.id}`;
|
||||
const temp = [writeFile(`${path}.chain.crt`, certAndPrivateKey[0]), writeFile(`${path}.key.pem`, certAndPrivateKey[1])];
|
||||
|
@ -38,13 +38,13 @@ export default class CWG_UpdateCert extends Command {
|
|||
await Promise.all(temp);
|
||||
if (!this.isMatchingPair(`${path}.chain.crt`, `${path}.key.pem`)) {
|
||||
await Promise.all(removeFiles);
|
||||
return message.channel.createMessage(`${this.client.stores.emojis.error} ***Certificate and private key do not match***`);
|
||||
return this.error(message.channel, 'The certificate and private key provided do not match');
|
||||
}
|
||||
|
||||
const writeTasks = [writeFile(cert, certAndPrivateKey[0], { encoding: 'utf8' }), writeFile(key, certAndPrivateKey[1], { encoding: 'utf8' }), ...removeFiles];
|
||||
await Promise.all(writeTasks);
|
||||
|
||||
return message.channel.createMessage(`${this.client.stores.emojis.success} ***Updated certificate for ${domain} on port ${port}***`);
|
||||
return this.success(message.channel, `Updated certificate for ${domain} on port ${port}`);
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
import { Message } from 'eris';
|
||||
import moment from 'moment';
|
||||
import { Client } from '..';
|
||||
import { RichEmbed, Command } from '../class';
|
||||
import { dataConversion } from '../functions';
|
||||
import 'moment-precise-range-plugin';
|
||||
|
||||
export default class Disk extends Command {
|
||||
constructor(client: Client) {
|
||||
super(client);
|
||||
this.name = 'disk';
|
||||
this.description = 'Checks the used disk space by a user';
|
||||
this.usage = `${this.client.config.prefix}disk [Username/User ID/Email]`;
|
||||
this.permissions = { roles: ['662163685439045632', '701454780828221450'] };
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (!args[0]) 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.root || args[0].includes('./')) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Permission denied***`);
|
||||
const diskReply = await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Fetching total disk size may up to 10 minutes. This message will edit when the disk size has been located.***`);
|
||||
const start = Date.now();
|
||||
const result = await this.client.util.exec(`du -s ${account.homepath}`);
|
||||
const end = Date.now();
|
||||
const totalTime: string = moment.preciseDiff(start, end);
|
||||
const embed = new RichEmbed();
|
||||
embed.setTitle('Disk Usage');
|
||||
embed.setColor('ff0000');
|
||||
embed.setDescription(result.split(/ +/g)[1]);
|
||||
embed.addField('Result', dataConversion(Number(result.split(/ +/g)[0])), true);
|
||||
embed.addField('Time taken', totalTime, true);
|
||||
embed.setFooter(`Requested by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL);
|
||||
embed.setTimestamp();
|
||||
return diskReply.edit({ content: '', embed });
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ export default class EmailCode extends Command {
|
|||
try {
|
||||
if (!args.length) return this.client.commands.get('help').run(message, [this.name]);
|
||||
const code = randomBytes(5).toString('hex');
|
||||
if (!this.client.util.isValidEmail(args[0])) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid email address supplied.***`);
|
||||
if (!this.client.util.isValidEmail(args[0])) return this.error(message.channel, 'The email address provided is invalid.');
|
||||
this.client.util.transport.sendMail({
|
||||
to: args[0],
|
||||
from: 'Library of Code sp-us | Cloud Services <help@libraryofcode.org>',
|
||||
|
@ -35,7 +35,7 @@ export default class EmailCode extends Command {
|
|||
</body>
|
||||
`,
|
||||
});
|
||||
return message.channel.createMessage(`***${this.client.stores.emojis.success} Code: \`${code}\` | Email Address: ${args[0]}***`);
|
||||
return this.success(message.channel, `Code: \`${code}\` | Email Address: ${args[0]}`);
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ export default class Exec extends Command {
|
|||
try {
|
||||
if (!args.length) return this.client.commands.get('help').run(message, [this.name]);
|
||||
|
||||
const response = await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Executing \`${args.join(' ')}\`***`);
|
||||
const response = await this.loading(message.channel, `***Executing \`${args.join(' ')}\``);
|
||||
let result: string;
|
||||
try {
|
||||
result = await this.client.util.exec(args.join(' '), { cwd: '/opt/CloudServices' });
|
||||
|
|
|
@ -14,16 +14,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 message.channel.createMessage(`***${this.client.stores.emojis.error} You do not have a Cloud Account.***`);
|
||||
if (!account) return this.error(message.channel, '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 message.channel.createMessage(`***${this.client.stores.emojis.error} You cannot set your notification limit to be set to or above your hard limit.***`);
|
||||
if (Number(args[0]) < 0) return message.channel.createMessage(`***${this.client.stores.emojis.error} You cannot set your notification limit to a negative number.***`);
|
||||
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]) === 0) {
|
||||
await account.updateOne({ $set: { ramLimitNotification: 0 } });
|
||||
return message.channel.createMessage(`***${this.client.stores.emojis.success} You have disabled notifications.***`);
|
||||
return this.success(message.channel, 'You have disabled notifications.');
|
||||
}
|
||||
await account.updateOne({ $set: { ramLimitNotification: Number(args[0]) } });
|
||||
return message.channel.createMessage(`***${this.client.stores.emojis.success} You will now receive notifications when you go above ${Number(args[0])} MB.***`);
|
||||
return this.success(message.channel, `You will now receive notifications when you go above ${Number(args[0])} MB.`);
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ export default class Load extends Command {
|
|||
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
|
||||
const allowed = ['config', 'util', 'command'];
|
||||
const type = args[0].toLowerCase();
|
||||
if (!allowed.includes(type)) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid type to (re)load***`);
|
||||
if (!allowed.includes(type)) return this.error(message.channel, 'Invalid type provided to (re)load.');
|
||||
|
||||
const corepath = '/opt/CloudServices/dist';
|
||||
if (type === 'config') {
|
||||
|
@ -33,20 +33,20 @@ export default class Load extends Command {
|
|||
delete require.cache[`${corepath}/commands/${args[1]}.js`];
|
||||
Object.keys(require.cache).filter((path) => path.includes(`${args[1]}_`)).forEach((path) => delete require.cache[path]);
|
||||
const cmdIndex = require('.');
|
||||
let Cmd = cmdIndex[args[1]];
|
||||
if (!Cmd) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Could not find file***`);
|
||||
Cmd = require(`${corepath}/commands/${args[1]}`).default;
|
||||
let cmd = cmdIndex[args[1]];
|
||||
if (!cmd) return this.error(message.channel, 'Could not find file.');
|
||||
cmd = require(`${corepath}/commands/${args[1]}`).default;
|
||||
this.client.commands.remove(args[1]);
|
||||
this.client.loadCommand(Cmd);
|
||||
this.client.loadCommand(cmd);
|
||||
delete require.cache[`${corepath}/commands/index.js`];
|
||||
delete require.cache[`${corepath}/commands/${args[1]}.js`];
|
||||
Object.keys(require.cache).filter((path) => path.includes(`${args[1]}_`)).forEach((path) => delete require.cache[path]);
|
||||
} catch (error) {
|
||||
if (error.message.includes('Cannot find module')) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Could not find file***`);
|
||||
if (error.message.includes('Cannot find module')) return this.error(message.channel, 'Could not find file.');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return message.channel.createMessage(`${this.client.stores.emojis.success} Reloaded ${type}`);
|
||||
return this.success(message.channel, `Reloaded ${type}.`);
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ export default class Lock extends Command {
|
|||
try {
|
||||
if (!args.length) 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].replace(/[<@!>]/gi, '') }] });
|
||||
if (!account) return message.channel.createMessage(`***${this.client.stores.emojis.error} Cannot find user.***`);
|
||||
if (account.locked) return message.channel.createMessage(`***${this.client.stores.emojis.error} This account is already locked.***`);
|
||||
const edit = await message.channel.createMessage(`***${this.client.stores.emojis.loading} Locking account...***`);
|
||||
if (!account) return this.error(message.channel, 'Cannot find user.');
|
||||
if (account.locked) return this.error(message.channel, 'This account is already locked.');
|
||||
const edit = await this.loading(message.channel, 'Locking account...');
|
||||
if (account.username === 'matthew' || account.root) return edit.edit(`***${this.client.stores.emojis.error} Permission denied.***`);
|
||||
await this.client.util.sendMessageToUserTerminal(account.username, 'ACCOUNT LOCKED BY TECHNICIAN | PREPARING TO LOGOUT').catch(() => { });
|
||||
await this.client.util.exec(`lock ${account.username}`);
|
||||
|
|
|
@ -16,7 +16,7 @@ export default class Modlogs extends Command {
|
|||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (!args.length) return this.client.commands.get('help').run(message, [this.name]);
|
||||
const msg: Message = await message.channel.createMessage(`***${this.client.stores.emojis.loading} Locating modlogs...***`);
|
||||
const msg: Message = await this.loading(message.channel, 'Locating modlogs...');
|
||||
const query = await this.client.db.Moderation.find({ $or: [{ username: args.join(' ') }, { userID: args.filter((a) => a)[0].replace(/[<@!>]/g, '') }] });
|
||||
if (!query.length) return msg.edit(`***${this.client.stores.emojis.error} Cannot locate modlogs for ${args.join(' ')}***`);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ export default class Notify extends Command {
|
|||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (!args.length) return this.client.commands.get('help').run(message, [this.name]);
|
||||
const edit = await message.channel.createMessage(`***${this.client.stores.emojis.loading} Sending notification...***`);
|
||||
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()
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
import fs from 'fs-extra';
|
||||
import { parseCert } from '@ghaiklor/x509';
|
||||
import { Message } from 'eris';
|
||||
import { Client } from '..';
|
||||
import { Command, RichEmbed } from '../class';
|
||||
import { parseCertificate, Certificate } from '../functions';
|
||||
|
||||
export default class Parse extends Command {
|
||||
constructor(client: Client) {
|
||||
super(client);
|
||||
this.name = 'parse';
|
||||
this.description = 'Gets information on a user\'s x509 certificate.';
|
||||
this.usage = `${this.client.config.prefix}parse [username || user ID]`;
|
||||
this.permissions = { roles: ['446104438969466890'] };
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
public async run(message: Message, args: string[]) { // eslint-disable-line
|
||||
try {
|
||||
if (!args.length) 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].replace(/[<@!>]/gi, '') }] });
|
||||
if (!account) return message.channel.createMessage(`***${this.client.stores.emojis.error} Cannot find user.***`);
|
||||
let dir: string[];
|
||||
try {
|
||||
dir = await fs.readdir(`${account.homepath}/Validation`);
|
||||
} catch (err) {
|
||||
return message.channel.createMessage(`***${this.client.stores.emojis.error} Cannot locate Validation directory.***`);
|
||||
}
|
||||
if (!dir.length) return message.channel.createMessage(`***${this.client.stores.emojis.error} Cannot locate certificate.***`);
|
||||
let cert: Certificate;
|
||||
try {
|
||||
cert = await parseCertificate(this.client, `${account.homepath}/Validation/${dir[0]}`);
|
||||
} catch (error) {
|
||||
if (error.message.includes('panic: Certificate PEM Encode == nil')) return message.channel.createMessage(`***${this.client.stores.emojis.error} Invalid certificate.***`);
|
||||
}
|
||||
// const cert = parseCert(`${account.homepath}/Validation/${dir[0]}`);
|
||||
const subjectCommonName = cert.subject.commonName || 'Not Specified';
|
||||
const subjectEmailAddress = cert.subject.emailAddress || 'Not Specified';
|
||||
const subjectOrganization = cert.subject.organizationName || 'Not Specified';
|
||||
const subjectOrganizationalUnit = cert.subject.organizationalUnitName || 'Not Specified';
|
||||
const subjectCountry = cert.subject.countryName || 'Not Specified';
|
||||
const issuerCommonName = cert.issuer.commonName || 'Not Specified';
|
||||
const issuerEmailAddress = cert.issuer.emailAddress || 'Not Specified';
|
||||
const issuerOrganization = cert.issuer.organizationName || 'Not Specified';
|
||||
const issuerOrganizationalUnit = cert.issuer.organizationalUnitName || 'Not Specified';
|
||||
const issuerCountry = cert.issuer.countryName || 'Not Specified';
|
||||
const user = this.client.users.get(account.userID) || await this.client.getRESTUser(account.userID);
|
||||
const embed = new RichEmbed();
|
||||
embed.setTitle('Parse x509 Certificate');
|
||||
embed.setDescription(`${account.homepath}/Validation/${dir[0]} | ${account.username} <@${user.id}>`);
|
||||
embed.setColor(3447003);
|
||||
embed.addField('Subject', `**Common Name:** ${subjectCommonName}\n**Email Address:** ${subjectEmailAddress}\n**Organization:** ${subjectOrganization}\n**Organizational Unit:** ${subjectOrganizationalUnit}\n**Country:** ${subjectCountry}`, true);
|
||||
embed.addField('Issuer', `**Common Name:** ${issuerCommonName}\n**Email Address:** ${issuerEmailAddress}\n**Organization:** ${issuerOrganization}\n**Organizational Unit:** ${issuerOrganizationalUnit}\n**Country:** ${issuerCountry}`, true);
|
||||
embed.addField('Serial Number', cert.serial, true);
|
||||
embed.addField('Fingerprint', cert.fingerPrint, true);
|
||||
embed.addField('Signature Algorithm', cert.signatureAlgorithm, true);
|
||||
embed.addField('Public Key Algorithm', cert.publicKeyAlgorithm, true);
|
||||
embed.addField('Key Usage', cert.extensions.keyUsage, true);
|
||||
embed.addField('Extended Key Usage', cert.extensions.extendedKeyUsage.join(', '), true);
|
||||
embed.addField('Policies', cert.extensions.certificatePolicies.join(', '), true);
|
||||
embed.addField('Issued On', new Date(cert.notBefore).toLocaleString('en-us'), true);
|
||||
embed.addField('Expires On', new Date(cert.notAfter).toLocaleString('en-us'), true);
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
|
||||
embed.setTimestamp();
|
||||
message.channel.createMessage({ embed });
|
||||
} catch (error) {
|
||||
await this.client.util.handleError(error, message, this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
import { parseCert } from '@ghaiklor/x509';
|
||||
import { Message } from 'eris';
|
||||
import { readdirSync } from 'fs';
|
||||
import moment from 'moment';
|
||||
import 'moment-precise-range-plugin';
|
||||
import { Client } from '..';
|
||||
import { Command, RichEmbed } from '../class';
|
||||
import { parseCertificate, Certificate } from '../functions';
|
||||
|
||||
export default class Parseall extends Command {
|
||||
constructor(client: Client) {
|
||||
super(client);
|
||||
|
||||
this.name = 'parseall';
|
||||
this.description = 'Displays certificate validation for all accounts';
|
||||
this.usage = `${this.client.config.prefix}parseall`;
|
||||
this.permissions = { roles: ['446104438969466890'] };
|
||||
this.aliases = ['checkcerts', 'verifyall', 'verifycerts'];
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
const msg = await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Loading...***`);
|
||||
const embed = new RichEmbed();
|
||||
embed.setTitle('Certificate Validation');
|
||||
embed.setAuthor(this.client.user.username, this.client.user.avatarURL);
|
||||
embed.setFooter(`Requested by ${message.member.username}#${message.member.discriminator}`, message.member.avatarURL);
|
||||
embed.setTimestamp();
|
||||
const search = await this.client.db.Account.find();
|
||||
|
||||
const files = search.map((acc) => {
|
||||
let certfile: string;
|
||||
try { certfile = readdirSync(`${acc.homepath}/Validation`)[0] } catch (error) { if (error.message.includes('no such file or directory') || error.message.includes('File doesn\'t exist.')) certfile = 'not_found.crt' } // eslint-disable-line
|
||||
return `${acc.homepath}/Validation/${certfile}`;
|
||||
});
|
||||
|
||||
const parsed = await Promise.allSettled(files.map((c) => parseCertificate(this.client, c)));
|
||||
|
||||
const final: string[] = await Promise.all(search.map(async (a) => {
|
||||
const result = parsed[search.findIndex((acc) => acc === a)];
|
||||
if (result.status === 'rejected') {
|
||||
if (result.reason.message.includes('no such file or directory') || result.reason.message.includes('File doesn\'t exist.')) return `${this.client.stores.emojis.error} **${a.username}** Unable to locate certificate`;
|
||||
if (result.reason.message.includes('panic: Certificate PEM Encode == nil')) return `${this.client.stores.emojis.error} **${a.username}** Invalid certificate`;
|
||||
throw result.reason;
|
||||
}
|
||||
const { notAfter } = result.value;
|
||||
const timeObject = moment.preciseDiff(new Date(), notAfter, true);
|
||||
const precise: [number, string][] = [];
|
||||
const timeArray: number[] = Object.values(timeObject).filter((v) => typeof v === 'number');
|
||||
timeArray.forEach((t) => { // eslint-disable-line
|
||||
const index = timeArray.indexOf(t);
|
||||
const measurements = ['yr', 'mo', 'd', 'h', 'm', 's'];
|
||||
precise.push([t, measurements[index]]);
|
||||
});
|
||||
const time = precise.filter((n) => n[0]).map(((v) => v.join(''))).join(', ');
|
||||
|
||||
if (notAfter < new Date()) return `${this.client.stores.emojis.error} **${a.username}** Expired ${time} ago`;
|
||||
return `${this.client.stores.emojis.success} **${a.username}** Expires in ${time}`;
|
||||
}));
|
||||
|
||||
if (final.join('\n').length < 2048) embed.setDescription(final.join('\n'));
|
||||
else {
|
||||
const split = this.client.util.splitString(final.join('\n'), 1024);
|
||||
split.forEach((s) => embed.addField('\u200B', s));
|
||||
}
|
||||
|
||||
return await msg.edit({ content: '', embed });
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,9 +15,9 @@ export default class Pull extends Command {
|
|||
|
||||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (this.client.updating) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Update in progress***`);
|
||||
if (this.client.updating) return this.error(message.channel, 'An update is already in progress.');
|
||||
this.client.updating = true;
|
||||
const updateMessage = await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Fetching latest commit...***`);
|
||||
const updateMessage = await this.loading(message.channel, 'Fetching latest commit...');
|
||||
let pull: string;
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/* eslint-disable consistent-return */
|
||||
import { Message } from 'eris';
|
||||
import { Command } from '../class';
|
||||
import { Client } from '..';
|
||||
|
||||
export default class Reload extends Command {
|
||||
constructor(client: Client) {
|
||||
super(client);
|
||||
this.name = 'reload';
|
||||
this.description = 'Reloads a command.';
|
||||
this.usage = `${this.client.config.prefix}reload [command name]`;
|
||||
this.permissions = { roles: ['525441307037007902'] };
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
public run(message: Message, args: string[]) {
|
||||
if (!args.length) return this.client.commands.get('help').run(message, [this.name]);
|
||||
}
|
||||
}
|
|
@ -18,10 +18,10 @@ export default class ResetPassword extends Command {
|
|||
try {
|
||||
if (!args[0]) 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.root) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Permission denied***`);
|
||||
if (!account) return this.error(message.channel, 'Account not found.');
|
||||
if (account.root) return this.error(message.channel, 'Permission denied.');
|
||||
|
||||
const msg = await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Resetting password for ${account.username}...***`);
|
||||
const msg = await this.loading(message.channel, `Resetting password for ${account.username}...`);
|
||||
const tempPass = this.client.util.randomPassword();
|
||||
await this.client.util.exec(`echo '${account.username}:${tempPass}' | chpasswd && chage -d0 ${account.username}`);
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@ export default class Restart extends Command {
|
|||
|
||||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (this.client.updating && args[0] !== '-f') return message.channel.createMessage(`${this.client.stores.emojis.error} ***Update in progress***`);
|
||||
if (this.client.buildError) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Build error, resolve before restarting. See CI job on Gitlab***`);
|
||||
await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Restarting...***`);
|
||||
if (this.client.updating && args[0] !== '-f') return this.error(message.channel, 'Update in process.');
|
||||
if (this.client.buildError) return this.error(message.channel, 'Build error detected, please resolve before continuing. See CI job on GitLab.');
|
||||
await this.loading(message.channel, 'Restarting...');
|
||||
return process.exit(1);
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
|
|
|
@ -16,10 +16,10 @@ export default class SetLimit_RAM extends Command {
|
|||
try {
|
||||
if (!args[0]) return this.client.commands.get('help').run(message, ['setlimit', this.name]);
|
||||
const tier = await this.client.db.Tier.findOne({ id: Number(args[0]) });
|
||||
if (!tier) return message.channel.createMessage(`***${this.client.stores.emojis.error} Cannot locate that tier.***`);
|
||||
if (Number.isNaN(Number(args[1]))) return message.channel.createMessage(`***${this.client.stores.emojis.error} This is not a valid number.***`);
|
||||
if (!tier) return this.error(message.channel, 'The tier you provided doesn\'t appear to exist.');
|
||||
if (Number.isNaN(Number(args[1]))) return this.error(message.channel, 'Invalid number in limit argument.');
|
||||
await tier.updateOne({ 'resourceLimits.ram': Number(args[1]) });
|
||||
return message.channel.createMessage(`***${this.client.stores.emojis.success} Tier ${tier.id} RAM resource limit set to ${args[1]} MB.***`);
|
||||
return this.success(message.channel, `Tier ${tier.id} RAM resource limit set to ${args[1]} MB.`);
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ export default class SysInfo extends Command {
|
|||
embed.addField('Load Average (last 15 minutes)', os.loadavg()[2].toFixed(3), true);
|
||||
embed.addField('Memory/RAM', `${usedMemory} / ${dataConversion(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.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.setTimestamp();
|
||||
message.channel.createMessage({ embed });
|
||||
|
|
|
@ -15,7 +15,7 @@ export default class Tier extends Command {
|
|||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (!args.length) return this.client.commands.get('help').run(message, [this.name]);
|
||||
const edit = await message.channel.createMessage(`***${this.client.stores.emojis.loading} Editing tier...***`);
|
||||
const edit = await this.loading(message.channel, 'Editing tier...');
|
||||
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.***`);
|
||||
|
|
|
@ -15,9 +15,9 @@ export default class Unlock extends Command {
|
|||
try {
|
||||
if (!args.length) 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].replace(/[<@!>]/gi, '') }] });
|
||||
if (!account) return message.channel.createMessage(`***${this.client.stores.emojis.error} Cannot find user.***`);
|
||||
if (!account.locked) return message.channel.createMessage(`***${this.client.stores.emojis.error} This account is already unlocked.***`);
|
||||
const edit = await message.channel.createMessage(`***${this.client.stores.emojis.loading} Unlocking account...***`);
|
||||
if (!account) return this.error(message.channel, 'Cannot find user.');
|
||||
if (!account.locked) return this.error(message.channel, 'This account is already unlocked.');
|
||||
const edit = await this.loading(message.channel, 'Unlocking account...');
|
||||
if (account.username === 'matthew' || account.root) return edit.edit(`***${this.client.stores.emojis.error} Permission denied.***`);
|
||||
await this.client.util.exec(`unlock ${account.username}`);
|
||||
await account.updateOne({ locked: false });
|
||||
|
|
|
@ -15,7 +15,7 @@ export default class Warn extends Command {
|
|||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (!args.length) return this.client.commands.get('help').run(message, [this.name]);
|
||||
const edit = await message.channel.createMessage(`***${this.client.stores.emojis.loading} Sending warning...***`);
|
||||
const edit = await this.loading(message.channel, 'Processing warning...');
|
||||
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.***`);
|
||||
|
|
|
@ -28,7 +28,7 @@ export default class Whois extends Command {
|
|||
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() }] });
|
||||
else account = await this.client.db.Account.findOne({ $or: [{ username: user }, { userID: user }] });
|
||||
if (!account) return message.channel.createMessage(`***${this.client.stores.emojis.error} Account not found.***`);
|
||||
if (!account) return this.error(message.channel, 'Account not found.');
|
||||
|
||||
const thumbnail = this.client.users.get(account.userID)?.avatarURL || message.channel.guild.iconURL;
|
||||
|
||||
|
|
Loading…
Reference in New Issue