added encryption
This commit is contained in:
parent
4a47b1d0fa
commit
65158b9368
7
package-lock.json
generated
7
package-lock.json
generated
@ -18,6 +18,7 @@
|
|||||||
"apexcharts": "^4.5.0",
|
"apexcharts": "^4.5.0",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"axios-retry": "^4.5.0",
|
"axios-retry": "^4.5.0",
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"dotenv-webpack": "^8.1.0",
|
"dotenv-webpack": "^8.1.0",
|
||||||
@ -2414,6 +2415,12 @@
|
|||||||
"node": ">= 8"
|
"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": {
|
"node_modules/csstype": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
"apexcharts": "^4.5.0",
|
"apexcharts": "^4.5.0",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"axios-retry": "^4.5.0",
|
"axios-retry": "^4.5.0",
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"dotenv-webpack": "^8.1.0",
|
"dotenv-webpack": "^8.1.0",
|
||||||
|
|||||||
64
src/services/encryption.jsx
Normal file
64
src/services/encryption.jsx
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -4,6 +4,7 @@ import axiosRetry from "axios-retry";
|
|||||||
import showToast from "../services/toastService";
|
import showToast from "../services/toastService";
|
||||||
import { startSignalR, stopSignalR } from "../services/signalRService";
|
import { startSignalR, stopSignalR } from "../services/signalRService";
|
||||||
import { BASE_URL } from "./constants";
|
import { BASE_URL } from "./constants";
|
||||||
|
import { decryptResponse } from "../services/encryption";
|
||||||
const base_Url = BASE_URL;
|
const base_Url = BASE_URL;
|
||||||
|
|
||||||
export const axiosClient = axios.create({
|
export const axiosClient = axios.create({
|
||||||
@ -134,7 +135,7 @@ const apiRequest = async (method, url, data = {}, config = {}) => {
|
|||||||
params: method === "get" ? data : undefined,
|
params: method === "get" ? data : undefined,
|
||||||
...config,
|
...config,
|
||||||
});
|
});
|
||||||
return response.data;
|
return decryptResponse(response.data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -179,11 +180,10 @@ export const api = {
|
|||||||
authRequired: true,
|
authRequired: true,
|
||||||
}),
|
}),
|
||||||
patch: (url, data = {}, customHeaders = {}) =>
|
patch: (url, data = {}, customHeaders = {}) =>
|
||||||
apiRequest("patch", url, data, {
|
apiRequest("patch", url, data, {
|
||||||
headers: { ...customHeaders },
|
headers: { ...customHeaders },
|
||||||
authRequired: true,
|
authRequired: true,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Redirect helper
|
// Redirect helper
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user