stegdoc 4.0.0 → 5.0.1

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.
@@ -1,306 +1,306 @@
1
- /**
2
- * Decoy Data Generator - Server Metrics Report
3
- * Generates realistic-looking server monitoring/metrics data
4
- */
5
-
6
- // Fixed list of servers (small dev team setup - ~10 servers total)
7
- const SERVERS = [
8
- 'app-prod-01',
9
- 'app-prod-02',
10
- 'api-prod-01',
11
- 'db-prod-01',
12
- 'redis-prod-01',
13
- 'nginx-prod-01',
14
- 'app-dev-01',
15
- 'db-dev-01',
16
- 'jenkins-01',
17
- 'gitlab-01',
18
- ];
19
-
20
- const STATUS_VALUES = [
21
- { status: 'healthy', weight: 85 },
22
- { status: 'warning', weight: 10 },
23
- { status: 'critical', weight: 3 },
24
- { status: 'maintenance', weight: 2 },
25
- ];
26
-
27
- /**
28
- * Generate a random float between min and max with specified decimal places
29
- */
30
- function randomFloat(min, max, decimals = 1) {
31
- const val = Math.random() * (max - min) + min;
32
- return parseFloat(val.toFixed(decimals));
33
- }
34
-
35
- /**
36
- * Generate a random integer between min and max (inclusive)
37
- */
38
- function randomInt(min, max) {
39
- return Math.floor(Math.random() * (max - min + 1)) + min;
40
- }
41
-
42
- /**
43
- * Generate a random element from an array
44
- */
45
- function randomElement(arr) {
46
- return arr[Math.floor(Math.random() * arr.length)];
47
- }
48
-
49
- /**
50
- * Generate a weighted random status
51
- */
52
- function generateStatus() {
53
- const totalWeight = STATUS_VALUES.reduce((sum, s) => sum + s.weight, 0);
54
- let random = Math.random() * totalWeight;
55
-
56
- for (const item of STATUS_VALUES) {
57
- random -= item.weight;
58
- if (random <= 0) {
59
- return item.status;
60
- }
61
- }
62
- return 'healthy';
63
- }
64
-
65
- /**
66
- * Pick a server from the fixed list
67
- */
68
- function generateServerId() {
69
- return randomElement(SERVERS);
70
- }
71
-
72
- // Time window configuration (last 4 hours of data)
73
- const HOURS_WINDOW = 4;
74
-
75
- // Shared time window for multi-part consistency
76
- let sharedTimeWindow = null;
77
-
78
- /**
79
- * Initialize or get the shared time window
80
- * This ensures multi-part files have continuous timestamps
81
- */
82
- function getTimeWindow() {
83
- if (!sharedTimeWindow) {
84
- const now = new Date();
85
- sharedTimeWindow = {
86
- end: now.getTime(),
87
- start: now.getTime() - (HOURS_WINDOW * 60 * 60 * 1000),
88
- };
89
- }
90
- return sharedTimeWindow;
91
- }
92
-
93
- /**
94
- * Reset the time window (called between separate encode sessions)
95
- */
96
- function resetTimeWindow() {
97
- sharedTimeWindow = null;
98
- }
99
-
100
- /**
101
- * Generate a realistic timestamp within the configured time window
102
- */
103
- function generateTimestamp() {
104
- const window = getTimeWindow();
105
- const timestamp = new Date(window.start + Math.random() * (window.end - window.start));
106
-
107
- // Format: YYYY-MM-DD HH:MM:SS
108
- const year = timestamp.getFullYear();
109
- const month = (timestamp.getMonth() + 1).toString().padStart(2, '0');
110
- const day = timestamp.getDate().toString().padStart(2, '0');
111
- const hours = timestamp.getHours().toString().padStart(2, '0');
112
- const minutes = timestamp.getMinutes().toString().padStart(2, '0');
113
- const seconds = timestamp.getSeconds().toString().padStart(2, '0');
114
-
115
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
116
- }
117
-
118
- /**
119
- * Generate CPU usage based on status
120
- */
121
- function generateCpuUsage(status) {
122
- switch (status) {
123
- case 'critical':
124
- return randomFloat(90, 99);
125
- case 'warning':
126
- return randomFloat(70, 89);
127
- case 'maintenance':
128
- return randomFloat(0, 10);
129
- default:
130
- return randomFloat(15, 69);
131
- }
132
- }
133
-
134
- /**
135
- * Generate memory usage based on status
136
- */
137
- function generateMemoryUsage(status) {
138
- switch (status) {
139
- case 'critical':
140
- return randomFloat(92, 99);
141
- case 'warning':
142
- return randomFloat(75, 91);
143
- case 'maintenance':
144
- return randomFloat(5, 20);
145
- default:
146
- return randomFloat(30, 74);
147
- }
148
- }
149
-
150
- /**
151
- * Generate disk usage (generally more stable than CPU/memory)
152
- */
153
- function generateDiskUsage(status) {
154
- switch (status) {
155
- case 'critical':
156
- return randomFloat(95, 99);
157
- case 'warning':
158
- return randomFloat(80, 94);
159
- default:
160
- return randomFloat(25, 79);
161
- }
162
- }
163
-
164
- /**
165
- * Generate network I/O in MB/s
166
- */
167
- function generateNetworkIO() {
168
- return randomFloat(0.5, 150, 2);
169
- }
170
-
171
- /**
172
- * Generate request count (for web/api servers)
173
- */
174
- function generateRequestCount(serverId) {
175
- // Higher for app/api/nginx servers
176
- if (serverId.match(/^(app|api|nginx)/)) {
177
- return randomInt(500, 15000);
178
- }
179
- // Low for CI/CD servers
180
- if (serverId.match(/^(jenkins|gitlab)/)) {
181
- return randomInt(10, 200);
182
- }
183
- return randomInt(50, 1000);
184
- }
185
-
186
- /**
187
- * Generate response time in ms
188
- */
189
- function generateResponseTime(status) {
190
- switch (status) {
191
- case 'critical':
192
- return randomInt(2000, 10000);
193
- case 'warning':
194
- return randomInt(500, 1999);
195
- default:
196
- return randomInt(5, 499);
197
- }
198
- }
199
-
200
- /**
201
- * Generate uptime in hours
202
- */
203
- function generateUptime(status) {
204
- if (status === 'maintenance') {
205
- return randomFloat(0, 2, 1);
206
- }
207
- // Servers typically have long uptimes
208
- return randomFloat(24, 2160, 1); // Up to 90 days
209
- }
210
-
211
- /**
212
- * Generate column headers
213
- */
214
- function generateDecoyHeaders() {
215
- return [
216
- 'Timestamp',
217
- 'Server ID',
218
- 'Status',
219
- 'CPU %',
220
- 'Memory %',
221
- 'Disk %',
222
- 'Network (MB/s)',
223
- 'Requests',
224
- 'Resp Time (ms)',
225
- 'Uptime (hrs)',
226
- ];
227
- }
228
-
229
- /**
230
- * Generate a single row of server metrics
231
- */
232
- function generateMetricsRow() {
233
- const serverId = generateServerId();
234
- const status = generateStatus();
235
-
236
- return {
237
- timestamp: generateTimestamp(),
238
- serverId,
239
- status,
240
- cpu: generateCpuUsage(status),
241
- memory: generateMemoryUsage(status),
242
- disk: generateDiskUsage(status),
243
- network: generateNetworkIO(),
244
- requests: generateRequestCount(serverId),
245
- responseTime: generateResponseTime(status),
246
- uptime: generateUptime(status),
247
- };
248
- }
249
-
250
- /**
251
- * Generate decoy data with specified number of rows
252
- * @param {number} rowCount - Number of rows to generate (default 100)
253
- * @returns {Array<object>} Array of metrics row objects
254
- */
255
- function generateDecoyData(rowCount = 100) {
256
- const rows = [];
257
- for (let i = 0; i < rowCount; i++) {
258
- rows.push(generateMetricsRow());
259
- }
260
- // Sort by timestamp descending (most recent first)
261
- rows.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
262
- return rows;
263
- }
264
-
265
- /**
266
- * Calculate appropriate row count based on payload size
267
- * @param {number} payloadSizeBytes - Size of encrypted payload
268
- * @returns {number} Recommended number of decoy rows
269
- */
270
- function calculateDecoyRowCount(payloadSizeBytes) {
271
- const estimatedBytesPerRow = 150;
272
- const targetDecoyRatio = 0.4;
273
-
274
- const minRows = 50;
275
- const maxRows = 10000;
276
-
277
- const calculatedRows = Math.floor((payloadSizeBytes * targetDecoyRatio) / estimatedBytesPerRow);
278
-
279
- return Math.max(minRows, Math.min(maxRows, calculatedRows));
280
- }
281
-
282
- /**
283
- * Convert row object to array of values (for Excel)
284
- */
285
- function rowToArray(row) {
286
- return [
287
- row.timestamp,
288
- row.serverId,
289
- row.status,
290
- row.cpu,
291
- row.memory,
292
- row.disk,
293
- row.network,
294
- row.requests,
295
- row.responseTime,
296
- row.uptime,
297
- ];
298
- }
299
-
300
- module.exports = {
301
- generateDecoyHeaders,
302
- generateDecoyData,
303
- calculateDecoyRowCount,
304
- rowToArray,
305
- resetTimeWindow,
306
- };
1
+ /**
2
+ * Decoy Data Generator - Server Metrics Report
3
+ * Generates realistic-looking server monitoring/metrics data
4
+ */
5
+
6
+ // Fixed list of servers (small dev team setup - ~10 servers total)
7
+ const SERVERS = [
8
+ 'app-prod-01',
9
+ 'app-prod-02',
10
+ 'api-prod-01',
11
+ 'db-prod-01',
12
+ 'redis-prod-01',
13
+ 'nginx-prod-01',
14
+ 'app-dev-01',
15
+ 'db-dev-01',
16
+ 'jenkins-01',
17
+ 'gitlab-01',
18
+ ];
19
+
20
+ const STATUS_VALUES = [
21
+ { status: 'healthy', weight: 85 },
22
+ { status: 'warning', weight: 10 },
23
+ { status: 'critical', weight: 3 },
24
+ { status: 'maintenance', weight: 2 },
25
+ ];
26
+
27
+ /**
28
+ * Generate a random float between min and max with specified decimal places
29
+ */
30
+ function randomFloat(min, max, decimals = 1) {
31
+ const val = Math.random() * (max - min) + min;
32
+ return parseFloat(val.toFixed(decimals));
33
+ }
34
+
35
+ /**
36
+ * Generate a random integer between min and max (inclusive)
37
+ */
38
+ function randomInt(min, max) {
39
+ return Math.floor(Math.random() * (max - min + 1)) + min;
40
+ }
41
+
42
+ /**
43
+ * Generate a random element from an array
44
+ */
45
+ function randomElement(arr) {
46
+ return arr[Math.floor(Math.random() * arr.length)];
47
+ }
48
+
49
+ /**
50
+ * Generate a weighted random status
51
+ */
52
+ function generateStatus() {
53
+ const totalWeight = STATUS_VALUES.reduce((sum, s) => sum + s.weight, 0);
54
+ let random = Math.random() * totalWeight;
55
+
56
+ for (const item of STATUS_VALUES) {
57
+ random -= item.weight;
58
+ if (random <= 0) {
59
+ return item.status;
60
+ }
61
+ }
62
+ return 'healthy';
63
+ }
64
+
65
+ /**
66
+ * Pick a server from the fixed list
67
+ */
68
+ function generateServerId() {
69
+ return randomElement(SERVERS);
70
+ }
71
+
72
+ // Time window configuration (last 4 hours of data)
73
+ const HOURS_WINDOW = 4;
74
+
75
+ // Shared time window for multi-part consistency
76
+ let sharedTimeWindow = null;
77
+
78
+ /**
79
+ * Initialize or get the shared time window
80
+ * This ensures multi-part files have continuous timestamps
81
+ */
82
+ function getTimeWindow() {
83
+ if (!sharedTimeWindow) {
84
+ const now = new Date();
85
+ sharedTimeWindow = {
86
+ end: now.getTime(),
87
+ start: now.getTime() - (HOURS_WINDOW * 60 * 60 * 1000),
88
+ };
89
+ }
90
+ return sharedTimeWindow;
91
+ }
92
+
93
+ /**
94
+ * Reset the time window (called between separate encode sessions)
95
+ */
96
+ function resetTimeWindow() {
97
+ sharedTimeWindow = null;
98
+ }
99
+
100
+ /**
101
+ * Generate a realistic timestamp within the configured time window
102
+ */
103
+ function generateTimestamp() {
104
+ const window = getTimeWindow();
105
+ const timestamp = new Date(window.start + Math.random() * (window.end - window.start));
106
+
107
+ // Format: YYYY-MM-DD HH:MM:SS
108
+ const year = timestamp.getFullYear();
109
+ const month = (timestamp.getMonth() + 1).toString().padStart(2, '0');
110
+ const day = timestamp.getDate().toString().padStart(2, '0');
111
+ const hours = timestamp.getHours().toString().padStart(2, '0');
112
+ const minutes = timestamp.getMinutes().toString().padStart(2, '0');
113
+ const seconds = timestamp.getSeconds().toString().padStart(2, '0');
114
+
115
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
116
+ }
117
+
118
+ /**
119
+ * Generate CPU usage based on status
120
+ */
121
+ function generateCpuUsage(status) {
122
+ switch (status) {
123
+ case 'critical':
124
+ return randomFloat(90, 99);
125
+ case 'warning':
126
+ return randomFloat(70, 89);
127
+ case 'maintenance':
128
+ return randomFloat(0, 10);
129
+ default:
130
+ return randomFloat(15, 69);
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Generate memory usage based on status
136
+ */
137
+ function generateMemoryUsage(status) {
138
+ switch (status) {
139
+ case 'critical':
140
+ return randomFloat(92, 99);
141
+ case 'warning':
142
+ return randomFloat(75, 91);
143
+ case 'maintenance':
144
+ return randomFloat(5, 20);
145
+ default:
146
+ return randomFloat(30, 74);
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Generate disk usage (generally more stable than CPU/memory)
152
+ */
153
+ function generateDiskUsage(status) {
154
+ switch (status) {
155
+ case 'critical':
156
+ return randomFloat(95, 99);
157
+ case 'warning':
158
+ return randomFloat(80, 94);
159
+ default:
160
+ return randomFloat(25, 79);
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Generate network I/O in MB/s
166
+ */
167
+ function generateNetworkIO() {
168
+ return randomFloat(0.5, 150, 2);
169
+ }
170
+
171
+ /**
172
+ * Generate request count (for web/api servers)
173
+ */
174
+ function generateRequestCount(serverId) {
175
+ // Higher for app/api/nginx servers
176
+ if (serverId.match(/^(app|api|nginx)/)) {
177
+ return randomInt(500, 15000);
178
+ }
179
+ // Low for CI/CD servers
180
+ if (serverId.match(/^(jenkins|gitlab)/)) {
181
+ return randomInt(10, 200);
182
+ }
183
+ return randomInt(50, 1000);
184
+ }
185
+
186
+ /**
187
+ * Generate response time in ms
188
+ */
189
+ function generateResponseTime(status) {
190
+ switch (status) {
191
+ case 'critical':
192
+ return randomInt(2000, 10000);
193
+ case 'warning':
194
+ return randomInt(500, 1999);
195
+ default:
196
+ return randomInt(5, 499);
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Generate uptime in hours
202
+ */
203
+ function generateUptime(status) {
204
+ if (status === 'maintenance') {
205
+ return randomFloat(0, 2, 1);
206
+ }
207
+ // Servers typically have long uptimes
208
+ return randomFloat(24, 2160, 1); // Up to 90 days
209
+ }
210
+
211
+ /**
212
+ * Generate column headers
213
+ */
214
+ function generateDecoyHeaders() {
215
+ return [
216
+ 'Timestamp',
217
+ 'Server ID',
218
+ 'Status',
219
+ 'CPU %',
220
+ 'Memory %',
221
+ 'Disk %',
222
+ 'Network (MB/s)',
223
+ 'Requests',
224
+ 'Resp Time (ms)',
225
+ 'Uptime (hrs)',
226
+ ];
227
+ }
228
+
229
+ /**
230
+ * Generate a single row of server metrics
231
+ */
232
+ function generateMetricsRow() {
233
+ const serverId = generateServerId();
234
+ const status = generateStatus();
235
+
236
+ return {
237
+ timestamp: generateTimestamp(),
238
+ serverId,
239
+ status,
240
+ cpu: generateCpuUsage(status),
241
+ memory: generateMemoryUsage(status),
242
+ disk: generateDiskUsage(status),
243
+ network: generateNetworkIO(),
244
+ requests: generateRequestCount(serverId),
245
+ responseTime: generateResponseTime(status),
246
+ uptime: generateUptime(status),
247
+ };
248
+ }
249
+
250
+ /**
251
+ * Generate decoy data with specified number of rows
252
+ * @param {number} rowCount - Number of rows to generate (default 100)
253
+ * @returns {Array<object>} Array of metrics row objects
254
+ */
255
+ function generateDecoyData(rowCount = 100) {
256
+ const rows = [];
257
+ for (let i = 0; i < rowCount; i++) {
258
+ rows.push(generateMetricsRow());
259
+ }
260
+ // Sort by timestamp descending (most recent first)
261
+ rows.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
262
+ return rows;
263
+ }
264
+
265
+ /**
266
+ * Calculate appropriate row count based on payload size
267
+ * @param {number} payloadSizeBytes - Size of encrypted payload
268
+ * @returns {number} Recommended number of decoy rows
269
+ */
270
+ function calculateDecoyRowCount(payloadSizeBytes) {
271
+ const estimatedBytesPerRow = 150;
272
+ const targetDecoyRatio = 0.4;
273
+
274
+ const minRows = 50;
275
+ const maxRows = 10000;
276
+
277
+ const calculatedRows = Math.floor((payloadSizeBytes * targetDecoyRatio) / estimatedBytesPerRow);
278
+
279
+ return Math.max(minRows, Math.min(maxRows, calculatedRows));
280
+ }
281
+
282
+ /**
283
+ * Convert row object to array of values (for Excel)
284
+ */
285
+ function rowToArray(row) {
286
+ return [
287
+ row.timestamp,
288
+ row.serverId,
289
+ row.status,
290
+ row.cpu,
291
+ row.memory,
292
+ row.disk,
293
+ row.network,
294
+ row.requests,
295
+ row.responseTime,
296
+ row.uptime,
297
+ ];
298
+ }
299
+
300
+ module.exports = {
301
+ generateDecoyHeaders,
302
+ generateDecoyData,
303
+ calculateDecoyRowCount,
304
+ rowToArray,
305
+ resetTimeWindow,
306
+ };