@ceon-oy/monitor-sdk 1.0.5 → 1.0.7
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/index.js +46 -44
- package/dist/index.mjs +46 -44
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -286,12 +286,12 @@ var MonitorClient = class {
|
|
|
286
286
|
/**
|
|
287
287
|
* Fetch with timeout to prevent hanging requests
|
|
288
288
|
*/
|
|
289
|
-
async fetchWithTimeout(url,
|
|
289
|
+
async fetchWithTimeout(url, options, timeoutMs = this.requestTimeoutMs) {
|
|
290
290
|
const controller = new AbortController();
|
|
291
291
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
292
292
|
try {
|
|
293
293
|
const response = await fetch(url, {
|
|
294
|
-
...
|
|
294
|
+
...options,
|
|
295
295
|
signal: controller.signal
|
|
296
296
|
});
|
|
297
297
|
return response;
|
|
@@ -374,13 +374,13 @@ var MonitorClient = class {
|
|
|
374
374
|
try {
|
|
375
375
|
const fsModule = await import("fs");
|
|
376
376
|
const pathModule = await import("path");
|
|
377
|
-
const
|
|
378
|
-
const
|
|
377
|
+
const fs = fsModule.default || fsModule;
|
|
378
|
+
const path = pathModule.default || pathModule;
|
|
379
379
|
const baseDir = process.cwd();
|
|
380
|
-
const resolvedPath =
|
|
381
|
-
const normalizedPath =
|
|
382
|
-
const normalizedBase =
|
|
383
|
-
if (!
|
|
380
|
+
const resolvedPath = path.isAbsolute(packagePath) ? packagePath : path.join(baseDir, packagePath);
|
|
381
|
+
const normalizedPath = path.normalize(resolvedPath);
|
|
382
|
+
const normalizedBase = path.normalize(baseDir);
|
|
383
|
+
if (!path.isAbsolute(packagePath)) {
|
|
384
384
|
if (!normalizedPath.startsWith(normalizedBase)) {
|
|
385
385
|
console.warn("[MonitorClient] Path traversal attempt blocked:", packagePath);
|
|
386
386
|
return [];
|
|
@@ -394,10 +394,10 @@ var MonitorClient = class {
|
|
|
394
394
|
console.warn("[MonitorClient] Path must point to package.json");
|
|
395
395
|
return [];
|
|
396
396
|
}
|
|
397
|
-
if (!
|
|
397
|
+
if (!fs.existsSync(normalizedPath)) {
|
|
398
398
|
return [];
|
|
399
399
|
}
|
|
400
|
-
const packageJson = JSON.parse(
|
|
400
|
+
const packageJson = JSON.parse(fs.readFileSync(normalizedPath, "utf-8"));
|
|
401
401
|
const technologies = [];
|
|
402
402
|
const deps = {
|
|
403
403
|
...packageJson.dependencies,
|
|
@@ -431,7 +431,7 @@ var MonitorClient = class {
|
|
|
431
431
|
async sendTechnologies(technologies) {
|
|
432
432
|
await this.sendTechnologiesWithEnvironment(technologies, this.environment);
|
|
433
433
|
}
|
|
434
|
-
async sendTechnologiesWithEnvironment(technologies,
|
|
434
|
+
async sendTechnologiesWithEnvironment(technologies, environment) {
|
|
435
435
|
const response = await this.fetchWithTimeout(`${this.endpoint}/api/v1/technologies/sync`, {
|
|
436
436
|
method: "POST",
|
|
437
437
|
headers: {
|
|
@@ -439,7 +439,7 @@ var MonitorClient = class {
|
|
|
439
439
|
Authorization: `Bearer ${this.apiKey}`
|
|
440
440
|
},
|
|
441
441
|
body: JSON.stringify({
|
|
442
|
-
environment
|
|
442
|
+
environment,
|
|
443
443
|
technologies
|
|
444
444
|
})
|
|
445
445
|
});
|
|
@@ -476,74 +476,74 @@ var MonitorClient = class {
|
|
|
476
476
|
/**
|
|
477
477
|
* Capture a login failure event (convenience method)
|
|
478
478
|
*/
|
|
479
|
-
async captureLoginFailure(
|
|
479
|
+
async captureLoginFailure(options) {
|
|
480
480
|
return this.captureSecurityEvent({
|
|
481
|
-
eventType: `login_failed_${
|
|
481
|
+
eventType: `login_failed_${options.authMethod || "other"}`,
|
|
482
482
|
category: "AUTHENTICATION",
|
|
483
483
|
severity: "MEDIUM",
|
|
484
|
-
ip:
|
|
485
|
-
identifier:
|
|
486
|
-
endpoint:
|
|
487
|
-
userAgent:
|
|
488
|
-
metadata: { reason:
|
|
484
|
+
ip: options.ip,
|
|
485
|
+
identifier: options.identifier,
|
|
486
|
+
endpoint: options.endpoint,
|
|
487
|
+
userAgent: options.userAgent,
|
|
488
|
+
metadata: { reason: options.reason, authMethod: options.authMethod }
|
|
489
489
|
});
|
|
490
490
|
}
|
|
491
491
|
/**
|
|
492
492
|
* Capture a successful login event
|
|
493
493
|
*/
|
|
494
|
-
async captureLoginSuccess(
|
|
494
|
+
async captureLoginSuccess(options) {
|
|
495
495
|
await this.captureSecurityEvent({
|
|
496
|
-
eventType: `login_success_${
|
|
496
|
+
eventType: `login_success_${options.authMethod || "other"}`,
|
|
497
497
|
category: "AUTHENTICATION",
|
|
498
498
|
severity: "LOW",
|
|
499
|
-
ip:
|
|
500
|
-
identifier:
|
|
501
|
-
endpoint:
|
|
502
|
-
userAgent:
|
|
503
|
-
metadata: { authMethod:
|
|
499
|
+
ip: options.ip,
|
|
500
|
+
identifier: options.identifier,
|
|
501
|
+
endpoint: options.endpoint,
|
|
502
|
+
userAgent: options.userAgent,
|
|
503
|
+
metadata: { authMethod: options.authMethod }
|
|
504
504
|
});
|
|
505
505
|
}
|
|
506
506
|
/**
|
|
507
507
|
* Capture a rate limit event
|
|
508
508
|
*/
|
|
509
|
-
async captureRateLimit(
|
|
509
|
+
async captureRateLimit(options) {
|
|
510
510
|
await this.captureSecurityEvent({
|
|
511
511
|
eventType: "rate_limit_exceeded",
|
|
512
512
|
category: "RATE_LIMIT",
|
|
513
513
|
severity: "MEDIUM",
|
|
514
|
-
ip:
|
|
515
|
-
identifier:
|
|
516
|
-
endpoint:
|
|
517
|
-
userAgent:
|
|
518
|
-
metadata: { limit:
|
|
514
|
+
ip: options.ip,
|
|
515
|
+
identifier: options.identifier,
|
|
516
|
+
endpoint: options.endpoint,
|
|
517
|
+
userAgent: options.userAgent,
|
|
518
|
+
metadata: { limit: options.limit, window: options.window }
|
|
519
519
|
});
|
|
520
520
|
}
|
|
521
521
|
/**
|
|
522
522
|
* Capture an authorization failure (user tried to access unauthorized resource)
|
|
523
523
|
*/
|
|
524
|
-
async captureAuthorizationFailure(
|
|
524
|
+
async captureAuthorizationFailure(options) {
|
|
525
525
|
await this.captureSecurityEvent({
|
|
526
526
|
eventType: "authorization_denied",
|
|
527
527
|
category: "AUTHORIZATION",
|
|
528
528
|
severity: "MEDIUM",
|
|
529
|
-
ip:
|
|
530
|
-
identifier:
|
|
531
|
-
endpoint:
|
|
532
|
-
userAgent:
|
|
533
|
-
metadata: { resource:
|
|
529
|
+
ip: options.ip,
|
|
530
|
+
identifier: options.identifier,
|
|
531
|
+
endpoint: options.endpoint,
|
|
532
|
+
userAgent: options.userAgent,
|
|
533
|
+
metadata: { resource: options.resource, action: options.action }
|
|
534
534
|
});
|
|
535
535
|
}
|
|
536
536
|
/**
|
|
537
537
|
* Check if an IP or identifier has triggered brute force detection
|
|
538
538
|
*/
|
|
539
|
-
async checkBruteForce(
|
|
539
|
+
async checkBruteForce(options) {
|
|
540
540
|
const response = await this.fetchWithTimeout(`${this.endpoint}/api/v1/security/detect/brute-force`, {
|
|
541
541
|
method: "POST",
|
|
542
542
|
headers: {
|
|
543
543
|
"Content-Type": "application/json",
|
|
544
544
|
Authorization: `Bearer ${this.apiKey}`
|
|
545
545
|
},
|
|
546
|
-
body: JSON.stringify(
|
|
546
|
+
body: JSON.stringify(options)
|
|
547
547
|
});
|
|
548
548
|
if (!response.ok) {
|
|
549
549
|
const errorText = await response.text().catch(() => "");
|
|
@@ -569,10 +569,12 @@ var MonitorClient = class {
|
|
|
569
569
|
let path;
|
|
570
570
|
let fs;
|
|
571
571
|
try {
|
|
572
|
-
const
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
572
|
+
const childProcess = await import("child_process");
|
|
573
|
+
const pathModule = await import("path");
|
|
574
|
+
const fsModule = await import("fs");
|
|
575
|
+
execSync = childProcess.execSync;
|
|
576
|
+
path = pathModule;
|
|
577
|
+
fs = fsModule;
|
|
576
578
|
} catch {
|
|
577
579
|
console.warn("[MonitorClient] auditDependencies requires Node.js (not available in bundled/browser environments)");
|
|
578
580
|
return null;
|
package/dist/index.mjs
CHANGED
|
@@ -250,12 +250,12 @@ var MonitorClient = class {
|
|
|
250
250
|
/**
|
|
251
251
|
* Fetch with timeout to prevent hanging requests
|
|
252
252
|
*/
|
|
253
|
-
async fetchWithTimeout(url,
|
|
253
|
+
async fetchWithTimeout(url, options, timeoutMs = this.requestTimeoutMs) {
|
|
254
254
|
const controller = new AbortController();
|
|
255
255
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
256
256
|
try {
|
|
257
257
|
const response = await fetch(url, {
|
|
258
|
-
...
|
|
258
|
+
...options,
|
|
259
259
|
signal: controller.signal
|
|
260
260
|
});
|
|
261
261
|
return response;
|
|
@@ -338,13 +338,13 @@ var MonitorClient = class {
|
|
|
338
338
|
try {
|
|
339
339
|
const fsModule = await import("fs");
|
|
340
340
|
const pathModule = await import("path");
|
|
341
|
-
const
|
|
342
|
-
const
|
|
341
|
+
const fs = fsModule.default || fsModule;
|
|
342
|
+
const path = pathModule.default || pathModule;
|
|
343
343
|
const baseDir = process.cwd();
|
|
344
|
-
const resolvedPath =
|
|
345
|
-
const normalizedPath =
|
|
346
|
-
const normalizedBase =
|
|
347
|
-
if (!
|
|
344
|
+
const resolvedPath = path.isAbsolute(packagePath) ? packagePath : path.join(baseDir, packagePath);
|
|
345
|
+
const normalizedPath = path.normalize(resolvedPath);
|
|
346
|
+
const normalizedBase = path.normalize(baseDir);
|
|
347
|
+
if (!path.isAbsolute(packagePath)) {
|
|
348
348
|
if (!normalizedPath.startsWith(normalizedBase)) {
|
|
349
349
|
console.warn("[MonitorClient] Path traversal attempt blocked:", packagePath);
|
|
350
350
|
return [];
|
|
@@ -358,10 +358,10 @@ var MonitorClient = class {
|
|
|
358
358
|
console.warn("[MonitorClient] Path must point to package.json");
|
|
359
359
|
return [];
|
|
360
360
|
}
|
|
361
|
-
if (!
|
|
361
|
+
if (!fs.existsSync(normalizedPath)) {
|
|
362
362
|
return [];
|
|
363
363
|
}
|
|
364
|
-
const packageJson = JSON.parse(
|
|
364
|
+
const packageJson = JSON.parse(fs.readFileSync(normalizedPath, "utf-8"));
|
|
365
365
|
const technologies = [];
|
|
366
366
|
const deps = {
|
|
367
367
|
...packageJson.dependencies,
|
|
@@ -395,7 +395,7 @@ var MonitorClient = class {
|
|
|
395
395
|
async sendTechnologies(technologies) {
|
|
396
396
|
await this.sendTechnologiesWithEnvironment(technologies, this.environment);
|
|
397
397
|
}
|
|
398
|
-
async sendTechnologiesWithEnvironment(technologies,
|
|
398
|
+
async sendTechnologiesWithEnvironment(technologies, environment) {
|
|
399
399
|
const response = await this.fetchWithTimeout(`${this.endpoint}/api/v1/technologies/sync`, {
|
|
400
400
|
method: "POST",
|
|
401
401
|
headers: {
|
|
@@ -403,7 +403,7 @@ var MonitorClient = class {
|
|
|
403
403
|
Authorization: `Bearer ${this.apiKey}`
|
|
404
404
|
},
|
|
405
405
|
body: JSON.stringify({
|
|
406
|
-
environment
|
|
406
|
+
environment,
|
|
407
407
|
technologies
|
|
408
408
|
})
|
|
409
409
|
});
|
|
@@ -440,74 +440,74 @@ var MonitorClient = class {
|
|
|
440
440
|
/**
|
|
441
441
|
* Capture a login failure event (convenience method)
|
|
442
442
|
*/
|
|
443
|
-
async captureLoginFailure(
|
|
443
|
+
async captureLoginFailure(options) {
|
|
444
444
|
return this.captureSecurityEvent({
|
|
445
|
-
eventType: `login_failed_${
|
|
445
|
+
eventType: `login_failed_${options.authMethod || "other"}`,
|
|
446
446
|
category: "AUTHENTICATION",
|
|
447
447
|
severity: "MEDIUM",
|
|
448
|
-
ip:
|
|
449
|
-
identifier:
|
|
450
|
-
endpoint:
|
|
451
|
-
userAgent:
|
|
452
|
-
metadata: { reason:
|
|
448
|
+
ip: options.ip,
|
|
449
|
+
identifier: options.identifier,
|
|
450
|
+
endpoint: options.endpoint,
|
|
451
|
+
userAgent: options.userAgent,
|
|
452
|
+
metadata: { reason: options.reason, authMethod: options.authMethod }
|
|
453
453
|
});
|
|
454
454
|
}
|
|
455
455
|
/**
|
|
456
456
|
* Capture a successful login event
|
|
457
457
|
*/
|
|
458
|
-
async captureLoginSuccess(
|
|
458
|
+
async captureLoginSuccess(options) {
|
|
459
459
|
await this.captureSecurityEvent({
|
|
460
|
-
eventType: `login_success_${
|
|
460
|
+
eventType: `login_success_${options.authMethod || "other"}`,
|
|
461
461
|
category: "AUTHENTICATION",
|
|
462
462
|
severity: "LOW",
|
|
463
|
-
ip:
|
|
464
|
-
identifier:
|
|
465
|
-
endpoint:
|
|
466
|
-
userAgent:
|
|
467
|
-
metadata: { authMethod:
|
|
463
|
+
ip: options.ip,
|
|
464
|
+
identifier: options.identifier,
|
|
465
|
+
endpoint: options.endpoint,
|
|
466
|
+
userAgent: options.userAgent,
|
|
467
|
+
metadata: { authMethod: options.authMethod }
|
|
468
468
|
});
|
|
469
469
|
}
|
|
470
470
|
/**
|
|
471
471
|
* Capture a rate limit event
|
|
472
472
|
*/
|
|
473
|
-
async captureRateLimit(
|
|
473
|
+
async captureRateLimit(options) {
|
|
474
474
|
await this.captureSecurityEvent({
|
|
475
475
|
eventType: "rate_limit_exceeded",
|
|
476
476
|
category: "RATE_LIMIT",
|
|
477
477
|
severity: "MEDIUM",
|
|
478
|
-
ip:
|
|
479
|
-
identifier:
|
|
480
|
-
endpoint:
|
|
481
|
-
userAgent:
|
|
482
|
-
metadata: { limit:
|
|
478
|
+
ip: options.ip,
|
|
479
|
+
identifier: options.identifier,
|
|
480
|
+
endpoint: options.endpoint,
|
|
481
|
+
userAgent: options.userAgent,
|
|
482
|
+
metadata: { limit: options.limit, window: options.window }
|
|
483
483
|
});
|
|
484
484
|
}
|
|
485
485
|
/**
|
|
486
486
|
* Capture an authorization failure (user tried to access unauthorized resource)
|
|
487
487
|
*/
|
|
488
|
-
async captureAuthorizationFailure(
|
|
488
|
+
async captureAuthorizationFailure(options) {
|
|
489
489
|
await this.captureSecurityEvent({
|
|
490
490
|
eventType: "authorization_denied",
|
|
491
491
|
category: "AUTHORIZATION",
|
|
492
492
|
severity: "MEDIUM",
|
|
493
|
-
ip:
|
|
494
|
-
identifier:
|
|
495
|
-
endpoint:
|
|
496
|
-
userAgent:
|
|
497
|
-
metadata: { resource:
|
|
493
|
+
ip: options.ip,
|
|
494
|
+
identifier: options.identifier,
|
|
495
|
+
endpoint: options.endpoint,
|
|
496
|
+
userAgent: options.userAgent,
|
|
497
|
+
metadata: { resource: options.resource, action: options.action }
|
|
498
498
|
});
|
|
499
499
|
}
|
|
500
500
|
/**
|
|
501
501
|
* Check if an IP or identifier has triggered brute force detection
|
|
502
502
|
*/
|
|
503
|
-
async checkBruteForce(
|
|
503
|
+
async checkBruteForce(options) {
|
|
504
504
|
const response = await this.fetchWithTimeout(`${this.endpoint}/api/v1/security/detect/brute-force`, {
|
|
505
505
|
method: "POST",
|
|
506
506
|
headers: {
|
|
507
507
|
"Content-Type": "application/json",
|
|
508
508
|
Authorization: `Bearer ${this.apiKey}`
|
|
509
509
|
},
|
|
510
|
-
body: JSON.stringify(
|
|
510
|
+
body: JSON.stringify(options)
|
|
511
511
|
});
|
|
512
512
|
if (!response.ok) {
|
|
513
513
|
const errorText = await response.text().catch(() => "");
|
|
@@ -533,10 +533,12 @@ var MonitorClient = class {
|
|
|
533
533
|
let path;
|
|
534
534
|
let fs;
|
|
535
535
|
try {
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
536
|
+
const childProcess = await import("child_process");
|
|
537
|
+
const pathModule = await import("path");
|
|
538
|
+
const fsModule = await import("fs");
|
|
539
|
+
execSync = childProcess.execSync;
|
|
540
|
+
path = pathModule;
|
|
541
|
+
fs = fsModule;
|
|
540
542
|
} catch {
|
|
541
543
|
console.warn("[MonitorClient] auditDependencies requires Node.js (not available in bundled/browser environments)");
|
|
542
544
|
return null;
|
package/package.json
CHANGED