@ceon-oy/monitor-sdk 1.0.2 → 1.0.3

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/README.md CHANGED
@@ -96,6 +96,7 @@ interface MonitorClientConfig {
96
96
  environment: string;
97
97
  }[];
98
98
  excludePatterns?: string[]; // Glob patterns to exclude (e.g., '@types/*')
99
+ autoAudit?: boolean; // Enable automatic vulnerability scanning (default: false)
99
100
  }
100
101
  ```
101
102
 
@@ -206,7 +207,29 @@ await monitor.auditDependencies({
206
207
  });
207
208
  ```
208
209
 
209
- #### Scheduled Auditing
210
+ #### Automatic Auditing (Recommended)
211
+
212
+ Enable `autoAudit: true` to let the SDK automatically scan for vulnerabilities based on the interval configured in the Ceon Monitor dashboard:
213
+
214
+ ```typescript
215
+ const monitor = new MonitorClient({
216
+ apiKey: process.env.CEON_MONITOR_API_KEY!,
217
+ endpoint: 'https://monitor.example.com',
218
+ autoAudit: true, // Enable automatic vulnerability scanning
219
+ });
220
+ ```
221
+
222
+ With `autoAudit` enabled:
223
+ - SDK fetches the scan interval from the server on startup
224
+ - Runs an initial vulnerability scan
225
+ - Schedules recurring scans based on server configuration (e.g., every 24 hours)
226
+ - Responds to on-demand "Run Scan" requests from the dashboard (polled every 5 minutes)
227
+
228
+ Configure the scan interval in the Ceon Monitor dashboard under the project's Vulnerabilities page.
229
+
230
+ #### Manual Scheduled Auditing
231
+
232
+ If you prefer manual control over scheduling:
210
233
 
