Compare commits
3 Commits
master
...
refactor/m
Author | SHA1 | Date |
---|---|---|
Hiroyuki | aa3c071c2b | |
Hiroyuki | 6de47a7e0d | |
Hiroyuki | b9d4a28c4f |
|
@ -39,6 +39,7 @@
|
||||||
"import/prefer-default-export": "off",
|
"import/prefer-default-export": "off",
|
||||||
"no-useless-constructor": "off",
|
"no-useless-constructor": "off",
|
||||||
"@typescript-eslint/no-useless-constructor": 2,
|
"@typescript-eslint/no-useless-constructor": 2,
|
||||||
"import/extensions": "off"
|
"import/extensions": "off",
|
||||||
|
"max-classes-per-file": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"eslint.enable": true,
|
|
||||||
"eslint.validate": [
|
|
||||||
{
|
|
||||||
"language": "typescript",
|
|
||||||
"autoFix": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"editor.tabSize": 2
|
|
||||||
}
|
|
|
@ -26,6 +26,7 @@
|
||||||
"mongoose": "^5.7.4",
|
"mongoose": "^5.7.4",
|
||||||
"nodemailer": "^6.3.1",
|
"nodemailer": "^6.3.1",
|
||||||
"signale": "^1.4.0",
|
"signale": "^1.4.0",
|
||||||
|
"@typegoose/typegoose": "^7.6.2",
|
||||||
"uuid": "^3.3.3",
|
"uuid": "^3.3.3",
|
||||||
"x509": "bsian03/node-x509"
|
"x509": "bsian03/node-x509"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import { AccountInterface } from '../models';
|
import { Account } from '../models';
|
||||||
|
|
||||||
export interface Req extends express.Request {
|
export interface Req extends express.Request {
|
||||||
account: AccountInterface
|
account: Account
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { randomBytes } from 'crypto';
|
import { randomBytes } from 'crypto';
|
||||||
import { AccountInterface } from '../models';
|
|
||||||
import { Client } from '..';
|
import { Client } from '..';
|
||||||
|
|
||||||
export default class AccountUtil {
|
export default class AccountUtil {
|
||||||
|
@ -19,7 +18,7 @@ export default class AccountUtil {
|
||||||
* @param data.emailAddress The user's email address.
|
* @param data.emailAddress The user's email address.
|
||||||
* @param moderator The Discord user ID for the Staff member that created the account.
|
* @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 }> {
|
public async createAccount(data: { userID: string, username: string, emailAddress: string }, moderator: string) {
|
||||||
const moderatorMember = this.client.guilds.get('446067825673633794').members.get(moderator);
|
const moderatorMember = this.client.guilds.get('446067825673633794').members.get(moderator);
|
||||||
const tempPass = this.client.util.randomPassword();
|
const tempPass = this.client.util.randomPassword();
|
||||||
let passHash = await this.client.util.createHash(tempPass); passHash = passHash.replace(/[$]/g, '\\$').replace('\n', '');
|
let passHash = await this.client.util.createHash(tempPass); passHash = passHash.replace(/[$]/g, '\\$').replace('\n', '');
|
||||||
|
@ -74,15 +73,15 @@ export default class AccountUtil {
|
||||||
this.client.guilds.get('446067825673633794').members.get(data.userID).addRole('546457886440685578');
|
this.client.guilds.get('446067825673633794').members.get(data.userID).addRole('546457886440685578');
|
||||||
const dmChannel = await this.client.getDMChannel(data.userID).catch();
|
const dmChannel = await this.client.getDMChannel(data.userID).catch();
|
||||||
dmChannel.createMessage('<:loc:607695848612167700> **Thank you for creating an account with us!** <:loc:607695848612167700>\n'
|
dmChannel.createMessage('<: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`
|
+ `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`
|
+ `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'
|
+ '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'
|
||||||
+ 'An email containing some useful information has also been sent.\n'
|
+ 'An email containing some useful information has also been sent.\n'
|
||||||
+ `Your support key is \`${code}\`. Pin this message, you may need this key to contact Library of Code in the future.`).catch();
|
+ `Your support key is \`${code}\`. Pin this message, you may need this key to contact Library of Code in the future.`).catch();
|
||||||
return { account: accountInterface, tempPass };
|
return { account: accountInterface, tempPass };
|
||||||
}
|
}
|
||||||
|
|
||||||
public async lock(username: string, moderatorID: string, data?: { reason?: string, time?: number}) {
|
public async lock(username: string, moderatorID: string, data?: { reason?: string, time?: number }) {
|
||||||
const account = await this.client.db.Account.findOne({ username });
|
const account = await this.client.db.Account.findOne({ username });
|
||||||
if (!account) throw new Error('Account does not exist.');
|
if (!account) throw new Error('Account does not exist.');
|
||||||
if (account.locked) throw new Error('Account is already locked.');
|
if (account.locked) throw new Error('Account is already locked.');
|
||||||
|
|
|
@ -3,10 +3,11 @@ import Redis from 'ioredis';
|
||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import signale from 'signale';
|
import signale from 'signale';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
|
import { getModelForClass } from '@typegoose/typegoose';
|
||||||
import config from '../config.json';
|
import config from '../config.json';
|
||||||
import { Account, AccountInterface, Moderation, ModerationInterface, Domain, DomainInterface, Tier, TierInterface } from '../models';
|
import { Account, Moderation, Domain, Tier } from '../models';
|
||||||
import { emojis } from '../stores';
|
import { emojis } from '../stores';
|
||||||
import { Command, CSCLI, Util, Collection, Server, Event } from '.';
|
import { Command, Util, Collection, Server, Event } from '.';
|
||||||
|
|
||||||
|
|
||||||
export default class Client extends Eris.Client {
|
export default class Client extends Eris.Client {
|
||||||
|
@ -18,7 +19,12 @@ export default class Client extends Eris.Client {
|
||||||
|
|
||||||
public events: Collection<Event>;
|
public events: Collection<Event>;
|
||||||
|
|
||||||
public db: { Account: mongoose.Model<AccountInterface>; Domain: mongoose.Model<DomainInterface>; Moderation: mongoose.Model<ModerationInterface>; Tier: mongoose.Model<TierInterface>; };
|
public db = {
|
||||||
|
Account: getModelForClass(Account),
|
||||||
|
Domain: getModelForClass(Domain),
|
||||||
|
Moderation: getModelForClass(Moderation),
|
||||||
|
Tier: getModelForClass(Tier),
|
||||||
|
}
|
||||||
|
|
||||||
public redis: Redis.Redis;
|
public redis: Redis.Redis;
|
||||||
|
|
||||||
|
@ -43,7 +49,6 @@ export default class Client extends Eris.Client {
|
||||||
this.commands = new Collection<Command>();
|
this.commands = new Collection<Command>();
|
||||||
this.events = new Collection<Event>();
|
this.events = new Collection<Event>();
|
||||||
this.functions = new Collection<Function>();
|
this.functions = new Collection<Function>();
|
||||||
this.db = { Account, Domain, Moderation, Tier };
|
|
||||||
this.redis = new Redis();
|
this.redis = new Redis();
|
||||||
this.stores = { emojis };
|
this.stores = { emojis };
|
||||||
this.signale = signale;
|
this.signale = signale;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
import { Client } from '.';
|
import { Client } from '.';
|
||||||
import { AccountInterface } from '../models';
|
|
||||||
|
|
||||||
export default class Security {
|
export default class Security {
|
||||||
public client: Client;
|
public client: Client;
|
||||||
|
@ -36,7 +35,7 @@ export default class Security {
|
||||||
* If the bearer token is valid, will return the Account, else will return null.
|
* If the bearer token is valid, will return the Account, else will return null.
|
||||||
* @param bearer The bearer token provided.
|
* @param bearer The bearer token provided.
|
||||||
*/
|
*/
|
||||||
public async checkBearer(bearer: string): Promise<null | AccountInterface> {
|
public async checkBearer(bearer: string) {
|
||||||
try {
|
try {
|
||||||
const res: any = jwt.verify(bearer, this.keys.key, { issuer: 'Library of Code sp-us | CSD' });
|
const res: any = jwt.verify(bearer, this.keys.key, { issuer: 'Library of Code sp-us | CSD' });
|
||||||
const account = await this.client.db.Account.findOne({ _id: res.id });
|
const account = await this.client.db.Account.findOne({ _id: res.id });
|
||||||
|
|
|
@ -10,7 +10,6 @@ import moment from 'moment';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { getUserByUid } from '../functions';
|
import { getUserByUid } from '../functions';
|
||||||
import { AccountUtil, Client, Command, RichEmbed } from '.';
|
import { AccountUtil, Client, Command, RichEmbed } from '.';
|
||||||
import { ModerationInterface, AccountInterface, Account } from '../models';
|
|
||||||
|
|
||||||
export default class Util {
|
export default class Util {
|
||||||
public client: Client;
|
public client: Client;
|
||||||
|
@ -36,7 +35,7 @@ export default class Util {
|
||||||
public async exec(command: string, options: childProcess.ExecOptions = {}): Promise<string> {
|
public async exec(command: string, options: childProcess.ExecOptions = {}): Promise<string> {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
let output = '';
|
let output = '';
|
||||||
const writeFunction = (data: string|Buffer|Error) => {
|
const writeFunction = (data: string | Buffer | Error) => {
|
||||||
output += `${data}`;
|
output += `${data}`;
|
||||||
};
|
};
|
||||||
const cmd = childProcess.exec(command, options);
|
const cmd = childProcess.exec(command, options);
|
||||||
|
@ -47,7 +46,7 @@ export default class Util {
|
||||||
cmd.stdout.off('data', writeFunction);
|
cmd.stdout.off('data', writeFunction);
|
||||||
cmd.stderr.off('data', writeFunction);
|
cmd.stderr.off('data', writeFunction);
|
||||||
cmd.off('error', writeFunction);
|
cmd.off('error', writeFunction);
|
||||||
setTimeout(() => {}, 1000);
|
setTimeout(() => { }, 1000);
|
||||||
if (code !== 0) rej(new Error(`Command failed: ${command}\n${output}`));
|
if (code !== 0) rej(new Error(`Command failed: ${command}\n${output}`));
|
||||||
res(output);
|
res(output);
|
||||||
});
|
});
|
||||||
|
@ -99,7 +98,7 @@ export default class Util {
|
||||||
* @param query Command input
|
* @param query Command input
|
||||||
* @param message Only used to check for errors
|
* @param message Only used to check for errors
|
||||||
*/
|
*/
|
||||||
public resolveCommand(query: string | string[], message?: Message): Promise<{cmd: Command, args: string[] }> {
|
public resolveCommand(query: string | string[], message?: Message): Promise<{ cmd: Command, args: string[] }> {
|
||||||
try {
|
try {
|
||||||
let resolvedCommand: Command;
|
let resolvedCommand: Command;
|
||||||
if (typeof query === 'string') query = query.split(' ');
|
if (typeof query === 'string') query = query.split(' ');
|
||||||
|
@ -153,7 +152,7 @@ export default class Util {
|
||||||
|
|
||||||
public splitFields(fields: { name: string, value: string, inline?: boolean }[]): { name: string, value: string, inline?: boolean }[][] {
|
public splitFields(fields: { name: string, value: string, inline?: boolean }[]): { name: string, value: string, inline?: boolean }[][] {
|
||||||
let index = 0;
|
let index = 0;
|
||||||
const array: {name: string, value: string, inline?: boolean}[][] = [[]];
|
const array: { name: string, value: string, inline?: boolean }[][] = [[]];
|
||||||
while (fields.length) {
|
while (fields.length) {
|
||||||
if (array[index].length >= 25) { index += 1; array[index] = []; }
|
if (array[index].length >= 25) { index += 1; array[index] = []; }
|
||||||
array[index].push(fields[0]); fields.shift();
|
array[index].push(fields[0]); fields.shift();
|
||||||
|
@ -198,7 +197,7 @@ export default class Util {
|
||||||
return tempPass;
|
return tempPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createAccount(hash: string, etcPasswd: string, username: string, userID: string, emailAddress: string, moderatorID: string, code: string): Promise<AccountInterface> {
|
public async createAccount(hash: string, etcPasswd: string, username: string, userID: string, emailAddress: string, moderatorID: string, code: string) {
|
||||||
await this.exec(`useradd -m -p ${hash} -c ${etcPasswd} -s /bin/bash ${username}`);
|
await this.exec(`useradd -m -p ${hash} -c ${etcPasswd} -s /bin/bash ${username}`);
|
||||||
await this.exec(`chage -d0 ${username}`);
|
await this.exec(`chage -d0 ${username}`);
|
||||||
const tier = await this.client.db.Tier.findOne({ id: 1 });
|
const tier = await this.client.db.Tier.findOne({ id: 1 });
|
||||||
|
@ -222,7 +221,7 @@ export default class Util {
|
||||||
await Promise.all(tasks);
|
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> {
|
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.createMessage(question);
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
const func = (Msg: Message) => {
|
const func = (Msg: Message) => {
|
||||||
|
@ -250,12 +249,12 @@ export default class Util {
|
||||||
*
|
*
|
||||||
* `4` - Delete
|
* `4` - Delete
|
||||||
*/
|
*/
|
||||||
public async createModerationLog(user: string, moderator: Member|User, type: number, reason?: string, duration?: number): Promise<ModerationInterface> {
|
public async createModerationLog(user: string, moderator: Member | User, type: number, reason?: string, duration?: number) {
|
||||||
const moderatorID = moderator.id;
|
const moderatorID = moderator.id;
|
||||||
const account = await this.client.db.Account.findOne({ $or: [{ username: user }, { userID: user }] });
|
const account = await this.client.db.Account.findOne({ $or: [{ username: user }, { userID: user }] });
|
||||||
if (!account) return Promise.reject(new Error(`Account ${user} not found`));
|
if (!account) return Promise.reject(new Error(`Account ${user} not found`));
|
||||||
const { username, userID } = account;
|
const { username, userID } = account;
|
||||||
const logInput: { username: string, userID: string, logID: string, moderatorID: string, reason?: string, type: number, date: Date, expiration?: { date: Date, processed: boolean }} = {
|
const logInput: { username: string, userID: string, logID: string, moderatorID: string, reason?: string, type: number, date: Date, expiration?: { date: Date, processed: boolean } } = {
|
||||||
username, userID, logID: uuid(), moderatorID, type, date: new Date(),
|
username, userID, logID: uuid(), moderatorID, type, date: new Date(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import fs, { writeFile, unlink } from 'fs-extra';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { randomBytes } from 'crypto';
|
import { randomBytes } from 'crypto';
|
||||||
import { Message } from 'eris';
|
import { Message } from 'eris';
|
||||||
import { AccountInterface } from '../models';
|
import { Account } from '../models';
|
||||||
import { Client, Command, RichEmbed } from '../class';
|
import { Client, Command, RichEmbed } from '../class';
|
||||||
import { parseCertificate } from '../functions';
|
import { parseCertificate } from '../functions';
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ export default class CWG_Create extends Command {
|
||||||
* @param x509Certificate The contents the certificate and key files.
|
* @param x509Certificate The contents the certificate and key files.
|
||||||
* @example await CWG.createDomain(account, 'mydomain.cloud.libraryofcode.org', 6781);
|
* @example await CWG.createDomain(account, 'mydomain.cloud.libraryofcode.org', 6781);
|
||||||
*/
|
*/
|
||||||
public async createDomain(account: AccountInterface, domain: string, port: number, x509Certificate: { cert?: string, key?: string }) {
|
public async createDomain(account: Account, domain: string, port: number, x509Certificate: { cert?: string, key?: string }) {
|
||||||
try {
|
try {
|
||||||
if (port <= 1024 || port >= 65535) throw new RangeError(`Port range must be between 1024 and 65535, received ${port}.`);
|
if (port <= 1024 || port >= 65535) throw new RangeError(`Port range must be between 1024 and 65535, received ${port}.`);
|
||||||
if (await this.client.db.Domain.exists({ domain })) throw new Error(`Domain ${domain} already exists in the database.`);
|
if (await this.client.db.Domain.exists({ domain })) throw new Error(`Domain ${domain} already exists in the database.`);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { Message, GuildTextableChannel, Member, Role } from 'eris';
|
import { Message, GuildTextableChannel, Member, Role } from 'eris';
|
||||||
import { Client, Command, Report, RichEmbed } from '../class';
|
import { Client, Command, RichEmbed } from '../class';
|
||||||
import { dataConversion } from '../functions';
|
import { dataConversion } from '../functions';
|
||||||
import { AccountInterface } from '../models';
|
import { Account } from '../models';
|
||||||
|
|
||||||
export default class Whois extends Command {
|
export default class Whois extends Command {
|
||||||
constructor(client: Client) {
|
constructor(client: Client) {
|
||||||
|
@ -21,7 +21,7 @@ export default class Whois extends Command {
|
||||||
public async run(message: Message<GuildTextableChannel>, args: string[]) {
|
public async run(message: Message<GuildTextableChannel>, args: string[]) {
|
||||||
try {
|
try {
|
||||||
let full = false;
|
let full = false;
|
||||||
let account: AccountInterface;
|
let account: Account;
|
||||||
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.includes(r) || message.author.id === '554168666938277889')) full = true;
|
||||||
|
|
||||||
const user = args[0] || message.author.id;
|
const user = args[0] || message.author.id;
|
||||||
|
@ -68,7 +68,7 @@ export default class Whois extends Command {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async full(account: AccountInterface, embed: RichEmbed, member: Member) {
|
public async full(account: Account, embed: RichEmbed, member: Member) {
|
||||||
const [cpuUsage, data, fingerInformation, chage, memory] = await Promise.all([
|
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.util.exec(`top -b -n 1 -u ${account.username} | awk 'NR>7 { sum += $9; } END { print sum; }'`),
|
||||||
this.client.redis.get(`storage-${account.username}`),
|
this.client.redis.get(`storage-${account.username}`),
|
||||||
|
@ -92,7 +92,7 @@ export default class Whois extends Command {
|
||||||
embed.addField('Storage', data ? dataConversion(Number(data)) : 'N/A', true);
|
embed.addField('Storage', data ? dataConversion(Number(data)) : 'N/A', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async default(account: AccountInterface, embed: RichEmbed) {
|
public async default(account: Account, embed: RichEmbed) {
|
||||||
const [cpuUsage, data, memory] = await Promise.all([
|
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.util.exec(`top -b -n 1 -u ${account.username} | awk 'NR>7 { sum += $9; } END { print sum; }'`),
|
||||||
this.client.redis.get(`storage-${account.username}`),
|
this.client.redis.get(`storage-${account.username}`),
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
/* eslint-disable no-continue */
|
/* eslint-disable no-continue */
|
||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
import { Client, RichEmbed } from '../class';
|
import { Client, RichEmbed } from '../class';
|
||||||
import { Tiers } from '../models';
|
|
||||||
|
|
||||||
const channelID = '691824484230889546';
|
const channelID = '691824484230889546';
|
||||||
|
|
||||||
|
@ -18,8 +17,7 @@ export default function memory(client: Client) {
|
||||||
// memory in megabytes
|
// memory in megabytes
|
||||||
const memoryConversion = mem / 1024 / 1024;
|
const memoryConversion = mem / 1024 / 1024;
|
||||||
const userLimits: { soft?: number, hard?: number } = {};
|
const userLimits: { soft?: number, hard?: number } = {};
|
||||||
// @ts-ignore
|
const tier = await client.db.Tier.findOne({ id: acc.tier }).lean().exec();
|
||||||
const tier: Tiers = await client.db.Tier.findOne({ id: acc.tier }).lean().exec();
|
|
||||||
userLimits.soft = acc.ramLimitNotification;
|
userLimits.soft = acc.ramLimitNotification;
|
||||||
userLimits.hard = tier.resourceLimits.ram;
|
userLimits.hard = tier.resourceLimits.ram;
|
||||||
if ((memoryConversion <= userLimits.soft) && (acc.ramLimitNotification !== 0)) {
|
if ((memoryConversion <= userLimits.soft) && (acc.ramLimitNotification !== 0)) {
|
||||||
|
|
|
@ -1,53 +1,72 @@
|
||||||
import { Document, Schema, model } from 'mongoose';
|
import { modelOptions, prop } from '@typegoose/typegoose';
|
||||||
|
import { Base } from '@typegoose/typegoose/lib/defaultClasses';
|
||||||
|
|
||||||
export interface AccountInterface extends Document {
|
export type Tier = 1 | 2 | 3;
|
||||||
username: string,
|
|
||||||
userID: string,
|
class Permissions {
|
||||||
homepath: string,
|
@prop()
|
||||||
emailAddress: string,
|
staff?: boolean;
|
||||||
createdBy: string,
|
|
||||||
createdAt: Date,
|
@prop()
|
||||||
locked: boolean,
|
technician?: boolean;
|
||||||
tier: number,
|
|
||||||
supportKey: string,
|
@prop()
|
||||||
referralCode: string,
|
director?: boolean;
|
||||||
totalReferrals: number,
|
|
||||||
permissions: {
|
|
||||||
staff: boolean,
|
|
||||||
technician: boolean,
|
|
||||||
director: boolean,
|
|
||||||
},
|
|
||||||
ramLimitNotification: number,
|
|
||||||
root: boolean,
|
|
||||||
hash: boolean,
|
|
||||||
salt: string,
|
|
||||||
authTag: Buffer
|
|
||||||
revokedBearers: string[],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Account = new Schema<AccountInterface>({
|
@modelOptions({ schemaOptions: { collection: 'Account' } })
|
||||||
username: String,
|
export default class Account extends Base {
|
||||||
userID: String,
|
@prop({ required: true, unique: true })
|
||||||
homepath: String,
|
username: string;
|
||||||
emailAddress: String,
|
|
||||||
createdBy: String,
|
|
||||||
createdAt: Date,
|
|
||||||
locked: Boolean,
|
|
||||||
tier: Number,
|
|
||||||
supportKey: String,
|
|
||||||
referralCode: String,
|
|
||||||
totalReferrals: Number,
|
|
||||||
permissions: {
|
|
||||||
staff: Boolean,
|
|
||||||
technician: Boolean,
|
|
||||||
director: Boolean,
|
|
||||||
},
|
|
||||||
ramLimitNotification: Number,
|
|
||||||
root: Boolean,
|
|
||||||
hash: Boolean,
|
|
||||||
salt: String,
|
|
||||||
authTag: Buffer,
|
|
||||||
revokedBearers: Array,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default model<AccountInterface>('Account', Account);
|
@prop({ required: true, unique: true })
|
||||||
|
userID: string;
|
||||||
|
|
||||||
|
@prop({ required: true, unique: true })
|
||||||
|
homepath: string;
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
emailAddress: string;
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
createdBy: string;
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
createdAt: Date;
|
||||||
|
|
||||||
|
@prop({ required: true, default: false })
|
||||||
|
locked: boolean;
|
||||||
|
|
||||||
|
@prop({ required: true, default: 1 })
|
||||||
|
tier: Tier;
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
supportKey: string;
|
||||||
|
|
||||||
|
@prop({ required: true, unique: true })
|
||||||
|
referralCode: string;
|
||||||
|
|
||||||
|
@prop({ required: true, default: 0 })
|
||||||
|
totalReferrals: number;
|
||||||
|
|
||||||
|
@prop()
|
||||||
|
permissions?: Permissions;
|
||||||
|
|
||||||
|
@prop()
|
||||||
|
ramLimitNotification: number;
|
||||||
|
|
||||||
|
@prop()
|
||||||
|
root: boolean;
|
||||||
|
|
||||||
|
@prop()
|
||||||
|
hash: boolean;
|
||||||
|
|
||||||
|
@prop()
|
||||||
|
salt: string;
|
||||||
|
|
||||||
|
@prop()
|
||||||
|
authTag: Buffer;
|
||||||
|
|
||||||
|
@prop({ type: () => String })
|
||||||
|
revokedBearers: string[];
|
||||||
|
}
|
||||||
|
|
|
@ -1,24 +1,28 @@
|
||||||
import { Document, Schema, model } from 'mongoose';
|
import { modelOptions, prop } from '@typegoose/typegoose';
|
||||||
import { AccountInterface } from './Account';
|
import { Account } from '.';
|
||||||
|
|
||||||
export interface DomainInterface extends Document {
|
class X509 {
|
||||||
account: AccountInterface,
|
@prop({ required: true })
|
||||||
domain: string,
|
cert: string;
|
||||||
port: number,
|
|
||||||
// Below is the full absolute path to the location of the x509 certificate and key files.
|
@prop({ required: true })
|
||||||
x509: {
|
key: string;
|
||||||
cert: string,
|
|
||||||
key: string
|
|
||||||
},
|
|
||||||
enabled: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Domain = new Schema<DomainInterface>({
|
@modelOptions({ schemaOptions: { collection: 'Domain' } })
|
||||||
account: Object,
|
export default class Domain {
|
||||||
domain: String,
|
@prop({ type: () => Account, required: true })
|
||||||
port: Number,
|
account: Account;
|
||||||
x509: { cert: String, key: String },
|
|
||||||
enabled: Boolean,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default model<DomainInterface>('Domain', Domain);
|
@prop({ required: true, unique: true })
|
||||||
|
domain: string;
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
port: number;
|
||||||
|
|
||||||
|
@prop({ required: true, type: () => X509 })
|
||||||
|
x509: X509;
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
enabled: boolean;
|
||||||
|
}
|
||||||
|
|
|
@ -1,38 +1,45 @@
|
||||||
import { Document, Schema, model } from 'mongoose';
|
import { modelOptions, prop } from '@typegoose/typegoose';
|
||||||
|
|
||||||
export interface ModerationInterface extends Document {
|
|
||||||
username: string,
|
class Expiration {
|
||||||
userID: string,
|
@prop({ required: true })
|
||||||
logID: string,
|
date: Date;
|
||||||
moderatorID: string,
|
|
||||||
reason: string,
|
@prop({ required: true, default: false })
|
||||||
/**
|
processed: boolean;
|
||||||
* @field 0 - Create
|
|
||||||
* @field 1 - Warn
|
|
||||||
* @field 2 - Lock
|
|
||||||
* @field 3 - Unlock
|
|
||||||
* @field 4 - Delete
|
|
||||||
*/
|
|
||||||
type: 0 | 1 | 2 | 3 | 4
|
|
||||||
date: Date,
|
|
||||||
expiration: {
|
|
||||||
date: Date,
|
|
||||||
processed: boolean
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Moderation = new Schema<ModerationInterface>({
|
enum Type {
|
||||||
username: String,
|
Create,
|
||||||
userID: String,
|
Warn,
|
||||||
logID: String,
|
Lock,
|
||||||
moderatorID: String,
|
Unlock,
|
||||||
reason: String,
|
Delete
|
||||||
type: Number,
|
}
|
||||||
date: Date,
|
|
||||||
expiration: {
|
|
||||||
date: Date,
|
|
||||||
processed: Boolean,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default model<ModerationInterface>('Moderation', Moderation);
|
@modelOptions({ schemaOptions: { collection: 'Moderation' } })
|
||||||
|
export default class Moderation {
|
||||||
|
@prop({ required: true })
|
||||||
|
username: string;
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
userID: string;
|
||||||
|
|
||||||
|
@prop({ required: true, unique: true })
|
||||||
|
logID: string;
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
moderatorID: string;
|
||||||
|
|
||||||
|
@prop()
|
||||||
|
reason?: string;
|
||||||
|
|
||||||
|
@prop({ enum: Type, required: true })
|
||||||
|
type: Type;
|
||||||
|
|
||||||
|
@prop({ required: true })
|
||||||
|
date: Date;
|
||||||
|
|
||||||
|
@prop()
|
||||||
|
expiration?: Expiration;
|
||||||
|
}
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
import { Document, Schema, model } from 'mongoose';
|
import { modelOptions, prop } from '@typegoose/typegoose';
|
||||||
|
|
||||||
export interface Tiers {
|
class ResourceLimits {
|
||||||
id: number,
|
@prop({ required: true })
|
||||||
resourceLimits: {
|
ram: number;
|
||||||
// In MB
|
|
||||||
ram: number, storage: number
|
@prop({ required: true })
|
||||||
}
|
storage: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TierInterface extends Tiers, Document {
|
@modelOptions({
|
||||||
id: number;
|
schemaOptions: {
|
||||||
}
|
_id: false,
|
||||||
|
collection: 'Tier',
|
||||||
const Tier = new Schema<TierInterface>({
|
|
||||||
id: Number,
|
|
||||||
resourceLimits: {
|
|
||||||
ram: Number,
|
|
||||||
storage: Number,
|
|
||||||
},
|
},
|
||||||
}, { id: false });
|
})
|
||||||
|
export default class Tier {
|
||||||
|
@prop({ required: true, unique: true })
|
||||||
|
id: number;
|
||||||
|
|
||||||
export default model<TierInterface>('Tier', Tier);
|
@prop({ required: true, type: () => ResourceLimits })
|
||||||
|
resourceLimits: ResourceLimits;
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export { default as Account, AccountInterface } from './Account';
|
export { default as Account } from './Account';
|
||||||
export { default as Domain, DomainInterface } from './Domain';
|
export { default as Domain } from './Domain';
|
||||||
export { default as Moderation, ModerationInterface } from './Moderation';
|
export { default as Moderation } from './Moderation';
|
||||||
export { default as Tier, TierInterface, Tiers } from './Tier';
|
export { default as Tier } from './Tier';
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
// "typeRoots": [], /* 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. */
|
// "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. */
|
// "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'. */
|
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||||
// "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. */
|
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||||
|
|
||||||
/* Experimental Options */
|
/* Experimental Options */
|
||||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
"emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue