merge-requests/1/merge
Bsian 2019-11-14 21:02:30 +00:00
commit b1c261cb57
No known key found for this signature in database
GPG Key ID: 097FB9A291026091
13 changed files with 69 additions and 21 deletions

View File

@ -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",

View File

@ -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]}`);
});
}
}

View File

@ -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()

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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 {

View File

@ -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[]) {

View File

@ -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;
}

View File

@ -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';

View File

@ -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;
}

View File

@ -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';

View File

@ -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]}`;
}

25
src/intervals/storage.ts Normal file
View File

@ -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);
}