Merge branches 'master' and 'master' of https://gitlab.libraryofcode.us/engineering/cloudservices-rewrite
commit
b1c261cb57
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "cloudservices-rewrite",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"description": "The official LOC Cloud Services system, this is a rewrite of the original version. ",
|
||||
"main": "dist/Client.js",
|
||||
"scripts": {
|
||||
|
@ -16,6 +16,7 @@
|
|||
"eris": "^0.10.1",
|
||||
"eris-pagination": "bsian03/eris-pagination",
|
||||
"fs-extra": "^8.1.0",
|
||||
"ioredis": "^4.14.1",
|
||||
"moment": "^2.24.0",
|
||||
"moment-precise-range-plugin": "^1.3.0",
|
||||
"mongoose": "^5.7.4",
|
||||
|
@ -25,6 +26,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^8.0.0",
|
||||
"@types/ioredis": "^4.0.18",
|
||||
"@types/mongoose": "^5.5.20",
|
||||
"@types/nodemailer": "^6.2.1",
|
||||
"@types/signale": "^1.2.1",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Eris from 'eris';
|
||||
import Redis from 'ioredis';
|
||||
import mongoose from 'mongoose';
|
||||
import signale from 'signale';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import config from './config.json';
|
||||
import { Account, AccountInterface, Moderation, ModerationInterface, Domain, DomainInterface } from './models';
|
||||
import { emojis } from './stores';
|
||||
|
@ -19,6 +19,8 @@ export default class Client extends Eris.Client {
|
|||
|
||||
public db: { Account: mongoose.Model<AccountInterface>; Domain: mongoose.Model<DomainInterface>; Moderation: mongoose.Model<ModerationInterface>; };
|
||||
|
||||
public redis: Redis.Redis;
|
||||
|
||||
public stores: { emojis: { success: string, loading: string, error: string }; };
|
||||
|
||||
public signale: signale.Signale;
|
||||
|
@ -31,6 +33,7 @@ export default class Client extends Eris.Client {
|
|||
this.util = new Util(this);
|
||||
this.commands = new Collection<Command>();
|
||||
this.db = { Account, Domain, Moderation };
|
||||
this.redis = new Redis();
|
||||
this.stores = { emojis };
|
||||
this.signale = signale;
|
||||
this.signale.config({
|
||||
|
@ -82,13 +85,6 @@ export default class Client extends Eris.Client {
|
|||
public async init() {
|
||||
const evtFiles = await fs.readdir('./events/');
|
||||
Object.values(commands).forEach((c: Function) => this.loadCommand(c));
|
||||
/*
|
||||
const commands = await fs.readdir(path.join(__dirname, './commands/'));
|
||||
commands.forEach((command) => {
|
||||
if (command === 'index.js') return;
|
||||
this.loadCommand(`./commands/${command}`);
|
||||
});
|
||||
*/
|
||||
|
||||
evtFiles.forEach((file) => {
|
||||
const eventName = file.split('.')[0];
|
||||
|
@ -105,6 +101,13 @@ export default class Client extends Eris.Client {
|
|||
this.on('ready', () => {
|
||||
this.signale.info(`Connected to Discord as ${this.user.username}#${this.user.discriminator}`);
|
||||
});
|
||||
const intervals = await fs.readdir('./intervals');
|
||||
intervals.forEach((interval) => {
|
||||
// eslint-disable-next-line
|
||||
if (interval === 'index.js') return;
|
||||
require(`./intervals/${interval}`).default(this);
|
||||
this.signale.complete(`Loaded interval ${interval.split('.')[0]}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -232,11 +232,11 @@ export default class Util {
|
|||
let color: string;
|
||||
let archType: string;
|
||||
switch (type) {
|
||||
default: archType = 'Moderator'; embedTitle = 'Cloud Account | Generic'; color = '0892e1'; break;
|
||||
default: archType = 'Staff'; embedTitle = 'Cloud Account | Generic'; color = '0892e1'; break;
|
||||
case 0: archType = 'Administrator'; embedTitle = 'Cloud Account | Create'; color = '00ff00'; break;
|
||||
case 1: archType = 'Moderator'; embedTitle = 'Account Warning | Warn'; color = 'ffff00'; break;
|
||||
case 2: archType = 'Supervisor'; embedTitle = 'Account Infraction | Lock'; color = 'ff6600'; break;
|
||||
case 3: archType = 'Supervisor'; embedTitle = 'Account Reclaim | Unlock'; color = '0099ff'; break;
|
||||
case 1: archType = 'Staff'; embedTitle = 'Account Warning | Warn'; color = 'ffff00'; break;
|
||||
case 2: archType = 'Moderator'; embedTitle = 'Account Infraction | Lock'; color = 'ff6600'; break;
|
||||
case 3: archType = 'Moderator'; embedTitle = 'Account Reclaim | Unlock'; color = '0099ff'; break;
|
||||
case 4: archType = 'Administrator'; embedTitle = 'Cloud Account | Delete'; color = 'ff0000'; break;
|
||||
}
|
||||
const embed = new RichEmbed()
|
||||
|
|
|
@ -9,7 +9,7 @@ export default class Announce extends Command {
|
|||
this.description = 'Sends an announcement to all active terminals';
|
||||
this.usage = `${this.client.config.prefix}announce Hi there! | ${this.client.config.prefix}announce -e EMERGENCY!`;
|
||||
this.aliases = ['ann'];
|
||||
this.permissions = { roles: ['608095934399643649', '521312697896271873'] };
|
||||
this.permissions = { roles: ['475817826251440128', '525441307037007902'] };
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,9 @@ export default class CWG_Delete extends Command {
|
|||
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.***`);
|
||||
// @ts-ignore
|
||||
return message.channel.createMessage({ embed });
|
||||
this.client.createMessage('580950455581147146', { embed });
|
||||
// @ts-ignore
|
||||
return this.client.getDMChannel(domain.account.userID).then((channel) => channel.createMessage({ embed })).catch(() => {});
|
||||
} catch (error) {
|
||||
return this.client.util.handleError(error, message, this);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Message, PrivateChannel } from 'eris';
|
||||
import uuid from 'uuid/v4';
|
||||
import { Command, RichEmbed } from '../class';
|
||||
import { Command } from '../class';
|
||||
import { Client } from '..';
|
||||
|
||||
export default class DeleteAccount extends Command {
|
||||
|
|
|
@ -3,6 +3,7 @@ import moment from 'moment';
|
|||
import { Client } from '..';
|
||||
import { RichEmbed, Command } from '../class';
|
||||
import { dataConversion } from '../functions';
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import 'moment-precise-range-plugin';
|
||||
|
||||
export default class Disk extends Command {
|
||||
|
@ -12,7 +13,7 @@ export default class Disk extends Command {
|
|||
this.description = 'Checks the used disk space by a user';
|
||||
this.usage = `${this.client.config.prefix}disk [Username/User ID/Email]`;
|
||||
this.permissions = { roles: ['446104438969466890'] };
|
||||
this.enabled = true;
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
async run(message: Message, args: string[]) {
|
||||
|
|
|
@ -8,7 +8,7 @@ export default class Lock extends Command {
|
|||
super(client);
|
||||
this.name = 'lock';
|
||||
this.description = 'Locks an account.';
|
||||
this.permissions = { roles: ['608095934399643649', '521312697896271873'] };
|
||||
this.permissions = { roles: ['455972169449734144', '643619219988152321'] };
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,13 @@ export default class Parse extends Command {
|
|||
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.***`);
|
||||
const dir = await fs.readdir(`/home/${account.username}/Validation`);
|
||||
let dir: string[];
|
||||
try {
|
||||
dir = await fs.readdir(`/home/${account.username}/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.***`);
|
||||
const cert = parseCert(`/home/${account.username}/Validation/${dir[0]}`);
|
||||
const subjectCommonName = cert.subject.commonName ? cert.subject.commonName : 'Not Specified';
|
||||
const subjectEmailAddress = cert.subject.emailAddress ? cert.subject.emailAddress : 'Not Specified';
|
||||
|
|
|
@ -8,7 +8,7 @@ export default class Unlock extends Command {
|
|||
super(client);
|
||||
this.name = 'unlock';
|
||||
this.description = 'Unlocks an account.';
|
||||
this.permissions = { roles: ['608095934399643649', '521312697896271873'] };
|
||||
this.permissions = { roles: ['455972169449734144', '643619219988152321'] };
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import moment from 'moment';
|
|||
import { Message } from 'eris';
|
||||
import { Client } from '..';
|
||||
import { Command, RichEmbed } from '../class';
|
||||
import { dataConversion } from '../functions';
|
||||
|
||||
export default class Whois extends Command {
|
||||
constructor(client: Client) {
|
||||
|
@ -30,6 +31,11 @@ export default class Whois extends Command {
|
|||
embed.addField('Email Address', account.emailAddress, true);
|
||||
embed.addField('Created By', `<@${this.client.users.get(account.createdBy).id}>`, true);
|
||||
embed.addField('Created At', moment(account.createdAt).format('dddd, MMMM Do YYYY, h:mm:ss A'), true);
|
||||
const cpuUsage = await this.client.util.exec(`top -b -n 1 -u ${account.username} | awk 'NR>7 { sum += $9; } END { print sum; }'`);
|
||||
embed.addField('CPU Usage', cpuUsage.split('\n')[0] ? `${cpuUsage.split('\n')[0]}%` : '0%', true);
|
||||
embed.addField('Memory', dataConversion(Number(await this.client.util.exec(`memory ${account.username}`)) * 1000), true);
|
||||
const data = await this.client.redis.get(`storage-${account.username}`) ? dataConversion(Number(await this.client.redis.get(`storage-${account.username}`))) : 'N/A';
|
||||
embed.addField('Storage', data, true);
|
||||
let details = '';
|
||||
if (account.locked) details += 'This account is currently locked.\n';
|
||||
if (account.permissions.engineer) details += 'This account belongs to an Engineer.\n';
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
export default function dataConversion(bytes: number) {
|
||||
export default function dataConversion(bytes) {
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
||||
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
if (bytes === 0) {
|
||||
return '0 KB';
|
||||
}
|
||||
return `${(bytes / 1024 ** i).toFixed(2)} ${sizes[i]}`;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/* eslint-disable no-await-in-loop */
|
||||
import fs from 'fs-extra';
|
||||
import { Client } from '..';
|
||||
|
||||
export default async function storage(client: Client) {
|
||||
const main = async () => {
|
||||
const accounts = await client.db.Account.find();
|
||||
for (const account of accounts) {
|
||||
const res = await client.util.exec(`du -bs /home/${account.username}`);
|
||||
let bytes = Number(res.split('/')[0].replace('\t', ''));
|
||||
try {
|
||||
await fs.access(`/var/mail/${account.username}`, fs.constants.F_OK);
|
||||
const res2 = await client.util.exec(`du -bs /var/mail/${account.username}`);
|
||||
bytes += Number(res2.split('/')[0].replace('\t', ''));
|
||||
} catch {
|
||||
bytes += 0;
|
||||
}
|
||||
await client.redis.set(`storage-${account.username}`, bytes);
|
||||
}
|
||||
};
|
||||
await main();
|
||||
setInterval(async () => {
|
||||
await main();
|
||||
}, 900000);
|
||||
}
|
Loading…
Reference in New Issue