create a support key on account creation

merge-requests/4/head
Matthew 2020-03-29 04:32:17 -04:00
parent ec6adfad41
commit efc8dc8f02
No known key found for this signature in database
GPG Key ID: 766BE43AE75F7559
5 changed files with 20 additions and 13 deletions

View File

@ -1,3 +1,4 @@
import { randomBytes } from 'crypto';
import { AccountInterface } from '../models'; import { AccountInterface } from '../models';
import { Client } from '..'; import { Client } from '..';
@ -22,20 +23,22 @@ export default class AccountUtil {
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', '');
const acctName = this.client.users.get(data.userID).username.replace(/[!@#$%^&*(),.?":{}|<>]/g, '-').replace(/\s/g, '-'); const acctName = this.client.users.get(data.userID).username.replace(/[!@#$%^&*(),.?":{}|<>]/g, '-').replace(/\s/g, '-');
const etcPasswd = `${acctName},${data.userID},,`; const etcPasswd = `${acctName},${data.userID},,`;
const code = randomBytes(3).toString('hex').toUpperCase();
const accountInterface = await this.client.util.createAccount(passHash, etcPasswd, data.username, data.userID, data.emailAddress, moderator); const accountInterface = await this.client.util.createAccount(passHash, etcPasswd, data.username, data.userID, data.emailAddress, moderator, code);
await this.client.util.createModerationLog(data.userID, moderatorMember, 0); await this.client.util.createModerationLog(data.userID, moderatorMember, 0);
this.client.util.transport.sendMail({ this.client.util.transport.sendMail({
to: data.emailAddress, to: data.emailAddress,
from: 'Library of Code sp-us | Cloud Services <help@libraryofcode.org>', from: 'Library of Code sp-us | Cloud Services <help@libraryofcode.org>',
subject: 'Your account has been created', subject: 'Your account has been created!',
html: ` html: `
<body> <body>
<style>* {font-family: 'Calibri';}</style> <style>* {font-family: 'Calibri';}</style>
<h1>Library of Code | Cloud Services</h1> <h1>Library of Code | Cloud Services</h1>
<h2>Your Cloud Account has been created, welcome! Please see below for some details regarding your account and our services</h2> <h2>Your Cloud Account has been created, welcome! Please see below for some details regarding your account and our services</h2>
<p><b>Username:</b> ${data.username}</p> <p><b>Username:</b> ${data.username}</p>
<p><b>Support Key:</b> ${code} || <i>You may be asked for this support key when contacting Library of Code, please keep the code in a safe area.</i></p>
<p><b>SSH Login:</b> <pre><code style="font-family: Courier;">ssh ${data.username}@cloud.libraryofcode.org</code></pre> <p><b>SSH Login:</b> <pre><code style="font-family: Courier;">ssh ${data.username}@cloud.libraryofcode.org</code></pre>
<h2>Useful information</h2> <h2>Useful information</h2>
<h3>How to log in:</h3> <h3>How to log in:</h3>
@ -67,7 +70,8 @@ export default class AccountUtil {
+ `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' + 'Bear in mind that when you enter your password, it will be blank, so be careful not to type in your password incorrectly.\n'
+ 'You may now return to Modmail, and continue setting up your account from there.\n\n' + 'You may now return to Modmail, and continue setting up your account from there.\n\n'
+ 'An email containing some useful information has also been sent').catch(); + '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();
return { account: accountInterface, tempPass }; return { account: accountInterface, tempPass };
} }
} }

View File

@ -147,12 +147,12 @@ export default class Util {
return tempPass; return tempPass;
} }
public async createAccount(hash: string, etcPasswd: string, username: string, userID: string, emailAddress: string, moderatorID: string): Promise<AccountInterface> { public async createAccount(hash: string, etcPasswd: string, username: string, userID: string, emailAddress: string, moderatorID: string, code: string): Promise<AccountInterface> {
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 account = new this.client.db.Account({ const account = new this.client.db.Account({
username, userID, emailAddress, createdBy: moderatorID, createdAt: new Date(), locked: false, tier: 1, ssInit: false, homepath: `/home/${username}`, username, userID, emailAddress, createdBy: moderatorID, createdAt: new Date(), locked: false, tier: 1, supportKey: code, ssInit: false, homepath: `/home/${username}`,
}); });
return account.save(); return account.save();
} }

View File

@ -24,17 +24,17 @@ export default class CreateAccount extends Command {
try { try {
if (message.channel instanceof PrivateChannel || message.channel instanceof GroupChannel) return message; // Stop TS being gay 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 (!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.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.get(args[0]).bot) return message.channel.createMessage(`${this.client.stores.emojis.error} ***I cannot create accounts for bots.***`);
const checkUser = await this.client.db.Account.findOne({ userID: args[0] }); 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 message.channel.createMessage(`${this.client.stores.emojis.error} ***<@${args[0]}> already has an account.***`);
const checkEmail = await this.client.db.Account.findOne({ emailAddress: args[1] }); 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 message.channel.createMessage(`${this.client.stores.emojis.error} ***Account already exists with this email address.***`);
const checkAccount = await this.client.db.Account.findOne({ username: args[2] }); 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 message.channel.createMessage(`${this.client.stores.emojis.error} ***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 (!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 (!/^[a-z][-a-z0-9]*$/.test(args[2])) return message.channel.createMessage(`${this.client.stores.emojis.error} ***Invalid username supplied.***`);
const confirmation = await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Creating account...***`); const confirmation = await message.channel.createMessage(`${this.client.stores.emojis.loading} ***Creating account...***`);
const data = await this.client.util.accounts.createAccount({ userID: args[0], username: args[2], emailAddress: args[1] }, message.author.id); const data = await this.client.util.accounts.createAccount({ userID: args[0], username: args[2], emailAddress: args[1] }, message.author.id);

View File

@ -39,6 +39,7 @@ export default class Whois extends Command {
embed.addField('ID', account.userID, true); embed.addField('ID', account.userID, true);
embed.addField('Email Address', account.emailAddress, true); embed.addField('Email Address', account.emailAddress, true);
embed.addField('Tier', String(account.tier), true); embed.addField('Tier', String(account.tier), true);
embed.addField('Support Key', account.supportKey, true);
embed.addField('Created By', `<@${this.client.users.get(account.createdBy).id}>`, 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); 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; }'`); const cpuUsage = await this.client.util.exec(`top -b -n 1 -u ${account.username} | awk 'NR>7 { sum += $9; } END { print sum; }'`);

View File

@ -8,7 +8,8 @@ export interface AccountInterface extends Document {
createdBy: string, createdBy: string,
createdAt: Date, createdAt: Date,
locked: boolean, locked: boolean,
tier: number; tier: number,
supportKey: string,
permissions: { permissions: {
staff: boolean, staff: boolean,
sheriff: boolean, sheriff: boolean,
@ -29,6 +30,7 @@ const Account: Schema = new Schema({
createdAt: Date, createdAt: Date,
locked: Boolean, locked: Boolean,
tier: Number, tier: Number,
supportKey: String,
permissions: { permissions: {
staff: Boolean, staff: Boolean,
sheriff: Boolean, sheriff: Boolean,