211
234
  ```typescript
212
235
  // Run on app startup
package/dist/index.d.mts CHANGED
@@ -31,6 +31,8 @@ interface MonitorClientConfig {
31
31
  maxRetries?: number;
32
32
  /** Request timeout in ms (default: 10000) */
33
33
  requestTimeoutMs?: number;
34
+ /** Enable automatic vulnerability scanning based on server-configured interval (default: false) */
35
+ autoAudit?: boolean;
34
36
  }
35
37
  interface TechnologyItem {
36
38
  name: string;
@@ -135,12 +137,41 @@ declare class MonitorClient {
135
137
  private retryCount;
136
138
  private isFlushInProgress;
137
139
  private requestTimeoutMs;
140
+ private autoAudit;
141
+ private auditIntervalTimer;
142
+ private settingsPollingTimer;
143
+ private lastScanTime;
144
+ private lastKnownScanRequestedAt;
138
145
  constructor(config: MonitorClientConfig);
139
146
  captureError(error: Error, context?: ErrorContext): Promise<void>;
140
147
  captureMessage(message: string, severity?: Severity, context?: ErrorContext): Promise<void>;
141
148
  flush(): Promise<void>;
142
149
  private getErrorKey;
143
150
  close(): Promise<void>;
151
+ private stopAuditIntervalTimer;
152
+ /**
153
+ * Fetch project settings from the monitoring server.
154
+ * Returns configuration including vulnerability scan interval and scan request timestamp.
155
+ */
156
+ fetchProjectSettings(): Promise<{
157
+ name: string;
158
+ vulnerabilityScanIntervalHours: number;
159
+ scanRequestedAt: string | null;
160
+ } | null>;
161
+ /**
162
+ * Setup automatic vulnerability scanning based on server-configured interval.
163
+ * Fetches settings from server and sets up recurring scans.
164
+ * Also sets up polling for on-demand scan requests from the server.
165
+ */
166
+ private setupAutoAudit;
167
+ /**
168
+ * Run a vulnerability scan and track the time it was run.
169
+ */
170
+ private runScanAndTrackTime;
171
+ /**
172
+ * Check if the server has requested an on-demand scan.
173
+ */
174
+ private checkForScanRequest;
144
175
  private enqueue;
145
176
  /**
146
177
  * Fetch with timeout to prevent hanging requests
package/dist/index.d.ts CHANGED
@@ -31,6 +31,8 @@ interface MonitorClientConfig {
31
31
  maxRetries?: number;
32
32
  /** Request timeout in ms (default: 10000) */
33
33
  requestTimeoutMs?: number;
34
+ /** Enable automatic vulnerability scanning based on server-configured interval (default: false) */
35
+ autoAudit?: boolean;
34
36
  }
35
37
  interface TechnologyItem {
36
38
  name: string;
@@ -135,12 +137,41 @@ declare class MonitorClient {
135
137
  private retryCount;
136
138
  private isFlushInProgress;
137
139
  private requestTimeoutMs;
140
+ private autoAudit;
141
+ private auditIntervalTimer;
142
+ private settingsPollingTimer;
143
+ private lastScanTime;
144
+ private lastKnownScanRequestedAt;
138
145
  constructor(config: MonitorClientConfig);
139
146
  captureError(error: Error, context?: ErrorContext): Promise<void>;
140
147
  captureMessage(message: string, severity?: Severity, context?: ErrorContext): Promise<void>;
141
148
  flush(): Promise<void>;
142
149
  private getErrorKey;
143
150
  close(): Promise<void>;
151
+ private stopAuditIntervalTimer;
152
+ /**
153
+ * Fetch project settings from the monitoring server.
154
+ * Returns configuration including vulnerability scan interval and scan request timestamp.
155
+ */
156
+ fetchProjectSettings(): Promise<{
157
+ name: string;
158
+ vulnerabilityScanIntervalHours: number;
159
+ scanRequestedAt: string | null;
160
+ } | null>;
161
+ /**
162
+ * Setup automatic vulnerability scanning based on server-configured interval.
163
+ * Fetches settings from server and sets up recurring scans.
164
+ * Also sets up polling for on-demand scan requests from the server.
165
+ */
166
+ private setupAutoAudit;
167
+ /**
168
+ * Run a vulnerability scan and track the time it was run.
169
+ */
170
+ private runScanAndTrackTime;
171
+ /**
172
+ * Check if the server has requested an on-demand scan.
173
+ */
174
+ private checkForScanRequest;
144
175
  private enqueue;
145
176
  /**
146
177
  * Fetch with timeout to prevent hanging requests
package/dist/index.js CHANGED
@@ -42,6 +42,10 @@ var MonitorClient = class {
42
42
  this.isClosed = false;
43
43
  this.retryCount = /* @__PURE__ */ new Map();
44
44
  this.isFlushInProgress = false;
45
+ this.auditIntervalTimer = null;
46
+ this.settingsPollingTimer = null;
47
+ this.lastScanTime = null;
48
+ this.lastKnownScanRequestedAt = null;
45
49
  if (!config.apiKey || config.apiKey.trim().length === 0) {
46
50
  throw new Error("[MonitorClient] API key is required");
47
51
  }
@@ -86,12 +90,18 @@ var MonitorClient = class {
86
90
  "@typescript-eslint/*"
87
91
  ];
88
92
  this.excludePatterns = config.excludePatterns || defaultExcludePatterns;
93
+ this.autoAudit = config.autoAudit || false;
89
94
  this.startFlushTimer();
90
95
  if (this.trackDependencies) {
91
96
  this.syncDependencies().catch((err) => {
92
97
  console.error("[MonitorClient] Failed to sync dependencies:", err instanceof Error ? err.message : String(err));
93
98
  });
94
99
  }
100
+ if (this.autoAudit) {
101
+ this.setupAutoAudit().catch((err) => {
102
+ console.error("[MonitorClient] Failed to setup auto audit:", err instanceof Error ? err.message : String(err));
103
+ });
104
+ }
95
105
  }
96
106
  async captureError(error, context) {
97
107
  if (this.isClosed) return;
@@ -168,8 +178,101 @@ var MonitorClient = class {
168
178
  async close() {
169
179
  this.isClosed = true;
170
180
  this.stopFlushTimer();
181
+ this.stopAuditIntervalTimer();
171
182
  await this.flush();
172
183
  }
184
+ stopAuditIntervalTimer() {
185
+ if (this.auditIntervalTimer) {
186
+ clearInterval(this.auditIntervalTimer);
187
+ this.auditIntervalTimer = null;
188
+ }
189
+ if (this.settingsPollingTimer) {
190
+ clearInterval(this.settingsPollingTimer);
191
+ this.settingsPollingTimer = null;
192
+ }
193
+ }
194
+ /**
195
+ * Fetch project settings from the monitoring server.
196
+ * Returns configuration including vulnerability scan interval and scan request timestamp.
197
+ */
198
+ async fetchProjectSettings() {
199
+ try {
200
+ const response = await this.fetchWithTimeout(`${this.endpoint}/api/v1/project/settings`, {
201
+ method: "GET",
202
+ headers: {
203
+ "Authorization": `Bearer ${this.apiKey}`,
204
+ "Content-Type": "application/json"
205
+ }
206
+ });
207
+ if (!response.ok) {
208
+ console.warn("[MonitorClient] Failed to fetch project settings:", response.status);
209
+ return null;
210
+ }
211
+ const result = await response.json();
212
+ return result.data || null;
213
+ } catch (err) {
214
+ console.warn("[MonitorClient] Failed to fetch project settings:", err instanceof Error ? err.message : String(err));
215
+ return null;
216
+ }
217
+ }
218
+ /**
219
+ * Setup automatic vulnerability scanning based on server-configured interval.
220
+ * Fetches settings from server and sets up recurring scans.
221
+ * Also sets up polling for on-demand scan requests from the server.
222
+ */
223
+ async setupAutoAudit() {
224
+ const settings = await this.fetchProjectSettings();
225
+ if (!settings) {
226
+ console.warn("[MonitorClient] Could not fetch project settings, auto audit disabled");
227
+ return;
228
+ }
229
+ if (settings.scanRequestedAt) {
230
+ this.lastKnownScanRequestedAt = new Date(settings.scanRequestedAt);
231
+ }
232
+ const intervalHours = settings.vulnerabilityScanIntervalHours;
233
+ if (intervalHours <= 0) {
234
+ console.log("[MonitorClient] Scheduled vulnerability scanning disabled by server configuration");
235
+ } else {
236
+ console.log(`[MonitorClient] Auto vulnerability scanning enabled (every ${intervalHours} hours)`);
237
+ await this.runScanAndTrackTime();
238
+ const intervalMs = intervalHours * 60 * 60 * 1e3;
239
+ this.auditIntervalTimer = setInterval(() => {
240
+ this.runScanAndTrackTime();
241
+ }, intervalMs);
242
+ }
243
+ console.log("[MonitorClient] Polling for scan requests enabled (every 5 minutes)");
244
+ this.settingsPollingTimer = setInterval(() => {
245
+ this.checkForScanRequest();
246
+ }, 5 * 60 * 1e3);
247
+ }
248
+ /**
249
+ * Run a vulnerability scan and track the time it was run.
250
+ */
251
+ async runScanAndTrackTime() {
252
+ try {
253
+ await this.auditDependencies();
254
+ this.lastScanTime = /* @__PURE__ */ new Date();
255
+ } catch (err) {
256
+ console.error("[MonitorClient] Vulnerability scan failed:", err instanceof Error ? err.message : String(err));
257
+ }
258
+ }
259
+ /**
260
+ * Check if the server has requested an on-demand scan.
261
+ */
262
+ async checkForScanRequest() {
263
+ try {
264
+ const settings = await this.fetchProjectSettings();
265
+ if (!settings || !settings.scanRequestedAt) return;
266
+ const scanRequestedAt = new Date(settings.scanRequestedAt);
267
+ if (!this.lastKnownScanRequestedAt || scanRequestedAt > this.lastKnownScanRequestedAt) {
268
+ console.log("[MonitorClient] On-demand scan requested by server");
269
+ this.lastKnownScanRequestedAt = scanRequestedAt;
270
+ await this.runScanAndTrackTime();
271
+ }
272
+ } catch (err) {
273
+ console.error("[MonitorClient] Failed to check for scan request:", err instanceof Error ? err.message : String(err));
274
+ }
275
+ }
173
276
  enqueue(payload) {
174
277
  if (this.queue.length >= this.maxQueueSize) {
175
278
  console.warn("[MonitorClient] Queue full, dropping oldest error");
package/dist/index.mjs CHANGED
@@ -13,6 +13,10 @@ var MonitorClient = class {
13
13
  this.isClosed = false;
14
14
  this.retryCount = /* @__PURE__ */ new Map();
15
15
  this.isFlushInProgress = false;
16
+ this.auditIntervalTimer = null;
17
+ this.settingsPollingTimer = null;
18
+ this.lastScanTime = null;
19
+ this.lastKnownScanRequestedAt = null;
16
20
  if (!config.apiKey || config.apiKey.trim().length === 0) {
17
21
  throw new Error("[MonitorClient] API key is required");
18
22
  }
@@ -57,12 +61,18 @@ var MonitorClient = class {
57
61
  "@typescript-eslint/*"
58
62
  ];
59
63
  this.excludePatterns = config.excludePatterns || defaultExcludePatterns;
64
+ this.autoAudit = config.autoAudit || false;
60
65
  this.startFlushTimer();
61
66
  if (this.trackDependencies) {
62
67
  this.syncDependencies().catch((err) => {
63
68
  console.error("[MonitorClient] Failed to sync dependencies:", err instanceof Error ? err.message : String(err));
64
69
  });
65
70
  }
71
+ if (this.autoAudit) {
72
+ this.setupAutoAudit().catch((err) => {
73
+ console.error("[MonitorClient] Failed to setup auto audit:", err instanceof Error ? err.message : String(err));
74
+ });
75
+ }
66
76
  }
67
77
  async captureError(error, context) {
68
78
  if (this.isClosed) return;
@@ -139,8 +149,101 @@ var MonitorClient = class {
139
149
  async close() {
140
150
  this.isClosed = true;
141
151
  this.stopFlushTimer();
152
+ this.stopAuditIntervalTimer();
142
153
  await this.flush();
143
154
  }
155
+ stopAuditIntervalTimer() {
156
+ if (this.auditIntervalTimer) {
157
+ clearInterval(this.auditIntervalTimer);
158
+ this.auditIntervalTimer = null;
159
+ }
160
+ if (this.settingsPollingTimer) {
161
+ clearInterval(this.settingsPollingTimer);
162
+ this.settingsPollingTimer = null;
163
+ }
164
+ }
165
+ /**
166
+ * Fetch project settings from the monitoring server.
167
+ * Returns configuration including vulnerability scan interval and scan request timestamp.
168
+ */
169
+ async fetchProjectSettings() {
170
+ try {
171
+ const response = await this.fetchWithTimeout(`${this.endpoint}/api/v1/project/settings`, {
172
+ method: "GET",
173
+ headers: {
174
+ "Authorization": `Bearer ${this.apiKey}`,
175
+ "Content-Type": "application/json"
176
+ }
177
+ });
178
+ if (!response.ok) {
179
+ console.warn("[MonitorClient] Failed to fetch project settings:", response.status);
180
+ return null;
181
+ }
182
+ const result = await response.json();
183
+ return result.data || null;
184
+ } catch (err) {
185
+ console.warn("[MonitorClient] Failed to fetch project settings:", err instanceof Error ? err.message : String(err));
186
+ return null;
187
+ }
188
+ }
189
+ /**
190
+ * Setup automatic vulnerability scanning based on server-configured interval.
191
+ * Fetches settings from server and sets up recurring scans.
192
+ * Also sets up polling for on-demand scan requests from the server.
193
+ */
194
+ async setupAutoAudit() {
195
+ const settings = await this.fetchProjectSettings();
196
+ if (!settings) {
197
+ console.warn("[MonitorClient] Could not fetch project settings, auto audit disabled");
198
+ return;
199
+ }
200
+ if (settings.scanRequestedAt) {
201
+ this.lastKnownScanRequestedAt = new Date(settings.scanRequestedAt);
202
+ }
203
+ const intervalHours = settings.vulnerabilityScanIntervalHours;
204
+ if (intervalHours <= 0) {
205
+ console.log("[MonitorClient] Scheduled vulnerability scanning disabled by server configuration");
206
+ } else {
207
+ console.log(`[MonitorClient] Auto vulnerability scanning enabled (every ${intervalHours} hours)`);
208
+ await this.runScanAndTrackTime();
209
+ const intervalMs = intervalHours * 60 * 60 * 1e3;
210
+ this.auditIntervalTimer = setInterval(() => {
211
+ this.runScanAndTrackTime();
212
+ }, intervalMs);
213
+ }
214
+ console.log("[MonitorClient] Polling for scan requests enabled (every 5 minutes)");
215
+ this.settingsPollingTimer = setInterval(() => {
216
+ this.checkForScanRequest();
217
+ }, 5 * 60 * 1e3);
218
+ }
219
+ /**
220
+ * Run a vulnerability scan and track the time it was run.
221
+ */
222
+ async runScanAndTrackTime() {
223
+ try {
224
+ await this.auditDependencies();
225
+ this.lastScanTime = /* @__PURE__ */ new Date();
226
+ } catch (err) {
227
+ console.error("[MonitorClient] Vulnerability scan failed:", err instanceof Error ? err.message : String(err));
228
+ }
229
+ }
230
+ /**
231
+ * Check if the server has requested an on-demand scan.
232
+ */
233
+ async checkForScanRequest() {
234
+ try {
235
+ const settings = await this.fetchProjectSettings();
236
+ if (!settings || !settings.scanRequestedAt) return;
237
+ const scanRequestedAt = new Date(settings.scanRequestedAt);
238
+ if (!this.lastKnownScanRequestedAt || scanRequestedAt > this.lastKnownScanRequestedAt) {
239
+ console.log("[MonitorClient] On-demand scan requested by server");
240
+ this.lastKnownScanRequestedAt = scanRequestedAt;
241
+ await this.runScanAndTrackTime();
242
+ }
243
+ } catch (err) {
244
+ console.error("[MonitorClient] Failed to check for scan request:", err instanceof Error ? err.message : String(err));
245
+ }
246
+ }
144
247
  enqueue(payload) {
145
248
  if (this.queue.length >= this.maxQueueSize) {
146
249
  console.warn("[MonitorClient] Queue full, dropping oldest error");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ceon-oy/monitor-sdk",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Client SDK for Ceon Monitor - Error tracking, health monitoring, security events, and vulnerability scanning",
5
5
  "author": "Ceon",
6
6
  "license": "MIT",