From dc9756442d26c0c7b60375af65877e77412e5af2 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sun, 1 Oct 2023 09:44:58 +0200 Subject: [PATCH 01/36] Add a command to change timezone --- clientDiscord/docker-compose.yml | 2 +- clientDiscord/events/interactionCreate.js | 14 +++++ clientDiscord/index.js | 4 +- .../interactions/commands/setTimeZone.js | 62 +++++++++++++++++++ clientDiscord/package-lock.json | 4 +- clientDiscord/package.json | 2 +- clientDiscord/utils/loadCommands.js | 40 ++++++++++++ 7 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 clientDiscord/events/interactionCreate.js create mode 100644 clientDiscord/interactions/commands/setTimeZone.js create mode 100644 clientDiscord/utils/loadCommands.js diff --git a/clientDiscord/docker-compose.yml b/clientDiscord/docker-compose.yml index d4230a4..f496069 100644 --- a/clientDiscord/docker-compose.yml +++ b/clientDiscord/docker-compose.yml @@ -3,7 +3,7 @@ version: "3" services: karassistant-client-discord: #build: . - image: codyisthesenate/karassistant-client-discord:1.1.1 + image: codyisthesenate/karassistant-client-discord:1.1.2 restart: always container_name: karassistant-client-discord volumes: diff --git a/clientDiscord/events/interactionCreate.js b/clientDiscord/events/interactionCreate.js new file mode 100644 index 0000000..6b23800 --- /dev/null +++ b/clientDiscord/events/interactionCreate.js @@ -0,0 +1,14 @@ +const { Events } = require("discord.js"); +const listCommands = require("../utils/loadCommands").listCommands; + +module.exports.run = async (client) => { + client.on(Events.InteractionCreate, (interaction) => { + if (interaction.isChatInputCommand()) { + try { + listCommands[interaction.commandName](interaction); + } catch (error) { + interaction.reply("There is an error with the command"); + } + } + }); +}; diff --git a/clientDiscord/index.js b/clientDiscord/index.js index 92b53a8..8840264 100644 --- a/clientDiscord/index.js +++ b/clientDiscord/index.js @@ -24,7 +24,9 @@ async function start() { }); }); - client.login(TOKEN).then(() => {}); + client.login(TOKEN).then(() => { + require("./utils/loadCommands").run(client); + }); } start(); diff --git a/clientDiscord/interactions/commands/setTimeZone.js b/clientDiscord/interactions/commands/setTimeZone.js new file mode 100644 index 0000000..c6b3c96 --- /dev/null +++ b/clientDiscord/interactions/commands/setTimeZone.js @@ -0,0 +1,62 @@ +const { ApplicationCommandOptionType } = require("discord.js"); +const updateUser = require("../../utils/updateUser").updateUser; + +const listOfTimezones = [ + "Pacific/Kiritimati", + "Pacific/Tongatapu", + "Pacific/Apia", + "Asia/Anadyr", + "Asia/Kamchatka", + "Asia/Tokyo", + "Asia/Hong_Kong", + "Asia/Kolkata", + "Asia/Dubai", + "Europe/Moscow", + "Europe/Paris", + "Europe/London", + "Africa/Cairo", + "Africa/Nairobi", + "Asia/Kuwait", + "Europe/Athens", + "Asia/Baghdad", + "Europe/Istanbul", + "Asia/Tehran", + "Asia/Kabul", + "Asia/Baku", + "Asia/Ashgabat", + "Asia/Muscat", + "Asia/Tashkent", + "Asia/Almaty", +]; + +const choices = []; +for (const timezone of listOfTimezones) { + choices.push({ name: timezone, value: timezone }); +} + +module.exports = { + data: { + name: "settimezone", + description: "Set the time zone, to get the time right", + options: [ + { + type: ApplicationCommandOptionType.String, + name: "timezone", + description: "Value for the new time zone", + required: true, + choices, + }, + ], + }, + async execute(interaction) { + await interaction.deferReply({ ephemeral: true }); + const timeZone = interaction.options.get("timezone").value; + const userName = interaction.user.userName; + const userId = interaction.user.id; + + const result = await updateUser({ userName: userName, userId: userId, data: { timeZone } }); + return interaction.followUp( + result ? "Time zone has been updated" : "ERROR: Could not update time zone. Try again later." + ); + }, +}; diff --git a/clientDiscord/package-lock.json b/clientDiscord/package-lock.json index 802bd2f..95c4afb 100644 --- a/clientDiscord/package-lock.json +++ b/clientDiscord/package-lock.json @@ -1,12 +1,12 @@ { "name": "clientdiscord", - "version": "1.0.0", + "version": "1.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "clientdiscord", - "version": "1.0.0", + "version": "1.1.1", "license": "ISC", "dependencies": { "axios": "^1.5.0", diff --git a/clientDiscord/package.json b/clientDiscord/package.json index 0770dc4..cc49d59 100644 --- a/clientDiscord/package.json +++ b/clientDiscord/package.json @@ -1,6 +1,6 @@ { "name": "clientdiscord", - "version": "1.1.1", + "version": "1.1.2", "description": "A discord bot for KarAssistant", "main": "index.js", "scripts": { diff --git a/clientDiscord/utils/loadCommands.js b/clientDiscord/utils/loadCommands.js new file mode 100644 index 0000000..a76d9f7 --- /dev/null +++ b/clientDiscord/utils/loadCommands.js @@ -0,0 +1,40 @@ +const { REST, Routes } = require("discord.js"); +const fs = require("fs"); +require("dotenv").config(); + +const GUILD_ID = process.env.GUILD_ID; +const TOKEN = process.env.DISCORD_TOKEN; + +const listCommands = {}; +module.exports.listCommands = listCommands; + +module.exports.run = async (client) => { + // Create all commands + const commands = []; + const commandFolders = fs.readdirSync(__dirname + "/../interactions/commands/"); + + for (const folder of commandFolders) { + // Grab all the command files from the commands directory you created earlier + const commandsPath = __dirname + "/../interactions/commands/" + folder; + + const command = require(commandsPath); + if ("data" in command && "execute" in command) { + const data = command.data; + listCommands[data.name] = command.execute; + commands.push(data); + } else { + console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`); + } + } + + // Construct and prepare an instance of the REST module + const rest = new REST().setToken(TOKEN); + + // and deploy your commands! + try { + client.application.commands.set(commands, GUILD_ID); + } catch (error) { + // And of course, make sure you catch and log any errors! + console.error(error); + } +}; From a80102b80d43b253e48a55d56c0c407d84e219f2 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Tue, 3 Oct 2023 10:59:12 +0200 Subject: [PATCH 02/36] Change RSA communication --- clientDiscord/.gitignore | 3 ++- clientDiscord/docker-compose.yml | 2 +- clientDiscord/package-lock.json | 4 ++-- clientDiscord/package.json | 2 +- clientDiscord/utils/RSA.js | 4 ++-- clientDiscord/utils/heyKara.js | 14 ++++++++++---- clientDiscord/utils/prepareRequest.js | 21 +++++++++++++-------- clientDiscord/utils/updateUser.js | 4 +++- 8 files changed, 34 insertions(+), 20 deletions(-) diff --git a/clientDiscord/.gitignore b/clientDiscord/.gitignore index 91489c1..55cff86 100644 --- a/clientDiscord/.gitignore +++ b/clientDiscord/.gitignore @@ -2,4 +2,5 @@ node_modules/ data/ logs/ coverage/ -.env \ No newline at end of file +.env +.vscode/ \ No newline at end of file diff --git a/clientDiscord/docker-compose.yml b/clientDiscord/docker-compose.yml index f496069..274b5c8 100644 --- a/clientDiscord/docker-compose.yml +++ b/clientDiscord/docker-compose.yml @@ -3,7 +3,7 @@ version: "3" services: karassistant-client-discord: #build: . - image: codyisthesenate/karassistant-client-discord:1.1.2 + image: codyisthesenate/karassistant-client-discord:1.2.0 restart: always container_name: karassistant-client-discord volumes: diff --git a/clientDiscord/package-lock.json b/clientDiscord/package-lock.json index 95c4afb..9efc179 100644 --- a/clientDiscord/package-lock.json +++ b/clientDiscord/package-lock.json @@ -1,12 +1,12 @@ { "name": "clientdiscord", - "version": "1.1.1", + "version": "1.1.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "clientdiscord", - "version": "1.1.1", + "version": "1.1.2", "license": "ISC", "dependencies": { "axios": "^1.5.0", diff --git a/clientDiscord/package.json b/clientDiscord/package.json index cc49d59..01f29bb 100644 --- a/clientDiscord/package.json +++ b/clientDiscord/package.json @@ -1,6 +1,6 @@ { "name": "clientdiscord", - "version": "1.1.2", + "version": "1.2.0", "description": "A discord bot for KarAssistant", "main": "index.js", "scripts": { diff --git a/clientDiscord/utils/RSA.js b/clientDiscord/utils/RSA.js index db72ef5..bb68a63 100644 --- a/clientDiscord/utils/RSA.js +++ b/clientDiscord/utils/RSA.js @@ -1,9 +1,9 @@ const NodeRSA = require("node-rsa"); module.exports.encryptData = encryptData; -async function encryptData({ data, publicKey }) { +async function encryptData({ data, key }) { try { - const keyPublic = new NodeRSA(publicKey); + const keyPublic = new NodeRSA(key); data.date = new Date().toUTCString(); const passPhraseEncrypted = keyPublic.encrypt(JSON.stringify(data), "base64"); return passPhraseEncrypted; diff --git a/clientDiscord/utils/heyKara.js b/clientDiscord/utils/heyKara.js index 46c8057..917d611 100644 --- a/clientDiscord/utils/heyKara.js +++ b/clientDiscord/utils/heyKara.js @@ -10,7 +10,7 @@ const prepareRequest = require("./prepareRequest").prepareRequest; const decryptResult = require("./prepareRequest").decryptResult; module.exports.makeRequest = makeRequest; -async function makeRequest({ query, clientToken, data }) { +async function makeRequest({ clientToken, data }) { return await new Promise((resolve, reject) => { api({ method: "GET", @@ -43,9 +43,14 @@ async function makeRequest({ query, clientToken, data }) { module.exports.heyKara = heyKara; async function heyKara({ userName, userId, messageContent, avatarUrl, retry = 0 }) { - const { err, clientToken, data, publicKey } = await prepareRequest({ userId, userName, avatarUrl, messageContent }); + const { err, clientToken, data, clientPrivateKey } = await prepareRequest({ + userId, + userName, + avatarUrl, + messageContent, + }); if (err) return err; - const dataRequest = data ? await makeRequest({ query: messageContent, clientToken, data }) : { clientExist: false }; + const dataRequest = data ? await makeRequest({ clientToken, data }) : { clientExist: false }; if (dataRequest.err && retry != 0) return dataRequest.err; if (!dataRequest || dataRequest.err) { @@ -55,9 +60,10 @@ async function heyKara({ userName, userId, messageContent, avatarUrl, retry = 0 } const resultDecrypted = data - ? await decryptResult({ data: dataRequest, publicKey }) + ? await decryptResult({ data: dataRequest, key: clientPrivateKey }) : { result: "Error with the request" }; + console.log(resultDecrypted); const phraseResult = resultDecrypted.result; return phraseResult; } diff --git a/clientDiscord/utils/prepareRequest.js b/clientDiscord/utils/prepareRequest.js index 7e5740f..4eb599b 100644 --- a/clientDiscord/utils/prepareRequest.js +++ b/clientDiscord/utils/prepareRequest.js @@ -44,10 +44,10 @@ async function createNewClient({ authautifierTag }) { } module.exports.decryptResult = decryptResult; -async function decryptResult({ data, publicKey }) { +async function decryptResult({ data, key }) { try { - const keyPublic = new NodeRSA(publicKey); - const resultDecrypted = keyPublic.decryptPublic(data, "utf8"); + const keyPublic = new NodeRSA(key); + const resultDecrypted = keyPublic.decrypt(data, "utf8"); return JSON.parse(resultDecrypted); } catch { return null; @@ -58,10 +58,14 @@ async function decryptResult({ data, publicKey }) { module.exports.prepareRequest = async ({ userId, userName, avatarUrl, messageContent }) => { const userExist = fs.existsSync(__dirname + "/../data/clients/" + userId + ".json"); - const { err, clientToken, publicKey } = await new Promise(async (resolve, reject) => { + const { err, clientToken, backPublicKey, clientPrivateKey } = await new Promise(async (resolve, reject) => { if (userExist) { const userData = JSON.parse(fs.readFileSync(__dirname + "/../data/clients/" + userId + ".json", "utf8")); - resolve({ clientToken: userData.clientToken, publicKey: userData.publicKey }); + resolve({ + clientToken: userData.clientToken, + backPublicKey: userData.backPublicKey, + clientPrivateKey: userData.clientPrivateKey, + }); } else { const newClient = await createNewClient({ authautifierTag: userId }); if (newClient.err) return resolve({ err: newClient.err }); @@ -69,7 +73,8 @@ module.exports.prepareRequest = async ({ userId, userName, avatarUrl, messageCon userName, avatarUrl, clientToken: newClient.clientToken, - publicKey: newClient.publicKey, + backPublicKey: newClient.backPublicKey, + clientPrivateKey: newClient.clientPrivateKey, }; fs.writeFileSync(__dirname + "/../data/clients/" + userId + ".json", JSON.stringify(userData)); const res = await updateUser({ @@ -84,8 +89,8 @@ module.exports.prepareRequest = async ({ userId, userName, avatarUrl, messageCon const data = await encryptData({ data: { query: messageContent }, - publicKey, + key: backPublicKey, }); - return { clientToken, data, publicKey }; + return { clientToken, data, backPublicKey, clientPrivateKey }; }; diff --git a/clientDiscord/utils/updateUser.js b/clientDiscord/utils/updateUser.js index a036a98..16d8d04 100644 --- a/clientDiscord/utils/updateUser.js +++ b/clientDiscord/utils/updateUser.js @@ -26,6 +26,8 @@ async function updateUserRequest({ data, clientToken }) { .catch(function (error) { if (error.code === "ECONNREFUSED") return resolve({ err: "Access to the Kara server cannot be established", status: 420 }); + else if (error.response && error.response.status === 400) + return resolve({ err: "Bad request for PUT /api/user", status: error.response.status }); else if (error.response && error.response.status === 403) return resolve({ err: "Access to the Kara server is forbidden", status: error.response.status }); else if (error.response && error.response.status === 404) @@ -49,7 +51,7 @@ async function updateUser({ userName, userId, data, retry = 0 }) { const clientToken = userData.clientToken; const dataEncrypted = await encryptData({ data, - publicKey: userData.publicKey, + key: userData.backPublicKey, }); const dataRequest = await updateUserRequest({ data: dataEncrypted, clientToken }); From 3ce8b69332b0d06af0c39e4ece0bab52f918dd9f Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Thu, 5 Oct 2023 15:43:00 +0200 Subject: [PATCH 03/36] Add AES encryption --- .gitguardian.yml | 26 +++ clientDiscord/docker-compose.yml | 2 +- clientDiscord/package-lock.json | 13 +- clientDiscord/package.json | 3 +- clientDiscord/tests/utils/encryption.test.js | 161 ++++++++++++++++++ .../tests/utils/getPassPhrase.test.js | 5 - clientDiscord/utils/encryption.js | 69 ++++++++ clientDiscord/utils/heyKara.js | 22 ++- clientDiscord/utils/prepareRequest.js | 9 +- 9 files changed, 292 insertions(+), 18 deletions(-) create mode 100644 .gitguardian.yml create mode 100644 clientDiscord/tests/utils/encryption.test.js delete mode 100644 clientDiscord/tests/utils/getPassPhrase.test.js create mode 100644 clientDiscord/utils/encryption.js diff --git a/.gitguardian.yml b/.gitguardian.yml new file mode 100644 index 0000000..59d3b73 --- /dev/null +++ b/.gitguardian.yml @@ -0,0 +1,26 @@ +# Example here : https://github.com/GitGuardian/ggshield/blob/main/.gitguardian.example.yml +# Required, otherwise ggshield considers the file to use the deprecated v1 format +version: 2 +# +# Set to true if the desired exit code for the CLI is always 0, otherwise the +# exit code will be 1 if incidents are found. +# The environment variable GITGUARDIAN_EXIT_ZERO=true can also be used toggle this behavior. +exit-zero: false # default: false +# +verbose: false # default: false +# +# The dashboard URL of the instance +instance: https://dashboard.gitguardian.com # default: https://dashboard.gitguardian.com +# +# Maximum commits to scan in a hook. +max-commits-for-hook: 50 # default: 50 +# +# Accept self-signed certificates for the API. +allow-self-signed: false # default: false +# +secret: + # Exclude files and paths by globbing + ignored-paths: + - "**/README.md" + - "back_node/tests/**" + - "clientDiscord/tests/**" diff --git a/clientDiscord/docker-compose.yml b/clientDiscord/docker-compose.yml index 274b5c8..cbdac53 100644 --- a/clientDiscord/docker-compose.yml +++ b/clientDiscord/docker-compose.yml @@ -3,7 +3,7 @@ version: "3" services: karassistant-client-discord: #build: . - image: codyisthesenate/karassistant-client-discord:1.2.0 + image: codyisthesenate/karassistant-client-discord:1.3.0 restart: always container_name: karassistant-client-discord volumes: diff --git a/clientDiscord/package-lock.json b/clientDiscord/package-lock.json index 9efc179..eb4c42d 100644 --- a/clientDiscord/package-lock.json +++ b/clientDiscord/package-lock.json @@ -1,17 +1,18 @@ { "name": "clientdiscord", - "version": "1.1.2", + "version": "1.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "clientdiscord", - "version": "1.1.2", + "version": "1.2.0", "license": "ISC", "dependencies": { "axios": "^1.5.0", "discord.js": "^14.13.0", "dotenv": "^16.3.1", + "node-forge": "^1.3.1", "node-rsa": "^1.1.1", "qs": "^6.11.2" }, @@ -3315,6 +3316,14 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "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-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", diff --git a/clientDiscord/package.json b/clientDiscord/package.json index 01f29bb..45bacc8 100644 --- a/clientDiscord/package.json +++ b/clientDiscord/package.json @@ -1,6 +1,6 @@ { "name": "clientdiscord", - "version": "1.2.0", + "version": "1.3.0", "description": "A discord bot for KarAssistant", "main": "index.js", "scripts": { @@ -24,6 +24,7 @@ "axios": "^1.5.0", "discord.js": "^14.13.0", "dotenv": "^16.3.1", + "node-forge": "^1.3.1", "node-rsa": "^1.1.1", "qs": "^6.11.2" }, diff --git a/clientDiscord/tests/utils/encryption.test.js b/clientDiscord/tests/utils/encryption.test.js new file mode 100644 index 0000000..fa03639 --- /dev/null +++ b/clientDiscord/tests/utils/encryption.test.js @@ -0,0 +1,161 @@ +const NodeRSA = require("node-rsa"); + +describe("Test rsa loadKey", () => { + test("Load public", async () => { + //Prepare + const key = + "-----BEGIN PUBLIC KEY-----\n" + + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGYAv73I12ZEBEqgJERAImH9p/\n" + + "/6sSkUP3vXG2S9O3R4WDP3PBqiaLJFEKn1aGIhc6+hs2wjXc6RduVj/CZjppOzW1\n" + + "Ni8q4S+PL1cYOimxX4PkwTGQkmg6VoPwELhOzuSEqsjalmzHg16FMY0JZTnKlyIw\n" + + "CICvRL9MmmoW1RP1TwIDAQAB\n" + + "-----END PUBLIC KEY-----"; + + //Execute + const result = require("../../utils/encryption").rsa.loadKey({ key }); + + //Test + expect(!!result.keyPair).toBe(true); + }); + + test("Load private", async () => { + //Prepare + const key = + "-----BEGIN RSA PRIVATE KEY-----\n" + + "MIICWwIBAAKBgQCZJ+rDmeiJzGMpOe4MNI+9DhZ+VnqplL6xUIQICexjU+02/F5H\n" + + "2vkXzeAiaAb5DZghaKdf4GGckUbBcwyHc/PceuzkAAatKPPATB8ACQ38RXqdGLak\n" + + "A7mo74GxUD0eKqbGeuue4nxmFUDDhcne0QPv4YLLlCYtOwWBsKikdKf8WQIDAQAB\n" + + "AoGAM6REAqRYxm4GWZZQ8AihFuwzJXJfdeLT0dIGUveVn4BjEhFScQQizaX7l15g\n" + + "S4YL7+fr1+Y+w54wr3XtmZa9eOawxdGY3YAknJpfSOK1mb1IJ714dF53KmJs7V8c\n" + + "MlO/bkihQNLrJIetYLi31V+l4LOStviboNVRkNVcinmFK6kCQQD+c8cGgXmX03W7\n" + + "SHdgW+Gv3bWR7v+5S+lvSqbIfWz6SYUEVZaQQbJuARd9Bodl2uYcvONW/TLgnhi3\n" + + "Yk4hgT1HAkEAmhZntxvKY4b4TXZdohwlQV6ow7yRjyG4EXMTYW5xc0HqUmx+8nhW\n" + + "zbYQSaGbCINfP1LLcnFpjkyOCMJdk39JXwJAZa1F/meGexDYnrnaWfrdODVT9LiY\n" + + "HyciZIJkGwFjpq/yI0VAIOzfq+1rwV32hNDv2tPv1DbhObhzD/SMW/8UyQJAMjwX\n" + + "uBSxWN1J2kc6o301kChCMP4rHlTJ47Z2nQ8aoY7dy91fTcF52zr9+GNdXdsmlEhz\n" + + "122uEhxXOffT9iBLVQJAa7pXvb7gmXoXV0MMGwzBl+fucjnl5TRIp5CbILETWS9F\n" + + "volGKmguKpLIchj+QYSisyXHsZ9a+k3ldBX/BVxXyg==\n" + + "-----END RSA PRIVATE KEY-----"; + + //Execute + const result = require("../../utils/encryption").rsa.loadKey({ key }); + + //Test + expect(!!result.keyPair).toBe(true); + }); + + test("Load failed", async () => { + //Prepare + const key = "Not a key"; + + //Execute + const result = require("../../utils/encryption").rsa.loadKey({ key }); + + //Test + expect(result).toBe(null); + }); +}); + +describe("Test rsa encryption/decrytion", () => { + test("encryption/decrytion", async () => { + //Prepare + const keyPublicString = + "-----BEGIN PUBLIC KEY-----\n" + + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwEbJyN+BDA4YrpNXNeCgEeYDb\n" + + "QYdiEl6FGmU+cyR8mH3jgbkw9SIjl19jpyaQL3rQYu6XJ8E8fV+izyauaUfGqA0X\n" + + "RbkGGEpZxkkAk8e+RpOjPOt8F6oaryTqg1SZassHTvWs9nfC/kYH/MLVncveHGVC\n" + + "bwLxzpkr1wfeUd9DAwIDAQAB\n" + + "-----END PUBLIC KEY-----"; + const keyPublic = new NodeRSA(keyPublicString); + const keyPrivateString = + "-----BEGIN RSA PRIVATE KEY-----\n" + + "MIICXAIBAAKBgQCwEbJyN+BDA4YrpNXNeCgEeYDbQYdiEl6FGmU+cyR8mH3jgbkw\n" + + "9SIjl19jpyaQL3rQYu6XJ8E8fV+izyauaUfGqA0XRbkGGEpZxkkAk8e+RpOjPOt8\n" + + "F6oaryTqg1SZassHTvWs9nfC/kYH/MLVncveHGVCbwLxzpkr1wfeUd9DAwIDAQAB\n" + + "AoGALzuAIG3m5nNSkfC1PlqGebTSoX7xv5hn7NMI5/jhh98snlSVhpGsJ9oax9P2\n" + + "X2WtT6vKj5glmYGUn0ts+ArcKvfPjcsZCLjUjkEjNmFAAdRsh/unqqtMHk0Zex20\n" + + "U/yT+a5RSkTGEA1EtqDvla4GN147Ir7Qz54k2q8hVUxeSvkCQQDUcKTBCkeNuZn+\n" + + "kZ8FaHaVmALQc3nHUxtAdBgNtPE+FgQi9fnDnxxH1LUBjmx1kO6YNxyhP7LWrZui\n" + + "Bm8jzfylAkEA1Cvhc0yPmRfrVkrkjmkFMuC9pTCNebnNGxVoVb4nDCnVOiNdyCbY\n" + + "5nRLzsaF74uKYekVmQ7EumC14IV7vGxohwJBALBwifWmcv1bvHG5Qmj8dRkTsqqs\n" + + "beVFuemTQnMH6CFXqcHbp8B4gsWJ/Xe4cY5HfFLB2y51uDQi5pLwYxhKud0CQGw7\n" + + "AiOFv46x4+u+An8e1XcRq8wTS2f3vsf9EJ8Eg/ixckLY/aL3JhfQ5UbSgEok3W96\n" + + "rfjIztPgN4cTsH36swsCQA4QJak5Omkb0KTnk6Q9e8qm0kLo2VOe3LPXFY73Rk+2\n" + + "CVm3BqS1NehnqgSxN98UgXRsT0z0NnFP8dQhh3qcbvQ=\n" + + "-----END RSA PRIVATE KEY-----"; + const keyPrivate = new NodeRSA(keyPrivateString); + const initData = { test: "test" }; + + //Execute encryption + const { encryptedData } = await require("../../utils/encryption").rsa.encrypt({ key: keyPublic, data: initData }); + + //Test encryption + expect(!!encryptedData).toBe(true); + + //Execute decryption + const { decryptedData } = await require("../../utils/encryption").rsa.decrypt({ + key: keyPrivate, + data: encryptedData, + }); + + //Test decryption + expect(JSON.stringify(decryptedData)).toBe(JSON.stringify(initData)); + }); +}); + +describe("Test aes encryption", () => { + test("Encrypt message and create key", async () => { + //Prepare + const message = "Test encrypt"; + + //Execute + const result = require("../../utils/encryption").aes.encrypt({ message }); + + //Test + expect(!!result.messageHex).toBe(true); + expect(!!result.keyBase64).toBe(true); + expect(!!result.ivBase64).toBe(true); + }); + + test("Encrypt message with specific keys", async () => { + //Prepare + const message = "Test encrypt"; + const keyBase64 = "SENyKJ2V1cL7nTNH0k1/Mg=="; + const ivBase64 = "hMraShc9/XkTn2m0Iwtw6w=="; + + //Execute + const result = require("../../utils/encryption").aes.encrypt({ message, keyBase64, ivBase64 }); + + //Test + expect(result.messageHex).toBe("2ccec94d3149368cf52a9e97589b6432"); + expect(result.keyBase64).toBe(keyBase64); + expect(result.ivBase64).toBe(ivBase64); + }); +}); + +describe("Test aes decryption", () => { + test("Decrypt message", async () => { + //Prepare + const messageHex = "2ccec94d3149368cf52a9e97589b6432"; + const keyBase64 = "SENyKJ2V1cL7nTNH0k1/Mg=="; + const ivBase64 = "hMraShc9/XkTn2m0Iwtw6w=="; + + //Execute + const result = require("../../utils/encryption").aes.decrypt({ messageHex, keyBase64, ivBase64 }); + + //Test + expect(result).toBe("Test encrypt"); + }); +}); + +describe("Test aes encryption and decryption", () => { + //Prepare + const message = JSON.stringify({ query: "Kara fait des tests" }); + + //Execute + const { messageHex, keyBase64, ivBase64 } = require("../../utils/encryption").aes.encrypt({ message }); + const result = require("../../utils/encryption").aes.decrypt({ messageHex, keyBase64, ivBase64 }); + + //Test + expect(result).toBe(message); +}); diff --git a/clientDiscord/tests/utils/getPassPhrase.test.js b/clientDiscord/tests/utils/getPassPhrase.test.js deleted file mode 100644 index 16720da..0000000 --- a/clientDiscord/tests/utils/getPassPhrase.test.js +++ /dev/null @@ -1,5 +0,0 @@ -describe("Get pass phrase", () => { - test("Example", async () => { - expect(true).toBe(true); - }); -}); diff --git a/clientDiscord/utils/encryption.js b/clientDiscord/utils/encryption.js new file mode 100644 index 0000000..9f669a7 --- /dev/null +++ b/clientDiscord/utils/encryption.js @@ -0,0 +1,69 @@ +const NodeRSA = require("node-rsa"); +const forge = require("node-forge"); + +module.exports = { + rsa: { + loadKey: ({ key }) => { + try { + const privateKeyObject = new NodeRSA(key); + return privateKeyObject; + } catch { + return null; + } + }, + encrypt: async ({ key, data }) => { + return await new Promise((resolve, reject) => { + try { + const encryptedData = key.encrypt(JSON.stringify(data), "base64"); + resolve({ encryptedData }); + /* c8 ignore start */ + } catch { + resolve({ encryptError: 403 }); + } + /* c8 ignore stop */ + }); + }, + decrypt: async ({ key, data }) => { + return await new Promise((resolve, reject) => { + try { + const decryptedData = key.decrypt(data, "utf8"); + resolve({ decryptedData: JSON.parse(decryptedData) }); + /* c8 ignore start */ + } catch (e) { + console.log(e); + resolve({ decryptError: 403 }); + } + /* c8 ignore stop */ + }); + }, + }, + aes: { + encrypt: ({ message, keyBase64, ivBase64 }) => { + const keyDecoded = keyBase64 ? forge.util.decode64(keyBase64) : forge.random.getBytesSync(16); + const ivDecoded = ivBase64 ? forge.util.decode64(ivBase64) : forge.random.getBytesSync(16); + + const keyBase64Export = forge.util.encode64(keyDecoded); + const ivBase64Export = forge.util.encode64(ivDecoded); + + const cipher = forge.cipher.createCipher("AES-CBC", keyDecoded); + cipher.start({ iv: ivDecoded }); + cipher.update(forge.util.createBuffer(message)); + cipher.finish(); + const messageHex = cipher.output.toHex(); + + return { messageHex, keyBase64: keyBase64Export, ivBase64: ivBase64Export }; + }, + decrypt: ({ keyBase64, ivBase64, messageHex }) => { + const messageBuff = Buffer.from(messageHex, "hex"); + const key = forge.util.decode64(keyBase64); + const iv = forge.util.decode64(ivBase64); + + const decipher = forge.cipher.createDecipher("AES-CBC", key); + decipher.start({ iv }); + decipher.update(forge.util.createBuffer(messageBuff)); + decipher.finish(); + + return decipher.output.toString("utf8"); + }, + }, +}; diff --git a/clientDiscord/utils/heyKara.js b/clientDiscord/utils/heyKara.js index 917d611..fc8f46c 100644 --- a/clientDiscord/utils/heyKara.js +++ b/clientDiscord/utils/heyKara.js @@ -15,9 +15,7 @@ async function makeRequest({ clientToken, data }) { api({ method: "GET", headers: { "Content-Type": "application/json", karaeatcookies: clientToken }, - params: { - data, - }, + params: data, url: process.env.BACK_URL + "/api/heyKara", }) .then(function (response) { @@ -50,6 +48,7 @@ async function heyKara({ userName, userId, messageContent, avatarUrl, retry = 0 messageContent, }); if (err) return err; + const dataRequest = data ? await makeRequest({ clientToken, data }) : { clientExist: false }; if (dataRequest.err && retry != 0) return dataRequest.err; @@ -59,11 +58,20 @@ async function heyKara({ userName, userId, messageContent, avatarUrl, retry = 0 return heyKara({ userName, userId, messageContent, avatarUrl, retry }); } - const resultDecrypted = data - ? await decryptResult({ data: dataRequest, key: clientPrivateKey }) - : { result: "Error with the request" }; + const clientPrivateKeyLoaded = require("../utils/encryption").rsa.loadKey({ key: clientPrivateKey }); + const { decryptClientAesError, decryptedData: dataAes } = await require("../utils/encryption").rsa.decrypt({ + key: clientPrivateKeyLoaded, + data: dataRequest.aes, + }); + if (decryptClientAesError) throw decryptClientAesError; + + const resultDecryptedString = require("../utils/encryption").aes.decrypt({ + messageHex: dataRequest.data, + keyBase64: dataAes.key, + ivBase64: dataAes.iv, + }); - console.log(resultDecrypted); + const resultDecrypted = JSON.parse(resultDecryptedString); const phraseResult = resultDecrypted.result; return phraseResult; } diff --git a/clientDiscord/utils/prepareRequest.js b/clientDiscord/utils/prepareRequest.js index 4eb599b..8351112 100644 --- a/clientDiscord/utils/prepareRequest.js +++ b/clientDiscord/utils/prepareRequest.js @@ -87,10 +87,15 @@ module.exports.prepareRequest = async ({ userId, userName, avatarUrl, messageCon }); if (err) return { err }; - const data = await encryptData({ - data: { query: messageContent }, + const { messageHex, keyBase64, ivBase64 } = require("../utils/encryption").aes.encrypt({ + message: JSON.stringify({ query: messageContent, date: new Date() }), + }); + + const aes = await encryptData({ + data: { key: keyBase64, iv: ivBase64 }, key: backPublicKey, }); + const data = { aes, data: messageHex }; return { clientToken, data, backPublicKey, clientPrivateKey }; }; From 9149ad4f8b515cf83b48894f58662507793a01cc Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Fri, 6 Oct 2023 00:35:57 +0200 Subject: [PATCH 04/36] Remove word 'failed' in test name --- clientDiscord/tests/utils/encryption.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clientDiscord/tests/utils/encryption.test.js b/clientDiscord/tests/utils/encryption.test.js index fa03639..34532d7 100644 --- a/clientDiscord/tests/utils/encryption.test.js +++ b/clientDiscord/tests/utils/encryption.test.js @@ -44,7 +44,7 @@ describe("Test rsa loadKey", () => { expect(!!result.keyPair).toBe(true); }); - test("Load failed", async () => { + test("Load error", async () => { //Prepare const key = "Not a key"; From d3f93e727ddf6b96d9db2c30978b3b42f87d5a51 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Fri, 6 Oct 2023 22:33:59 +0200 Subject: [PATCH 05/36] Remove date in AES object --- clientDiscord/utils/RSA.js | 1 - 1 file changed, 1 deletion(-) diff --git a/clientDiscord/utils/RSA.js b/clientDiscord/utils/RSA.js index bb68a63..6cd59a3 100644 --- a/clientDiscord/utils/RSA.js +++ b/clientDiscord/utils/RSA.js @@ -4,7 +4,6 @@ module.exports.encryptData = encryptData; async function encryptData({ data, key }) { try { const keyPublic = new NodeRSA(key); - data.date = new Date().toUTCString(); const passPhraseEncrypted = keyPublic.encrypt(JSON.stringify(data), "base64"); return passPhraseEncrypted; } catch { From a765d7bbe3f2621931567746bccb9d062cbd2921 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sat, 7 Oct 2023 15:46:21 +0200 Subject: [PATCH 06/36] Add publish test --- .github/workflows/client_discord-dockerPush.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 09b2430..c400bd3 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -50,7 +50,13 @@ jobs: continue-on-error: true working-directory: ./clientDiscord run: | - export NODE_OPTIONS=--no-experimental-fetch && npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt + export NODE_OPTIONS=--no-experimental-fetch && npm test --json --outputFile=/tmp/test/jest-output.json 2>> /tmp/results.txt >> /tmp/coverage0.txt + - name: Publish Test Results + - uses: EnricoMi/publish-unit-test-result-action@v2 + if: always() + with: + files: | + /tmp/test/*.json - name: Prepare data id: data run: | From 871cea9b93fb957dbc745940b19a218d047efdbb Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sat, 7 Oct 2023 15:46:58 +0200 Subject: [PATCH 07/36] Add publish test --- .github/workflows/client_discord-dockerPush.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index c400bd3..645d863 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -2,8 +2,8 @@ name: "[CLIENT_DISCORD] Docker push" run-name: "[CLIENT_DISCORD] DockerPush : ${{ github.actor }} push '${{ github.event.head_commit.message }}' 🚀" on: push: - paths: - - clientDiscord/** + # paths: + # - clientDiscord/** jobs: Check: runs-on: ubuntu-latest From f8e60a91cfc4dc61513ec2f6e3016aca7b82a2c8 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sat, 7 Oct 2023 15:48:47 +0200 Subject: [PATCH 08/36] Add publish test --- .github/workflows/client_discord-dockerPush.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 645d863..5be1ca4 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -51,8 +51,8 @@ jobs: working-directory: ./clientDiscord run: | export NODE_OPTIONS=--no-experimental-fetch && npm test --json --outputFile=/tmp/test/jest-output.json 2>> /tmp/results.txt >> /tmp/coverage0.txt - - name: Publish Test Results - - uses: EnricoMi/publish-unit-test-result-action@v2 + - name: Publish Test Results + uses: EnricoMi/publish-unit-test-result-action@v2 if: always() with: files: | From 8f7fb0c9cf7a06d3b58f07491431d251b7953c82 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sat, 7 Oct 2023 15:51:49 +0200 Subject: [PATCH 09/36] Add publish test --- .github/workflows/client_discord-dockerPush.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 5be1ca4..ed4f63b 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -50,7 +50,7 @@ jobs: continue-on-error: true working-directory: ./clientDiscord run: | - export NODE_OPTIONS=--no-experimental-fetch && npm test --json --outputFile=/tmp/test/jest-output.json 2>> /tmp/results.txt >> /tmp/coverage0.txt + export NODE_OPTIONS=--no-experimental-fetch && npm test -- --json --outputFile=/tmp/test/jest-output.json 2>> /tmp/results.txt >> /tmp/coverage0.txt - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 if: always() From 98244f50a67d37c51d5e9551f835edf05154b4d7 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sat, 7 Oct 2023 15:54:10 +0200 Subject: [PATCH 10/36] Add publish test --- .github/workflows/client_discord-dockerPush.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index ed4f63b..b04f101 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -51,6 +51,7 @@ jobs: working-directory: ./clientDiscord run: | export NODE_OPTIONS=--no-experimental-fetch && npm test -- --json --outputFile=/tmp/test/jest-output.json 2>> /tmp/results.txt >> /tmp/coverage0.txt + ll /tmp/test/ - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 if: always() From 7878a10ede43523c44f0e0feaeabe22baff189ab Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sat, 7 Oct 2023 15:59:45 +0200 Subject: [PATCH 11/36] Add publish test --- .github/workflows/client_discord-dockerPush.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index b04f101..0272f14 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -50,8 +50,8 @@ jobs: continue-on-error: true working-directory: ./clientDiscord run: | - export NODE_OPTIONS=--no-experimental-fetch && npm test -- --json --outputFile=/tmp/test/jest-output.json 2>> /tmp/results.txt >> /tmp/coverage0.txt - ll /tmp/test/ + mkdir /tmp/test/ + npm test -i -- --json --outputFile=/tmp/test/jest-output.json 2>> /tmp/results.txt >> /tmp/coverage0.txt - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 if: always() From a7f0aebe68c673e9e4eba7c95a9098527fbc4fe2 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sat, 7 Oct 2023 16:02:19 +0200 Subject: [PATCH 12/36] Add publish test --- .github/workflows/client_discord-dockerPush.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 0272f14..b08497b 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -52,6 +52,7 @@ jobs: run: | mkdir /tmp/test/ npm test -i -- --json --outputFile=/tmp/test/jest-output.json 2>> /tmp/results.txt >> /tmp/coverage0.txt + ll /tmp/test/ - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 if: always() From 10065317204ca8c7170d6c7434f291cf4638bfd7 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sat, 7 Oct 2023 16:04:07 +0200 Subject: [PATCH 13/36] Add publish test --- .github/workflows/client_discord-dockerPush.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index b08497b..f8785bc 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -52,7 +52,7 @@ jobs: run: | mkdir /tmp/test/ npm test -i -- --json --outputFile=/tmp/test/jest-output.json 2>> /tmp/results.txt >> /tmp/coverage0.txt - ll /tmp/test/ + ls -l /tmp/test/ - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 if: always() From 997414a7be59477682fd1a49f80700e95e9e6f8a Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sat, 7 Oct 2023 16:05:58 +0200 Subject: [PATCH 14/36] Add publish test --- .github/workflows/client_discord-dockerPush.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index f8785bc..3e766df 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -58,7 +58,7 @@ jobs: if: always() with: files: | - /tmp/test/*.json + /tmp/test/jest-output.json - name: Prepare data id: data run: | From 1ebc65db9a53c21673ace60113eed54842f3d624 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sat, 7 Oct 2023 16:07:23 +0200 Subject: [PATCH 15/36] Add publish test --- .github/workflows/client_discord-dockerPush.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 3e766df..34fb58f 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -52,7 +52,7 @@ jobs: run: | mkdir /tmp/test/ npm test -i -- --json --outputFile=/tmp/test/jest-output.json 2>> /tmp/results.txt >> /tmp/coverage0.txt - ls -l /tmp/test/ + cat /tmp/test/jest-output.json - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 if: always() From 42b283bc89366be5b75c5b87f2afa204653d9a4a Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sat, 7 Oct 2023 16:09:34 +0200 Subject: [PATCH 16/36] Add publish test --- .github/workflows/client_discord-dockerPush.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 34fb58f..93d2d3c 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -4,6 +4,9 @@ on: push: # paths: # - clientDiscord/** +permissions: + checks: write + pull-requests: write jobs: Check: runs-on: ubuntu-latest From aa7ab374111405d7ad3a8591c16c733bff4354de Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sun, 8 Oct 2023 00:07:09 +0200 Subject: [PATCH 17/36] Add report for test --- .github/workflows/client_discord-dockerPush.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 93d2d3c..35847dd 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -54,14 +54,13 @@ jobs: working-directory: ./clientDiscord run: | mkdir /tmp/test/ - npm test -i -- --json --outputFile=/tmp/test/jest-output.json 2>> /tmp/results.txt >> /tmp/coverage0.txt - cat /tmp/test/jest-output.json + export NODE_OPTIONS=--no-experimental-fetch && export JEST_JUNIT_OUTPUT_DIR="/tmp/report/" && npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 if: always() with: files: | - /tmp/test/jest-output.json + /tmp/tmp/report/*.xml - name: Prepare data id: data run: | From 17478d3dd721720e9601a4cc1837b1b35ee95763 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sun, 8 Oct 2023 00:08:09 +0200 Subject: [PATCH 18/36] Add report for test --- .github/workflows/client_discord-dockerPush.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 35847dd..92b057a 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -60,7 +60,7 @@ jobs: if: always() with: files: | - /tmp/tmp/report/*.xml + /tmp/report/*.xml - name: Prepare data id: data run: | From efea3406fe8fd18da08b80e08ba1ec816d884234 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sun, 8 Oct 2023 00:10:42 +0200 Subject: [PATCH 19/36] Add report for test --- .github/workflows/client_discord-dockerPush.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 92b057a..6a491b7 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -54,7 +54,9 @@ jobs: working-directory: ./clientDiscord run: | mkdir /tmp/test/ - export NODE_OPTIONS=--no-experimental-fetch && export JEST_JUNIT_OUTPUT_DIR="/tmp/report/" && npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt + export NODE_OPTIONS=--no-experimental-fetch && npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt + ls -l + ls -l report/ - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 if: always() From 2f796976e078b248415efa7712c204f633eedbda Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sun, 8 Oct 2023 00:12:26 +0200 Subject: [PATCH 20/36] Add report for test --- .github/workflows/client_discord-dockerPush.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 6a491b7..92b057a 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -54,9 +54,7 @@ jobs: working-directory: ./clientDiscord run: | mkdir /tmp/test/ - export NODE_OPTIONS=--no-experimental-fetch && npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt - ls -l - ls -l report/ + export NODE_OPTIONS=--no-experimental-fetch && export JEST_JUNIT_OUTPUT_DIR="/tmp/report/" && npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 if: always() From d2a5eeaa205e7eee9bf427f3dc6c9a33f71bc250 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sun, 8 Oct 2023 00:20:39 +0200 Subject: [PATCH 21/36] Add report for test --- .github/workflows/client_discord-dockerPush.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 92b057a..6337c00 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -55,6 +55,8 @@ jobs: run: | mkdir /tmp/test/ export NODE_OPTIONS=--no-experimental-fetch && export JEST_JUNIT_OUTPUT_DIR="/tmp/report/" && npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt + ls -l + ls -l report - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 if: always() From a0d2c742973d1b79e3da822f936510573b546cd0 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sun, 8 Oct 2023 00:23:50 +0200 Subject: [PATCH 22/36] Add report for test --- .github/workflows/client_discord-dockerPush.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 6337c00..bf15d23 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -53,8 +53,7 @@ jobs: continue-on-error: true working-directory: ./clientDiscord run: | - mkdir /tmp/test/ - export NODE_OPTIONS=--no-experimental-fetch && export JEST_JUNIT_OUTPUT_DIR="/tmp/report/" && npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt + npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt ls -l ls -l report - name: Publish Test Results From 403721b17484ebaab0175bb508797e6d2f87709b Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sun, 8 Oct 2023 00:28:39 +0200 Subject: [PATCH 23/36] Add report for test --- .github/workflows/client_discord-dockerPush.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index bf15d23..2aaaa5b 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -53,6 +53,7 @@ jobs: continue-on-error: true working-directory: ./clientDiscord run: | + npm test npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt ls -l ls -l report From 9bc822ad04becbef76136d94313d60189d5422b5 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sun, 8 Oct 2023 00:32:36 +0200 Subject: [PATCH 24/36] Add report for test --- .github/workflows/client_discord-dockerPush.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 2aaaa5b..907fd9c 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -55,8 +55,7 @@ jobs: run: | npm test npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt - ls -l - ls -l report + cat jest.config.js - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 if: always() From f269d58a2fe09bd3a8d85a87ae75f1868a418b0c Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sun, 8 Oct 2023 00:35:35 +0200 Subject: [PATCH 25/36] Add report for test --- .../workflows/client_discord-dockerPush.yml | 7 +-- clientDiscord/.gitignore | 1 + clientDiscord/jest.config.js | 2 +- clientDiscord/package-lock.json | 45 +++++++++++++++++-- clientDiscord/package.json | 1 + 5 files changed, 48 insertions(+), 8 deletions(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 907fd9c..6337c00 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -53,9 +53,10 @@ jobs: continue-on-error: true working-directory: ./clientDiscord run: | - npm test - npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt - cat jest.config.js + mkdir /tmp/test/ + export NODE_OPTIONS=--no-experimental-fetch && export JEST_JUNIT_OUTPUT_DIR="/tmp/report/" && npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt + ls -l + ls -l report - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 if: always() diff --git a/clientDiscord/.gitignore b/clientDiscord/.gitignore index 55cff86..6a93561 100644 --- a/clientDiscord/.gitignore +++ b/clientDiscord/.gitignore @@ -2,5 +2,6 @@ node_modules/ data/ logs/ coverage/ +reports/ .env .vscode/ \ No newline at end of file diff --git a/clientDiscord/jest.config.js b/clientDiscord/jest.config.js index 331f977..ee4f8d5 100644 --- a/clientDiscord/jest.config.js +++ b/clientDiscord/jest.config.js @@ -99,7 +99,7 @@ module.exports = { // projects: undefined, // Use this configuration option to add custom reporters to Jest - // reporters: undefined, + reporters: ["default", ["jest-junit", { outputDirectory: "reports", outputName: "report.xml" }]], // Automatically reset mock state before every test // resetMocks: false, diff --git a/clientDiscord/package-lock.json b/clientDiscord/package-lock.json index eb4c42d..d2ba418 100644 --- a/clientDiscord/package-lock.json +++ b/clientDiscord/package-lock.json @@ -1,17 +1,18 @@ { "name": "clientdiscord", - "version": "1.2.0", + "version": "1.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "clientdiscord", - "version": "1.2.0", + "version": "1.3.0", "license": "ISC", "dependencies": { "axios": "^1.5.0", "discord.js": "^14.13.0", "dotenv": "^16.3.1", + "jest-junit": "^16.0.0", "node-forge": "^1.3.1", "node-rsa": "^1.1.1", "qs": "^6.11.2" @@ -1293,7 +1294,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -2734,6 +2734,20 @@ "fsevents": "^2.3.2" } }, + "node_modules/jest-junit": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-16.0.0.tgz", + "integrity": "sha512-A94mmw6NfJab4Fg/BlvVOUXzXgF0XIH6EmTgJ5NDPp4xoKq0Kr7sErb+4Xs9nZvu58pJojz5RFGpqnZYJTrRfQ==", + "dependencies": { + "mkdirp": "^1.0.4", + "strip-ansi": "^6.0.1", + "uuid": "^8.3.2", + "xml": "^1.0.1" + }, + "engines": { + "node": ">=10.12.0" + } + }, "node_modules/jest-leak-detector": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.3.tgz", @@ -3304,6 +3318,17 @@ "node": "*" } }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4003,7 +4028,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4196,6 +4220,14 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-to-istanbul": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", @@ -4296,6 +4328,11 @@ } } }, + "node_modules/xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==" + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/clientDiscord/package.json b/clientDiscord/package.json index 45bacc8..dd1fde8 100644 --- a/clientDiscord/package.json +++ b/clientDiscord/package.json @@ -24,6 +24,7 @@ "axios": "^1.5.0", "discord.js": "^14.13.0", "dotenv": "^16.3.1", + "jest-junit": "^16.0.0", "node-forge": "^1.3.1", "node-rsa": "^1.1.1", "qs": "^6.11.2" From c6c648e940713f6f8d84e069b8cedfb4e367c61a Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sun, 8 Oct 2023 00:39:43 +0200 Subject: [PATCH 26/36] Add report for test --- .github/workflows/client_discord-dockerPush.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 6337c00..9cdaca8 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -56,7 +56,8 @@ jobs: mkdir /tmp/test/ export NODE_OPTIONS=--no-experimental-fetch && export JEST_JUNIT_OUTPUT_DIR="/tmp/report/" && npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt ls -l - ls -l report + grep -rni "> /tmp/results.txt >> /tmp/coverage0.txt - ls -l - grep -rni "> /tmp/results.txt >> /tmp/coverage0.txt - grep -rni "> $GITHUB_STEP_SUMMARY - cat /tmp/results.txt >> $GITHUB_STEP_SUMMARY - echo -e "\n" >> $GITHUB_STEP_SUMMARY - echo "❌ Errors with the test" >> $GITHUB_STEP_SUMMARY + # sed '$ d' /tmp/coverage1.txt > $GITHUB_STEP_SUMMARY + # echo -e "\n" >> $GITHUB_STEP_SUMMARY + # cat /tmp/results.txt >> $GITHUB_STEP_SUMMARY + # echo -e "\n" >> $GITHUB_STEP_SUMMARY + # echo "❌ Errors with the test" >> $GITHUB_STEP_SUMMARY exit 1 - - name: Echo success - if: steps.tests.outcome == 'success' - run: | - echo -e "\n" >> $GITHUB_STEP_SUMMARY - sed '$ d' /tmp/coverage1.txt > $GITHUB_STEP_SUMMARY - cat /tmp/results.txt >> $GITHUB_STEP_SUMMARY - echo -e "\n" >> $GITHUB_STEP_SUMMARY - echo "✅ All test are checked" >> $GITHUB_STEP_SUMMARY + # - name: Echo success + # if: steps.tests.outcome == 'success' + # run: | + # echo -e "\n" >> $GITHUB_STEP_SUMMARY + # sed '$ d' /tmp/coverage1.txt > $GITHUB_STEP_SUMMARY + # cat /tmp/results.txt >> $GITHUB_STEP_SUMMARY + # echo -e "\n" >> $GITHUB_STEP_SUMMARY + # echo "✅ All test are checked" >> $GITHUB_STEP_SUMMARY Build_Push: runs-on: ubuntu-latest From e866e27cc19524edd5167d009cd0c2da1271f79f Mon Sep 17 00:00:00 2001 From: CodySen <58334020+MathieuSchl@users.noreply.github.com> Date: Sun, 8 Oct 2023 09:43:46 +0200 Subject: [PATCH 33/36] Add condition for run job --- .github/workflows/client_discord-dockerPush.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 8598012..0e14834 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -2,8 +2,11 @@ name: "[CLIENT_DISCORD] Docker push" run-name: "[CLIENT_DISCORD] DockerPush : ${{ github.actor }} push '${{ github.event.head_commit.message }}' 🚀" on: push: - # paths: - # - clientDiscord/** + paths: + - clientDiscord/** + pull_request: + paths: + - clientDiscord/** permissions: checks: write pull-requests: write From f93db8ab20d2cf9fb7d201b9b7fbbc802f265640 Mon Sep 17 00:00:00 2001 From: CodySen <58334020+MathieuSchl@users.noreply.github.com> Date: Sun, 8 Oct 2023 09:51:44 +0200 Subject: [PATCH 34/36] Update client_discord-dockerPush.yml --- .github/workflows/client_discord-dockerPush.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/client_discord-dockerPush.yml b/.github/workflows/client_discord-dockerPush.yml index 0e14834..3bcc7d8 100644 --- a/.github/workflows/client_discord-dockerPush.yml +++ b/.github/workflows/client_discord-dockerPush.yml @@ -16,6 +16,7 @@ jobs: outputs: RUN_BUILD: ${{ steps.define_docker_data.outputs.run_build }} VERSION: ${{ steps.define_docker_data.outputs.version }} + if: github.event_name == 'push' steps: - name: Check out repository code uses: actions/checkout@v3 @@ -101,7 +102,7 @@ jobs: needs: - Check - Tests - if: ${{ needs.Check.outputs.RUN_BUILD == 'yes' && needs.Tests.result == 'success' }} + if: ${{ github.event_name == 'push' && needs.Check.outputs.RUN_BUILD == 'yes' && needs.Tests.result == 'success' }} steps: - name: Check out repository code uses: actions/checkout@v3 From 8b36be903e521dba56bf2a391785614ffa5e29dc Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Tue, 10 Oct 2023 12:27:40 +0200 Subject: [PATCH 35/36] Encryption is now easier to use --- clientDiscord/tests/utils/encryption.test.js | 76 +++++++- clientDiscord/utils/encryption.js | 191 +++++++++++++------ clientDiscord/utils/heyKara.js | 17 +- clientDiscord/utils/prepareRequest.js | 12 +- 4 files changed, 204 insertions(+), 92 deletions(-) diff --git a/clientDiscord/tests/utils/encryption.test.js b/clientDiscord/tests/utils/encryption.test.js index 34532d7..56163cb 100644 --- a/clientDiscord/tests/utils/encryption.test.js +++ b/clientDiscord/tests/utils/encryption.test.js @@ -149,13 +149,75 @@ describe("Test aes decryption", () => { }); describe("Test aes encryption and decryption", () => { - //Prepare - const message = JSON.stringify({ query: "Kara fait des tests" }); + test("Encrypt and decrypt", async () => { + //Prepare + const message = JSON.stringify({ query: "Kara fait des tests" }); + + //Execute + const { messageHex, keyBase64, ivBase64 } = require("../../utils/encryption").aes.encrypt({ message }); + const result = require("../../utils/encryption").aes.decrypt({ messageHex, keyBase64, ivBase64 }); + + //Test + expect(result).toBe(message); + }); +}); + +describe("Test encryption for request", () => { + test("Encryption", async () => { + //Prepare + const keyPublicString = + "-----BEGIN PUBLIC KEY-----\n" + + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwEbJyN+BDA4YrpNXNeCgEeYDb\n" + + "QYdiEl6FGmU+cyR8mH3jgbkw9SIjl19jpyaQL3rQYu6XJ8E8fV+izyauaUfGqA0X\n" + + "RbkGGEpZxkkAk8e+RpOjPOt8F6oaryTqg1SZassHTvWs9nfC/kYH/MLVncveHGVC\n" + + "bwLxzpkr1wfeUd9DAwIDAQAB\n" + + "-----END PUBLIC KEY-----"; + const query = "This is a test message. Test avec des charactères très spéciaux"; + + //Execute + const result = await require("../../utils/encryption").encryptionForRequest({ + query, + backPublicKey: keyPublicString, + }); + + //Test + expect(!!result.aes).toBe(true); + expect(!!result.data).toBe(true); + }); +}); - //Execute - const { messageHex, keyBase64, ivBase64 } = require("../../utils/encryption").aes.encrypt({ message }); - const result = require("../../utils/encryption").aes.decrypt({ messageHex, keyBase64, ivBase64 }); +describe("Test decryption for result", () => { + test("Decryption", async () => { + //Prepare + const keyPrivateString = + "-----BEGIN RSA PRIVATE KEY-----\n" + + "MIICXAIBAAKBgQCwEbJyN+BDA4YrpNXNeCgEeYDbQYdiEl6FGmU+cyR8mH3jgbkw\n" + + "9SIjl19jpyaQL3rQYu6XJ8E8fV+izyauaUfGqA0XRbkGGEpZxkkAk8e+RpOjPOt8\n" + + "F6oaryTqg1SZassHTvWs9nfC/kYH/MLVncveHGVCbwLxzpkr1wfeUd9DAwIDAQAB\n" + + "AoGALzuAIG3m5nNSkfC1PlqGebTSoX7xv5hn7NMI5/jhh98snlSVhpGsJ9oax9P2\n" + + "X2WtT6vKj5glmYGUn0ts+ArcKvfPjcsZCLjUjkEjNmFAAdRsh/unqqtMHk0Zex20\n" + + "U/yT+a5RSkTGEA1EtqDvla4GN147Ir7Qz54k2q8hVUxeSvkCQQDUcKTBCkeNuZn+\n" + + "kZ8FaHaVmALQc3nHUxtAdBgNtPE+FgQi9fnDnxxH1LUBjmx1kO6YNxyhP7LWrZui\n" + + "Bm8jzfylAkEA1Cvhc0yPmRfrVkrkjmkFMuC9pTCNebnNGxVoVb4nDCnVOiNdyCbY\n" + + "5nRLzsaF74uKYekVmQ7EumC14IV7vGxohwJBALBwifWmcv1bvHG5Qmj8dRkTsqqs\n" + + "beVFuemTQnMH6CFXqcHbp8B4gsWJ/Xe4cY5HfFLB2y51uDQi5pLwYxhKud0CQGw7\n" + + "AiOFv46x4+u+An8e1XcRq8wTS2f3vsf9EJ8Eg/ixckLY/aL3JhfQ5UbSgEok3W96\n" + + "rfjIztPgN4cTsH36swsCQA4QJak5Omkb0KTnk6Q9e8qm0kLo2VOe3LPXFY73Rk+2\n" + + "CVm3BqS1NehnqgSxN98UgXRsT0z0NnFP8dQhh3qcbvQ=\n" + + "-----END RSA PRIVATE KEY-----"; + const data = { + aes: "csq80fC5PEE1MGCGpqkIlP1QyZKvoQ74tzpmS+Utbi6nlyaI+ZRRLV4Gr4FNCVAUhKmO8mcmBhuto6EvlfVr5bnT9pmKj8rwu+Q4uVxE7tcPc+huHJ6ARAYQIklP/mtLLXJDxRiohq7ePJn73qch3iEKaVvpap2lva8+flc8luc=", + data: "daa9fe620ffdeb7cd78abd0071395c993b1dfad57be2738b6380174cfd328230ccaed52f539f9e10364dd15a4bdbe90c70de582af1cf3a14251a24d11ce25686316e8f6ddf925c9c8dbf211ade892a8f30836cc9e1eb6fc024db7ae0c6118cbae80089b8c120f6b095ea0bf889b550832c444531655d478d6d53911e02038b2a", + }; + + //Executeawait decryptionForResult({ clientPrivateKey, data: dataRequest }); + const result = await require("../../utils/encryption").decryptionForResult({ + clientPrivateKey: keyPrivateString, + data: data, + }); - //Test - expect(result).toBe(message); + //Test + expect(result.query).toBe("This is a test message. Test avec des charactères très spéciaux"); + expect(!!result.date).toBe(true); + }); }); diff --git a/clientDiscord/utils/encryption.js b/clientDiscord/utils/encryption.js index 9f669a7..f669ca5 100644 --- a/clientDiscord/utils/encryption.js +++ b/clientDiscord/utils/encryption.js @@ -1,69 +1,140 @@ const NodeRSA = require("node-rsa"); const forge = require("node-forge"); +const regexSpectialChar = /[^\x00-\x7F]/; +function convertExceptionToHex(text) { + let result = ""; + for (let i = 0; i < text.length; i++) { + const char = text.charAt(i); + const codeAsciiHex = char.charCodeAt(0).toString(16); // Convertit le code ASCII en hexadécimal + if (regexSpectialChar.test(char)) result = result + "\\x" + codeAsciiHex; + else result = result + char; + } + return result; +} + +function convertExceptionToString(text) { + const decodedString = eval(`"${text}"`); + return decodedString; +} + +function loadKeyRSA({ key }) { + try { + const privateKeyObject = new NodeRSA(key); + return privateKeyObject; + } catch { + return null; + } +} + +async function encryptRSA({ key, data }) { + return await new Promise((resolve, reject) => { + try { + const encryptedData = key.encrypt(JSON.stringify(data), "base64"); + resolve({ encryptedData }); + /* c8 ignore start */ + } catch { + resolve({ encryptError: 403 }); + } + /* c8 ignore stop */ + }); +} + +async function decryptRSA({ key, data }) { + return await new Promise((resolve, reject) => { + try { + const decryptedData = key.decrypt(data, "utf8"); + resolve({ decryptedData: JSON.parse(decryptedData) }); + /* c8 ignore start */ + } catch (e) { + console.log(e); + resolve({ decryptError: 403 }); + } + /* c8 ignore stop */ + }); +} + +function encryptAES({ message, keyBase64, ivBase64 }) { + const keyDecoded = keyBase64 ? forge.util.decode64(keyBase64) : forge.random.getBytesSync(16); + const ivDecoded = ivBase64 ? forge.util.decode64(ivBase64) : forge.random.getBytesSync(16); + + const keyBase64Export = forge.util.encode64(keyDecoded); + const ivBase64Export = forge.util.encode64(ivDecoded); + + const cipher = forge.cipher.createCipher("AES-CBC", keyDecoded); + cipher.start({ iv: ivDecoded }); + cipher.update(forge.util.createBuffer(message)); + cipher.finish(); + const messageHex = cipher.output.toHex(); + + return { messageHex, keyBase64: keyBase64Export, ivBase64: ivBase64Export }; +} + +function decryptAES({ keyBase64, ivBase64, messageHex }) { + try { + const messageBuff = Buffer.from(messageHex, "hex"); + const key = forge.util.decode64(keyBase64); + const iv = forge.util.decode64(ivBase64); + + const decipher = forge.cipher.createDecipher("AES-CBC", key); + decipher.start({ iv }); + decipher.update(forge.util.createBuffer(messageBuff)); + decipher.finish(); + + return decipher.output.toString("utf8"); + /* c8 ignore start */ + } catch (error) { + return JSON.stringify({ result: "ERROR FOR DECRYPT AES" }); + } + /* c8 ignore stop */ +} + +async function encryptionForRequest({ query, backPublicKey }) { + const { messageHex, keyBase64, ivBase64 } = encryptAES({ + message: JSON.stringify({ query: convertExceptionToHex(query), date: new Date() }), + }); + + const key = loadKeyRSA({ key: backPublicKey }); + const { encryptedData } = await encryptRSA({ + data: { key: keyBase64, iv: ivBase64 }, + key, + }); + const data = { aes: encryptedData, data: messageHex }; + + return data; +} + +async function decryptionForResult({ data, clientPrivateKey }) { + const clientPrivateKeyLoaded = loadKeyRSA({ key: clientPrivateKey }); + const { decryptClientAesError, decryptedData: dataAes } = await decryptRSA({ + key: clientPrivateKeyLoaded, + data: data.aes, + }); + /* c8 ignore start */ + if (decryptClientAesError) throw decryptClientAesError; + /* c8 ignore stop */ + + const resultDecryptedString = decryptAES({ + messageHex: data.data, + keyBase64: dataAes.key, + ivBase64: dataAes.iv, + }); + + const resultDecrypted = JSON.parse(resultDecryptedString); + if (resultDecrypted.query) resultDecrypted.query = convertExceptionToString(resultDecrypted.query); + return resultDecrypted; +} + module.exports = { rsa: { - loadKey: ({ key }) => { - try { - const privateKeyObject = new NodeRSA(key); - return privateKeyObject; - } catch { - return null; - } - }, - encrypt: async ({ key, data }) => { - return await new Promise((resolve, reject) => { - try { - const encryptedData = key.encrypt(JSON.stringify(data), "base64"); - resolve({ encryptedData }); - /* c8 ignore start */ - } catch { - resolve({ encryptError: 403 }); - } - /* c8 ignore stop */ - }); - }, - decrypt: async ({ key, data }) => { - return await new Promise((resolve, reject) => { - try { - const decryptedData = key.decrypt(data, "utf8"); - resolve({ decryptedData: JSON.parse(decryptedData) }); - /* c8 ignore start */ - } catch (e) { - console.log(e); - resolve({ decryptError: 403 }); - } - /* c8 ignore stop */ - }); - }, + loadKey: loadKeyRSA, + encrypt: encryptRSA, + decrypt: decryptRSA, }, aes: { - encrypt: ({ message, keyBase64, ivBase64 }) => { - const keyDecoded = keyBase64 ? forge.util.decode64(keyBase64) : forge.random.getBytesSync(16); - const ivDecoded = ivBase64 ? forge.util.decode64(ivBase64) : forge.random.getBytesSync(16); - - const keyBase64Export = forge.util.encode64(keyDecoded); - const ivBase64Export = forge.util.encode64(ivDecoded); - - const cipher = forge.cipher.createCipher("AES-CBC", keyDecoded); - cipher.start({ iv: ivDecoded }); - cipher.update(forge.util.createBuffer(message)); - cipher.finish(); - const messageHex = cipher.output.toHex(); - - return { messageHex, keyBase64: keyBase64Export, ivBase64: ivBase64Export }; - }, - decrypt: ({ keyBase64, ivBase64, messageHex }) => { - const messageBuff = Buffer.from(messageHex, "hex"); - const key = forge.util.decode64(keyBase64); - const iv = forge.util.decode64(ivBase64); - - const decipher = forge.cipher.createDecipher("AES-CBC", key); - decipher.start({ iv }); - decipher.update(forge.util.createBuffer(messageBuff)); - decipher.finish(); - - return decipher.output.toString("utf8"); - }, + encrypt: encryptAES, + decrypt: decryptAES, }, + encryptionForRequest, + decryptionForResult, }; diff --git a/clientDiscord/utils/heyKara.js b/clientDiscord/utils/heyKara.js index fc8f46c..50f4e33 100644 --- a/clientDiscord/utils/heyKara.js +++ b/clientDiscord/utils/heyKara.js @@ -7,7 +7,7 @@ const api = axios.create({ }, }); const prepareRequest = require("./prepareRequest").prepareRequest; -const decryptResult = require("./prepareRequest").decryptResult; +const decryptionForResult = require("../utils/encryption").decryptionForResult; module.exports.makeRequest = makeRequest; async function makeRequest({ clientToken, data }) { @@ -58,20 +58,7 @@ async function heyKara({ userName, userId, messageContent, avatarUrl, retry = 0 return heyKara({ userName, userId, messageContent, avatarUrl, retry }); } - const clientPrivateKeyLoaded = require("../utils/encryption").rsa.loadKey({ key: clientPrivateKey }); - const { decryptClientAesError, decryptedData: dataAes } = await require("../utils/encryption").rsa.decrypt({ - key: clientPrivateKeyLoaded, - data: dataRequest.aes, - }); - if (decryptClientAesError) throw decryptClientAesError; - - const resultDecryptedString = require("../utils/encryption").aes.decrypt({ - messageHex: dataRequest.data, - keyBase64: dataAes.key, - ivBase64: dataAes.iv, - }); - - const resultDecrypted = JSON.parse(resultDecryptedString); + const resultDecrypted = await decryptionForResult({ clientPrivateKey, data: dataRequest }); const phraseResult = resultDecrypted.result; return phraseResult; } diff --git a/clientDiscord/utils/prepareRequest.js b/clientDiscord/utils/prepareRequest.js index 8351112..f76a460 100644 --- a/clientDiscord/utils/prepareRequest.js +++ b/clientDiscord/utils/prepareRequest.js @@ -1,5 +1,5 @@ const fs = require("fs"); -const encryptData = require("./RSA").encryptData; +const encryptionForRequest = require("./encryption").encryptionForRequest; const updateUser = require("./updateUser").updateUser; const { stringify } = require("qs"); const axios = require("axios"); @@ -87,15 +87,7 @@ module.exports.prepareRequest = async ({ userId, userName, avatarUrl, messageCon }); if (err) return { err }; - const { messageHex, keyBase64, ivBase64 } = require("../utils/encryption").aes.encrypt({ - message: JSON.stringify({ query: messageContent, date: new Date() }), - }); - - const aes = await encryptData({ - data: { key: keyBase64, iv: ivBase64 }, - key: backPublicKey, - }); - const data = { aes, data: messageHex }; + const data = await encryptionForRequest({ query: messageContent, backPublicKey }); return { clientToken, data, backPublicKey, clientPrivateKey }; }; From 8198a137869fced39dc778fec4e67315f594ec06 Mon Sep 17 00:00:00 2001 From: CodyIsTheSenate Date: Sun, 15 Oct 2023 16:09:30 +0200 Subject: [PATCH 36/36] Add special characters --- clientDiscord/docker-compose.yml | 2 +- clientDiscord/package.json | 2 +- clientDiscord/tests/utils/encryption.test.js | 38 +++++++++++--------- clientDiscord/utils/encryption.js | 6 ++-- clientDiscord/utils/heyKara.js | 15 ++++---- 5 files changed, 34 insertions(+), 29 deletions(-) diff --git a/clientDiscord/docker-compose.yml b/clientDiscord/docker-compose.yml index cbdac53..739ce12 100644 --- a/clientDiscord/docker-compose.yml +++ b/clientDiscord/docker-compose.yml @@ -3,7 +3,7 @@ version: "3" services: karassistant-client-discord: #build: . - image: codyisthesenate/karassistant-client-discord:1.3.0 + image: codyisthesenate/karassistant-client-discord:1.3.1 restart: always container_name: karassistant-client-discord volumes: diff --git a/clientDiscord/package.json b/clientDiscord/package.json index dd1fde8..6e07f00 100644 --- a/clientDiscord/package.json +++ b/clientDiscord/package.json @@ -1,6 +1,6 @@ { "name": "clientdiscord", - "version": "1.3.0", + "version": "1.3.1", "description": "A discord bot for KarAssistant", "main": "index.js", "scripts": { diff --git a/clientDiscord/tests/utils/encryption.test.js b/clientDiscord/tests/utils/encryption.test.js index 56163cb..74bde1b 100644 --- a/clientDiscord/tests/utils/encryption.test.js +++ b/clientDiscord/tests/utils/encryption.test.js @@ -191,23 +191,23 @@ describe("Test decryption for result", () => { //Prepare const keyPrivateString = "-----BEGIN RSA PRIVATE KEY-----\n" + - "MIICXAIBAAKBgQCwEbJyN+BDA4YrpNXNeCgEeYDbQYdiEl6FGmU+cyR8mH3jgbkw\n" + - "9SIjl19jpyaQL3rQYu6XJ8E8fV+izyauaUfGqA0XRbkGGEpZxkkAk8e+RpOjPOt8\n" + - "F6oaryTqg1SZassHTvWs9nfC/kYH/MLVncveHGVCbwLxzpkr1wfeUd9DAwIDAQAB\n" + - "AoGALzuAIG3m5nNSkfC1PlqGebTSoX7xv5hn7NMI5/jhh98snlSVhpGsJ9oax9P2\n" + - "X2WtT6vKj5glmYGUn0ts+ArcKvfPjcsZCLjUjkEjNmFAAdRsh/unqqtMHk0Zex20\n" + - "U/yT+a5RSkTGEA1EtqDvla4GN147Ir7Qz54k2q8hVUxeSvkCQQDUcKTBCkeNuZn+\n" + - "kZ8FaHaVmALQc3nHUxtAdBgNtPE+FgQi9fnDnxxH1LUBjmx1kO6YNxyhP7LWrZui\n" + - "Bm8jzfylAkEA1Cvhc0yPmRfrVkrkjmkFMuC9pTCNebnNGxVoVb4nDCnVOiNdyCbY\n" + - "5nRLzsaF74uKYekVmQ7EumC14IV7vGxohwJBALBwifWmcv1bvHG5Qmj8dRkTsqqs\n" + - "beVFuemTQnMH6CFXqcHbp8B4gsWJ/Xe4cY5HfFLB2y51uDQi5pLwYxhKud0CQGw7\n" + - "AiOFv46x4+u+An8e1XcRq8wTS2f3vsf9EJ8Eg/ixckLY/aL3JhfQ5UbSgEok3W96\n" + - "rfjIztPgN4cTsH36swsCQA4QJak5Omkb0KTnk6Q9e8qm0kLo2VOe3LPXFY73Rk+2\n" + - "CVm3BqS1NehnqgSxN98UgXRsT0z0NnFP8dQhh3qcbvQ=\n" + + "MIICXgIBAAKBgQDKBVEb0V14yZe824p++J4WrldboXRXoBJZbFmJukFaRXqMhu2i\n" + + "o9Z+8onfbeMMfkbD21YLPivZYLx52v7qocq+znVtU/F77LrnsP6tUMLQKaUDMOM6\n" + + "J1i+lLjsFnxJO0IdQNOk6hHPcre88pGDlY8gUKGXzbYEu7v46szU9skpGwIDAQAB\n" + + "AoGAfVVNG7gJiI1xQS7nPpzZ33JsKiIBvvdFSwtIhYTzVKD0RcjUF2oUAhBQ7zgK\n" + + "e86/8nTabgE1TRiR9fui2UhlMl8iojR9agFJmjH6cqdXf/T6hRfe/mq7Kj561FFc\n" + + "zNoTGsIxQcCXhI+Vdf6dLl2oiw4kTPWfTxFrI2XtuCZfsNECQQDrqIAKc5JKU6a/\n" + + "0ahk4PkYMXkGNUXxSJVZb/c4P/yMk1xYQPrlQUsI97kEdBvwKcKSyxwNqpQEUUm+\n" + + "ibFYtPS5AkEA23WB4nF2OCgBLrLuOyHiRcOXC+JHyiKXJDimhCD/YKc7BdNFP3tA\n" + + "kFiW1Y7tPcdhysMG/IGN0DD2EyOwU3AKcwJBANz9rOUgMCXHgG4NnI7Ncoq/ijDK\n" + + "MIbufC/dEccMKjdh0Y1pkl7+9fC47iZBBBoZ7z9dfTdLqXbLDA7EbS00tPECQQC4\n" + + "849DB9xZ910HvkSIEUZhBTWHDmzyLbSzEgtDz4tqKYXUovj5RyZigEaeNJY8Ooxw\n" + + "FW0N4SFjE+BOwQUZTJOBAkEA6Ch5im1xvBW3iDo2JVKMzjNZu/FvOMxdgrox+JmU\n" + + "GJa5L3R9piU4RzntMb04KG3BLZ9jTUzIUafLlusDhI6mdw==\n" + "-----END RSA PRIVATE KEY-----"; const data = { - aes: "csq80fC5PEE1MGCGpqkIlP1QyZKvoQ74tzpmS+Utbi6nlyaI+ZRRLV4Gr4FNCVAUhKmO8mcmBhuto6EvlfVr5bnT9pmKj8rwu+Q4uVxE7tcPc+huHJ6ARAYQIklP/mtLLXJDxRiohq7ePJn73qch3iEKaVvpap2lva8+flc8luc=", - data: "daa9fe620ffdeb7cd78abd0071395c993b1dfad57be2738b6380174cfd328230ccaed52f539f9e10364dd15a4bdbe90c70de582af1cf3a14251a24d11ce25686316e8f6ddf925c9c8dbf211ade892a8f30836cc9e1eb6fc024db7ae0c6118cbae80089b8c120f6b095ea0bf889b550832c444531655d478d6d53911e02038b2a", + aes: "a9eTCsLtKXNFzsKAdAOpOpfczmTu7Eh1o9yecGtWlmvxhlBeqV6KFljK7YYSWkD5SnaaAa76yPknhlpsCY8kyjpPayJw2B68QSAqZEDmjS3OTDZunC/Z4NRSG5a0h2fy9UKr9KYLvw4xDjxlPEj/yA9q0VSQGOxn3O+4m7r2h6o=", + data: "330c28589035ff92e6f86a786ddb98d6cc4a15f91b4b6c2601d2e891d405dacd22db25d4ed9e3037f0937fdda4835dcd68942cd3d1fd4a7eabc4e40b8d214861855ac9c618e495d8c5c7fe808c22bfa8c40ef99080193de7a03f91c7fb85bbda97136e78399b282eac6995dff0ec4948937e1391f6320c245bd05b28e3c4edb30935525e4652646ec576f97e11c28e4580b960ee772ca0f2663f54281cfaa3872d56b5ff64a4e959c41add36d38ebba495690973a16a626deabc4f9750673a7d661e27c9de610477084d2053de8c9bd8901699c2ab509b06e67e9398bd52676486287cc0df7610eab268cadcfbc0a1c2", }; //Executeawait decryptionForResult({ clientPrivateKey, data: dataRequest }); @@ -217,7 +217,11 @@ describe("Test decryption for result", () => { }); //Test - expect(result.query).toBe("This is a test message. Test avec des charactères très spéciaux"); - expect(!!result.date).toBe(true); + expect(result.result).toBe("Quelle est la ville, dont vous souhaitez connaître la météo ?"); + expect(!!result.similarity).toBe(true); + expect(!!result.bestPhrase).toBe(true); + expect(result.shortAnswerExpected).toBe(true); + expect(!!result.lang).toBe(true); + expect(!!result.skill).toBe(true); }); }); diff --git a/clientDiscord/utils/encryption.js b/clientDiscord/utils/encryption.js index f669ca5..865d8c6 100644 --- a/clientDiscord/utils/encryption.js +++ b/clientDiscord/utils/encryption.js @@ -48,7 +48,7 @@ async function decryptRSA({ key, data }) { /* c8 ignore start */ } catch (e) { console.log(e); - resolve({ decryptError: 403 }); + resolve({ decryptError: 406 }); } /* c8 ignore stop */ }); @@ -119,9 +119,9 @@ async function decryptionForResult({ data, clientPrivateKey }) { keyBase64: dataAes.key, ivBase64: dataAes.iv, }); - const resultDecrypted = JSON.parse(resultDecryptedString); - if (resultDecrypted.query) resultDecrypted.query = convertExceptionToString(resultDecrypted.query); + if (resultDecrypted.bestPhrase) resultDecrypted.bestPhrase = convertExceptionToString(resultDecrypted.bestPhrase); + if (resultDecrypted.result) resultDecrypted.result = convertExceptionToString(resultDecrypted.result); return resultDecrypted; } diff --git a/clientDiscord/utils/heyKara.js b/clientDiscord/utils/heyKara.js index 50f4e33..c2d8afd 100644 --- a/clientDiscord/utils/heyKara.js +++ b/clientDiscord/utils/heyKara.js @@ -25,15 +25,15 @@ async function makeRequest({ clientToken, data }) { }) .catch(function (error) { if (error.code === "ECONNREFUSED") - resolve({ err: "Access to the Kara server cannot be established", status: 420 }); - if (error.response && error.response.status === 403) - resolve({ err: "Access to the Kara server is forbidden", status: error.response.status }); + return resolve({ err: "Access to the Kara server cannot be established", status: 420 }); + else if (error.response && error.response.status === 403) + return resolve({ err: "Access to the Kara server is forbidden", status: error.response.status }); else if (error.response && error.response.status === 404) return resolve({ err: "User does not exist", status: error.response.status }); - if (error.response && error.response.status === 500) - resolve({ err: "Kara as an internal error", status: error.response.status }); + else if (error.response && error.response.status === 500) + return resolve({ err: "Kara as an internal error", status: error.response.status }); else { - resolve({ err: error.code, status: error.response ? error.response.status : 420 }); + return resolve({ err: error.code, status: error.response ? error.response.status : 420 }); } }); }); @@ -53,7 +53,8 @@ async function heyKara({ userName, userId, messageContent, avatarUrl, retry = 0 if (dataRequest.err && retry != 0) return dataRequest.err; if (!dataRequest || dataRequest.err) { - if (dataRequest && dataRequest.status === 404) fs.unlinkSync(__dirname + "/../data/clients/" + userId + ".json"); + if (dataRequest && (dataRequest.status === 404 || dataRequest.status === 406)) + fs.unlinkSync(__dirname + "/../data/clients/" + userId + ".json"); retry++; return heyKara({ userName, userId, messageContent, avatarUrl, retry }); }