was bored, heres a cool eval command

master
Jan 2021-05-19 22:57:21 +02:00
parent 98d1745cce
commit 9d51a06432
4 changed files with 207 additions and 1 deletions

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
node_modules
.env
.idea/
.idea/
data/

124
commands/eval.js Normal file
View File

@ -0,0 +1,124 @@
const Revolt = require('revolt.js');
const { client, logger, config } = require('..');
const { exec } = require('child_process');
let evalEnabled = [];
let OTP = [];
let OTPTimer = [];
module.exports = {
OTP, evalEnabled, OTPTimer
}
module.exports.meta = {
name: 'eval',
aliases: [],
description: 'Evaluate code.',
devLevel: 99
}
/**
*
* @param { Revolt.Message } message
* @param { string[] } args
*/
module.exports.run = async (message, args) => new Promise(async (resolve, reject) => {
if (!evalEnabled[message.author] && process.env['DISABLE_EVAL_OTP'] != 'true') {
OTP[message.author] = createOTP();
client.channels.sendMessage(message.channel, `OTP has been printed to console. Use \`${config.prefix}verify [code]\` to verify.`);
console.log(`Admin authentication required`);
console.log(`OTP: \u001b[31;1m${OTP[message.author]}\u001b[0m`);
console.log(`Code expires in 120 seconds.`);
if (OTPTimer[message.author]) {
console.log('Old OTP code has been invalidated.');
clearTimeout(OTPTimer[message.author]);
}
OTPTimer[message.author] = setTimeout(() => {
console.log(`OTP Code \u001b[31;1m${OTP[message.author]}\u001b[0m has been invalidated.`);
OTP[message.author] = null;
}, 120000);
return;
}
let command = args.join(' ');
if (command.length == 0) return client.channels.sendMessage(message.channel, `❌ No command provided`);
if (command.startsWith('js:')) {
// Execute javascript
command = command.substring(3);
if (command.length == 0) return client.channels.sendMessage(message.channel, `❌ No command provided`);
let mesg = await client.channels.sendMessage(message.channel, `Evaluating JavaScript...`);
let parseOutput = (output) => {
if (output instanceof Error) return `${output.name || 'Error'} : ${output.message}`;
if (output instanceof Object) return `${JSON.stringify(output, null, 4)}`;
return `${output}`;
}
try {
let output = eval(command);
if (output instanceof Promise) {
client.channels.editMessage(message.channel, mesg._id, { content: `\`\`\`js\nPromise : Pending\n\`\`\`` });
output
.then(val => {
client.channels.editMessage(message.channel, mesg._id, { content: `\`\`\`js\nPromise : Resolved\n${parseOutput(val)}\n\`\`\`` });
})
.catch(val => {
client.channels.editMessage(message.channel, mesg._id, { content: `\`\`\`js\nPromise : Rejected\n${parseOutput(val)}\n\`\`\`` });
});
} else {
client.channels.editMessage(message.channel, mesg._id, { content: `\`\`\`js\n${parseOutput(output)}\n\`\`\`` });
}
} catch(e) {
client.channels.editMessage(message.channel, mesg._id, { content: `\`\`\`js\n${parseOutput(e)}\n\`\`\`` });
}
} else {
let mesg = await client.channels.sendMessage(message.channel, `Executing: \`${command}\``);
let outTxt = '';
let cOutTxt = '';
let prevTxt = '';
let cutLetters = 0;
let exited = false;
let updateMsg = (msg, exitCode) => {
outTxt += `${msg}`
.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '')
.replace(/`/g, '\u200b`');
while (outTxt.length >= 1920) {
outTxt = outTxt.slice(2, outTxt.length);
cutLetters++;
}
let charCutTxt = '';
if (cutLetters > 0) charCutTxt = `${cutLetters} character${cutLetters == 1 ? ' has' : 's have'} been cut\n`;
let exitText = '';
if (exitCode != null) {
exitText = `\nExited with code ${exitCode}`;
exited = true;
}
cOutTxt = `${charCutTxt}\`\`\`bash\n${outTxt.trimRight() || 'No output'}\n\`\`\`${exitText}`;
}
let execution = exec(command);
execution.stdout.on('data', updateMsg);
execution.stderr.on('data', updateMsg);
execution.once('exit', (exitCode) => {
updateMsg('', exitCode);
});
let interval = setInterval(() => {
if (cOutTxt != prevTxt) {
prevTxt = cOutTxt;
client.channels.editMessage(message.channel, mesg._id, { content: cOutTxt });
}
}, 200);
}
});
// $\color{red}\text{h}$
function createOTP() {
let code = '';
for (let i = 0; i < 6; i++) code += Math.round(Math.random() * 10);
return code.substr(0, 6);
}

30
commands/evaloff.js Normal file
View File

@ -0,0 +1,30 @@
const Revolt = require('revolt.js');
const { client, logger, config } = require('..');
const { OTP, evalEnabled, OTPTimer } = require('./eval');
module.exports.meta = {
name: 'evaloff',
aliases: [],
description: 'Disable eval functionality.',
devLevel: 99
}
/**
*
* @param { Revolt.Message } message
* @param { string[] } args
*/
module.exports.run = async (message, args) => new Promise(async (resolve, reject) => {
if (OTPTimer[message.author]) clearTimeout(OTPTimer[message.author]);
if (evalEnabled[message.author]) {
evalEnabled[message.author] = null;
OTP[message.author] = null;
return client.channels.sendMessage(message.channel, 'Access has been revoked.');
}
if (OTP[message.author]) {
OTP[message.author] = null;
return client.channels.sendMessage(message.channel, 'Existing OTP has been invalidated.');
}
return client.channels.sendMessage(message.channel, 'You were not authenticated.');
});

51
commands/verify.js Normal file
View File

@ -0,0 +1,51 @@
const Revolt = require('revolt.js');
const { client, logger, config } = require('..');
const { OTP, evalEnabled, OTPTimer } = require('./eval');
const banIntervals = [ 5, 10, 15, 30, 60, 120, 300 ];
const failedAttempts = [];
const failedTimeouts = [];
module.exports.meta = {
name: 'verify',
aliases: [ 'v' ],
description: 'Verify dev actions.',
devLevel: 1
}
/**
*
* @param { Revolt.Message } message
* @param { string[] } args
*/
module.exports.run = async (message, args) => new Promise(async (resolve, reject) => {
if (failedAttempts[message.author] == null) failedAttempts[message.author] = 0;
if (failedAttempts[message.author] > 0 && failedTimeouts[message.author] != null) {
let timeout = (banIntervals[failedAttempts[message.author] - 1] ?? Infinity) * 1000;
if (failedTimeouts[message.author] + timeout > Date.now()) {
if (timeout == Infinity)
return client.channels.sendMessage(message.channel, `❌ Blocked`);
else
return client.channels.sendMessage(message.channel, `❌ Blocked for ${timeout / 1000} seconds`);
}
}
let otp = OTP[message.author];
let code = args[0];
if (!otp) return client.channels.sendMessage(message.channel, 'There is nothing to verify right now.');
if (!code) return client.channels.sendMessage(message.channel, 'You need to specify a code.');
if (code != otp) {
failedAttempts[message.author]++;
failedTimeouts[message.author] = Date.now();
return client.channels.sendMessage(message.channel, '❌ Invalid code');
}
logger.warn('Enabled eval for ' + message.author);
clearTimeout(OTPTimer[message.author]);
evalEnabled[message.author] = true;
client.channels.sendMessage(message.channel, `Authenticated - Use \`${config.prefix}evaloff\` to disable`);
});