Compare commits

...

2 Commits

Author SHA1 Message Date
Jan 9d51a06432 was bored, heres a cool eval command 2021-05-19 22:57:21 +02:00
Jan 98d1745cce bump revolt.js to latest 2021-05-19 18:00:49 +02:00
6 changed files with 239 additions and 59 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`);
});

88
package-lock.json generated
View File

@ -12,38 +12,26 @@
"better-sqlite3": "^7.1.2",
"dotenv": "^8.2.0",
"log75": "^2.0.1",
"revolt.js": "^4.0.0-alpha.12"
"revolt.js": "^4.1.3-alpha.3-patch.0"
},
"devDependencies": {
"enmap": "^5.8.4"
}
},
"node_modules/@insertish/mutable": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@insertish/mutable/-/mutable-1.0.3.tgz",
"integrity": "sha512-DDNdqs4r0KgdUxNFGlHDYVkyam27KsqEq+WQUNQA0+XA2g+VhowMmHjVA7Kxf70ONhhoE2R9XL4I4YMbxp43Dw==",
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@insertish/mutable/-/mutable-1.0.6.tgz",
"integrity": "sha512-FTaPbesmBwcr3iKfbA2udFto61/sL7rOiCM08vBbE2X0wC63nsvTos6gnkwa1Nwom1v15jjrc/4B0YqI3vbZ/Q==",
"dependencies": {
"@insertish/zangodb": "1.0.11",
"@insertish/zangodb": "^1.0.12",
"eventemitter3": "^4.0.7",
"lodash.isequal": "^4.5.0"
}
},
"node_modules/@insertish/mutable/node_modules/@insertish/zangodb": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@insertish/zangodb/-/zangodb-1.0.11.tgz",
"integrity": "sha512-ubHJQC1+2pBlsUqJFDtFnhqXfHxEoXS4zZIllVe3EQhfe/wvNjtL48peE6dE7nkKos6a1Dan831aldJeltIbuA==",
"dependencies": {
"clone": "^2.1.2",
"deepmerge": "^4.2.2",
"memoizee": "^0.4.15",
"object-hash": "^2.1.1",
"q": "^1.5.1"
}
},
"node_modules/@insertish/zangodb": {
"version": "1.0.10-patch.0",
"resolved": "https://registry.npmjs.org/@insertish/zangodb/-/zangodb-1.0.10-patch.0.tgz",
"integrity": "sha512-o6fEynGz/QMEIv/eZLmmzDaeJljGPq14XdrHQoNfKxNp53KkbGF6j+vIwQtNF+6osgXKBSC+BgeVEvFBN84QjA==",
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/@insertish/zangodb/-/zangodb-1.0.12.tgz",
"integrity": "sha512-JlLI12Xqt1xvv/p2/AHs163ZYMZsB3sJyjB8yaAs6QcG0tyRBTIyxV5ISEAkAPo5kzlFza5z5oH82yQe/qw5RQ==",
"dependencies": {
"clone": "^2.1.2",
"deepmerge": "^4.2.2",
@ -393,9 +381,9 @@
}
},
"node_modules/ext/node_modules/type": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/type/-/type-2.3.0.tgz",
"integrity": "sha512-rgPIqOdfK/4J9FhiVrZ3cveAjRRo5rsQBAIhnylX874y1DX/kEKSVdLsnuHB6l1KTjHyU01VjiMBHgU2adejyg=="
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz",
"integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw=="
},
"node_modules/file-uri-to-path": {
"version": "1.0.0",
@ -832,12 +820,12 @@
}
},
"node_modules/revolt.js": {
"version": "4.0.0-alpha.12",
"resolved": "https://registry.npmjs.org/revolt.js/-/revolt.js-4.0.0-alpha.12.tgz",
"integrity": "sha512-7TgvlaKXm/IcdAKW2qDRzFB/ke4zXnkv7ouJ1OTK/C6zvaL/Wt3t8x1PzbRhNgioRvTMLR7nQXeTLsjqe1aCpQ==",
"version": "4.1.3-alpha.3-patch.0",
"resolved": "https://registry.npmjs.org/revolt.js/-/revolt.js-4.1.3-alpha.3-patch.0.tgz",
"integrity": "sha512-lGzlisLpJquTKUcdKb35HK5QQUJ47y8H2Ja7AIyhwx2jmSfDUJkKg5cbwVKocP/qf3RTUFflXT6Uwi8ZR34Jcg==",
"dependencies": {
"@insertish/mutable": "1.0.3",
"@insertish/zangodb": "1.0.10-patch.0",
"@insertish/mutable": "1.0.6",
"@insertish/zangodb": "1.0.12",
"axios": "^0.19.2",
"eventemitter3": "^4.0.7",
"exponential-backoff": "^3.1.0",
@ -1172,33 +1160,19 @@
},
"dependencies": {
"@insertish/mutable": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@insertish/mutable/-/mutable-1.0.3.tgz",
"integrity": "sha512-DDNdqs4r0KgdUxNFGlHDYVkyam27KsqEq+WQUNQA0+XA2g+VhowMmHjVA7Kxf70ONhhoE2R9XL4I4YMbxp43Dw==",
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@insertish/mutable/-/mutable-1.0.6.tgz",
"integrity": "sha512-FTaPbesmBwcr3iKfbA2udFto61/sL7rOiCM08vBbE2X0wC63nsvTos6gnkwa1Nwom1v15jjrc/4B0YqI3vbZ/Q==",
"requires": {
"@insertish/zangodb": "1.0.11",
"@insertish/zangodb": "^1.0.12",
"eventemitter3": "^4.0.7",
"lodash.isequal": "^4.5.0"
},
"dependencies": {
"@insertish/zangodb": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@insertish/zangodb/-/zangodb-1.0.11.tgz",
"integrity": "sha512-ubHJQC1+2pBlsUqJFDtFnhqXfHxEoXS4zZIllVe3EQhfe/wvNjtL48peE6dE7nkKos6a1Dan831aldJeltIbuA==",
"requires": {
"clone": "^2.1.2",
"deepmerge": "^4.2.2",
"memoizee": "^0.4.15",
"object-hash": "^2.1.1",
"q": "^1.5.1"
}
}
}
},
"@insertish/zangodb": {
"version": "1.0.10-patch.0",
"resolved": "https://registry.npmjs.org/@insertish/zangodb/-/zangodb-1.0.10-patch.0.tgz",
"integrity": "sha512-o6fEynGz/QMEIv/eZLmmzDaeJljGPq14XdrHQoNfKxNp53KkbGF6j+vIwQtNF+6osgXKBSC+BgeVEvFBN84QjA==",
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/@insertish/zangodb/-/zangodb-1.0.12.tgz",
"integrity": "sha512-JlLI12Xqt1xvv/p2/AHs163ZYMZsB3sJyjB8yaAs6QcG0tyRBTIyxV5ISEAkAPo5kzlFza5z5oH82yQe/qw5RQ==",
"requires": {
"clone": "^2.1.2",
"deepmerge": "^4.2.2",
@ -1510,9 +1484,9 @@
},
"dependencies": {
"type": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/type/-/type-2.3.0.tgz",
"integrity": "sha512-rgPIqOdfK/4J9FhiVrZ3cveAjRRo5rsQBAIhnylX874y1DX/kEKSVdLsnuHB6l1KTjHyU01VjiMBHgU2adejyg=="
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz",
"integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw=="
}
}
},
@ -1889,12 +1863,12 @@
}
},
"revolt.js": {
"version": "4.0.0-alpha.12",
"resolved": "https://registry.npmjs.org/revolt.js/-/revolt.js-4.0.0-alpha.12.tgz",
"integrity": "sha512-7TgvlaKXm/IcdAKW2qDRzFB/ke4zXnkv7ouJ1OTK/C6zvaL/Wt3t8x1PzbRhNgioRvTMLR7nQXeTLsjqe1aCpQ==",
"version": "4.1.3-alpha.3-patch.0",
"resolved": "https://registry.npmjs.org/revolt.js/-/revolt.js-4.1.3-alpha.3-patch.0.tgz",
"integrity": "sha512-lGzlisLpJquTKUcdKb35HK5QQUJ47y8H2Ja7AIyhwx2jmSfDUJkKg5cbwVKocP/qf3RTUFflXT6Uwi8ZR34Jcg==",
"requires": {
"@insertish/mutable": "1.0.3",
"@insertish/zangodb": "1.0.10-patch.0",
"@insertish/mutable": "1.0.6",
"@insertish/zangodb": "1.0.12",
"axios": "^0.19.2",
"eventemitter3": "^4.0.7",
"exponential-backoff": "^3.1.0",

View File

@ -13,7 +13,7 @@
"better-sqlite3": "^7.1.2",
"dotenv": "^8.2.0",
"log75": "^2.0.1",
"revolt.js": "^4.0.0-alpha.12"
"revolt.js": "^4.1.3-alpha.3-patch.0"
},
"devDependencies": {
"enmap": "^5.8.4"