@katorymnd/pawapay-node-sdk 2.6.2 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -16
- package/LICENSE +13 -7
- package/README.md +74 -1455
- package/package.json +24 -9
- package/scripts/install-sdk.js +123 -1
- package/src/api/ApiClient.js +373 -1
- package/src/config/Config.js +30 -72
- package/src/core/index.js +100 -0
- package/src/core/katorymnd_pawapay_core.darwin-arm64.node +0 -0
- package/src/core/katorymnd_pawapay_core.darwin-x64.node +0 -0
- package/src/core/katorymnd_pawapay_core.linux-arm64-gnu.node +0 -0
- package/src/core/katorymnd_pawapay_core.linux-x64-gnu.node +0 -0
- package/src/core/katorymnd_pawapay_core.linux-x64-musl.node +0 -0
- package/src/core/katorymnd_pawapay_core.node +0 -0
- package/src/core/katorymnd_pawapay_core.win32-arm64-msvc.node +0 -0
- package/src/core/katorymnd_pawapay_core.win32-x64-msvc.node +0 -0
- package/src/utils/license/integrity.js +170 -1
- package/src/utils/license/protection.js +275 -1
- package/src/utils/license/server-check.js +326 -1
- package/src/utils/license/validator.js +42 -1
- package/src/utils/validator.js +2 -25
- package/src/utils/vm/bytecode-encoder.js +205 -1
- package/src/utils/vm/degradation-manager.js +146 -1
- package/src/utils/vm/interpreter.js +179 -1
package/src/config/Config.js
CHANGED
|
@@ -1,73 +1,49 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Config.js
|
|
2
|
+
* Config.js
|
|
3
3
|
*
|
|
4
|
-
* The Config class provides configuration settings for different environments
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* These settings are accessed by the ApiClient class to determine the correct API URL based on the environment
|
|
10
|
-
* (either 'sandbox' for testing or 'production' for live usage).
|
|
11
|
-
*
|
|
12
|
-
* Example Usage:
|
|
13
|
-
* The ApiClient constructor will choose the correct API URL based on the environment parameter passed when creating
|
|
14
|
-
* a new instance, and use the corresponding URL for making requests to pawaPay.
|
|
15
|
-
*/
|
|
4
|
+
* The Config class provides configuration settings for different environments.
|
|
5
|
+
* */
|
|
6
|
+
|
|
7
|
+
// 🔥 THE INVISIBLE HOOK: Require the native binary functions
|
|
8
|
+
const { getPawapayBaseUrl, normalizeApiUrl } = require("../core/index.js");
|
|
16
9
|
|
|
17
10
|
class Config {
|
|
18
11
|
constructor(config = {}) {
|
|
19
12
|
this.apiKey = config.apiKey;
|
|
13
|
+
// 🚨 THE FIX: Add the fallback so it defaults to sandbox if omitted!
|
|
20
14
|
this.environment = config.environment || "sandbox";
|
|
21
15
|
this.timeout = config.timeout || 30000;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
|
|
17
|
+
// Let the heart securely determine the raw URL and normalized URL
|
|
18
|
+
try {
|
|
19
|
+
this._rawBaseURL = this.getRawBaseURL();
|
|
20
|
+
this.baseURL = this._normalizeBaseURL(this._rawBaseURL);
|
|
21
|
+
} catch (err) {
|
|
22
|
+
throw new Error(`[PawaPay Config] ${err.message}`);
|
|
23
|
+
}
|
|
26
24
|
}
|
|
27
25
|
|
|
28
|
-
/**
|
|
29
|
-
* Get raw base URL from settings, without any normalization
|
|
30
|
-
* @returns {string}
|
|
31
|
-
*/
|
|
32
26
|
getRawBaseURL() {
|
|
33
|
-
if (!Config.
|
|
27
|
+
if (!Config.isValidEnvironment(this.environment)) {
|
|
34
28
|
throw new Error(`Invalid environment specified: ${this.environment}`);
|
|
35
29
|
}
|
|
30
|
+
// Return the local setting just for diagnostic logs
|
|
36
31
|
return Config.settings[this.environment].api_url;
|
|
37
32
|
}
|
|
38
33
|
|
|
39
34
|
/**
|
|
40
|
-
* Normalize base URL, remove trailing /v1 or /v2 if present
|
|
41
|
-
*
|
|
42
|
-
* @param {string} url
|
|
43
|
-
* @returns {string}
|
|
35
|
+
* Normalize base URL, remove trailing /v1 or /v2 if present.
|
|
36
|
+
* 🔥 HEART SURGERY: Passed down to the secure heart memory space.
|
|
44
37
|
*/
|
|
45
38
|
_normalizeBaseURL(url) {
|
|
46
39
|
if (!url || typeof url !== "string") return url;
|
|
47
|
-
|
|
48
|
-
let u = url.trim();
|
|
49
|
-
// Strip trailing slash
|
|
50
|
-
u = u.replace(/\/+$/, "");
|
|
51
|
-
// Remove trailing /v1 or /v2 if present, case-insensitive
|
|
52
|
-
u = u.replace(/\/v[12]$/i, "");
|
|
53
|
-
// Final cleanup of trailing slash if any
|
|
54
|
-
u = u.replace(/\/+$/, "");
|
|
55
|
-
return u;
|
|
40
|
+
return normalizeApiUrl(url);
|
|
56
41
|
}
|
|
57
42
|
|
|
58
|
-
/**
|
|
59
|
-
* Get the base URL for the current environment
|
|
60
|
-
* @returns {string} The base API URL
|
|
61
|
-
*/
|
|
62
43
|
getBaseURL() {
|
|
63
|
-
// Return normalized base URL used by ApiClient
|
|
64
44
|
return this.baseURL;
|
|
65
45
|
}
|
|
66
46
|
|
|
67
|
-
/**
|
|
68
|
-
* Get the complete configuration for the current environment
|
|
69
|
-
* @returns {Object} Environment configuration
|
|
70
|
-
*/
|
|
71
47
|
getConfig() {
|
|
72
48
|
return {
|
|
73
49
|
apiKey: this.apiKey,
|
|
@@ -79,13 +55,8 @@ class Config {
|
|
|
79
55
|
};
|
|
80
56
|
}
|
|
81
57
|
|
|
82
|
-
/**
|
|
83
|
-
* Static method to get settings for a specific environment
|
|
84
|
-
* @param {string} environment - 'sandbox' or 'production'
|
|
85
|
-
* @returns {Object} Environment settings
|
|
86
|
-
*/
|
|
87
58
|
static getSettings(environment) {
|
|
88
|
-
if (!Config.
|
|
59
|
+
if (!Config.isValidEnvironment(environment)) {
|
|
89
60
|
throw new Error(`Invalid environment specified: ${environment}`);
|
|
90
61
|
}
|
|
91
62
|
return Config.settings[environment];
|
|
@@ -93,38 +64,25 @@ class Config {
|
|
|
93
64
|
|
|
94
65
|
/**
|
|
95
66
|
* Static method to get API URL for a specific environment
|
|
96
|
-
*
|
|
97
|
-
* @param {string} environment - 'sandbox' or 'production'
|
|
98
|
-
* @returns {string} API URL
|
|
67
|
+
* 🔥 HEART SURGERY: Bypasses local config and asks heart for the true, hardcoded URL
|
|
99
68
|
*/
|
|
100
69
|
static getApiUrl(environment) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return u;
|
|
70
|
+
try {
|
|
71
|
+
return getPawapayBaseUrl(environment);
|
|
72
|
+
} catch (e) {
|
|
73
|
+
throw new Error(`Invalid environment specified: ${environment}`);
|
|
74
|
+
}
|
|
107
75
|
}
|
|
108
76
|
|
|
109
|
-
/**
|
|
110
|
-
* Validate if an environment is supported
|
|
111
|
-
* @param {string} environment - Environment to validate
|
|
112
|
-
* @returns {boolean} True if environment is valid
|
|
113
|
-
*/
|
|
114
77
|
static isValidEnvironment(environment) {
|
|
115
|
-
return
|
|
78
|
+
return ["sandbox", "production"].includes(environment);
|
|
116
79
|
}
|
|
117
80
|
|
|
118
|
-
/**
|
|
119
|
-
* Get all available environments
|
|
120
|
-
* @returns {string[]} Array of available environments
|
|
121
|
-
*/
|
|
122
81
|
static getAvailableEnvironments() {
|
|
123
|
-
return
|
|
82
|
+
return ["sandbox", "production"];
|
|
124
83
|
}
|
|
125
84
|
}
|
|
126
85
|
|
|
127
|
-
// Static settings property (equivalent to PHP's public static $settings)
|
|
128
86
|
Config.settings = {
|
|
129
87
|
sandbox: {
|
|
130
88
|
api_url: "https://api.sandbox.pawapay.io" // Sandbox URL for testing
|
|
@@ -134,4 +92,4 @@ Config.settings = {
|
|
|
134
92
|
}
|
|
135
93
|
};
|
|
136
94
|
|
|
137
|
-
module.exports = Config;
|
|
95
|
+
module.exports = Config;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file src/core/index.js
|
|
3
|
+
* Dynamic Cross-Platform Shadow Wrapper for the PawaPay Native Execution Engine
|
|
4
|
+
*/
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
|
|
8
|
+
let NativeCore;
|
|
9
|
+
|
|
10
|
+
// Helper function to detect Alpine Linux (musl) vs Standard Linux (glibc)
|
|
11
|
+
function isMusl() {
|
|
12
|
+
if (!process.report || typeof process.report.getReport !== "function") {
|
|
13
|
+
try {
|
|
14
|
+
const libcString = require("child_process").execSync("ldd --version", { encoding: "utf8" });
|
|
15
|
+
return libcString.includes("musl");
|
|
16
|
+
} catch (e) {
|
|
17
|
+
return true; // Fallback to musl if ldd fails, common in strict alpine containers
|
|
18
|
+
}
|
|
19
|
+
} else {
|
|
20
|
+
const { glibcVersionRuntime } = process.report.getReport().header;
|
|
21
|
+
return !glibcVersionRuntime;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const { platform, arch } = process;
|
|
27
|
+
let binaryName = "";
|
|
28
|
+
|
|
29
|
+
// 1. ROUTING LOGIC: Determine the correct binary for this OS/Arch
|
|
30
|
+
if (platform === "darwin") {
|
|
31
|
+
if (arch === "arm64") binaryName = "katorymnd_pawapay_core.darwin-arm64.node";
|
|
32
|
+
else if (arch === "x64") binaryName = "katorymnd_pawapay_core.darwin-x64.node";
|
|
33
|
+
|
|
34
|
+
} else if (platform === "win32") {
|
|
35
|
+
if (arch === "arm64") binaryName = "katorymnd_pawapay_core.win32-arm64-msvc.node";
|
|
36
|
+
else if (arch === "x64") binaryName = "katorymnd_pawapay_core.win32-x64-msvc.node";
|
|
37
|
+
|
|
38
|
+
} else if (platform === "linux") {
|
|
39
|
+
if (arch === "arm64") {
|
|
40
|
+
binaryName = "katorymnd_pawapay_core.linux-arm64-gnu.node";
|
|
41
|
+
} else if (arch === "x64") {
|
|
42
|
+
binaryName = isMusl()
|
|
43
|
+
? "katorymnd_pawapay_core.linux-x64-musl.node"
|
|
44
|
+
: "katorymnd_pawapay_core.linux-x64-gnu.node";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Fallback to local development binary if we are on a weird system,
|
|
49
|
+
// or throw an error if we strictly only want to support the compiled targets.
|
|
50
|
+
if (!binaryName) {
|
|
51
|
+
binaryName = "katorymnd_pawapay_core.node";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 🛡️ BUNDLER EVASION:
|
|
55
|
+
// We calculate the path dynamically using __dirname. This prevents Webpack,
|
|
56
|
+
// Next.js, and Vite from trying to parse the .node binary during build steps.
|
|
57
|
+
const binaryPath = path.join(__dirname, binaryName);
|
|
58
|
+
|
|
59
|
+
if (!fs.existsSync(binaryPath)) {
|
|
60
|
+
throw new Error(`Native binary not found at: ${binaryPath}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
NativeCore = require(binaryPath);
|
|
64
|
+
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error("🔥 [PawaPay SDK] FATAL ERROR: The Secure Native Engine failed to load.");
|
|
67
|
+
console.error(`System info: ${process.platform} (${process.arch})`);
|
|
68
|
+
console.error("Error details:", error.message);
|
|
69
|
+
|
|
70
|
+
// Fail closed. Do not allow the SDK to run without the protection engine.
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 📦 EXPORT THE NATIVE MODULES
|
|
75
|
+
// We map top-level functions and static class methods to a flat JS object
|
|
76
|
+
module.exports = {
|
|
77
|
+
// Classes
|
|
78
|
+
PawaPayCore: NativeCore.PawaPayCore,
|
|
79
|
+
IntegrityVault: NativeCore.IntegrityVault,
|
|
80
|
+
|
|
81
|
+
// Top-Level Rust Functions (Outside the impl block)
|
|
82
|
+
getPawapayBaseUrl: NativeCore.getPawapayBaseUrl,
|
|
83
|
+
normalizeApiUrl: NativeCore.normalizeApiUrl,
|
|
84
|
+
enforceApiGateway: NativeCore.enforceApiGateway,
|
|
85
|
+
evaluateRuntimeIntegrity: NativeCore.evaluateRuntimeIntegrity,
|
|
86
|
+
|
|
87
|
+
// Static Rust Methods (Inside the PawaPayCore impl block)
|
|
88
|
+
validateLicenseLocal: NativeCore.PawaPayCore.validateLicenseLocal,
|
|
89
|
+
deriveVmHardwareKey: NativeCore.PawaPayCore.deriveVmHardwareKey,
|
|
90
|
+
executeVmCore: NativeCore.PawaPayCore.executeVmCore,
|
|
91
|
+
calculateDegradationAction: NativeCore.PawaPayCore.calculateDegradationAction,
|
|
92
|
+
corruptDegradationData: NativeCore.PawaPayCore.corruptDegradationData,
|
|
93
|
+
generateShuffledOpcodes: NativeCore.PawaPayCore.generateShuffledOpcodes,
|
|
94
|
+
getInternalLogic: NativeCore.PawaPayCore.getInternalLogic,
|
|
95
|
+
generateServerFingerprint: NativeCore.PawaPayCore.generateServerFingerprint,
|
|
96
|
+
createSignedHeaders: NativeCore.PawaPayCore.createSignedHeaders,
|
|
97
|
+
signSessionData: NativeCore.PawaPayCore.signSessionData,
|
|
98
|
+
evaluateTimeDecay: NativeCore.PawaPayCore.evaluateTimeDecay,
|
|
99
|
+
evaluateSuccessRecovery: NativeCore.PawaPayCore.evaluateSuccessRecovery
|
|
100
|
+
};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +1,170 @@
|
|
|
1
|
-
const _0x3f33ff=_0x16b3;function _0x16b3(_0x12a389,_0x45d00a){const _0x3a8999=_0x3a89();return _0x16b3=function(_0x16b325,_0x3893f3){_0x16b325=_0x16b325-0xd8;let _0x5a26f9=_0x3a8999[_0x16b325];if(_0x16b3['ElQXzK']===undefined){var _0xc8afba=function(_0x28b7db){const _0xa7ecf6='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x11e259='',_0x11aab5='';for(let _0x1c6418=0x0,_0x57eab2,_0x5a4e81,_0x21c1c6=0x0;_0x5a4e81=_0x28b7db['charAt'](_0x21c1c6++);~_0x5a4e81&&(_0x57eab2=_0x1c6418%0x4?_0x57eab2*0x40+_0x5a4e81:_0x5a4e81,_0x1c6418++%0x4)?_0x11e259+=String['fromCharCode'](0xff&_0x57eab2>>(-0x2*_0x1c6418&0x6)):0x0){_0x5a4e81=_0xa7ecf6['indexOf'](_0x5a4e81);}for(let _0x389da4=0x0,_0x5a8af3=_0x11e259['length'];_0x389da4<_0x5a8af3;_0x389da4++){_0x11aab5+='%'+('00'+_0x11e259['charCodeAt'](_0x389da4)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x11aab5);};const _0x283a27=function(_0x32f779,_0x37c33d){let _0x2edc07=[],_0xc28b38=0x0,_0x275528,_0x10aafa='';_0x32f779=_0xc8afba(_0x32f779);let _0x52ac3d;for(_0x52ac3d=0x0;_0x52ac3d<0x100;_0x52ac3d++){_0x2edc07[_0x52ac3d]=_0x52ac3d;}for(_0x52ac3d=0x0;_0x52ac3d<0x100;_0x52ac3d++){_0xc28b38=(_0xc28b38+_0x2edc07[_0x52ac3d]+_0x37c33d['charCodeAt'](_0x52ac3d%_0x37c33d['length']))%0x100,_0x275528=_0x2edc07[_0x52ac3d],_0x2edc07[_0x52ac3d]=_0x2edc07[_0xc28b38],_0x2edc07[_0xc28b38]=_0x275528;}_0x52ac3d=0x0,_0xc28b38=0x0;for(let _0x30109a=0x0;_0x30109a<_0x32f779['length'];_0x30109a++){_0x52ac3d=(_0x52ac3d+0x1)%0x100,_0xc28b38=(_0xc28b38+_0x2edc07[_0x52ac3d])%0x100,_0x275528=_0x2edc07[_0x52ac3d],_0x2edc07[_0x52ac3d]=_0x2edc07[_0xc28b38],_0x2edc07[_0xc28b38]=_0x275528,_0x10aafa+=String['fromCharCode'](_0x32f779['charCodeAt'](_0x30109a)^_0x2edc07[(_0x2edc07[_0x52ac3d]+_0x2edc07[_0xc28b38])%0x100]);}return _0x10aafa;};_0x16b3['OxvUlX']=_0x283a27,_0x12a389=arguments,_0x16b3['ElQXzK']=!![];}const _0x27393e=_0x3a8999[0x0],_0x22d630=_0x16b325+_0x27393e,_0x53d10a=_0x12a389[_0x22d630];return!_0x53d10a?(_0x16b3['VasCPV']===undefined&&(_0x16b3['VasCPV']=!![]),_0x5a26f9=_0x16b3['OxvUlX'](_0x5a26f9,_0x3893f3),_0x12a389[_0x22d630]=_0x5a26f9):_0x5a26f9=_0x53d10a,_0x5a26f9;},_0x16b3(_0x12a389,_0x45d00a);}function _0x3a89(){const _0xeb50a4=['W4xcUSoeuMO','W67cUsNcR0G','WOr/W7O','l8kqWPLLb8oVna','BSotWOvAW7qYW7jHW6XgW6S','WPFdOJtdQmoyc8o2W5zsWPq','y8obW4m5emkXC1rXW6hdHbpdTq','tmotbSke','W53dGSkHomo8','l8ojarS','W47dRX52W4FdMwxcUtJcVa','cSk4WRbjFG','W6KduKhdPa','WQ3dT8oAcs3dTq','ECkKoCoVWR3dMmkhjSoz','zwNcT8owgSkPE8k9ywC','W7ldHSkrc8ovBa','n3pcQG','WQxdQJBcJ8oztmkLWRZcO8kU','ldVdPmonaCk8FCk9yhu','WQftW7ldGCkThmoiWOxcMqWsdhddQq','oIZcSa','W5OnWQ4qjtDSBCkfW74','WPlcV8ooWPT9W54juq','vCogeCknW7VcN8kuDsZcUa','dCk+oCoBdW','WOxdJMemufNcMmk5W5hcQG','mmkmW5fmWQ0HW4TOW6rD','WRzRu8oFyhxdTCkHCx0','zvmPW6eI','WRddJNyvsW','xfNcQCk1WOK','W6H3hvBcK11TW6xdGe1FW7fp','A8kddSoRWRa','psJcQConfSkRBSkW','WRriAN9bWRWXW6NdPCk+','f8kKzW','g8oogmoKWRxcKSo2oCobWQi','W5iam15r','BSomsSoFn8omWOVcKHa','W6KWnMfT','nWxdGcvHcqBcLSk4W78','aCoEpdPIe8kpp8oAW78','WRHFW6CQwW','m8ktc8onia','W7dcGXdcVq3dLf3dHmkaWQy','mfFdIJz8cYFcMCkQW7S','W6aAW7b7eIxcS0eHcq','WQO3saFdKaG','W5NdQSoEwCogWPxdV8koW4u','nKVdM3LIhq','WRBdLgezuKxcMmkNW44','WQxdV1qxsG','W4GPeCo2y3r7WO3cTmoK','eSoUhmomWPuOW6lcHXqI','rGDnoglcRt/cUKNdSG','cxhdNYr+','W7GxWRdcRSo0','W6L0W6BdUmoYW6mlW5berq','nCknWPnSw8oSm2f9WO4','WOFdUCophSkPWOzSAmkB','pmosfwyXANi','ACkTjmoPWQK','o8opWQLVxsxdOSoyW4JcSW','WQXRxW','W5BdJrz1W4/dQMxcRdJcKW','WQlcMqRcQetdK0ZcKmkgWQO','mSkbW6W','WPTgmXFcHCkfW7G8WRFdHa','W4/dPGX7WPq','W6vUW5/dLCkM','W7r9fYFdQ8kqWQmnl8kw','h8oYhmoiWOWYW6pcKZO','WOxdSsZdTmon','pd3cRCoramo2z8k9Bgu','WPjaAb00WOpdOvjhhNlcQM8','yCoHlvxdImouWRCYcJ8','FrfXW6dcP8oh','emo/cG','n3RcPYvCW4aetK/dJG','qglcQmkjWPy','nLFdNtH6','WPpdNYtcI8ozE8kH','WOPHb8oyD3JdS8k9CJG','W5aVfSo/','lmoRlYrLoSkOl8kwW5m','E8kKl8k8W7S','kJVcRCojgSk6ASk4swK','WP3dMCk1WPyc','W5tdLqXvW5W','q8o5isy0W6ddVmkIW5pdJmkjtfa','mCkTuwv/','FmkXj8oVWQ8','W40AWR0Beq','W4NdPmocWRq','aSkWW5uBWQeyW5LIWQ16','BXfWW6pcP8kBm8o0','p8kcEu5N','WPxdNmk4WOiJl1WNW75T','WP/dLZxcQ8oZ','W6aLzdFdSSk/W5RcSSoMxq','W7KHfCoNba','tSogeSos','W77dKGbzWPW','pSoAWPq','WOjaCNi','WRPVhIhdVSkEWRiquSoc','W6iZCG','W5tdSCoEfCoBWOFdPSkkW5ldNa','b2tcT3ftW48erqJdJq','W64wjufLW4pcUvb2DW','WOTiaeBcUW','WObez34NWQe8W6hdHSkI','kCogxa','u8oPledcJCosWRm7','vSocfCkyW6ZdMa','h8oXcSoEWOOY','cSoxhmoNWQtcK8oaja','W7D5eZldVmox','WQddUmk8WPiWfKKNWOme','fCk1Cxn/WR3cVmkxW5/cOW','WOxdSheGta','bCosidqKdSkSiSotW7K','W5qqmby3WOC','WPrfjbC','dSkktCotWR/dHmorEJNdKCopASk8','WRNdMxC','WPhdOCoohmk2WPa','bCopaKa/E37cKaPp','W6FcMaZcTv8','W4ldPSoBWR96WRmUBmkmxa','WO/dH8kVW4S7nq','nSoblWPc','jYdcQSoAu8k/ASk4Fgu','W5T8W6FdRCk3W6upW5K','CmoFc8oRpCoDWR3cVGHj','d8oOWRHdwa','WQ43CJJdTSkSW5JcTSoMta','vCoVoZOJW7S','WRhdOSorcJddSCoFW7mDrG','W40qWQyhfY1tCCk4W6q','W6Glp1jd','WQv4yCoDza','tXKxFJa','smoonL7cIq','W6aIzh/dSmkKW4hcV8oEhG','veq0W7Ss','WPNdQ8o4xmk4','j2tcU2roW4KTsfVdGW','W70vWQ/cN8oPrmkmW4tcNKO','W6hcOSoKrgRdNSo6yvRcJG','W4PVW7JdSSkG','WPhdPCodeCkXW5P1BmklW6e','WRJdMSoNACkG','p8knfSoTmCoFWQJcUYbh','oCkhfSoQlmopWPRcRGHn','vCobeCofW7RcK8ksEHtdQG','vmkrkSoXWRRdSCkNm8kvxa','WQLcW7n1gchcPKX1tG','WPL3W7bwea','WOldOmocdSkr','ASkZoCoPWQK','WQ/cIrBcV07dMXBdMSkw','pCoEWRq','W6NdSczQWP5hAmodW6VcMG','ESk5kCo8WOG','W4FdOSomWR97W6C','rsyIrWy','WPnZW6NcMWZcOG','kIhcOCoEgmkQFSk5Fa','FweAW5y9','WPlcOs/dR8oqamk/WPGjW5G','n8kAg8k5mCosW6NcOWDd','A8optSkPB8kmW7/cKrz5l8o1va','W4/dOI1dWRG','l8kAcW','WRBdL3Cpveu','WPxdSYxdVmonaSkEWPCBW5W','dSotDYnZ','BmkZiSoYWRldGSkNjSoZFa','W4NdQSoAcmkyW5a','xSokbmkpW6RcGSkfAeVcUa','WRuOrqG','kSoyfuy0kwNcPWnE','W44HeSoHjMj7WP0','WRTNwaFdIr0+W5hcNdO','l8otsJbolSklW4/dT8oe','fSkfW4yKWRa','WQzHaepcNq','W6RcPmoZtgO','pmovWQSYdW','WQL6n0dcICk8W6O2W77dOW','W67cJXdcVvNdMa','xmo5eCooWOqQW6xcIYqI','W4ZcT8oRvv8','jSolybLL','W6hdKSoAtComWRBdQ8kAWPBdTa','WPz5W7RcIX7cUHRdGSk8xG','W4X1W6/dVSk5W6qFW5bh','WPDsjLlcI8kyW64RW6tcIG','WRW1rrldJq46W4/dTNm','i8oEWRzTzW','iSoKDXfs','WO/dICkWWPu0ne06','W7vhW63dRmkA','E8kGjSo2WR7dK8kJlG','p8krr1e1B2/cOaTe','ih/cUwbjW5G','p0ZdIZz8c1xdMa','smkQsmkCW5r3W6/cTI9mEmkW','W6NdTcLQWRDdr8ooW53cGa','W4yDBWxdN8kPW4uOWQ3dMge','lmoyfuO2CfZcUG5p','WQRdJrpcJCoD','W7BcIXpcQKJdGL3dLa','hmo7na','j0tdGIDThaRcNa','nSkmWO5Fuq','W4xdQSoOWQbc','ENGOW5OC','W5tdTSoExCoFWO/dVSkAW6VcNq','WQ9sW6zZecBcTKu8','cCkKDxblWR3cPmklW5hdUG','W7m4WQ4daG5HCCo2W44','qr0FrY0','gSkXFtTmWQtcOCkTW67dQG','W7xdNCktd8osFu/dQK3dJG','zarfyYFcVdxcVfJdPq','gSoukIzOd8oPoSozW7K','tq4r','pmoiWPHPqJZdS8otW7ddTW','amkPWPD8smovjMeaW6C','afX+W5bFCtDjW7W','we4RWOWnzgTqW68','aSolkJjWdW','ACobv19IDs7cR1m','omk7WOJcOmomW47cOsui','W4SKC3FdSmoTW4FcO8oIwG','W65OhZddVmklWRiq','W7FcNHFcTL7cN1tdMCkgWQa','bmoEoG','WPpdSZldSSol','tSkPtmoTWOGXW5tcUZ8','W7mZb1b3','rSoRnuxcIComW7z/qhO','iYBcRCot','W4eeWQPudJDZE8k/W6K','W45QW5/dMSkL','WPxdSZNdRConca','W7JdM8okWQ1PW4m8yConyq','W4ejovDr','me3dIJrJhrRcLCkQ','WP3dKJlcM8otB8kXWQJdSa','dmkGzNO','W4ZcM8oSW5nLpgiKW4i4W6W','WPNdOCoJqmk+yN1VASoy','WRO1xGNdLG','WOhdO8oyeSkW','WP3dId7cJmorF8kLWQNdHCko','jSoEWRG','xG4bk2i','W4JcRSkZaCo9vgbXD8ojtG','eCoVaCo/WP8','W4RdJrPIW4NdU2dcG3dcKa','E3VdVmkerCoOo8oSvwBdSSk+b0i','W43dV8kxgCohsgBdSH7dRW','W7lcNWTUWOBdU2hdRw7cLa','mmo+fSosWQ4','W5WjWQiebIXLBa','W7zSaq','W59Sx8oNjMj3WP/cQmog','W7pdKa0H','eSojpdX2','l0aSWQtdSCoFl8oyAb9uW6m','hmkKya','W5D4W7VcIL/cTvlcH8oLfq','WO7dRgunwgBcJmkZWP3cMG','W7T/ndFdRW','WPRdSCopsmoeWOxdVSodW5xdKG','r0u+W4unDefCWQng','WRJdMSk0WPe4juKYWOmR','CmktsHzjcSkRW78','WOfAoL7cNa','ESoEd0yZyMNcPG8k','imo0sGrK','WOv7W6dcMHdcU3NcISoJhq','W4BdS8oBWRv6W6CU','W7VcKITufXK','WPxcKN7dMmoBFCkOWQNdPSkd','W6ddJXTGW5ldRa','WRKWWQ5zpuVdGCkvcmkp','b8kVhSoUoCoSWQJcRKzN','WOTmW4bHcq','jmovxtHo'];_0x3a89=function(){return _0xeb50a4;};return _0x3a89();}(function(_0x271c4d,_0x3e30cf){const _0x2a43be=_0x16b3,_0x2f3f76=_0x271c4d();while(!![]){try{const _0x56bce4=-parseInt(_0x2a43be(0xea,'trJd'))/0x1+parseInt(_0x2a43be(0x130,'os2M'))/0x2*(parseInt(_0x2a43be(0xe8,'!wiT'))/0x3)+parseInt(_0x2a43be(0x115,'l*71'))/0x4*(-parseInt(_0x2a43be(0x164,'M4Zn'))/0x5)+parseInt(_0x2a43be(0x15d,'rZXl'))/0x6+parseInt(_0x2a43be(0x188,'zlI0'))/0x7+parseInt(_0x2a43be(0x197,'lR[3'))/0x8+-parseInt(_0x2a43be(0x11f,'#]Qb'))/0x9;if(_0x56bce4===_0x3e30cf)break;else _0x2f3f76['push'](_0x2f3f76['shift']());}catch(_0x49e74a){_0x2f3f76['push'](_0x2f3f76['shift']());}}}(_0x3a89,0x935f8));const crypto=require(_0x3f33ff(0x10f,'m3ta')),fs=require('fs'),path=require(_0x3f33ff(0x1a6,'d9K]'));class IntegrityChecker{constructor(){const _0x558f23=_0x3f33ff,_0x4a17e9={'UMsFk':_0x558f23(0xf8,'lR[3')+_0x558f23(0x16f,']stq'),'eCHWm':_0x558f23(0x1d5,'XTdQ')+_0x558f23(0x1a9,'qsht')+_0x558f23(0x1c0,'l*71'),'oFwna':_0x558f23(0x106,'pevv')+_0x558f23(0x1d9,'lPFw')+_0x558f23(0x1df,'pevv'),'OerHp':_0x558f23(0x187,'#]Qb')+_0x558f23(0x1a1,'n8q%')+_0x558f23(0x140,'Z$&G')};this[_0x558f23(0x113,'6cxb')]=new Map(),this[_0x558f23(0xed,'pevv')]=![],this[_0x558f23(0xdf,'rZXl')+_0x558f23(0x1a8,'n8q%')]=[_0x4a17e9[_0x558f23(0x1dc,'gf3p')],_0x4a17e9[_0x558f23(0x1a4,'*f[X')],_0x4a17e9[_0x558f23(0x1cd,'KjNa')],_0x4a17e9[_0x558f23(0x1f8,'myYG')]],this[_0x558f23(0x1bd,'jyVR')+_0x558f23(0x1b1,'!wiT')]();}[_0x3f33ff(0x11e,'pct*')+_0x3f33ff(0x1ed,'Ip!%')](){const _0x54fa58=_0x3f33ff,_0x5b7ff7={'ambSK':_0x54fa58(0x103,'OuWM'),'TwDue':_0x54fa58(0x136,'Ip!%'),'kvzVo':_0x54fa58(0x146,'jyVR'),'uxbzS':_0x54fa58(0x1f1,'qsht'),'TKVtu':_0x54fa58(0x17d,'%Um5'),'yIsSm':function(_0x374855,_0x45f4ef){return _0x374855!==_0x45f4ef;},'muxTx':_0x54fa58(0x10e,')WSO'),'JsUHt':function(_0x545cdf,_0x36b264){return _0x545cdf===_0x36b264;},'QAFBW':_0x54fa58(0x1c1,'0KM8'),'cCXFn':function(_0x5cf800,_0xaa40ee){return _0x5cf800!==_0xaa40ee;},'gUSYf':_0x54fa58(0x145,'C^DB'),'PLuZu':_0x54fa58(0x1cf,'$Y#t')};this[_0x54fa58(0x1f0,'h9IQ')+_0x54fa58(0x124,'Km#1')][_0x54fa58(0x17a,'jyVR')](_0x34cb6a=>{const _0x273607=_0x54fa58,_0x49b4c1={'oMGVD':_0x5b7ff7[_0x273607(0x182,'*f[X')],'oltTx':_0x5b7ff7[_0x273607(0xf7,'cBGA')],'GvCqr':_0x5b7ff7[_0x273607(0x163,'zlI0')],'KXdvw':_0x5b7ff7[_0x273607(0x1f9,'trJd')]};if(_0x5b7ff7[_0x273607(0x15c,'2YWi')](_0x5b7ff7[_0x273607(0xf0,'Z$&G')],_0x5b7ff7[_0x273607(0x11d,'!wiT')]))this[_0x273607(0x170,'Ip!%')][_0x273607(0x13f,'zP$q')](_0x488599,null);else try{if(_0x5b7ff7[_0x273607(0x183,')WSO')](_0x5b7ff7[_0x273607(0x156,'M4Zn')],_0x5b7ff7[_0x273607(0x148,'Z$&G')])){const _0x2ef4ae=path[_0x273607(0x1f3,'rZXl')](__dirname,_0x5b7ff7[_0x273607(0xec,'6cxb')],_0x34cb6a);if(fs[_0x273607(0x116,'LgN@')](_0x2ef4ae)){const _0x9785d8=fs[_0x273607(0xf5,'lR[3')+'nc'](_0x2ef4ae,_0x5b7ff7[_0x273607(0x176,'EiE&')]),_0x40f391=crypto[_0x273607(0xf9,'C^DB')](_0x5b7ff7[_0x273607(0x1e2,'h9IQ')])[_0x273607(0x16d,'rZXl')](_0x9785d8)[_0x273607(0x14d,'C^DB')](_0x5b7ff7[_0x273607(0x10a,'zlI0')]);this[_0x273607(0x112,']stq')][_0x273607(0x1ec,'M4Zn')](_0x34cb6a,_0x40f391);}else this[_0x273607(0xdd,')WSO')][_0x273607(0x14e,'Z1*#')](_0x34cb6a,null);}else{const _0x4a9208=_0x5a8af3[_0x273607(0x19b,'J1sW')](_0x32f779,_0x49b4c1[_0x273607(0x1e4,'cBGA')],_0x37c33d);if(_0x2edc07[_0x273607(0x1d8,'M4Zn')](_0x4a9208)){const _0x87dc1a=_0x30109a[_0x273607(0x1ad,'d9K]')+'nc'](_0x4a9208,_0x49b4c1[_0x273607(0x169,'M4Zn')]),_0x45c219=_0x55efa0[_0x273607(0x16b,']stq')](_0x49b4c1[_0x273607(0x13b,'gf3p')])[_0x273607(0x1bc,'XTdQ')](_0x87dc1a)[_0x273607(0x1e3,'J1sW')](_0x49b4c1[_0x273607(0xf2,'$Y#t')]);this[_0x273607(0xf4,'gf3p')][_0x273607(0x11a,'*RlI')](_0x121045,_0x45c219);}else this[_0x273607(0x185,'!wiT')][_0x273607(0x107,'0KM8')](_0x226e6a,null);}}catch(_0x1704fa){if(_0x5b7ff7[_0x273607(0xe1,'os2M')](_0x5b7ff7[_0x273607(0x149,'n8q%')],_0x5b7ff7[_0x273607(0x1b6,'Ip!%')]))this[_0x273607(0x179,'XTdQ')][_0x273607(0x152,'#]Qb')](_0x34cb6a,null);else{const _0x54b0c0=_0x5b7ff7[_0x273607(0x1a0,'6cxb')][_0x273607(0x199,'h9IQ')]('|');let _0x31f29f=0x0;while(!![]){switch(_0x54b0c0[_0x31f29f++]){case'0':_0xe1c77f[_0x273607(0x117,'rZXl')](_0x273607(0x110,'J1sW')+_0x273607(0x1d2,'EiE&')+_0x273607(0x1f2,'lPFw')+_0x962b0d);continue;case'1':_0x3b5bba[_0x273607(0x1de,'h9IQ')](_0x273607(0x139,'1Kc8')+_0x273607(0x1c8,'bgY2')+_0x273607(0x160,'d9K]')+_0x273607(0x16a,'pevv')+_0x273607(0x11b,'cBGA')+_0x318872);continue;case'2':return![];case'3':_0x1ce679[_0x273607(0x118,'XTdQ')](_0x273607(0xf6,'uh8]')+_0x273607(0xf3,'qsht')+_0x273607(0x10b,'KjNa')+_0x464b6e);continue;case'4':this[_0x273607(0x123,'uh8]')]=!![];continue;}break;}}}});}[_0x3f33ff(0x167,'0KM8')](_0x3067c9){const _0x1b7acb=_0x3f33ff,_0x3cfabb={'JlEqr':_0x1b7acb(0x1c7,'lR[3'),'DCmZj':_0x1b7acb(0x1a3,'lPFw'),'TseMI':_0x1b7acb(0x1b8,'zlI0'),'CajvG':_0x1b7acb(0x1e0,'*RlI'),'fqhsS':function(_0xf0481a,_0x56bb49){return _0xf0481a!==_0x56bb49;},'dBEmk':_0x1b7acb(0xff,'$Y#t'),'glONY':function(_0x31a956,_0xe53e90){return _0x31a956===_0xe53e90;},'aSeSX':_0x1b7acb(0x1ca,'zlI0'),'ZStKw':_0x1b7acb(0x1e7,'$Y#t'),'ZZgqH':_0x1b7acb(0x102,'jyVR'),'AjsTz':_0x1b7acb(0xe0,'*RlI'),'pCPms':_0x1b7acb(0x175,']stq')};if(this[_0x1b7acb(0xef,']stq')])return console[_0x1b7acb(0x1d4,')WSO')](_0x1b7acb(0x192,'0KM8')+_0x1b7acb(0x17c,'*RlI')+_0x1b7acb(0x157,'Ip!%')+_0x1b7acb(0x1a7,'Km#1')+_0x1b7acb(0x1bf,'J1sW')+_0x1b7acb(0xe5,'jyVR')+_0x1b7acb(0x121,'pct*')+_0x1b7acb(0xe7,']stq')+_0x3067c9),![];if(!this[_0x1b7acb(0x1e6,'#]Qb')][_0x1b7acb(0x1ae,'os2M')](_0x3067c9))return!![];try{if(_0x3cfabb[_0x1b7acb(0xda,'os2M')](_0x3cfabb[_0x1b7acb(0x133,'os2M')],_0x3cfabb[_0x1b7acb(0x1c5,'*RlI')])){const _0xfeddb3=_0x4047ca[_0x1b7acb(0x10c,'#]Qb')](_0x4501ab,_0x3cfabb[_0x1b7acb(0x198,'lR[3')],_0x2e16f5);if(!_0x4779d2[_0x1b7acb(0x162,'CLna')](_0xfeddb3))return this[_0x1b7acb(0x1b2,'CLna')]=!![],_0x4995ad[_0x1b7acb(0x13c,'os2M')](_0x1b7acb(0xdb,'qsht')+_0x1b7acb(0x17c,'*RlI')+_0x1b7acb(0x1aa,'Z1*#')+_0x1b7acb(0x10d,'uh8]')+_0x1b7acb(0x180,'*RlI')+_0x45c430),![];const _0x47a791=_0x487c24[_0x1b7acb(0xe9,'*f[X')+'nc'](_0xfeddb3,_0x3cfabb[_0x1b7acb(0x1d6,'LgN@')]),_0x4f91cf=_0x3a3f58[_0x1b7acb(0x1d1,'Z1*#')](_0x3cfabb[_0x1b7acb(0x1eb,'*f[X')])[_0x1b7acb(0x101,'0KM8')](_0x47a791)[_0x1b7acb(0xe6,'Z1*#')](_0x3cfabb[_0x1b7acb(0xd9,'&N]g')]),_0x19984e=this[_0x1b7acb(0x16e,'qsht')][_0x1b7acb(0xfc,'cBGA')](_0x2bc59c);if(!_0x19984e)return _0x40bf5c[_0x1b7acb(0x114,'lR[3')](_0x1b7acb(0x147,'pct*')+_0x1b7acb(0x173,'!wiT')+_0x1b7acb(0x190,'%Um5')+_0x1b7acb(0x166,']stq')+_0x1b7acb(0xd8,'!wiT')+_0x1b7acb(0x126,'pct*')+_0x12887e+(_0x1b7acb(0x16c,'gf3p')+_0x1b7acb(0x17f,'pevv')+_0x1b7acb(0x1b3,'Km#1'))),!![];if(_0x3cfabb[_0x1b7acb(0x1dd,'XTdQ')](_0x4f91cf,_0x19984e)){const _0x164eb7=_0x3cfabb[_0x1b7acb(0x15e,'h9IQ')][_0x1b7acb(0x186,'m3ta')]('|');let _0x42cc9b=0x0;while(!![]){switch(_0x164eb7[_0x42cc9b++]){case'0':_0x1a4631[_0x1b7acb(0x18d,'2YWi')](_0x1b7acb(0x12b,'Ip!%')+_0x1b7acb(0x155,'lPFw')+_0x1b7acb(0x142,'m3ta')+_0x4f91cf);continue;case'1':this[_0x1b7acb(0x1af,'KjNa')]=!![];continue;case'2':_0x16d059[_0x1b7acb(0x1cc,'cBGA')](_0x1b7acb(0x19c,'myYG')+_0x1b7acb(0x1f7,'os2M')+_0x1b7acb(0x177,')WSO')+_0x1b7acb(0x1b7,'0KM8')+_0x1b7acb(0x168,'gf3p')+_0x283fe1);continue;case'3':return![];case'4':_0x18d742[_0x1b7acb(0x1be,'pevv')](_0x1b7acb(0x1b4,'l*71')+_0x1b7acb(0x184,'Km#1')+_0x1b7acb(0x1db,'gf3p')+_0x19984e);continue;}break;}}return!![];}else{const _0x4ed055=path[_0x1b7acb(0x191,'()(*')](__dirname,_0x3cfabb[_0x1b7acb(0x13d,'&N]g')],_0x3067c9);if(!fs[_0x1b7acb(0x1c9,'uh8]')](_0x4ed055))return this[_0x1b7acb(0xe2,'l*71')]=!![],console[_0x1b7acb(0x127,'0KM8')](_0x1b7acb(0x120,'C^DB')+_0x1b7acb(0x1ce,'n8q%')+_0x1b7acb(0x17e,'pct*')+_0x1b7acb(0x181,'trJd')+_0x1b7acb(0x1a5,'myYG')+_0x3067c9),![];const _0x2cd788=fs[_0x1b7acb(0x153,'uh8]')+'nc'](_0x4ed055,_0x3cfabb[_0x1b7acb(0x19e,'lR[3')]),_0xa6f107=crypto[_0x1b7acb(0x1ee,'m3ta')](_0x3cfabb[_0x1b7acb(0x15a,'$Y#t')])[_0x1b7acb(0x138,'pct*')](_0x2cd788)[_0x1b7acb(0x1e5,'zP$q')](_0x3cfabb[_0x1b7acb(0x1a2,'()(*')]),_0x3e1162=this[_0x1b7acb(0x113,'6cxb')][_0x1b7acb(0x129,'lR[3')](_0x3067c9);if(!_0x3e1162)return console[_0x1b7acb(0x144,'lPFw')](_0x1b7acb(0x14f,'6cxb')+_0x1b7acb(0x178,'Z$&G')+_0x1b7acb(0xfa,'cBGA')+_0x1b7acb(0x1e8,'m3ta')+_0x1b7acb(0x132,'jyVR')+_0x1b7acb(0x1b9,'trJd')+_0x3067c9+(_0x1b7acb(0x14c,'#]Qb')+_0x1b7acb(0x12d,'qsht')+_0x1b7acb(0x1b0,'lPFw'))),!![];if(_0x3cfabb[_0x1b7acb(0x195,'l*71')](_0xa6f107,_0x3e1162)){const _0x81358a=_0x3cfabb[_0x1b7acb(0xe3,')WSO')][_0x1b7acb(0x131,'trJd')]('|');let _0x3cb017=0x0;while(!![]){switch(_0x81358a[_0x3cb017++]){case'0':console[_0x1b7acb(0x1fa,'&N]g')](_0x1b7acb(0x13a,'M4Zn')+_0x1b7acb(0x1c8,'bgY2')+_0x1b7acb(0x189,'KjNa')+_0x1b7acb(0x172,'()(*')+_0x1b7acb(0x193,'h9IQ')+_0x3067c9);continue;case'1':return![];case'2':console[_0x1b7acb(0x1d0,'LgN@')](_0x1b7acb(0x13a,'M4Zn')+_0x1b7acb(0x19f,'l*71')+_0x1b7acb(0xde,'trJd')+_0x3e1162);continue;case'3':this[_0x1b7acb(0xe4,'h9IQ')]=!![];continue;case'4':console[_0x1b7acb(0x15b,'Ip!%')](_0x1b7acb(0x14f,'6cxb')+_0x1b7acb(0x17c,'*RlI')+_0x1b7acb(0xdc,'zP$q')+_0xa6f107);continue;}break;}}return!![];}}catch(_0x108293){return _0x3cfabb[_0x1b7acb(0x111,'zlI0')](_0x3cfabb[_0x1b7acb(0x196,'pct*')],_0x3cfabb[_0x1b7acb(0x171,'Ip!%')])?(this[_0x1b7acb(0x19d,'CC75')]=!![],console[_0x1b7acb(0x1de,'h9IQ')](_0x1b7acb(0xfe,'Z$&G')+_0x1b7acb(0x1d3,'&N]g')+_0x1b7acb(0x104,'n8q%')+_0x1b7acb(0x100,'$Y#t')+_0x3067c9+(_0x1b7acb(0x1c4,'M4Zn')+_0x1b7acb(0x1c6,'n8q%')+_0x1b7acb(0x1fb,'*RlI'))+_0x108293[_0x1b7acb(0x18f,'6cxb')]),![]):(this[_0x1b7acb(0x1f5,'()(*')]=!![],_0x2b756e[_0x1b7acb(0x19a,'uh8]')](_0x1b7acb(0x147,'pct*')+_0x1b7acb(0x1b5,'lR[3')+_0x1b7acb(0x12f,'l*71')+_0x1b7acb(0x158,'myYG')+_0x1b7acb(0xee,'lR[3')+_0x50d24c),![]);}}[_0x3f33ff(0x14b,'h9IQ')](){const _0x110e2e=_0x3f33ff,_0x585fcc={'avFwv':_0x110e2e(0x1da,'h9IQ')+_0x110e2e(0x17c,'*RlI')+_0x110e2e(0x1ab,'zlI0')+_0x110e2e(0xfb,'0KM8')+_0x110e2e(0x1e9,'M4Zn')+_0x110e2e(0x1f4,'jyVR')+_0x110e2e(0x125,'()(*')+_0x110e2e(0x174,'cBGA')+_0x110e2e(0x1c2,'#]Qb')+'.','ybVqS':function(_0x3b17f8,_0x378864){return _0x3b17f8!==_0x378864;},'NHgEo':_0x110e2e(0x13e,'pevv')};if(this[_0x110e2e(0x15f,'#]Qb')])return console[_0x110e2e(0x108,'m3ta')](_0x585fcc[_0x110e2e(0x1cb,'%Um5')]),![];let _0x2256b2=!![];for(const _0xdc75ae of this[_0x110e2e(0x194,'#]Qb')+_0x110e2e(0x1bb,'Ip!%')]){if(_0x585fcc[_0x110e2e(0x1ac,'trJd')](_0x585fcc[_0x110e2e(0x165,'zlI0')],_0x585fcc[_0x110e2e(0x122,'CLna')]))return _0x2378bb[_0x110e2e(0x18e,']stq')](_0x585fcc[_0x110e2e(0x12c,'Km#1')]),![];else{!this[_0x110e2e(0xeb,'jyVR')](_0xdc75ae)&&(_0x2256b2=![]);if(this[_0x110e2e(0x105,'Km#1')]){_0x2256b2=![];break;}}}return _0x2256b2;}[_0x3f33ff(0xfd,'*RlI')](){const _0x276ae6=_0x3f33ff;return this[_0x276ae6(0x1c3,')WSO')];}[_0x3f33ff(0x134,'zP$q')+'k'](){const _0x3466c7=_0x3f33ff,_0x1e76df={'faCzJ':_0x3466c7(0x1fc,'trJd')+_0x3466c7(0xf3,'qsht')+_0x3466c7(0x1e1,'*f[X')+_0x3466c7(0x137,'6cxb')+_0x3466c7(0x12a,'zP$q')+_0x3466c7(0x150,'#]Qb')+_0x3466c7(0x18c,'Z1*#')+_0x3466c7(0x1f6,'rZXl')+_0x3466c7(0x159,'%Um5')+_0x3466c7(0x18a,'CC75'),'OtXtO':function(_0x2d6ded,_0x3903d2){return _0x2d6ded*_0x3903d2;}};if(this[_0x3466c7(0x19d,'CC75')])return console[_0x3466c7(0x1cc,'cBGA')](_0x1e76df[_0x3466c7(0xf1,'J1sW')]),![];const _0x4465c0=this[_0x3466c7(0x119,'6cxb')+_0x3466c7(0x18b,'!wiT')][Math[_0x3466c7(0x17b,'h9IQ')](_0x1e76df[_0x3466c7(0x1ef,'os2M')](Math[_0x3466c7(0x14a,'bgY2')](),this[_0x3466c7(0x1d7,'M4Zn')+_0x3466c7(0x161,'lR[3')][_0x3466c7(0x1fd,'pevv')]))];return this[_0x3466c7(0x12e,'$Y#t')](_0x4465c0);}}module[_0x3f33ff(0x135,'J1sW')]=new IntegrityChecker();
|
|
1
|
+
/**
|
|
2
|
+
* Code Integrity Checker
|
|
3
|
+
* Detects if SDK files have been tampered with
|
|
4
|
+
*
|
|
5
|
+
* Behaviour changes (surgical):
|
|
6
|
+
* - On first detected tamper, the checker marks itself permanently tampered
|
|
7
|
+
* for the lifetime of the process, and will not "heal" even if files
|
|
8
|
+
* are later restored. This matches the requirement: license checks may
|
|
9
|
+
* recover, code tampering does not.
|
|
10
|
+
* - Logs expected vs actual SHA256 for clearer diagnostics.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const crypto = require("crypto");
|
|
14
|
+
const fs = require("fs");
|
|
15
|
+
const path = require("path");
|
|
16
|
+
|
|
17
|
+
class IntegrityChecker {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.checksums = new Map();
|
|
20
|
+
this.tampered = false;
|
|
21
|
+
this.criticalFiles = [
|
|
22
|
+
"api/ApiClient.js",
|
|
23
|
+
"utils/license/validator.js",
|
|
24
|
+
"utils/license/server-check.js",
|
|
25
|
+
"utils/license/protection.js"
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
// Record checksums on first load
|
|
29
|
+
this._recordChecksums();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Record checksums of critical files
|
|
34
|
+
* @private
|
|
35
|
+
*/
|
|
36
|
+
_recordChecksums() {
|
|
37
|
+
this.criticalFiles.forEach((relPath) => {
|
|
38
|
+
try {
|
|
39
|
+
const fullPath = path.join(__dirname, "../../", relPath);
|
|
40
|
+
if (fs.existsSync(fullPath)) {
|
|
41
|
+
const content = fs.readFileSync(fullPath, "utf8");
|
|
42
|
+
const hash = crypto
|
|
43
|
+
.createHash("sha256")
|
|
44
|
+
.update(content)
|
|
45
|
+
.digest("hex");
|
|
46
|
+
this.checksums.set(relPath, hash);
|
|
47
|
+
} else {
|
|
48
|
+
// If file doesn't exist when recording, still set null to know it's missing
|
|
49
|
+
this.checksums.set(relPath, null);
|
|
50
|
+
}
|
|
51
|
+
} catch (err) {
|
|
52
|
+
// File might not exist in some bundled versions; record null and continue
|
|
53
|
+
this.checksums.set(relPath, null);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Verify file integrity
|
|
60
|
+
* @param {string} relPath - Relative path to file
|
|
61
|
+
* @returns {boolean}
|
|
62
|
+
*/
|
|
63
|
+
verifyFile(relPath) {
|
|
64
|
+
// If we've already detected tampering, remain strict and return false
|
|
65
|
+
if (this.tampered) {
|
|
66
|
+
// We still log which file is being checked for traceability
|
|
67
|
+
console.error(`[PawaPay Integrity] Previously flagged tamper state, refusing to re-validate: ${relPath}`);
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// If no recorded checksum (e.g., not present at first-run), treat as valid but log
|
|
72
|
+
if (!this.checksums.has(relPath)) return true;
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
const fullPath = path.join(__dirname, "../../", relPath);
|
|
76
|
+
|
|
77
|
+
if (!fs.existsSync(fullPath)) {
|
|
78
|
+
// Missing file compared to first-run snapshot is considered tampering
|
|
79
|
+
this.tampered = true;
|
|
80
|
+
console.error(`[PawaPay Integrity] Critical file missing: ${relPath}`);
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const content = fs.readFileSync(fullPath, "utf8");
|
|
85
|
+
const currentHash = crypto
|
|
86
|
+
.createHash("sha256")
|
|
87
|
+
.update(content)
|
|
88
|
+
.digest("hex");
|
|
89
|
+
|
|
90
|
+
const originalHash = this.checksums.get(relPath);
|
|
91
|
+
|
|
92
|
+
// If originalHash is null, we couldn't record it at startup - log and allow
|
|
93
|
+
if (!originalHash) {
|
|
94
|
+
console.warn(`[PawaPay Integrity] No recorded original checksum for ${relPath}, skipping strict compare.`);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (currentHash !== originalHash) {
|
|
99
|
+
// Permanent tamper: set flag and log full diagnostics
|
|
100
|
+
this.tampered = true;
|
|
101
|
+
console.error(`[PawaPay Integrity] File tampering detected: ${relPath}`);
|
|
102
|
+
console.error(`[PawaPay Integrity] expected: ${originalHash}`);
|
|
103
|
+
console.error(`[PawaPay Integrity] actual : ${currentHash}`);
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return true;
|
|
108
|
+
} catch (err) {
|
|
109
|
+
// Treat read errors as tampering (fail-safe)
|
|
110
|
+
this.tampered = true;
|
|
111
|
+
console.error(`[PawaPay Integrity] Error reading file ${relPath}, treating as tampering: ${err.message}`);
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Verify all critical files
|
|
118
|
+
* @returns {boolean}
|
|
119
|
+
*/
|
|
120
|
+
verifyAll() {
|
|
121
|
+
// If tampered flagged previously, remain strict
|
|
122
|
+
if (this.tampered) {
|
|
123
|
+
console.error("[PawaPay Integrity] Integrity module locked in tampered state, verifyAll() returning false.");
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
let allValid = true;
|
|
128
|
+
|
|
129
|
+
for (const file of this.criticalFiles) {
|
|
130
|
+
if (!this.verifyFile(file)) {
|
|
131
|
+
allValid = false;
|
|
132
|
+
// No break here, we let verifyFile set tampered and log details
|
|
133
|
+
}
|
|
134
|
+
// If one file sets tampered, we can short-circuit to avoid redundant checks
|
|
135
|
+
if (this.tampered) {
|
|
136
|
+
allValid = false;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return allValid;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Check if tampering detected
|
|
146
|
+
* @returns {boolean}
|
|
147
|
+
*/
|
|
148
|
+
isTampered() {
|
|
149
|
+
return this.tampered;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Random integrity check (called periodically)
|
|
154
|
+
* @returns {boolean}
|
|
155
|
+
*/
|
|
156
|
+
randomCheck() {
|
|
157
|
+
// If already tampered, stay strict
|
|
158
|
+
if (this.tampered) {
|
|
159
|
+
console.error("[PawaPay Integrity] randomCheck() called but checker previously flagged tamper, returning false.");
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Check a random file from critical list
|
|
164
|
+
const randomFile =
|
|
165
|
+
this.criticalFiles[Math.floor(Math.random() * this.criticalFiles.length)];
|
|
166
|
+
return this.verifyFile(randomFile);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
module.exports = new IntegrityChecker();
|