From 65158b9368bd213ad8f9fa2ec8cbe9b81cb80c9a Mon Sep 17 00:00:00 2001 From: "pramod.mahajan" Date: Tue, 9 Dec 2025 16:37:13 +0530 Subject: [PATCH] added encryption --- package-lock.json | 7 ++++ package.json | 1 + src/services/encryption.jsx | 64 +++++++++++++++++++++++++++++++++++++ src/utils/axiosClient.jsx | 12 +++---- 4 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 src/services/encryption.jsx diff --git a/package-lock.json b/package-lock.json index 703df311..c7c0a754 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "apexcharts": "^4.5.0", "axios": "^1.7.9", "axios-retry": "^4.5.0", + "crypto-js": "^4.2.0", "date-fns": "^4.1.0", "dotenv": "^16.4.7", "dotenv-webpack": "^8.1.0", @@ -2414,6 +2415,12 @@ "node": ">= 8" } }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "license": "MIT" + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", diff --git a/package.json b/package.json index 02c59115..ba616768 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "apexcharts": "^4.5.0", "axios": "^1.7.9", "axios-retry": "^4.5.0", + "crypto-js": "^4.2.0", "date-fns": "^4.1.0", "dotenv": "^16.4.7", "dotenv-webpack": "^8.1.0", diff --git a/src/services/encryption.jsx b/src/services/encryption.jsx new file mode 100644 index 00000000..12ac3efe --- /dev/null +++ b/src/services/encryption.jsx @@ -0,0 +1,64 @@ +import CryptoJS from 'crypto-js'; + +// The key from your C# Middleware +// In a real app, prefer storing this in process.env.REACT_APP_ENCRYPTION_KEY +const KEY_BASE64 = "u4J7p9Qx2hF5vYtLz8Kq3mN1sG0bRwXyZcD6eH8jFQw="; + +/** + * Decrypts the specific format sent by the C# EncryptionMiddleware. + * Format: Base64([IV (16 bytes)] + [Encrypted Data]) + * * @param {string} encryptedBase64Str - The raw response text from the API + * @returns {any} - The parsed JSON object or string + */ +export const decryptResponse = (encryptedBase64Str) => { + try { + // 1. Parse the Key + const key = CryptoJS.enc.Base64.parse(KEY_BASE64); + + // 2. Parse the incoming Base64 string to a WordArray + const fullWordArray = CryptoJS.enc.Base64.parse(encryptedBase64Str); + + // 3. Convert to Hex to easily slice the IV (16 bytes = 32 hex chars) + // This is safer than manipulating WordArray indices directly + const fullHex = CryptoJS.enc.Hex.stringify(fullWordArray); + + // 4. Extract IV (First 16 bytes / 32 hex characters) + const ivHex = fullHex.substring(0, 32); + const iv = CryptoJS.enc.Hex.parse(ivHex); + + // 5. Extract Ciphertext (The rest of the string) + const cipherTextHex = fullHex.substring(32); + const cipherParams = CryptoJS.lib.CipherParams.create({ + ciphertext: CryptoJS.enc.Hex.parse(cipherTextHex) + }); + + // 6. Decrypt + const decrypted = CryptoJS.AES.decrypt( + cipherParams, + key, + { + iv: iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + } + ); + + // 7. Convert to UTF-8 String + const decryptedString = decrypted.toString(CryptoJS.enc.Utf8); + + if (!decryptedString) { + throw new Error("Decryption produced empty result (Wrong Key/IV?)"); + } + + // 8. Try to parse JSON, otherwise return plain string + try { + return JSON.parse(decryptedString); + } catch { + return decryptedString; + } + + } catch (error) { + console.error("Decryption Failed:", error); + return null; + } +}; \ No newline at end of file diff --git a/src/utils/axiosClient.jsx b/src/utils/axiosClient.jsx index 40981633..fb79796f 100644 --- a/src/utils/axiosClient.jsx +++ b/src/utils/axiosClient.jsx @@ -4,6 +4,7 @@ import axiosRetry from "axios-retry"; import showToast from "../services/toastService"; import { startSignalR, stopSignalR } from "../services/signalRService"; import { BASE_URL } from "./constants"; +import { decryptResponse } from "../services/encryption"; const base_Url = BASE_URL; export const axiosClient = axios.create({ @@ -134,7 +135,7 @@ const apiRequest = async (method, url, data = {}, config = {}) => { params: method === "get" ? data : undefined, ...config, }); - return response.data; + return decryptResponse(response.data); } catch (error) { throw error; } @@ -179,11 +180,10 @@ export const api = { authRequired: true, }), patch: (url, data = {}, customHeaders = {}) => - apiRequest("patch", url, data, { - headers: { ...customHeaders }, - authRequired: true, - }), - + apiRequest("patch", url, data, { + headers: { ...customHeaders }, + authRequired: true, + }), }; // Redirect helper