diff --git a/.gitignore b/.gitignore index e14f27b..5f5aa88 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ site/ # files .env +sskey.env user/config.js user/database.sqlite user/plugins/*/ \ No newline at end of file diff --git a/package.json b/package.json index 2ac8e65..cb7b5df 100644 --- a/package.json +++ b/package.json @@ -35,12 +35,14 @@ "fastify": "^3.12.0", "fastify-secure-session": "^2.3.1", "fastify-static": "^4.0.1", + "form-data": "^4.0.0", "fs-extra": "^9.1.0", "leeks.js": "^0.0.9", - "leekslazylogger-fastify": "^0.0.6", + "leekslazylogger-fastify": "^0.1.0", "node-fetch": "^2.6.1", "semver": "^7.3.4", "sequelize": "^6.5.0", + "socket.io": "^3.1.2", "terminal-link": "^2.1.1" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4811cc2..dd75c0d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,12 +6,14 @@ dependencies: fastify: 3.12.0 fastify-secure-session: 2.3.1 fastify-static: 4.0.1 + form-data: 4.0.0 fs-extra: 9.1.0 leeks.js: 0.0.9 - leekslazylogger-fastify: 0.0.6 + leekslazylogger-fastify: 0.1.0 node-fetch: 2.6.1 semver: 7.3.4 sequelize: 6.5.0_fb66e8c649bde1be622cc06164c9e22d + socket.io: 3.1.2 terminal-link: 2.1.1 devDependencies: eslint: 7.20.0 @@ -110,6 +112,10 @@ packages: node: '>= 6' resolution: integrity: sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg== + /@eartharoid/deep-merge/0.0.1: + dev: false + resolution: + integrity: sha512-nxv2DRXgyqjNcbgDMOB2SoGlzPvge+yjZEI6+Ez+Ei5j00kAT4tzMG/mxseFhTRgZIlPgcaJ03THInVQnNmwqA== /@eartharoid/dtf/1.0.8: dev: false resolution: @@ -166,6 +172,18 @@ packages: node: '>=6' resolution: integrity: sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + /@types/component-emitter/1.2.10: + dev: false + resolution: + integrity: sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg== + /@types/cookie/0.4.0: + dev: false + resolution: + integrity: sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg== + /@types/cors/2.8.10: + dev: false + resolution: + integrity: sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ== /@types/geojson/7946.0.7: dev: true resolution: @@ -180,6 +198,10 @@ packages: /@types/node/14.14.28: resolution: integrity: sha512-lg55ArB+ZiHHbBBttLpzD07akz0QPrZgUODNakeC09i62dnrywr9mFErHuaPlB6I7z+sEbK+IYmplahvplCj2g== + /@types/node/14.14.31: + dev: false + resolution: + integrity: sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g== /@types/node/8.10.66: dev: true resolution: @@ -204,6 +226,15 @@ packages: dev: false resolution: integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA== + /accepts/1.3.7: + dependencies: + mime-types: 2.1.29 + negotiator: 0.6.2 + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== /acorn-jsx/5.3.1_acorn@7.4.1: dependencies: acorn: 7.4.1 @@ -420,10 +451,22 @@ packages: /balanced-match/1.0.0: resolution: integrity: sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + /base64-arraybuffer/0.1.4: + dev: false + engines: + node: '>= 0.6.0' + resolution: + integrity: sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= /base64-js/1.5.1: dev: true resolution: integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + /base64id/2.0.0: + dev: false + engines: + node: ^4.5.0 || >= 5.9 + resolution: + integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== /bcrypt-pbkdf/1.0.2: dependencies: tweetnacl: 0.14.5 @@ -657,6 +700,10 @@ packages: node: '>= 0.8' resolution: integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + /component-emitter/1.3.0: + dev: false + resolution: + integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== /concat-map/0.0.1: resolution: integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= @@ -701,6 +748,15 @@ packages: /core-util-is/1.0.2: resolution: integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + /cors/2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + dev: false + engines: + node: '>= 0.10' + resolution: + integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== /cross-spawn/7.0.3: dependencies: path-key: 3.1.1 @@ -898,6 +954,28 @@ packages: dev: true resolution: integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + /engine.io-parser/4.0.2: + dependencies: + base64-arraybuffer: 0.1.4 + dev: false + engines: + node: '>=8.0.0' + resolution: + integrity: sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg== + /engine.io/4.1.1: + dependencies: + accepts: 1.3.7 + base64id: 2.0.0 + cookie: 0.4.1 + cors: 2.8.5 + debug: 4.3.1 + engine.io-parser: 4.0.2 + ws: 7.4.3 + dev: false + engines: + node: '>=10.0.0' + resolution: + integrity: sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w== /enquirer/2.3.6: dependencies: ansi-colors: 4.1.1 @@ -1264,6 +1342,16 @@ packages: node: '>= 6' resolution: integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + /form-data/4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.29 + dev: false + engines: + node: '>= 6' + resolution: + integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== /fresh/0.5.2: dev: false engines: @@ -1799,21 +1887,22 @@ packages: dev: false resolution: integrity: sha512-axz4CyTYNcjmQc19S0I9HSC5ONGflLVm1N0uUz/MdYvuvC94yZUP/panEm9tLAj88DesBSo6D8cuyO/ctB9kYA== - /leekslazylogger-fastify/0.0.6: + /leekslazylogger-fastify/0.1.0: dependencies: fastify-plugin: 3.0.0 - leekslazylogger: 3.0.0 + leekslazylogger: 3.0.1 on-finished: 2.3.0 dev: false resolution: - integrity: sha512-6qnAjMKEomfmjPNA4/rfH0yV9SR+ze+jTjIG5mBmOnL/LtyiLJHcBiZKY5N689zMBpRdXCb/QOvszgNkcZG7Og== - /leekslazylogger/3.0.0: + integrity: sha512-i0sEvJbzR3gFBA7zf95cMF3CORXfC5Wv4Elv34ZAdjG5zi8S4tZY4Pw5jygG0iu0W1sMxwXR+IY+4Zi9s78zTA== + /leekslazylogger/3.0.1: dependencies: + '@eartharoid/deep-merge': 0.0.1 '@eartharoid/dtf': 1.0.8 leeks.js: 0.1.1 dev: false resolution: - integrity: sha512-vk9I2qejv4B4xFPdLUFODnulMMJn3eLVtFq+JSfejU1yDBPNji+jermGm0I7YhF7ebNlU5AfdR+HbjkTPwaXlg== + integrity: sha512-8o0iFuChUyjYYPFz64OfXEdQYn/H4DXyDHyuEP2hFwU/R2Bru4zP4NZbo64PzNwLBDmYZx+06xrsU4oE9WQaJg== /levn/0.4.1: dependencies: prelude-ls: 1.2.1 @@ -1933,6 +2022,12 @@ packages: node: '>= 0.6' resolution: integrity: sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w== + /mime-db/1.46.0: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ== /mime-types/2.1.28: dependencies: mime-db: 1.45.0 @@ -1940,6 +2035,14 @@ packages: node: '>= 0.6' resolution: integrity: sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ== + /mime-types/2.1.29: + dependencies: + mime-db: 1.46.0 + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ== /mime/1.6.0: dev: false engines: @@ -2055,6 +2158,12 @@ packages: optional: true resolution: integrity: sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg== + /negotiator/0.6.2: + dev: false + engines: + node: '>= 0.6' + resolution: + integrity: sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== /node-abort-controller/1.1.0: dev: true resolution: @@ -2213,7 +2322,6 @@ packages: dev: false engines: node: '>=0.10.0' - optional: true resolution: integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= /on-finished/2.3.0: @@ -2851,6 +2959,36 @@ packages: node: '>=10' resolution: integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + /socket.io-adapter/2.1.0: + dev: false + resolution: + integrity: sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg== + /socket.io-parser/4.0.4: + dependencies: + '@types/component-emitter': 1.2.10 + component-emitter: 1.3.0 + debug: 4.3.1 + dev: false + engines: + node: '>=10.0.0' + resolution: + integrity: sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== + /socket.io/3.1.2: + dependencies: + '@types/cookie': 0.4.0 + '@types/cors': 2.8.10 + '@types/node': 14.14.31 + accepts: 1.3.7 + base64id: 2.0.0 + debug: 4.3.1 + engine.io: 4.1.1 + socket.io-adapter: 2.1.0 + socket.io-parser: 4.0.4 + dev: false + engines: + node: '>=10.0.0' + resolution: + integrity: sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw== /sodium-native/3.2.1: dependencies: ini: 1.3.8 @@ -3302,6 +3440,12 @@ packages: node: '>= 0.10' resolution: integrity: sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw== + /vary/1.1.2: + dev: false + engines: + node: '>= 0.8' + resolution: + integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= /verror/1.10.0: dependencies: assert-plus: 1.0.0 @@ -3454,10 +3598,11 @@ specifiers: fastify: ^3.12.0 fastify-secure-session: ^2.3.1 fastify-static: ^4.0.1 + form-data: ^4.0.0 fs-extra: ^9.1.0 jsdoc: ^3.6.6 leeks.js: ^0.0.9 - leekslazylogger-fastify: ^0.0.6 + leekslazylogger-fastify: ^0.1.0 mariadb: ^2.5.2 mysql2: ^2.2.5 node-fetch: ^2.6.1 @@ -3466,6 +3611,7 @@ specifiers: pg-hstore: ^2.3.3 semver: ^7.3.4 sequelize: ^6.5.0 + socket.io: ^3.1.2 sqlite3: ^5.0.2 tedious: ^11.0.3 terminal-link: ^2.1.1 diff --git a/src/logger.js b/src/logger.js index b0990a8..b278a74 100644 --- a/src/logger.js +++ b/src/logger.js @@ -40,10 +40,6 @@ module.exports = new Logger({ type: 'info', format: '&7[{timestamp}]&r &3[INFO] &d(COMMANDS)&r {text}' }, - http: { - type: 'info', - format: '&7[{timestamp}]&r &3[INFO] &d(HTTP)&r {text}' - }, plugins: { type: 'info', format: '&7[{timestamp}]&r &3[INFO] &d(PLUGINS)&r {text}' @@ -51,6 +47,14 @@ module.exports = new Logger({ tickets: { type: 'info', format: '&7[{timestamp}]&r &3[INFO] &d(TICKETS)&r {text}' + }, + http: { + type: 'info', + format: '&7[{timestamp}]&r &3[INFO] &d(HTTP)&r {text}' + }, + ws: { + type: 'info', + format: '&7[{timestamp}]&r &3[INFO] &d(WS)&r {text}' } } }); \ No newline at end of file diff --git a/src/modules/plugins/manager.js b/src/modules/plugins/manager.js index e8f9106..11f3418 100644 --- a/src/modules/plugins/manager.js +++ b/src/modules/plugins/manager.js @@ -34,7 +34,7 @@ module.exports = class PluginManager { * @param {Plugin} Main The Plugin class * @param {Object} pkg Contents of package.json */ - registerPlugin(npm, Main, pkg) { + register(npm, Main, pkg) { let { name: id, version, @@ -85,7 +85,7 @@ module.exports = class PluginManager { try { let main = require(plugin); let pkg = require(`${plugin}/package.json`); - this.registerPlugin(true, main, pkg); + this.register(true, main, pkg); } catch (e) { this.client.log.warn(`An error occurred whilst loading ${plugin}; have you installed it?`); this.client.log.error(e); @@ -99,7 +99,7 @@ module.exports = class PluginManager { if (!fs.existsSync(path(`./user/plugins/${dir}/package.json`))) return; let pkg = require(`../../../user/plugins/${dir}/package.json`); let main = require(join(`../../../user/plugins/${dir}/`, pkg.main)); - this.registerPlugin(false, main, pkg); + this.register(false, main, pkg); }); } diff --git a/src/server/index.js b/src/server/index.js index bfa2c74..54dfb28 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -1,6 +1,8 @@ const { Plugin } = require('../modules/plugins'); const fastify = require('fastify'); +const session = require('fastify-secure-session'); const { randomBytes } = require('crypto'); +const fs = require('fs'); const { path } = require('../utils/fs'); module.exports = class SettingsServer extends Plugin { @@ -19,39 +21,59 @@ module.exports = class SettingsServer extends Plugin { } async preload() { - this.fastify.register(this.client.log.fastify, { + this.fastify.register(this.client.log.fastify(), { level: 'http', - format: '{method} {status-colour}{status} &7{route} {time-colour}({time})' + format: '&lSETTINGS:&r {status-colour}{status}&r {method} &7{route} {time-colour}({time})' }); - this.fastify.register(require('fastify-secure-session'), { - key: randomBytes(48).toString('hex') + this.fastify.register(session, { + secret: randomBytes(48).toString('hex'), + salt: randomBytes(8).toString('hex'), + cookie: { + path: '/', + httpOnly: true , + }, }); this.fastify.register(require('fastify-static'), { root: path('./src/server/public'), - prefix: '/public/', + // prefix: '/public/', }); - } - - async load() { let host = process.env.HTTP_HOST; if (!host.endsWith('/')) host = host + '/'; + this.redirect_uri = encodeURI(`${host}auth/callback`); + } - let redirect_url = encodeURI(`${host}auth/callback`); - let oauth2_url = `https://discord.com/api/oauth2/authorize?client_id=${this.client.user.id}&redirect_uri=${redirect_url}&response_type=code&scope=identify%20guilds&state=apollo`; - - this.fastify.get('/', async (req, res) => { - // res.type('application/json').code(200); - // return { hello: 'world' }; - res.code(200); - return 'Hello!'; - }); + async load() { + const routes = fs.readdirSync(path('./src/server/routes')) + .filter(file => file.endsWith('.js')); + for (const r of routes) { + const { + method, + route, + execute + } = require(`./routes/${r}`); + this.fastify[method](route, (...args) => execute(this, ...args)); + } this.fastify.listen(process.env.HTTP_PORT || 8080, (err, host) => { if (err) throw err; this.client.log.info(`Settings server listening at ${host}`); }); + + this.io = require('socket.io')(process.env.HTTP_PORT || 8080); + + this.io.on('connection', socket => { + const events = fs.readdirSync(path('./src/server/socket')) + .filter(file => file.endsWith('.js')); + for (const e of events) { + const { + event, + execute + } = require(`./socket/${e}`); + socket.on(event, (...args) => execute(this, ...args)); + } + }); } }; \ No newline at end of file diff --git a/src/server/public/index.html b/src/server/public/index.html index e69de29..87564c6 100644 --- a/src/server/public/index.html +++ b/src/server/public/index.html @@ -0,0 +1,12 @@ + + +
+