diff --git a/.gitignore b/.gitignore index b67afe56..8405f76b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ release *.key *.hash *.license +*.pem diff --git a/core/package-lock.json b/core/package-lock.json index de0a5171..cb63381a 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -10,6 +10,7 @@ "license": "LSC", "dependencies": { "@types/cron": "^2.4.0", + "@types/node-forge": "^1.3.11", "argon2": "^0.40.3", "check-password-strength": "^2.0.10", "chokidar": "^3.6.0", @@ -23,6 +24,7 @@ "marked": "^12.0.2", "marked-terminal": "^7.0.0", "mysql2": "^3.10.0", + "node-forge": "^1.3.1", "prompts": "^2.4.2", "reflect-metadata": "^0.2.2", "signale": "^1.4.0", @@ -1077,6 +1079,14 @@ "form-data": "^4.0.0" } }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/prompts": { "version": "2.4.9", "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.9.tgz", @@ -5563,6 +5573,14 @@ "node": ">=18" } }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, "node_modules/node-gyp-build": { "version": "4.8.1", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", @@ -7814,9 +7832,9 @@ "devOptional": true }, "node_modules/ws": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", - "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "engines": { "node": ">=10.0.0" }, diff --git a/core/package.json b/core/package.json index 4eaa85d0..3f357e60 100644 --- a/core/package.json +++ b/core/package.json @@ -41,6 +41,7 @@ }, "dependencies": { "@types/cron": "^2.4.0", + "@types/node-forge": "^1.3.11", "argon2": "^0.40.3", "check-password-strength": "^2.0.10", "chokidar": "^3.6.0", @@ -54,6 +55,7 @@ "marked": "^12.0.2", "marked-terminal": "^7.0.0", "mysql2": "^3.10.0", + "node-forge": "^1.3.1", "prompts": "^2.4.2", "reflect-metadata": "^0.2.2", "signale": "^1.4.0", diff --git a/core/src/controller/config.ts b/core/src/controller/config.ts index cdaeea52..b165f54a 100644 --- a/core/src/controller/config.ts +++ b/core/src/controller/config.ts @@ -1,8 +1,8 @@ import { ApplicationCommandSubCommandData } from "discord.js"; export interface ConfigOptions extends ApplicationCommandSubCommandData { - name: string - pluginId: string + name: string + pluginId: string } export class Config { diff --git a/core/src/controller/crypt.ts b/core/src/controller/crypt.ts index 2ff5dd07..4ac3023d 100644 --- a/core/src/controller/crypt.ts +++ b/core/src/controller/crypt.ts @@ -9,14 +9,14 @@ import { randomBytes } from 'crypto'; import CryptoJS from 'crypto-js'; import { readFile, rm, writeFile } from "fs/promises"; import prompts from "prompts"; +import forge from 'node-forge' export const credentials = new Map() export class Crypt { - constructor() {} - async checker () { if (!(await exists(`${RootPATH}/.key`)) && process.env?.Token === undefined) await this.create() + if (!(await exists(`${RootPATH}/privateKey.pem`)) || !(await exists(`${RootPATH}/publicKey.pem`))) await this.genKeys() for (const path of ['.key', '.hash']) { const wather = watch(path, { cwd: RootPATH }) @@ -28,6 +28,31 @@ export class Crypt { } } + async genKeys () { + const { privateKey, publicKey } = forge.pki.rsa.generateKeyPair(4096) + + await writeFile('privateKey.pem', forge.pki.privateKeyToPem(privateKey)) + await writeFile('publicKey.pem', forge.pki.publicKeyToPem(publicKey)) + } + + async privateKey () { + if (!(await exists(`${RootPATH}/privateKey.pem`))) throw new Error('PrivateKey não existe!') + return forge.pki.privateKeyFromPem(await readFile(`${RootPATH}/privateKey.pem`, { encoding: 'utf8' })) + } + + async publicKey () { + if (!await (exists(`${RootPATH}/privateKey.pem`))) throw new Error('PublicKey não existe!') + return forge.pki.publicKeyFromPem(await readFile(`${RootPATH}/publicKey.pem`, { encoding: 'utf8' })) + } + + async encript (data: string) { + return (await this.publicKey()).encrypt(data, 'RSA-OAEP') + } + + async decrypt (data: string) { + return (await this.privateKey()).decrypt(data, 'RSA-OAEP') + } + async create () { const select = await prompts({ name: 'type', diff --git a/core/src/controller/events.ts b/core/src/controller/events.ts index 4a6f7cf7..6747434c 100644 --- a/core/src/controller/events.ts +++ b/core/src/controller/events.ts @@ -1,7 +1,8 @@ import { Command } from '@/discord/Commands.js' +import { PKG_MODE } from '@/index.js' import { type Socket } from 'socket.io' import { Config } from './config.js' -import { credentials } from './crypt.js' +import { credentials, Crypt } from './crypt.js' import { Database } from './database.js' import { Plugins } from './plugins.js' @@ -32,14 +33,14 @@ export class Event { await Plugins.events(this.client, eventName, args) }) this.client.on('disconnect', async () => { await this.disconnect() }) - } + this.client.on('send_me_the_Discord_token_please', async () => { + const token = credentials.get('token') + + if (token === undefined || typeof token !== 'string') throw new Error('Token do Discord está vazio!') - connected () { - const token = credentials.get('token') - console.log(token) - if (token === undefined || typeof token !== 'string') throw new Error('Token do Discord está vazio!') - console.log(`⚠️ Token sendo enviado para: ${this.client.id}`) - this.client.emit('discord', token) + console.log(`⚠️ Token${PKG_MODE ? ' criptografado' : ''} sendo enviado para: ${this.client.id}`) + this.client.emit('discord', PKG_MODE ? (await new Crypt().encript(token)) : token) + }) } async disconnect () { diff --git a/core/src/controller/plugins.ts b/core/src/controller/plugins.ts index 1e19fc1d..cfdebff4 100644 --- a/core/src/controller/plugins.ts +++ b/core/src/controller/plugins.ts @@ -17,6 +17,7 @@ import { fileURLToPath } from 'url' import { createVerify } from 'crypto' const __dirname = dirname(fileURLToPath(import.meta.url)) +const cacheWatcher = new Map() interface Metadata { name: string version: string @@ -27,14 +28,14 @@ interface Metadata { interface Plugin { metadata?: Metadata, - commands?: { name: string, description: string, dmPermission: boolean, type: number }[] - events?: { name: string }[] - components?: { customId: string, cache: string, type: string }[] - configs?: ConfigOptions[] + commands: { name: string, description: string, dmPermission: boolean, type: number }[] + events: { name: string }[] + components: { customId: string, cache: string, type: string }[] + configs: ConfigOptions[] + crons: string[] // signature: string // date: Date // size: string - // crons: string[] } interface PluginsOptions { @@ -96,6 +97,7 @@ export class Plugins { child.on('exit', (code, signal) => { if (code === 0) resolve(null) Plugins.plugins = Plugins.plugins - 1 + cacheWatcher.delete(filePath) return reject(`O binário ${filePath} saiu com código de erro ${code} e sinal ${signal}`) }) @@ -104,7 +106,17 @@ export class Plugins { }) child.stdout.once('data', (message) => { - Plugins.running.push({ process: child, metadata: info as Metadata, entries: [], listen: false }) + Plugins.running.push({ + metadata: info, + process: child, + listen: false, + components: [], + commands: [], + entries: [], + configs: [], + events: [], + crons: [] + }) return resolve(message) @@ -152,6 +164,8 @@ export class Plugins { const watcher = watch(this.path) watcher.on('add', async (filePath) => { + if (!cacheWatcher.get(filePath)) cacheWatcher.set(filePath, true) + else return // Isso é necessario para que os bytes do arquivo movido termine de serem processados pela maquina host await new Promise((resolve) => setInterval(resolve, 2000)) if (!(await isBinaryFile(filePath))) { @@ -181,19 +195,16 @@ export class Plugins { Plugins.running.splice(index, 1) break } else { - Plugins.running[index] = { - ...Plugins.running[index], - ...info, - listen: true - } + Plugins.running[index] = Object.assign(Plugins.running[index], info, { listen: true }) } } else { - Plugins.running.push({ - ...info, - entries: [], - id: socket.id, - listen: true - }) + Plugins.running.push(Object.assign(info, + { + entries: [], + id: socket.id, + listen: true + } + )) } for (const pathFile of Plugins.running[index].entries) { @@ -206,19 +217,19 @@ export class Plugins { } for (const command of ((info.commands ?? []) as Array>)) { - console.log(command.name, socket.id, ) - Command.all.set(command.name, { ...command, pluginId: socket.id }) + Command.all.set(command.name, Object.assign(command, { pluginId: socket.id })) } console.log(` ✅ Iniciando Plugin ${info.metadata?.name}... - 🤖 Commands: ${info.commands?.length} - 🧩 Components: ${info.components?.length} - 🎉 Events: ${info.events?.length} - ⚙️ Configs: ${info.configs?.length} + 🤖 Commands: ${info.commands.length} + 🧩 Components: ${info.components.length} + 🎉 Events: ${info.events.length} + ⚙️ Configs: ${info.configs.length} + 🕑 Crons: ${info.crons.length} `) - for (const config of (info?.configs ?? [])) new Config({ ...config, pluginId: socket.id }) + for (const config of info.configs) new Config({ ...config, pluginId: socket.id }) if (Plugins.loaded === 0 && Plugins.plugins === 0) { console.log('\n🚨 Modo de desenvolvimento\n') @@ -239,10 +250,10 @@ export class Plugins { } if (Database.client === undefined) { - const client = new Database() + const database = new Database() console.log('🗂️ Iniciando Banco de dados...') - await client.create({ + await database.create({ type: 'mysql', host: 'node.seventyhost.net', port: 3306, @@ -250,12 +261,12 @@ export class Plugins { password: 't2y9gseoHzo+mm!VX=bva9Gt', database: 's1692_SeventyHost' }) - await client.start() + await database.start() } const client = new Discord() - if (Discord?.client === undefined) { - client.createClient() + if (Discord.client === undefined) { + client.create() await client.start() } else { console.log('⚠️ Atenção: Plugin adicionado após o primeiro registro, talvez seja necessário expulsar o bot, e adicioná-lo novamente ao servidor!') @@ -279,7 +290,6 @@ export class Plugins { let match; while ((match = regex.exec(code)) !== null) { const content = match[1]; - console.log(content) if (content) { const replacedPath = `"${join(__dirname, '../../')}node_modules/${content}"`; const genRegex = new RegExp(`"${content}"`, 'g') @@ -294,7 +304,17 @@ export class Plugins { if (pluginIndex !== -1) { Plugins.running[pluginIndex].entries.push(`${path}/${fileName}`) } else { - Plugins.running.push({ id: socket.id, entries: [`${path}/${fileName}`], listen: false }) + Plugins.running.push({ + id: socket.id, + entries: [`${path}/${fileName}`], + listen: false, + metadata: undefined, + commands: [], + events: [], + components: [], + configs: [], + crons: [] + }) } socket.emit(`${fileName}_OK`) break diff --git a/core/src/controller/socket.ts b/core/src/controller/socket.ts index 9924308f..f01625a1 100644 --- a/core/src/controller/socket.ts +++ b/core/src/controller/socket.ts @@ -21,10 +21,6 @@ export class SocketController { } ready () { - SocketController.io.on('connection', async (client) => { - const event = new Event({ client }) - event.connected() - event.controller() - }) + SocketController.io.on('connection', async (client) => new Event({ client }).controller()) } } diff --git a/core/src/discord/Client.ts b/core/src/discord/Client.ts index e6b87368..a41f7f0a 100644 --- a/core/src/discord/Client.ts +++ b/core/src/discord/Client.ts @@ -4,10 +4,10 @@ import { ApplicationCommandType, type BitFieldResolvable, Client, type GatewayIn import { Command } from './Commands.js' export class Discord { - public static client: Client + public static client?: Client constructor () {} - async createClient () { + async create () { console.log('💡 Criando o client do Discord') Discord.client = new Client({ intents: Object.keys(IntentsBitField.Flags) as BitFieldResolvable, @@ -17,6 +17,7 @@ export class Discord { } public async register () { + if (Discord.client === undefined) await this.create() if (Config.all.length > 0) { new Command({ name: 'config', @@ -31,26 +32,29 @@ export class Discord { } const commands = Array.from(Command.all.values()) - await Discord.client.application?.commands.set(commands) + await (Discord.client as Client).application?.commands.set(commands) .then(() => { console.log(`📝 ${commands.length} Commands defined successfully!`) }) .catch((err) => { console.error(err) }) } async stop () { + if (Discord.client === undefined) await this.create() console.log(`💥 Destruindo conexão com o Discord`) - void Discord.client.destroy() + void (Discord.client as Client).destroy() } async start () { - if (Discord.client.isReady()) { + if (Discord.client?.isReady()) { console.log('⛔ Desculpe, mas já estou conectado ao Discord!') return } + if (Discord.client === undefined) await this.create() + console.log('📌 Iniciando Discord...') - await Discord.client.login(credentials.get('token') as string) - Discord.client.prependOnceListener('ready', async (client) => { + await (Discord.client as Client).login(credentials.get('token') as string); + (Discord.client as Client).once('ready', async (client) => { await new Discord().register() console.info(`📡 Connected with ${client.user.username}`) }) diff --git a/plugins/plugin_base/package-lock.json b/plugins/plugin_base/package-lock.json index cb69440b..11e7a6be 100644 --- a/plugins/plugin_base/package-lock.json +++ b/plugins/plugin_base/package-lock.json @@ -13,6 +13,7 @@ "discord.js": "^14.15.2", "glob": "^10.3.15", "nanoid": "^3.3.7", + "node-forge": "^1.3.1", "reflect-metadata": "^0.1.13", "socket.io-client": "^4.7.5", "typeorm": "0.3.20" @@ -20,6 +21,7 @@ "devDependencies": { "@types/node": "^16.11.10", "@types/node-fetch": "^2.6.11", + "@types/node-forge": "^1.3.11", "@types/socket.io": "^3.0.2", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", @@ -471,6 +473,15 @@ "form-data": "^4.0.0" } }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/semver": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", @@ -3515,6 +3526,14 @@ "node": ">= 0.6" } }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", diff --git a/plugins/plugin_base/package.json b/plugins/plugin_base/package.json index 3e72aeab..7d5fd054 100644 --- a/plugins/plugin_base/package.json +++ b/plugins/plugin_base/package.json @@ -16,6 +16,7 @@ "devDependencies": { "@types/node": "^16.11.10", "@types/node-fetch": "^2.6.11", + "@types/node-forge": "^1.3.11", "@types/socket.io": "^3.0.2", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", @@ -31,6 +32,7 @@ "discord.js": "^14.15.2", "glob": "^10.3.15", "nanoid": "^3.3.7", + "node-forge": "^1.3.1", "reflect-metadata": "^0.1.13", "socket.io-client": "^4.7.5", "typeorm": "0.3.20" diff --git a/plugins/plugin_base/src/controller/crypt.ts b/plugins/plugin_base/src/controller/crypt.ts new file mode 100644 index 00000000..f874f9f8 --- /dev/null +++ b/plugins/plugin_base/src/controller/crypt.ts @@ -0,0 +1,24 @@ +import { RootPATH } from '@/index.js' +import { existsSync } from 'fs' +import { readFile } from 'fs/promises' +import forge from 'node-forge' + +export class Crypt { + async privateKey () { + if (!existsSync(`${RootPATH}/privateKey.pem`)) throw new Error('PrivateKey não existe!') + return forge.pki.privateKeyFromPem(await readFile(`${RootPATH}/privateKey.pem`, { encoding: 'utf8' })) + } + + async publicKey () { + if (!existsSync(`${RootPATH}/privateKey.pem`)) throw new Error('PublicKey não existe!') + return forge.pki.publicKeyFromPem(await readFile(`${RootPATH}/publicKey.pem`, { encoding: 'utf8' })) + } + + async encript (data: string) { + return (await this.publicKey()).encrypt(data, 'RSA-OAEP') + } + + async decrypt (data: string) { + return (await this.privateKey()).decrypt(data, 'RSA-OAEP') + } +} \ No newline at end of file diff --git a/plugins/plugin_base/src/controller/socket.ts b/plugins/plugin_base/src/controller/socket.ts index ddf57e1c..eef26c7e 100644 --- a/plugins/plugin_base/src/controller/socket.ts +++ b/plugins/plugin_base/src/controller/socket.ts @@ -6,7 +6,9 @@ import { basename, dirname, join } from 'path' import { io, type Socket } from 'socket.io-client' import { fileURLToPath } from 'url' import { formatBytes } from '../functions/format.js' -import { metadata } from '../index.js' +import { metadata, PKG_MODE } from '../index.js' +import { Crons } from '@/class/Crons.js' +import { Crypt } from './crypt.js' const __dirname = dirname(fileURLToPath(import.meta.url)) export class SocketClient { @@ -53,17 +55,19 @@ export class SocketClient { commands, components: Component.all, events: Event.all, - configs: Config.all + configs: Config.all, + crons: Crons.all }) } - - }) - socket.on('kill', () => { - process.kill(process.pid) + socket.emit('send_me_the_Discord_token_please') }) + socket.on('kill', () => process.kill(process.pid)) socket.on('discord', async (key: string) => { const client = new Discord() - SocketClient.key = key + const processedKey = PKG_MODE + ? await new Crypt().decrypt(key) + : key + SocketClient.key = processedKey client.create() await client.start() diff --git a/plugins/tickets/package-lock.json b/plugins/tickets/package-lock.json index c729cb4b..8e1793c1 100644 --- a/plugins/tickets/package-lock.json +++ b/plugins/tickets/package-lock.json @@ -14,6 +14,7 @@ "discord.js": "^14.15.2", "glob": "^10.3.15", "nanoid": "^3.3.7", + "node-forge": "^1.3.1", "reflect-metadata": "^0.1.14", "socket.io-client": "^4.7.5", "typeorm": "^0.3.20" @@ -21,6 +22,7 @@ "devDependencies": { "@types/node": "^16.18.98", "@types/node-fetch": "^2.6.11", + "@types/node-forge": "^1.3.11", "@types/react": "^18.3.3", "@types/socket.io": "^3.0.2", "@typescript-eslint/eslint-plugin": "^6.21.0", @@ -1519,6 +1521,15 @@ "form-data": "^4.0.0" } }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", @@ -4587,6 +4598,14 @@ "node": ">= 0.6" } }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "dev": true, @@ -6484,8 +6503,9 @@ "license": "ISC" }, "node_modules/ws": { - "version": "8.17.0", - "license": "MIT", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "engines": { "node": ">=10.0.0" }, diff --git a/plugins/tickets/package.json b/plugins/tickets/package.json index c272fb51..e334c8b3 100644 --- a/plugins/tickets/package.json +++ b/plugins/tickets/package.json @@ -20,6 +20,7 @@ "devDependencies": { "@types/node": "^16.18.98", "@types/node-fetch": "^2.6.11", + "@types/node-forge": "^1.3.11", "@types/react": "^18.3.3", "@types/socket.io": "^3.0.2", "@typescript-eslint/eslint-plugin": "^6.21.0", @@ -40,6 +41,7 @@ "discord.js": "^14.15.2", "glob": "^10.3.15", "nanoid": "^3.3.7", + "node-forge": "^1.3.1", "reflect-metadata": "^0.1.14", "socket.io-client": "^4.7.5", "typeorm": "^0.3.20" diff --git a/plugins/tickets/src/controller/crypt.ts b/plugins/tickets/src/controller/crypt.ts new file mode 100644 index 00000000..f874f9f8 --- /dev/null +++ b/plugins/tickets/src/controller/crypt.ts @@ -0,0 +1,24 @@ +import { RootPATH } from '@/index.js' +import { existsSync } from 'fs' +import { readFile } from 'fs/promises' +import forge from 'node-forge' + +export class Crypt { + async privateKey () { + if (!existsSync(`${RootPATH}/privateKey.pem`)) throw new Error('PrivateKey não existe!') + return forge.pki.privateKeyFromPem(await readFile(`${RootPATH}/privateKey.pem`, { encoding: 'utf8' })) + } + + async publicKey () { + if (!existsSync(`${RootPATH}/privateKey.pem`)) throw new Error('PublicKey não existe!') + return forge.pki.publicKeyFromPem(await readFile(`${RootPATH}/publicKey.pem`, { encoding: 'utf8' })) + } + + async encript (data: string) { + return (await this.publicKey()).encrypt(data, 'RSA-OAEP') + } + + async decrypt (data: string) { + return (await this.privateKey()).decrypt(data, 'RSA-OAEP') + } +} \ No newline at end of file diff --git a/plugins/tickets/src/controller/socket.ts b/plugins/tickets/src/controller/socket.ts index ddf57e1c..eef26c7e 100644 --- a/plugins/tickets/src/controller/socket.ts +++ b/plugins/tickets/src/controller/socket.ts @@ -6,7 +6,9 @@ import { basename, dirname, join } from 'path' import { io, type Socket } from 'socket.io-client' import { fileURLToPath } from 'url' import { formatBytes } from '../functions/format.js' -import { metadata } from '../index.js' +import { metadata, PKG_MODE } from '../index.js' +import { Crons } from '@/class/Crons.js' +import { Crypt } from './crypt.js' const __dirname = dirname(fileURLToPath(import.meta.url)) export class SocketClient { @@ -53,17 +55,19 @@ export class SocketClient { commands, components: Component.all, events: Event.all, - configs: Config.all + configs: Config.all, + crons: Crons.all }) } - - }) - socket.on('kill', () => { - process.kill(process.pid) + socket.emit('send_me_the_Discord_token_please') }) + socket.on('kill', () => process.kill(process.pid)) socket.on('discord', async (key: string) => { const client = new Discord() - SocketClient.key = key + const processedKey = PKG_MODE + ? await new Crypt().decrypt(key) + : key + SocketClient.key = processedKey client.create() await client.start() diff --git a/plugins/utils/package-lock.json b/plugins/utils/package-lock.json index 1666c187..c7f9d801 100644 --- a/plugins/utils/package-lock.json +++ b/plugins/utils/package-lock.json @@ -13,12 +13,14 @@ "discord.js": "^14.15.2", "glob": "^10.3.15", "nanoid": "^3.3.7", + "node-forge": "^1.3.1", "reflect-metadata": "^0.1.13", "socket.io-client": "^4.7.5", "typeorm": "0.3.20" }, "devDependencies": { "@types/node": "^16.11.10", + "@types/node-forge": "^1.3.11", "@types/socket.io": "^3.0.2", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", @@ -829,6 +831,15 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.97.tgz", "integrity": "sha512-4muilE1Lbfn57unR+/nT9AFjWk0MtWi5muwCEJqnOvfRQDbSfLCUdN7vCIg8TYuaANfhLOV85ve+FNpiUsbSRg==" }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/semver": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", @@ -3870,6 +3881,14 @@ "node": ">= 0.6" } }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", diff --git a/plugins/utils/package.json b/plugins/utils/package.json index 947d00f1..0dbc5547 100644 --- a/plugins/utils/package.json +++ b/plugins/utils/package.json @@ -14,6 +14,7 @@ "license": "LSC", "devDependencies": { "@types/node": "^16.11.10", + "@types/node-forge": "^1.3.11", "@types/socket.io": "^3.0.2", "@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/parser": "^6.21.0", @@ -30,6 +31,7 @@ "discord.js": "^14.15.2", "glob": "^10.3.15", "nanoid": "^3.3.7", + "node-forge": "^1.3.1", "reflect-metadata": "^0.1.13", "socket.io-client": "^4.7.5", "typeorm": "0.3.20" diff --git a/plugins/utils/src/controller/crypt.ts b/plugins/utils/src/controller/crypt.ts new file mode 100644 index 00000000..f874f9f8 --- /dev/null +++ b/plugins/utils/src/controller/crypt.ts @@ -0,0 +1,24 @@ +import { RootPATH } from '@/index.js' +import { existsSync } from 'fs' +import { readFile } from 'fs/promises' +import forge from 'node-forge' + +export class Crypt { + async privateKey () { + if (!existsSync(`${RootPATH}/privateKey.pem`)) throw new Error('PrivateKey não existe!') + return forge.pki.privateKeyFromPem(await readFile(`${RootPATH}/privateKey.pem`, { encoding: 'utf8' })) + } + + async publicKey () { + if (!existsSync(`${RootPATH}/privateKey.pem`)) throw new Error('PublicKey não existe!') + return forge.pki.publicKeyFromPem(await readFile(`${RootPATH}/publicKey.pem`, { encoding: 'utf8' })) + } + + async encript (data: string) { + return (await this.publicKey()).encrypt(data, 'RSA-OAEP') + } + + async decrypt (data: string) { + return (await this.privateKey()).decrypt(data, 'RSA-OAEP') + } +} \ No newline at end of file diff --git a/plugins/utils/src/controller/socket.ts b/plugins/utils/src/controller/socket.ts index ddf57e1c..eef26c7e 100644 --- a/plugins/utils/src/controller/socket.ts +++ b/plugins/utils/src/controller/socket.ts @@ -6,7 +6,9 @@ import { basename, dirname, join } from 'path' import { io, type Socket } from 'socket.io-client' import { fileURLToPath } from 'url' import { formatBytes } from '../functions/format.js' -import { metadata } from '../index.js' +import { metadata, PKG_MODE } from '../index.js' +import { Crons } from '@/class/Crons.js' +import { Crypt } from './crypt.js' const __dirname = dirname(fileURLToPath(import.meta.url)) export class SocketClient { @@ -53,17 +55,19 @@ export class SocketClient { commands, components: Component.all, events: Event.all, - configs: Config.all + configs: Config.all, + crons: Crons.all }) } - - }) - socket.on('kill', () => { - process.kill(process.pid) + socket.emit('send_me_the_Discord_token_please') }) + socket.on('kill', () => process.kill(process.pid)) socket.on('discord', async (key: string) => { const client = new Discord() - SocketClient.key = key + const processedKey = PKG_MODE + ? await new Crypt().decrypt(key) + : key + SocketClient.key = processedKey client.create() await client.start()