xypriss 9.7.2 → 9.7.5
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/dist/cjs/src/plugins/core/manager/PluginSecurity.js +55 -56
- package/dist/cjs/src/plugins/core/manager/PluginSecurity.js.map +1 -1
- package/dist/esm/src/plugins/core/manager/PluginSecurity.js +55 -56
- package/dist/esm/src/plugins/core/manager/PluginSecurity.js.map +1 -1
- package/package.json +3 -2
- package/dist/cjs/src/config.js +0 -368
- package/dist/cjs/src/config.js.map +0 -1
- package/dist/esm/src/config.js +0 -364
- package/dist/esm/src/config.js.map +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var fs = require('fs');
|
|
4
4
|
var path = require('path');
|
|
5
|
-
var
|
|
5
|
+
var xyprissSecurity = require('xypriss-security');
|
|
6
6
|
var ProjectDiscovery = require('../../../utils/ProjectDiscovery.js');
|
|
7
7
|
var plugingSchema = require('../../../schemas/plugingSchema.js');
|
|
8
8
|
var OFFICIAL_PLUGINS = require('../../const/OFFICIAL_PLUGINS.js');
|
|
@@ -155,42 +155,53 @@ class PluginSecurity {
|
|
|
155
155
|
const metadata = {};
|
|
156
156
|
for (const line of lines) {
|
|
157
157
|
const trimmedLine = line.trim();
|
|
158
|
-
if (trimmedLine
|
|
159
|
-
|
|
158
|
+
if (!trimmedLine)
|
|
159
|
+
continue;
|
|
160
|
+
const proofMatch = trimmedLine.match(/^--- (BEGIN CRYPTOGRAPHIC PROOF|END XYPRISS SIGNATURE) ---$/);
|
|
161
|
+
if (proofMatch) {
|
|
162
|
+
if (proofMatch[1] === "BEGIN CRYPTOGRAPHIC PROOF") {
|
|
163
|
+
inProof = true;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
160
168
|
continue;
|
|
161
|
-
}
|
|
162
|
-
if (trimmedLine.startsWith("--- END XYPRISS SIGNATURE ---")) {
|
|
163
|
-
break;
|
|
164
169
|
}
|
|
165
170
|
if (inProof) {
|
|
166
|
-
|
|
167
|
-
|
|
171
|
+
const b64Match = trimmedLine.match(/^base64:\s*(.+)$/);
|
|
172
|
+
if (b64Match) {
|
|
173
|
+
signatureBase64 = b64Match[1].trim();
|
|
168
174
|
}
|
|
169
175
|
continue;
|
|
170
176
|
}
|
|
171
177
|
// Collect metadata lines (including header) for verification
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
178
|
+
sigContentLines.push(line);
|
|
179
|
+
const metaMatch = trimmedLine.match(/^([a-zA-Z0-9-]+):\s*(.+)$/);
|
|
180
|
+
if (metaMatch) {
|
|
181
|
+
const [, key, value] = metaMatch;
|
|
182
|
+
const v = value.trim();
|
|
183
|
+
switch (key) {
|
|
184
|
+
case "Manifest":
|
|
185
|
+
const parts = v.split("@");
|
|
186
|
+
metadata.name = parts[0];
|
|
187
|
+
metadata.version = parts[1];
|
|
188
|
+
break;
|
|
189
|
+
case "Min-Engine":
|
|
190
|
+
metadata.min_version = v;
|
|
191
|
+
break;
|
|
192
|
+
case "Fingerprint":
|
|
193
|
+
metadata.content_hash = v;
|
|
194
|
+
break;
|
|
195
|
+
case "Identity":
|
|
196
|
+
metadata.author_key = v;
|
|
197
|
+
break;
|
|
198
|
+
case "Expires":
|
|
199
|
+
metadata.expires_at = v;
|
|
200
|
+
break;
|
|
201
|
+
case "Revision":
|
|
202
|
+
metadata.prev_sig_hash = v;
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
194
205
|
}
|
|
195
206
|
}
|
|
196
207
|
const sigContent = sigContentLines.join("\n") + "\n";
|
|
@@ -230,41 +241,29 @@ class PluginSecurity {
|
|
|
230
241
|
filesToHash = this.walkDir(pluginRoot);
|
|
231
242
|
}
|
|
232
243
|
// Filter out the signature file itself
|
|
233
|
-
filesToHash = filesToHash.filter((f) =>
|
|
244
|
+
filesToHash = filesToHash.filter((f) => !/\.xsig$/.test(f));
|
|
234
245
|
// Match Go's sort by relative path for deterministic cross-machine hashing
|
|
235
246
|
const fileRelList = filesToHash.map((f) => ({
|
|
236
247
|
abs: f,
|
|
237
248
|
rel: path.relative(pluginRoot, f),
|
|
238
249
|
}));
|
|
239
250
|
fileRelList.sort((a, b) => a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0);
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
const contentHash = `sha256:${hash.digest("hex")}`;
|
|
251
|
+
const fileBuffers = fileRelList.map((file) => fs.readFileSync(file.abs));
|
|
252
|
+
const combinedBuffer = Buffer.concat(fileBuffers);
|
|
253
|
+
const hashResult = xyprissSecurity.Cipher.hash.create(combinedBuffer);
|
|
254
|
+
const contentHash = `sha256:${hashResult}`;
|
|
245
255
|
if (contentHash !== metadata.content_hash) {
|
|
246
|
-
throw new Error(`FATAL(INTERNAL::NODE): Content integrity violation for ${pluginName}. Computed: ${contentHash
|
|
256
|
+
throw new Error(`FATAL(INTERNAL::NODE): Content integrity violation for ${pluginName}. Computed: ${contentHash.slice(0, 10)}..., Manifest: ${metadata.content_hash.slice(0, 10)}...`);
|
|
247
257
|
}
|
|
248
|
-
const
|
|
258
|
+
const authKey = metadata.author_key || "";
|
|
259
|
+
const pubKeyMatch = authKey.match(/^(?:ed25519:)?([a-fA-F0-9]{64})$/);
|
|
260
|
+
const pubKeyHex = pubKeyMatch ? pubKeyMatch[1] : "";
|
|
249
261
|
if (!pubKeyHex)
|
|
250
|
-
throw new Error(`FATAL(INTERNAL::NODE): Missing Identity (author_key) for ${pluginName}`);
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const spkiBuf = Buffer.concat([derPrefix, pubKeyBuf]);
|
|
256
|
-
const pubKey = crypto.createPublicKey({
|
|
257
|
-
key: spkiBuf,
|
|
258
|
-
format: "der",
|
|
259
|
-
type: "spki",
|
|
260
|
-
});
|
|
261
|
-
const isVerified = crypto.verify(null, Buffer.from(sigContent), pubKey, sigBuf);
|
|
262
|
-
if (!isVerified) {
|
|
263
|
-
throw new Error(`FATAL(INTERNAL::NODE): Cryptographic signature verification failed for ${pluginName}`);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
catch (e) {
|
|
267
|
-
throw new Error(`FATAL(INTERNAL::NODE): Security audit failed for ${pluginName}: ${e.message}`);
|
|
262
|
+
throw new Error(`FATAL(INTERNAL::NODE): Missing or invalid Identity (author_key) for ${pluginName}`);
|
|
263
|
+
const sigBuf = Buffer.from(signatureBase64, "base64");
|
|
264
|
+
const isVerified = xyprissSecurity.Cipher.crypto.ed25519Verify(pubKeyHex, sigContent, sigBuf);
|
|
265
|
+
if (!isVerified) {
|
|
266
|
+
throw new Error(`FATAL(INTERNAL::NODE): Cryptographic signature verification failed for ${pluginName}`);
|
|
268
267
|
}
|
|
269
268
|
}
|
|
270
269
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginSecurity.js","sources":["../../../../../../src/plugins/core/manager/PluginSecurity.ts"],"sourcesContent":[null],"names":["getCallerProjectRoot","OFFICIAL_PLUGINS","isCoreFrameworkPath","verifyPluginContract","validatePlgInput"],"mappings":";;;;;;;;;AAAA;;;;;;;AAOiF;
|
|
1
|
+
{"version":3,"file":"PluginSecurity.js","sources":["../../../../../../src/plugins/core/manager/PluginSecurity.ts"],"sourcesContent":[null],"names":["getCallerProjectRoot","OFFICIAL_PLUGINS","isCoreFrameworkPath","verifyPluginContract","Cipher","validatePlgInput"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs__default from 'fs';
|
|
2
2
|
import path__default from 'path';
|
|
3
|
-
import
|
|
3
|
+
import { Cipher } from 'xypriss-security';
|
|
4
4
|
import { getCallerProjectRoot, isCoreFrameworkPath, verifyPluginContract } from '../../../utils/ProjectDiscovery.js';
|
|
5
5
|
import { validatePlgInput } from '../../../schemas/plugingSchema.js';
|
|
6
6
|
import { OFFICIAL_PLUGINS } from '../../const/OFFICIAL_PLUGINS.js';
|
|
@@ -153,42 +153,53 @@ class PluginSecurity {
|
|
|
153
153
|
const metadata = {};
|
|
154
154
|
for (const line of lines) {
|
|
155
155
|
const trimmedLine = line.trim();
|
|
156
|
-
if (trimmedLine
|
|
157
|
-
|
|
156
|
+
if (!trimmedLine)
|
|
157
|
+
continue;
|
|
158
|
+
const proofMatch = trimmedLine.match(/^--- (BEGIN CRYPTOGRAPHIC PROOF|END XYPRISS SIGNATURE) ---$/);
|
|
159
|
+
if (proofMatch) {
|
|
160
|
+
if (proofMatch[1] === "BEGIN CRYPTOGRAPHIC PROOF") {
|
|
161
|
+
inProof = true;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
158
166
|
continue;
|
|
159
|
-
}
|
|
160
|
-
if (trimmedLine.startsWith("--- END XYPRISS SIGNATURE ---")) {
|
|
161
|
-
break;
|
|
162
167
|
}
|
|
163
168
|
if (inProof) {
|
|
164
|
-
|
|
165
|
-
|
|
169
|
+
const b64Match = trimmedLine.match(/^base64:\s*(.+)$/);
|
|
170
|
+
if (b64Match) {
|
|
171
|
+
signatureBase64 = b64Match[1].trim();
|
|
166
172
|
}
|
|
167
173
|
continue;
|
|
168
174
|
}
|
|
169
175
|
// Collect metadata lines (including header) for verification
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
176
|
+
sigContentLines.push(line);
|
|
177
|
+
const metaMatch = trimmedLine.match(/^([a-zA-Z0-9-]+):\s*(.+)$/);
|
|
178
|
+
if (metaMatch) {
|
|
179
|
+
const [, key, value] = metaMatch;
|
|
180
|
+
const v = value.trim();
|
|
181
|
+
switch (key) {
|
|
182
|
+
case "Manifest":
|
|
183
|
+
const parts = v.split("@");
|
|
184
|
+
metadata.name = parts[0];
|
|
185
|
+
metadata.version = parts[1];
|
|
186
|
+
break;
|
|
187
|
+
case "Min-Engine":
|
|
188
|
+
metadata.min_version = v;
|
|
189
|
+
break;
|
|
190
|
+
case "Fingerprint":
|
|
191
|
+
metadata.content_hash = v;
|
|
192
|
+
break;
|
|
193
|
+
case "Identity":
|
|
194
|
+
metadata.author_key = v;
|
|
195
|
+
break;
|
|
196
|
+
case "Expires":
|
|
197
|
+
metadata.expires_at = v;
|
|
198
|
+
break;
|
|
199
|
+
case "Revision":
|
|
200
|
+
metadata.prev_sig_hash = v;
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
192
203
|
}
|
|
193
204
|
}
|
|
194
205
|
const sigContent = sigContentLines.join("\n") + "\n";
|
|
@@ -228,41 +239,29 @@ class PluginSecurity {
|
|
|
228
239
|
filesToHash = this.walkDir(pluginRoot);
|
|
229
240
|
}
|
|
230
241
|
// Filter out the signature file itself
|
|
231
|
-
filesToHash = filesToHash.filter((f) =>
|
|
242
|
+
filesToHash = filesToHash.filter((f) => !/\.xsig$/.test(f));
|
|
232
243
|
// Match Go's sort by relative path for deterministic cross-machine hashing
|
|
233
244
|
const fileRelList = filesToHash.map((f) => ({
|
|
234
245
|
abs: f,
|
|
235
246
|
rel: path__default.relative(pluginRoot, f),
|
|
236
247
|
}));
|
|
237
248
|
fileRelList.sort((a, b) => a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0);
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
}
|
|
242
|
-
const contentHash = `sha256:${hash.digest("hex")}`;
|
|
249
|
+
const fileBuffers = fileRelList.map((file) => fs__default.readFileSync(file.abs));
|
|
250
|
+
const combinedBuffer = Buffer.concat(fileBuffers);
|
|
251
|
+
const hashResult = Cipher.hash.create(combinedBuffer);
|
|
252
|
+
const contentHash = `sha256:${hashResult}`;
|
|
243
253
|
if (contentHash !== metadata.content_hash) {
|
|
244
|
-
throw new Error(`FATAL(INTERNAL::NODE): Content integrity violation for ${pluginName}. Computed: ${contentHash
|
|
254
|
+
throw new Error(`FATAL(INTERNAL::NODE): Content integrity violation for ${pluginName}. Computed: ${contentHash.slice(0, 10)}..., Manifest: ${metadata.content_hash.slice(0, 10)}...`);
|
|
245
255
|
}
|
|
246
|
-
const
|
|
256
|
+
const authKey = metadata.author_key || "";
|
|
257
|
+
const pubKeyMatch = authKey.match(/^(?:ed25519:)?([a-fA-F0-9]{64})$/);
|
|
258
|
+
const pubKeyHex = pubKeyMatch ? pubKeyMatch[1] : "";
|
|
247
259
|
if (!pubKeyHex)
|
|
248
|
-
throw new Error(`FATAL(INTERNAL::NODE): Missing Identity (author_key) for ${pluginName}`);
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const spkiBuf = Buffer.concat([derPrefix, pubKeyBuf]);
|
|
254
|
-
const pubKey = crypto__default.createPublicKey({
|
|
255
|
-
key: spkiBuf,
|
|
256
|
-
format: "der",
|
|
257
|
-
type: "spki",
|
|
258
|
-
});
|
|
259
|
-
const isVerified = crypto__default.verify(null, Buffer.from(sigContent), pubKey, sigBuf);
|
|
260
|
-
if (!isVerified) {
|
|
261
|
-
throw new Error(`FATAL(INTERNAL::NODE): Cryptographic signature verification failed for ${pluginName}`);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
catch (e) {
|
|
265
|
-
throw new Error(`FATAL(INTERNAL::NODE): Security audit failed for ${pluginName}: ${e.message}`);
|
|
260
|
+
throw new Error(`FATAL(INTERNAL::NODE): Missing or invalid Identity (author_key) for ${pluginName}`);
|
|
261
|
+
const sigBuf = Buffer.from(signatureBase64, "base64");
|
|
262
|
+
const isVerified = Cipher.crypto.ed25519Verify(pubKeyHex, sigContent, sigBuf);
|
|
263
|
+
if (!isVerified) {
|
|
264
|
+
throw new Error(`FATAL(INTERNAL::NODE): Cryptographic signature verification failed for ${pluginName}`);
|
|
266
265
|
}
|
|
267
266
|
}
|
|
268
267
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginSecurity.js","sources":["../../../../../../src/plugins/core/manager/PluginSecurity.ts"],"sourcesContent":[null],"names":["fs","path"
|
|
1
|
+
{"version":3,"file":"PluginSecurity.js","sources":["../../../../../../src/plugins/core/manager/PluginSecurity.ts"],"sourcesContent":[null],"names":["fs","path"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xypriss",
|
|
3
|
-
"version": "9.7.
|
|
3
|
+
"version": "9.7.5",
|
|
4
4
|
"description": "XyPriss is a high-performance, TypeScript-first hyper-system web framework powered by a native Go core (XHSC), featuring robust multi-tenant sandboxing, secure native file streaming, and zero Express dependencies.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Nehonix",
|
|
@@ -74,7 +74,8 @@
|
|
|
74
74
|
"ws": "^8.19.0",
|
|
75
75
|
"xss": "^1.0.15",
|
|
76
76
|
"xypriss-compression-pluging": "^1.0.3",
|
|
77
|
-
"xypriss-security": "^2.1.
|
|
77
|
+
"xypriss-security": "^2.1.16",
|
|
78
|
+
"xypriss-swagger": "workspace:*"
|
|
78
79
|
},
|
|
79
80
|
"devDependencies": {
|
|
80
81
|
"@rollup/plugin-commonjs": "^25.0.8",
|
package/dist/cjs/src/config.js
DELETED
|
@@ -1,368 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var _default = require('./server/const/default.js');
|
|
4
|
-
var crypto = require('crypto');
|
|
5
|
-
var mergeWithDefaults = require('./utils/mergeWithDefaults.js');
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* XyPriss Configuration Manager
|
|
9
|
-
*
|
|
10
|
-
* Provides a safe way to access and update XyPriss configurations
|
|
11
|
-
* without encountering "cannot access before initialization" errors.
|
|
12
|
-
*
|
|
13
|
-
* This class acts as a singleton configuration store that can be used
|
|
14
|
-
* in modular structures where accessing `app.configs` directly might
|
|
15
|
-
* cause initialization timing issues.
|
|
16
|
-
*
|
|
17
|
-
* **IMPORTANT**: This is the SINGLE SOURCE OF TRUTH for all XyPriss configurations.
|
|
18
|
-
* All components should use `Configs.get()` to access configuration values
|
|
19
|
-
* instead of copying values during initialization.
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```typescript
|
|
23
|
-
* import { Configs } from 'xypriss';
|
|
24
|
-
*
|
|
25
|
-
* // Set configuration
|
|
26
|
-
* Configs.set({
|
|
27
|
-
* fileUpload: {
|
|
28
|
-
* enabled: true,
|
|
29
|
-
* maxFileSize: 5 * 1024 * 1024
|
|
30
|
-
* }
|
|
31
|
-
* });
|
|
32
|
-
*
|
|
33
|
-
* // Get configuration
|
|
34
|
-
* const fileUploadConfig = Configs.get('fileUpload');
|
|
35
|
-
*
|
|
36
|
-
* // Get entire config
|
|
37
|
-
* const allConfigs = Configs.getAll();
|
|
38
|
-
*
|
|
39
|
-
* // Update specific config (updates the source of truth)
|
|
40
|
-
* Configs.update('fileUpload', { maxFileSize: 10 * 1024 * 1024 });
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
/**
|
|
44
|
-
* Configuration Manager Class
|
|
45
|
-
* Singleton pattern for managing XyPriss configurations
|
|
46
|
-
*/
|
|
47
|
-
class ConfigurationManager {
|
|
48
|
-
/**
|
|
49
|
-
* Private constructor to enforce singleton pattern
|
|
50
|
-
* Initializes with default configuration
|
|
51
|
-
*/
|
|
52
|
-
constructor() {
|
|
53
|
-
this.initialized = false;
|
|
54
|
-
// Initialize with default configuration
|
|
55
|
-
this.config = { ..._default.DEFAULT_OPTIONS };
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Get the singleton instance
|
|
59
|
-
*/
|
|
60
|
-
static getInstance() {
|
|
61
|
-
if (!ConfigurationManager.instance) {
|
|
62
|
-
ConfigurationManager.instance = new ConfigurationManager();
|
|
63
|
-
}
|
|
64
|
-
return ConfigurationManager.instance;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Set the entire configuration
|
|
68
|
-
* @param config - XP Server configuration options
|
|
69
|
-
*/
|
|
70
|
-
static set(config) {
|
|
71
|
-
const instance = ConfigurationManager.getInstance();
|
|
72
|
-
instance.config = ConfigurationManager.deepMerge(instance.config, config);
|
|
73
|
-
// Strict validation for XEMS if persistence is enabled
|
|
74
|
-
ConfigurationManager.validateXemsConfig(instance.config);
|
|
75
|
-
instance.initialized = true;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Get a specific configuration section
|
|
79
|
-
* @param key - Configuration key (e.g., 'fileUpload', 'security', 'cache')
|
|
80
|
-
* @returns The configuration value for the specified key
|
|
81
|
-
*/
|
|
82
|
-
static get(key) {
|
|
83
|
-
const instance = ConfigurationManager.getInstance();
|
|
84
|
-
return instance.config[key];
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Get the entire configuration object
|
|
88
|
-
* @returns Complete XyPriss Server Configuration (XPSC)
|
|
89
|
-
*/
|
|
90
|
-
static getAll() {
|
|
91
|
-
const instance = ConfigurationManager.getInstance();
|
|
92
|
-
return { ...instance.config };
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Update a specific XyPriss configuration section (deep merge)
|
|
96
|
-
* @param key - Configuration key to update
|
|
97
|
-
* @param value - Partial value to merge with existing configuration
|
|
98
|
-
*/
|
|
99
|
-
static update(key, value) {
|
|
100
|
-
const instance = ConfigurationManager.getInstance();
|
|
101
|
-
const currentValue = instance.config[key];
|
|
102
|
-
// Deep merge the new value with the existing value
|
|
103
|
-
if (typeof currentValue === "object" &&
|
|
104
|
-
currentValue !== null &&
|
|
105
|
-
!Array.isArray(currentValue)) {
|
|
106
|
-
instance.config[key] = {
|
|
107
|
-
...currentValue,
|
|
108
|
-
...value,
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
// For non-object values, just replace
|
|
113
|
-
instance.config[key] = value;
|
|
114
|
-
}
|
|
115
|
-
// Validate XEMS if it was part of the update
|
|
116
|
-
if (key === "server") {
|
|
117
|
-
ConfigurationManager.validateXemsConfig(instance.config);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Deep merge helper function
|
|
122
|
-
* @param target - Target object
|
|
123
|
-
* @param source - Source object to merge
|
|
124
|
-
* @returns Merged object
|
|
125
|
-
*/
|
|
126
|
-
/**
|
|
127
|
-
* Deeply merge two configuration objects
|
|
128
|
-
* @param target - Target object to merge into
|
|
129
|
-
* @param source - Source object to merge from
|
|
130
|
-
* @returns Merged object
|
|
131
|
-
*/
|
|
132
|
-
static deepMerge(target, source) {
|
|
133
|
-
// Create a plain copy of target. If target is a Proxy, this spreads its properties.
|
|
134
|
-
(Array.isArray(target) ? [...target] : { ...target });
|
|
135
|
-
// for (const key in source) {
|
|
136
|
-
// const sourceValue = source[key];
|
|
137
|
-
// const targetValue = result[key];
|
|
138
|
-
// const isSourceObj =
|
|
139
|
-
// sourceValue &&
|
|
140
|
-
// typeof sourceValue === "object" &&
|
|
141
|
-
// !Array.isArray(sourceValue);
|
|
142
|
-
// const isTargetObj =
|
|
143
|
-
// targetValue &&
|
|
144
|
-
// typeof targetValue === "object" &&
|
|
145
|
-
// !Array.isArray(targetValue);
|
|
146
|
-
// if (isSourceObj && isTargetObj) {
|
|
147
|
-
// // Both are objects, merge them recursively
|
|
148
|
-
// if (targetValue === sourceValue) {
|
|
149
|
-
// continue;
|
|
150
|
-
// }
|
|
151
|
-
// if ((targetValue as any).__isXyPrissImmutable) {
|
|
152
|
-
// // Target is immutable. We must merge recursively into it to trigger traps
|
|
153
|
-
// // and ensure compatibility.
|
|
154
|
-
// ConfigurationManager.deepMerge(targetValue, sourceValue);
|
|
155
|
-
// result[key] = targetValue;
|
|
156
|
-
// } else {
|
|
157
|
-
// // Target is plain, merge recursively
|
|
158
|
-
// result[key] = ConfigurationManager.deepMerge(
|
|
159
|
-
// targetValue,
|
|
160
|
-
// sourceValue,
|
|
161
|
-
// ) as any;
|
|
162
|
-
// }
|
|
163
|
-
// } else if (
|
|
164
|
-
// Array.isArray(sourceValue) &&
|
|
165
|
-
// Array.isArray(targetValue)
|
|
166
|
-
// ) {
|
|
167
|
-
// // For arrays, concatenate them to allow additive configuration (e.g., plugins)
|
|
168
|
-
// result[key] = [...targetValue, ...sourceValue] as any;
|
|
169
|
-
// } else if (sourceValue !== undefined) {
|
|
170
|
-
// // Primitive, non-matching types, or target is not an object.
|
|
171
|
-
// // If the parent (target) is immutable, try to set it there to trigger trap
|
|
172
|
-
// // This will throw if the value is different from the current one.
|
|
173
|
-
// if ((target as any).__isXyPrissImmutable) {
|
|
174
|
-
// (target as any)[key] = sourceValue;
|
|
175
|
-
// }
|
|
176
|
-
// result[key] = sourceValue as any;
|
|
177
|
-
// }
|
|
178
|
-
// }
|
|
179
|
-
return mergeWithDefaults.mergeWithDefaults(target, source);
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Merge configuration with existing config (deep merge)
|
|
183
|
-
* @param config - Partial configuration to merge
|
|
184
|
-
*/
|
|
185
|
-
static merge(config) {
|
|
186
|
-
const instance = ConfigurationManager.getInstance();
|
|
187
|
-
// Check if the incoming config is marked as immutable
|
|
188
|
-
const shouldBeImmutable = config?.__isXyPrissImmutable;
|
|
189
|
-
instance.config = ConfigurationManager.deepMerge(instance.config, config);
|
|
190
|
-
// Strict validation for XEMS
|
|
191
|
-
ConfigurationManager.validateXemsConfig(instance.config);
|
|
192
|
-
// If it should be immutable, wrap it using the global __const__.vars.make
|
|
193
|
-
if (shouldBeImmutable &&
|
|
194
|
-
typeof globalThis.__const__ !== "undefined") {
|
|
195
|
-
instance.config = globalThis.__const__.vars.make(instance.config, "Configs");
|
|
196
|
-
}
|
|
197
|
-
instance.initialized = true;
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Check if configuration has been initialized
|
|
201
|
-
* @returns true if configuration has been set, false otherwise
|
|
202
|
-
*/
|
|
203
|
-
static isInitialized() {
|
|
204
|
-
const instance = ConfigurationManager.getInstance();
|
|
205
|
-
return instance.initialized;
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Reset configuration to empty state
|
|
209
|
-
* Useful for testing or reinitializing
|
|
210
|
-
*/
|
|
211
|
-
static reset() {
|
|
212
|
-
const instance = ConfigurationManager.getInstance();
|
|
213
|
-
instance.config = {};
|
|
214
|
-
instance.initialized = false;
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* Check if a specific configuration section exists
|
|
218
|
-
* @param key - Configuration key to check
|
|
219
|
-
* @returns true if the configuration section exists
|
|
220
|
-
*/
|
|
221
|
-
static has(key) {
|
|
222
|
-
const instance = ConfigurationManager.getInstance();
|
|
223
|
-
return key in instance.config && instance.config[key] !== undefined;
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Get configuration with a default value if not set
|
|
227
|
-
* @param key - Configuration key
|
|
228
|
-
* @param defaultValue - Default value to return if key doesn't exist
|
|
229
|
-
* @returns Configuration value or default value
|
|
230
|
-
*/
|
|
231
|
-
static getOrDefault(key, defaultValue) {
|
|
232
|
-
const instance = ConfigurationManager.getInstance();
|
|
233
|
-
return instance.config[key] ?? defaultValue;
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Delete a specific configuration section
|
|
237
|
-
* @param key - Configuration key to delete
|
|
238
|
-
*/
|
|
239
|
-
static delete(key) {
|
|
240
|
-
const instance = ConfigurationManager.getInstance();
|
|
241
|
-
delete instance.config[key];
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Validates XEMS configuration strictly
|
|
245
|
-
* @param config - Current server configuration
|
|
246
|
-
* @throws Error if XEMS persistence is enabled but secret is invalid
|
|
247
|
-
*/
|
|
248
|
-
static validateXemsConfig(config) {
|
|
249
|
-
const xems = config.server?.xems;
|
|
250
|
-
if (typeof xems !== "object" || !xems.persistence?.enabled)
|
|
251
|
-
return;
|
|
252
|
-
const secret = xems.persistence.secret;
|
|
253
|
-
if (!secret || typeof secret !== "string") {
|
|
254
|
-
throw new Error("[XyPriss] XEMS Persistence enabled but no secret provided. " +
|
|
255
|
-
"Generate one with: node -e \"console.log(require('crypto').randomBytes(32).toString('hex').slice(0,32))\"");
|
|
256
|
-
}
|
|
257
|
-
// 0. Vérification de l'extension du fichier
|
|
258
|
-
if (xems?.persistence?.enabled
|
|
259
|
-
// !xems?.persistence?.path?.endsWith(".xems")
|
|
260
|
-
) {
|
|
261
|
-
if (!xems?.persistence?.path) {
|
|
262
|
-
throw new Error(`[XyPriss] XEMS Persistence path is required when persistence is enabled.`);
|
|
263
|
-
}
|
|
264
|
-
// if (xems.persistence.path.length > 20) {
|
|
265
|
-
// throw new Error(
|
|
266
|
-
// `[XyPriss] XEMS Persistence path too long. Maximum 20 characters allowed.`,
|
|
267
|
-
// );
|
|
268
|
-
// }
|
|
269
|
-
if (!xems?.persistence?.path?.endsWith(".xems")) {
|
|
270
|
-
throw new Error(`[XyPriss] XEMS Persistence path must end with ".xems". Got ${xems?.persistence?.path}`);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
// 1. Longueur exacte en bytes
|
|
274
|
-
const byteLength = Buffer.byteLength(secret, "utf8");
|
|
275
|
-
if (byteLength !== 32) {
|
|
276
|
-
throw new Error(`[XyPriss] Secret must be exactly 32 bytes. Got ${byteLength} bytes (${secret.length} chars).`);
|
|
277
|
-
}
|
|
278
|
-
// 2. Timing-safe check contre placeholders connus
|
|
279
|
-
const WEAK_SECRETS = [
|
|
280
|
-
"CHANGE_ME_TO_A_SECURE_32_CHAR_KEY",
|
|
281
|
-
"00000000000000000000000000000000",
|
|
282
|
-
"12345678901234567890123456789012",
|
|
283
|
-
];
|
|
284
|
-
const secretBuf = Buffer.from(secret);
|
|
285
|
-
for (const weak of WEAK_SECRETS) {
|
|
286
|
-
const weakBuf = Buffer.from(weak);
|
|
287
|
-
if (secretBuf.length === weakBuf.length &&
|
|
288
|
-
crypto.timingSafeEqual(secretBuf, weakBuf)) {
|
|
289
|
-
throw new Error("[XyPriss] Secret matches a known weak placeholder.");
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
// 3. Entropie de Shannon (bits par caractère)
|
|
293
|
-
const entropy = ConfigurationManager.shannonEntropy(secret);
|
|
294
|
-
if (entropy < 3.5) {
|
|
295
|
-
throw new Error(`[XyPriss] Secret entropy too low (${entropy.toFixed(2)} bits/char, minimum 3.5). ` +
|
|
296
|
-
"Avoid dictionary words, repeated patterns, or predictable sequences.");
|
|
297
|
-
}
|
|
298
|
-
// 4. Détection de patterns répétitifs (ex: "abcabc...", "aaa...")
|
|
299
|
-
if (ConfigurationManager.hasRepetitivePattern(secret)) {
|
|
300
|
-
throw new Error("[XyPriss] Secret contains repetitive patterns. Use a randomly generated key.");
|
|
301
|
-
}
|
|
302
|
-
// 5. Détection de mots du dictionnaire évidents
|
|
303
|
-
const COMMON_WORDS = [
|
|
304
|
-
"secret",
|
|
305
|
-
"password",
|
|
306
|
-
"key",
|
|
307
|
-
"admin",
|
|
308
|
-
"xems",
|
|
309
|
-
"change",
|
|
310
|
-
"secure",
|
|
311
|
-
];
|
|
312
|
-
const lowerSecret = secret.toLowerCase();
|
|
313
|
-
for (const word of COMMON_WORDS) {
|
|
314
|
-
if (lowerSecret.includes(word)) {
|
|
315
|
-
throw new Error(`[XyPriss] Secret contains a common word ("${word}"). ` +
|
|
316
|
-
"Use a randomly generated key with no dictionary words.");
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Calcule l'entropie de Shannon en bits par caractère
|
|
322
|
-
* Une clé aléatoire de 32 chars ASCII aura ~4.5-5 bits/char
|
|
323
|
-
* "a_very_secret_32_chars_key_12345" aura ~3.2 bits/char → rejeté
|
|
324
|
-
*/
|
|
325
|
-
static shannonEntropy(str) {
|
|
326
|
-
const freq = new Map();
|
|
327
|
-
for (const char of str) {
|
|
328
|
-
freq.set(char, (freq.get(char) ?? 0) + 1);
|
|
329
|
-
}
|
|
330
|
-
let entropy = 0;
|
|
331
|
-
for (const count of freq.values()) {
|
|
332
|
-
const p = count / str.length;
|
|
333
|
-
entropy -= p * Math.log2(p);
|
|
334
|
-
}
|
|
335
|
-
return entropy;
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Détecte si une string contient un pattern qui se répète
|
|
339
|
-
* ex: "abcdabcdabcdabcdabcdabcdabcdabcd" → true
|
|
340
|
-
*/
|
|
341
|
-
static hasRepetitivePattern(str) {
|
|
342
|
-
const len = str.length;
|
|
343
|
-
// Teste les périodes de 2 à len/2
|
|
344
|
-
for (let period = 2; period <= len / 2; period++) {
|
|
345
|
-
if (len % period !== 0)
|
|
346
|
-
continue;
|
|
347
|
-
const pattern = str.slice(0, period);
|
|
348
|
-
if (pattern.repeat(len / period) === str)
|
|
349
|
-
return true;
|
|
350
|
-
}
|
|
351
|
-
return false;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
// Self-register global __cfg__ if in a global environment
|
|
355
|
-
if (typeof globalThis !== "undefined") {
|
|
356
|
-
globalThis.__cfg__ =
|
|
357
|
-
globalThis.__cfg__ || ConfigurationManager;
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
* Default instance for easy access
|
|
361
|
-
*/
|
|
362
|
-
const __cfg__ = globalThis
|
|
363
|
-
.__cfg__;
|
|
364
|
-
|
|
365
|
-
exports.CM = ConfigurationManager;
|
|
366
|
-
exports.Configs = ConfigurationManager;
|
|
367
|
-
exports.__cfg__ = __cfg__;
|
|
368
|
-
//# sourceMappingURL=config.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sources":["../../../src/config.ts"],"sourcesContent":[null],"names":["DEFAULT_OPTIONS","mergeWithDefaults","timingSafeEqual"],"mappings":"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"}
|
package/dist/esm/src/config.js
DELETED
|
@@ -1,364 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_OPTIONS } from './server/const/default.js';
|
|
2
|
-
import { timingSafeEqual } from 'crypto';
|
|
3
|
-
import { mergeWithDefaults } from './utils/mergeWithDefaults.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* XyPriss Configuration Manager
|
|
7
|
-
*
|
|
8
|
-
* Provides a safe way to access and update XyPriss configurations
|
|
9
|
-
* without encountering "cannot access before initialization" errors.
|
|
10
|
-
*
|
|
11
|
-
* This class acts as a singleton configuration store that can be used
|
|
12
|
-
* in modular structures where accessing `app.configs` directly might
|
|
13
|
-
* cause initialization timing issues.
|
|
14
|
-
*
|
|
15
|
-
* **IMPORTANT**: This is the SINGLE SOURCE OF TRUTH for all XyPriss configurations.
|
|
16
|
-
* All components should use `Configs.get()` to access configuration values
|
|
17
|
-
* instead of copying values during initialization.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* import { Configs } from 'xypriss';
|
|
22
|
-
*
|
|
23
|
-
* // Set configuration
|
|
24
|
-
* Configs.set({
|
|
25
|
-
* fileUpload: {
|
|
26
|
-
* enabled: true,
|
|
27
|
-
* maxFileSize: 5 * 1024 * 1024
|
|
28
|
-
* }
|
|
29
|
-
* });
|
|
30
|
-
*
|
|
31
|
-
* // Get configuration
|
|
32
|
-
* const fileUploadConfig = Configs.get('fileUpload');
|
|
33
|
-
*
|
|
34
|
-
* // Get entire config
|
|
35
|
-
* const allConfigs = Configs.getAll();
|
|
36
|
-
*
|
|
37
|
-
* // Update specific config (updates the source of truth)
|
|
38
|
-
* Configs.update('fileUpload', { maxFileSize: 10 * 1024 * 1024 });
|
|
39
|
-
* ```
|
|
40
|
-
*/
|
|
41
|
-
/**
|
|
42
|
-
* Configuration Manager Class
|
|
43
|
-
* Singleton pattern for managing XyPriss configurations
|
|
44
|
-
*/
|
|
45
|
-
class ConfigurationManager {
|
|
46
|
-
/**
|
|
47
|
-
* Private constructor to enforce singleton pattern
|
|
48
|
-
* Initializes with default configuration
|
|
49
|
-
*/
|
|
50
|
-
constructor() {
|
|
51
|
-
this.initialized = false;
|
|
52
|
-
// Initialize with default configuration
|
|
53
|
-
this.config = { ...DEFAULT_OPTIONS };
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Get the singleton instance
|
|
57
|
-
*/
|
|
58
|
-
static getInstance() {
|
|
59
|
-
if (!ConfigurationManager.instance) {
|
|
60
|
-
ConfigurationManager.instance = new ConfigurationManager();
|
|
61
|
-
}
|
|
62
|
-
return ConfigurationManager.instance;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Set the entire configuration
|
|
66
|
-
* @param config - XP Server configuration options
|
|
67
|
-
*/
|
|
68
|
-
static set(config) {
|
|
69
|
-
const instance = ConfigurationManager.getInstance();
|
|
70
|
-
instance.config = ConfigurationManager.deepMerge(instance.config, config);
|
|
71
|
-
// Strict validation for XEMS if persistence is enabled
|
|
72
|
-
ConfigurationManager.validateXemsConfig(instance.config);
|
|
73
|
-
instance.initialized = true;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Get a specific configuration section
|
|
77
|
-
* @param key - Configuration key (e.g., 'fileUpload', 'security', 'cache')
|
|
78
|
-
* @returns The configuration value for the specified key
|
|
79
|
-
*/
|
|
80
|
-
static get(key) {
|
|
81
|
-
const instance = ConfigurationManager.getInstance();
|
|
82
|
-
return instance.config[key];
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Get the entire configuration object
|
|
86
|
-
* @returns Complete XyPriss Server Configuration (XPSC)
|
|
87
|
-
*/
|
|
88
|
-
static getAll() {
|
|
89
|
-
const instance = ConfigurationManager.getInstance();
|
|
90
|
-
return { ...instance.config };
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Update a specific XyPriss configuration section (deep merge)
|
|
94
|
-
* @param key - Configuration key to update
|
|
95
|
-
* @param value - Partial value to merge with existing configuration
|
|
96
|
-
*/
|
|
97
|
-
static update(key, value) {
|
|
98
|
-
const instance = ConfigurationManager.getInstance();
|
|
99
|
-
const currentValue = instance.config[key];
|
|
100
|
-
// Deep merge the new value with the existing value
|
|
101
|
-
if (typeof currentValue === "object" &&
|
|
102
|
-
currentValue !== null &&
|
|
103
|
-
!Array.isArray(currentValue)) {
|
|
104
|
-
instance.config[key] = {
|
|
105
|
-
...currentValue,
|
|
106
|
-
...value,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
// For non-object values, just replace
|
|
111
|
-
instance.config[key] = value;
|
|
112
|
-
}
|
|
113
|
-
// Validate XEMS if it was part of the update
|
|
114
|
-
if (key === "server") {
|
|
115
|
-
ConfigurationManager.validateXemsConfig(instance.config);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Deep merge helper function
|
|
120
|
-
* @param target - Target object
|
|
121
|
-
* @param source - Source object to merge
|
|
122
|
-
* @returns Merged object
|
|
123
|
-
*/
|
|
124
|
-
/**
|
|
125
|
-
* Deeply merge two configuration objects
|
|
126
|
-
* @param target - Target object to merge into
|
|
127
|
-
* @param source - Source object to merge from
|
|
128
|
-
* @returns Merged object
|
|
129
|
-
*/
|
|
130
|
-
static deepMerge(target, source) {
|
|
131
|
-
// Create a plain copy of target. If target is a Proxy, this spreads its properties.
|
|
132
|
-
(Array.isArray(target) ? [...target] : { ...target });
|
|
133
|
-
// for (const key in source) {
|
|
134
|
-
// const sourceValue = source[key];
|
|
135
|
-
// const targetValue = result[key];
|
|
136
|
-
// const isSourceObj =
|
|
137
|
-
// sourceValue &&
|
|
138
|
-
// typeof sourceValue === "object" &&
|
|
139
|
-
// !Array.isArray(sourceValue);
|
|
140
|
-
// const isTargetObj =
|
|
141
|
-
// targetValue &&
|
|
142
|
-
// typeof targetValue === "object" &&
|
|
143
|
-
// !Array.isArray(targetValue);
|
|
144
|
-
// if (isSourceObj && isTargetObj) {
|
|
145
|
-
// // Both are objects, merge them recursively
|
|
146
|
-
// if (targetValue === sourceValue) {
|
|
147
|
-
// continue;
|
|
148
|
-
// }
|
|
149
|
-
// if ((targetValue as any).__isXyPrissImmutable) {
|
|
150
|
-
// // Target is immutable. We must merge recursively into it to trigger traps
|
|
151
|
-
// // and ensure compatibility.
|
|
152
|
-
// ConfigurationManager.deepMerge(targetValue, sourceValue);
|
|
153
|
-
// result[key] = targetValue;
|
|
154
|
-
// } else {
|
|
155
|
-
// // Target is plain, merge recursively
|
|
156
|
-
// result[key] = ConfigurationManager.deepMerge(
|
|
157
|
-
// targetValue,
|
|
158
|
-
// sourceValue,
|
|
159
|
-
// ) as any;
|
|
160
|
-
// }
|
|
161
|
-
// } else if (
|
|
162
|
-
// Array.isArray(sourceValue) &&
|
|
163
|
-
// Array.isArray(targetValue)
|
|
164
|
-
// ) {
|
|
165
|
-
// // For arrays, concatenate them to allow additive configuration (e.g., plugins)
|
|
166
|
-
// result[key] = [...targetValue, ...sourceValue] as any;
|
|
167
|
-
// } else if (sourceValue !== undefined) {
|
|
168
|
-
// // Primitive, non-matching types, or target is not an object.
|
|
169
|
-
// // If the parent (target) is immutable, try to set it there to trigger trap
|
|
170
|
-
// // This will throw if the value is different from the current one.
|
|
171
|
-
// if ((target as any).__isXyPrissImmutable) {
|
|
172
|
-
// (target as any)[key] = sourceValue;
|
|
173
|
-
// }
|
|
174
|
-
// result[key] = sourceValue as any;
|
|
175
|
-
// }
|
|
176
|
-
// }
|
|
177
|
-
return mergeWithDefaults(target, source);
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Merge configuration with existing config (deep merge)
|
|
181
|
-
* @param config - Partial configuration to merge
|
|
182
|
-
*/
|
|
183
|
-
static merge(config) {
|
|
184
|
-
const instance = ConfigurationManager.getInstance();
|
|
185
|
-
// Check if the incoming config is marked as immutable
|
|
186
|
-
const shouldBeImmutable = config?.__isXyPrissImmutable;
|
|
187
|
-
instance.config = ConfigurationManager.deepMerge(instance.config, config);
|
|
188
|
-
// Strict validation for XEMS
|
|
189
|
-
ConfigurationManager.validateXemsConfig(instance.config);
|
|
190
|
-
// If it should be immutable, wrap it using the global __const__.vars.make
|
|
191
|
-
if (shouldBeImmutable &&
|
|
192
|
-
typeof globalThis.__const__ !== "undefined") {
|
|
193
|
-
instance.config = globalThis.__const__.vars.make(instance.config, "Configs");
|
|
194
|
-
}
|
|
195
|
-
instance.initialized = true;
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Check if configuration has been initialized
|
|
199
|
-
* @returns true if configuration has been set, false otherwise
|
|
200
|
-
*/
|
|
201
|
-
static isInitialized() {
|
|
202
|
-
const instance = ConfigurationManager.getInstance();
|
|
203
|
-
return instance.initialized;
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Reset configuration to empty state
|
|
207
|
-
* Useful for testing or reinitializing
|
|
208
|
-
*/
|
|
209
|
-
static reset() {
|
|
210
|
-
const instance = ConfigurationManager.getInstance();
|
|
211
|
-
instance.config = {};
|
|
212
|
-
instance.initialized = false;
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Check if a specific configuration section exists
|
|
216
|
-
* @param key - Configuration key to check
|
|
217
|
-
* @returns true if the configuration section exists
|
|
218
|
-
*/
|
|
219
|
-
static has(key) {
|
|
220
|
-
const instance = ConfigurationManager.getInstance();
|
|
221
|
-
return key in instance.config && instance.config[key] !== undefined;
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Get configuration with a default value if not set
|
|
225
|
-
* @param key - Configuration key
|
|
226
|
-
* @param defaultValue - Default value to return if key doesn't exist
|
|
227
|
-
* @returns Configuration value or default value
|
|
228
|
-
*/
|
|
229
|
-
static getOrDefault(key, defaultValue) {
|
|
230
|
-
const instance = ConfigurationManager.getInstance();
|
|
231
|
-
return instance.config[key] ?? defaultValue;
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Delete a specific configuration section
|
|
235
|
-
* @param key - Configuration key to delete
|
|
236
|
-
*/
|
|
237
|
-
static delete(key) {
|
|
238
|
-
const instance = ConfigurationManager.getInstance();
|
|
239
|
-
delete instance.config[key];
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* Validates XEMS configuration strictly
|
|
243
|
-
* @param config - Current server configuration
|
|
244
|
-
* @throws Error if XEMS persistence is enabled but secret is invalid
|
|
245
|
-
*/
|
|
246
|
-
static validateXemsConfig(config) {
|
|
247
|
-
const xems = config.server?.xems;
|
|
248
|
-
if (typeof xems !== "object" || !xems.persistence?.enabled)
|
|
249
|
-
return;
|
|
250
|
-
const secret = xems.persistence.secret;
|
|
251
|
-
if (!secret || typeof secret !== "string") {
|
|
252
|
-
throw new Error("[XyPriss] XEMS Persistence enabled but no secret provided. " +
|
|
253
|
-
"Generate one with: node -e \"console.log(require('crypto').randomBytes(32).toString('hex').slice(0,32))\"");
|
|
254
|
-
}
|
|
255
|
-
// 0. Vérification de l'extension du fichier
|
|
256
|
-
if (xems?.persistence?.enabled
|
|
257
|
-
// !xems?.persistence?.path?.endsWith(".xems")
|
|
258
|
-
) {
|
|
259
|
-
if (!xems?.persistence?.path) {
|
|
260
|
-
throw new Error(`[XyPriss] XEMS Persistence path is required when persistence is enabled.`);
|
|
261
|
-
}
|
|
262
|
-
// if (xems.persistence.path.length > 20) {
|
|
263
|
-
// throw new Error(
|
|
264
|
-
// `[XyPriss] XEMS Persistence path too long. Maximum 20 characters allowed.`,
|
|
265
|
-
// );
|
|
266
|
-
// }
|
|
267
|
-
if (!xems?.persistence?.path?.endsWith(".xems")) {
|
|
268
|
-
throw new Error(`[XyPriss] XEMS Persistence path must end with ".xems". Got ${xems?.persistence?.path}`);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
// 1. Longueur exacte en bytes
|
|
272
|
-
const byteLength = Buffer.byteLength(secret, "utf8");
|
|
273
|
-
if (byteLength !== 32) {
|
|
274
|
-
throw new Error(`[XyPriss] Secret must be exactly 32 bytes. Got ${byteLength} bytes (${secret.length} chars).`);
|
|
275
|
-
}
|
|
276
|
-
// 2. Timing-safe check contre placeholders connus
|
|
277
|
-
const WEAK_SECRETS = [
|
|
278
|
-
"CHANGE_ME_TO_A_SECURE_32_CHAR_KEY",
|
|
279
|
-
"00000000000000000000000000000000",
|
|
280
|
-
"12345678901234567890123456789012",
|
|
281
|
-
];
|
|
282
|
-
const secretBuf = Buffer.from(secret);
|
|
283
|
-
for (const weak of WEAK_SECRETS) {
|
|
284
|
-
const weakBuf = Buffer.from(weak);
|
|
285
|
-
if (secretBuf.length === weakBuf.length &&
|
|
286
|
-
timingSafeEqual(secretBuf, weakBuf)) {
|
|
287
|
-
throw new Error("[XyPriss] Secret matches a known weak placeholder.");
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
// 3. Entropie de Shannon (bits par caractère)
|
|
291
|
-
const entropy = ConfigurationManager.shannonEntropy(secret);
|
|
292
|
-
if (entropy < 3.5) {
|
|
293
|
-
throw new Error(`[XyPriss] Secret entropy too low (${entropy.toFixed(2)} bits/char, minimum 3.5). ` +
|
|
294
|
-
"Avoid dictionary words, repeated patterns, or predictable sequences.");
|
|
295
|
-
}
|
|
296
|
-
// 4. Détection de patterns répétitifs (ex: "abcabc...", "aaa...")
|
|
297
|
-
if (ConfigurationManager.hasRepetitivePattern(secret)) {
|
|
298
|
-
throw new Error("[XyPriss] Secret contains repetitive patterns. Use a randomly generated key.");
|
|
299
|
-
}
|
|
300
|
-
// 5. Détection de mots du dictionnaire évidents
|
|
301
|
-
const COMMON_WORDS = [
|
|
302
|
-
"secret",
|
|
303
|
-
"password",
|
|
304
|
-
"key",
|
|
305
|
-
"admin",
|
|
306
|
-
"xems",
|
|
307
|
-
"change",
|
|
308
|
-
"secure",
|
|
309
|
-
];
|
|
310
|
-
const lowerSecret = secret.toLowerCase();
|
|
311
|
-
for (const word of COMMON_WORDS) {
|
|
312
|
-
if (lowerSecret.includes(word)) {
|
|
313
|
-
throw new Error(`[XyPriss] Secret contains a common word ("${word}"). ` +
|
|
314
|
-
"Use a randomly generated key with no dictionary words.");
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* Calcule l'entropie de Shannon en bits par caractère
|
|
320
|
-
* Une clé aléatoire de 32 chars ASCII aura ~4.5-5 bits/char
|
|
321
|
-
* "a_very_secret_32_chars_key_12345" aura ~3.2 bits/char → rejeté
|
|
322
|
-
*/
|
|
323
|
-
static shannonEntropy(str) {
|
|
324
|
-
const freq = new Map();
|
|
325
|
-
for (const char of str) {
|
|
326
|
-
freq.set(char, (freq.get(char) ?? 0) + 1);
|
|
327
|
-
}
|
|
328
|
-
let entropy = 0;
|
|
329
|
-
for (const count of freq.values()) {
|
|
330
|
-
const p = count / str.length;
|
|
331
|
-
entropy -= p * Math.log2(p);
|
|
332
|
-
}
|
|
333
|
-
return entropy;
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* Détecte si une string contient un pattern qui se répète
|
|
337
|
-
* ex: "abcdabcdabcdabcdabcdabcdabcdabcd" → true
|
|
338
|
-
*/
|
|
339
|
-
static hasRepetitivePattern(str) {
|
|
340
|
-
const len = str.length;
|
|
341
|
-
// Teste les périodes de 2 à len/2
|
|
342
|
-
for (let period = 2; period <= len / 2; period++) {
|
|
343
|
-
if (len % period !== 0)
|
|
344
|
-
continue;
|
|
345
|
-
const pattern = str.slice(0, period);
|
|
346
|
-
if (pattern.repeat(len / period) === str)
|
|
347
|
-
return true;
|
|
348
|
-
}
|
|
349
|
-
return false;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
// Self-register global __cfg__ if in a global environment
|
|
353
|
-
if (typeof globalThis !== "undefined") {
|
|
354
|
-
globalThis.__cfg__ =
|
|
355
|
-
globalThis.__cfg__ || ConfigurationManager;
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Default instance for easy access
|
|
359
|
-
*/
|
|
360
|
-
const __cfg__ = globalThis
|
|
361
|
-
.__cfg__;
|
|
362
|
-
|
|
363
|
-
export { ConfigurationManager as CM, ConfigurationManager as Configs, __cfg__ };
|
|
364
|
-
//# sourceMappingURL=config.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sources":["../../../src/config.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|