@oneuptime/common 9.5.13 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/Server/API/UserCallAPI.ts +19 -0
  2. package/Server/API/UserEmailAPI.ts +19 -0
  3. package/Server/API/UserPushAPI.ts +66 -22
  4. package/Server/API/UserSmsAPI.ts +19 -0
  5. package/Server/API/UserWhatsAppAPI.ts +19 -0
  6. package/Server/EnvironmentConfig.ts +15 -0
  7. package/Server/Services/PushNotificationService.ts +136 -12
  8. package/Server/Services/UserNotificationRuleService.ts +153 -111
  9. package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +142 -0
  10. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +13 -0
  11. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +21 -0
  12. package/Server/Utils/VM/VMRunner.ts +214 -37
  13. package/Types/Monitor/CriteriaFilter.ts +9 -1
  14. package/Types/Monitor/DomainMonitor/DomainMonitorResponse.ts +15 -0
  15. package/Types/Monitor/MonitorCriteriaInstance.ts +67 -0
  16. package/Types/Monitor/MonitorStep.ts +32 -0
  17. package/Types/Monitor/MonitorStepDomainMonitor.ts +33 -0
  18. package/Types/Monitor/MonitorType.ts +16 -2
  19. package/Types/Probe/ProbeMonitorResponse.ts +2 -0
  20. package/build/dist/Server/API/UserCallAPI.js +17 -0
  21. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  22. package/build/dist/Server/API/UserEmailAPI.js +17 -0
  23. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  24. package/build/dist/Server/API/UserPushAPI.js +50 -12
  25. package/build/dist/Server/API/UserPushAPI.js.map +1 -1
  26. package/build/dist/Server/API/UserSmsAPI.js +17 -0
  27. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  28. package/build/dist/Server/API/UserWhatsAppAPI.js +17 -0
  29. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  30. package/build/dist/Server/EnvironmentConfig.js +5 -0
  31. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  32. package/build/dist/Server/Services/PushNotificationService.js +74 -12
  33. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  34. package/build/dist/Server/Services/UserNotificationRuleService.js +96 -109
  35. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  36. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +113 -0
  37. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -0
  38. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +10 -0
  39. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  40. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +16 -0
  41. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  42. package/build/dist/Server/Utils/VM/VMRunner.js +182 -20
  43. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  44. package/build/dist/Types/Monitor/CriteriaFilter.js +8 -1
  45. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  46. package/build/dist/Types/Monitor/DomainMonitor/DomainMonitorResponse.js +2 -0
  47. package/build/dist/Types/Monitor/DomainMonitor/DomainMonitorResponse.js.map +1 -0
  48. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +62 -0
  49. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  50. package/build/dist/Types/Monitor/MonitorStep.js +22 -0
  51. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  52. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +24 -0
  53. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -0
  54. package/build/dist/Types/Monitor/MonitorType.js +14 -2
  55. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  56. package/package.json +2 -1
@@ -1,12 +1,8 @@
1
- import Dictionary from "../../../Types/Dictionary";
2
- import GenericObject from "../../../Types/GenericObject";
3
1
  import ReturnResult from "../../../Types/IsolatedVM/ReturnResult";
4
- import { JSONObject, JSONValue } from "../../../Types/JSON";
5
- import axios from "axios";
6
- import http from "http";
7
- import https from "https";
2
+ import { JSONObject } from "../../../Types/JSON";
3
+ import axios, { AxiosResponse } from "axios";
8
4
  import crypto from "crypto";
9
- import vm, { Context } from "node:vm";
5
+ import ivm from "isolated-vm";
10
6
  import CaptureSpan from "../Telemetry/CaptureSpan";
11
7
 
12
8
  export default class VMRunner {
@@ -16,49 +12,230 @@ export default class VMRunner {
16
12
  options: {
17
13
  timeout?: number;
18
14
  args?: JSONObject | undefined;
19
- context?: Dictionary<GenericObject | string> | undefined;
20
15
  };
21
16
  }): Promise<ReturnResult> {
22
17
  const { code, options } = data;
18
+ const timeout: number = options.timeout || 5000;
23
19
 
24
20
  const logMessages: string[] = [];
25
21
 
26
- let sandbox: Context = {
27
- console: {
28
- log: (...args: JSONValue[]) => {
22
+ const isolate: ivm.Isolate = new ivm.Isolate({ memoryLimit: 128 });
23
+
24
+ try {
25
+ const context: ivm.Context = await isolate.createContext();
26
+ const jail: ivm.Reference<Record<string, unknown>> = context.global;
27
+
28
+ // Set up global object
29
+ await jail.set("global", jail.derefInto());
30
+
31
+ // console.log - fire-and-forget callback
32
+ await jail.set(
33
+ "_log",
34
+ new ivm.Callback((...args: string[]) => {
29
35
  logMessages.push(args.join(" "));
36
+ }),
37
+ );
38
+
39
+ await context.eval(`
40
+ const console = { log: (...a) => _log(...a.map(v => {
41
+ try { return typeof v === 'object' ? JSON.stringify(v) : String(v); }
42
+ catch(_) { return String(v); }
43
+ }))};
44
+ `);
45
+
46
+ // args - deep copy into isolate
47
+ if (options.args) {
48
+ await jail.set("_args", new ivm.ExternalCopy(options.args).copyInto());
49
+ await context.eval("const args = _args;");
50
+ } else {
51
+ await context.eval("const args = {};");
52
+ }
53
+
54
+ // axios (get, post, put, delete) - bridged via applySyncPromise
55
+ const axiosRef: ivm.Reference<
56
+ (method: string, url: string, dataOrConfig?: string) => Promise<string>
57
+ > = new ivm.Reference(
58
+ async (
59
+ method: string,
60
+ url: string,
61
+ dataOrConfig?: string,
62
+ ): Promise<string> => {
63
+ const parsed: JSONObject | undefined = dataOrConfig
64
+ ? (JSON.parse(dataOrConfig) as JSONObject)
65
+ : undefined;
66
+
67
+ let response: AxiosResponse;
68
+
69
+ switch (method) {
70
+ case "get":
71
+ response = await axios.get(url, parsed);
72
+ break;
73
+ case "post":
74
+ response = await axios.post(url, parsed);
75
+ break;
76
+ case "put":
77
+ response = await axios.put(url, parsed);
78
+ break;
79
+ case "delete":
80
+ response = await axios.delete(url, parsed);
81
+ break;
82
+ default:
83
+ throw new Error(`Unsupported HTTP method: ${method}`);
84
+ }
85
+
86
+ return JSON.stringify({
87
+ status: response.status,
88
+ headers: response.headers,
89
+ data: response.data,
90
+ });
30
91
  },
31
- },
32
- http: http,
33
- https: https,
34
- axios: axios,
35
- crypto: crypto,
36
- setTimeout: setTimeout,
37
- clearTimeout: clearTimeout,
38
- setInterval: setInterval,
39
- ...options.context,
40
- };
92
+ );
41
93
 
42
- if (options.args) {
43
- sandbox = {
44
- ...sandbox,
45
- args: options.args,
46
- };
47
- }
94
+ await jail.set("_axiosRef", axiosRef);
95
+
96
+ await context.eval(`
97
+ const axios = {
98
+ get: async (url, config) => {
99
+ const r = await _axiosRef.applySyncPromise(undefined, ['get', url, config ? JSON.stringify(config) : undefined]);
100
+ return JSON.parse(r);
101
+ },
102
+ post: async (url, data) => {
103
+ const r = await _axiosRef.applySyncPromise(undefined, ['post', url, data ? JSON.stringify(data) : undefined]);
104
+ return JSON.parse(r);
105
+ },
106
+ put: async (url, data) => {
107
+ const r = await _axiosRef.applySyncPromise(undefined, ['put', url, data ? JSON.stringify(data) : undefined]);
108
+ return JSON.parse(r);
109
+ },
110
+ delete: async (url, config) => {
111
+ const r = await _axiosRef.applySyncPromise(undefined, ['delete', url, config ? JSON.stringify(config) : undefined]);
112
+ return JSON.parse(r);
113
+ },
114
+ };
115
+ `);
48
116
 
49
- vm.createContext(sandbox); // Contextify the object.
117
+ // crypto (createHash, createHmac, randomBytes) - bridged via applySync
118
+ const cryptoRef: ivm.Reference<
119
+ (op: string, ...args: string[]) => string
120
+ > = new ivm.Reference((op: string, ...args: string[]): string => {
121
+ switch (op) {
122
+ case "createHash": {
123
+ const [algorithm, inputData, encoding] = args;
124
+ return crypto
125
+ .createHash(algorithm!)
126
+ .update(inputData!)
127
+ .digest((encoding as crypto.BinaryToTextEncoding) || "hex");
128
+ }
129
+ case "createHmac": {
130
+ const [algorithm, key, inputData, encoding] = args;
131
+ return crypto
132
+ .createHmac(algorithm!, key!)
133
+ .update(inputData!)
134
+ .digest((encoding as crypto.BinaryToTextEncoding) || "hex");
135
+ }
136
+ case "randomBytes": {
137
+ const [size] = args;
138
+ return crypto.randomBytes(parseInt(size!)).toString("hex");
139
+ }
140
+ default:
141
+ throw new Error(`Unsupported crypto operation: ${op}`);
142
+ }
143
+ });
50
144
 
51
- const script: string = `(async()=>{
52
- ${code}
145
+ await jail.set("_cryptoRef", cryptoRef);
146
+
147
+ await context.eval(`
148
+ const crypto = {
149
+ createHash: (algorithm) => ({
150
+ _alg: algorithm, _data: '',
151
+ update(d) { this._data = d; return this; },
152
+ digest(enc) { return _cryptoRef.applySync(undefined, ['createHash', this._alg, this._data, enc || 'hex']); }
153
+ }),
154
+ createHmac: (algorithm, key) => ({
155
+ _alg: algorithm, _key: key, _data: '',
156
+ update(d) { this._data = d; return this; },
157
+ digest(enc) { return _cryptoRef.applySync(undefined, ['createHmac', this._alg, this._key, this._data, enc || 'hex']); }
158
+ }),
159
+ randomBytes: (size) => ({
160
+ toString(enc) { return _cryptoRef.applySync(undefined, ['randomBytes', String(size)]); }
161
+ }),
162
+ };
163
+ `);
164
+
165
+ // setTimeout / sleep - bridged via applySyncPromise
166
+ const sleepRef: ivm.Reference<(ms: number) => Promise<void>> =
167
+ new ivm.Reference((ms: number): Promise<void> => {
168
+ return new Promise((resolve: () => void) => {
169
+ global.setTimeout(resolve, Math.min(ms, timeout));
170
+ });
171
+ });
172
+
173
+ await jail.set("_sleepRef", sleepRef);
174
+
175
+ await context.eval(`
176
+ function setTimeout(fn, ms) {
177
+ _sleepRef.applySyncPromise(undefined, [ms || 0]);
178
+ if (typeof fn === 'function') fn();
179
+ }
180
+ async function sleep(ms) {
181
+ await _sleepRef.applySyncPromise(undefined, [ms || 0]);
182
+ }
183
+ `);
184
+
185
+ /*
186
+ * Wrap user code in async IIFE. JSON.stringify the return value inside
187
+ * the isolate so only a plain string crosses the boundary — this avoids
188
+ * "A non-transferable value was passed" errors when user code returns
189
+ * objects containing functions, class instances, or other non-cloneable types.
190
+ */
191
+ const wrappedCode: string = `(async () => {
192
+ const __result = await (async () => {
193
+ ${code}
194
+ })();
195
+ try { return JSON.stringify(__result); }
196
+ catch(_) { return undefined; }
53
197
  })()`;
54
198
 
55
- const returnVal: any = await vm.runInContext(script, sandbox, {
56
- timeout: options.timeout || 5000,
57
- }); // run the script
199
+ // Run with overall timeout covering both CPU and I/O wait
200
+ const resultPromise: Promise<unknown> = context.eval(wrappedCode, {
201
+ promise: true,
202
+ timeout: timeout,
203
+ });
58
204
 
59
- return {
60
- returnValue: returnVal,
61
- logMessages,
62
- };
205
+ const overallTimeout: Promise<never> = new Promise(
206
+ (_resolve: (value: never) => void, reject: (reason: Error) => void) => {
207
+ global.setTimeout(() => {
208
+ reject(new Error("Script execution timed out"));
209
+ }, timeout + 5000); // 5s grace period beyond isolate timeout
210
+ },
211
+ );
212
+
213
+ const result: unknown = await Promise.race([
214
+ resultPromise,
215
+ overallTimeout,
216
+ ]);
217
+
218
+ // Parse the JSON string returned from inside the isolate
219
+ let returnValue: unknown;
220
+
221
+ if (typeof result === "string") {
222
+ try {
223
+ returnValue = JSON.parse(result);
224
+ } catch {
225
+ returnValue = result;
226
+ }
227
+ } else {
228
+ returnValue = result;
229
+ }
230
+
231
+ return {
232
+ returnValue,
233
+ logMessages,
234
+ };
235
+ } finally {
236
+ if (!isolate.isDisposed) {
237
+ isolate.dispose();
238
+ }
239
+ }
63
240
  }
64
241
  }
@@ -67,6 +67,13 @@ export enum CheckOn {
67
67
  DnsRecordValue = "DNS Record Value",
68
68
  DnssecIsValid = "DNSSEC Is Valid",
69
69
  DnsRecordExists = "DNS Record Exists",
70
+
71
+ // Domain monitors.
72
+ DomainExpiresDaysIn = "Domain Expires In Days",
73
+ DomainRegistrar = "Domain Registrar",
74
+ DomainNameServer = "Domain Name Server",
75
+ DomainStatusCode = "Domain Status Code",
76
+ DomainIsExpired = "Domain Is Expired",
70
77
  }
71
78
 
72
79
  export interface ServerMonitorOptions {
@@ -151,7 +158,8 @@ export class CriteriaFilterUtil {
151
158
  if (
152
159
  checkOn === CheckOn.IsOnline ||
153
160
  checkOn === CheckOn.SnmpIsOnline ||
154
- checkOn === CheckOn.DnsIsOnline
161
+ checkOn === CheckOn.DnsIsOnline ||
162
+ checkOn === CheckOn.DomainIsExpired
155
163
  ) {
156
164
  return false;
157
165
  }
@@ -0,0 +1,15 @@
1
+ export default interface DomainMonitorResponse {
2
+ isOnline: boolean;
3
+ responseTimeInMs: number;
4
+ failureCause: string;
5
+ domainName: string;
6
+ registrar?: string | undefined;
7
+ registrarUrl?: string | undefined;
8
+ createdDate?: string | undefined;
9
+ updatedDate?: string | undefined;
10
+ expiresDate?: string | undefined;
11
+ nameServers?: Array<string> | undefined;
12
+ dnssec?: string | undefined;
13
+ domainStatus?: Array<string> | undefined;
14
+ isTimeout?: boolean | undefined;
15
+ }
@@ -421,6 +421,33 @@ export default class MonitorCriteriaInstance extends DatabaseProperty {
421
421
  return monitorCriteriaInstance;
422
422
  }
423
423
 
424
+ if (arg.monitorType === MonitorType.Domain) {
425
+ const monitorCriteriaInstance: MonitorCriteriaInstance =
426
+ new MonitorCriteriaInstance();
427
+
428
+ monitorCriteriaInstance.data = {
429
+ id: ObjectID.generate().toString(),
430
+ monitorStatusId: arg.monitorStatusId,
431
+ filterCondition: FilterCondition.All,
432
+ filters: [
433
+ {
434
+ checkOn: CheckOn.DomainIsExpired,
435
+ filterType: FilterType.False,
436
+ value: undefined,
437
+ },
438
+ ],
439
+ incidents: [],
440
+ alerts: [],
441
+ createAlerts: false,
442
+ changeMonitorStatus: true,
443
+ createIncidents: false,
444
+ name: `Check if ${arg.monitorName} is not expired`,
445
+ description: `This criteria checks if the ${arg.monitorName} domain registration is not expired`,
446
+ };
447
+
448
+ return monitorCriteriaInstance;
449
+ }
450
+
424
451
  return null;
425
452
  }
426
453
 
@@ -562,6 +589,46 @@ export default class MonitorCriteriaInstance extends DatabaseProperty {
562
589
  };
563
590
  }
564
591
 
592
+ if (arg.monitorType === MonitorType.Domain) {
593
+ monitorCriteriaInstance.data = {
594
+ id: ObjectID.generate().toString(),
595
+ monitorStatusId: arg.monitorStatusId,
596
+ filterCondition: FilterCondition.Any,
597
+ filters: [
598
+ {
599
+ checkOn: CheckOn.DomainIsExpired,
600
+ filterType: FilterType.True,
601
+ value: undefined,
602
+ },
603
+ ],
604
+ incidents: [
605
+ {
606
+ title: `${arg.monitorName} domain is expired`,
607
+ description: `${arg.monitorName} domain registration has expired.`,
608
+ incidentSeverityId: arg.incidentSeverityId,
609
+ autoResolveIncident: true,
610
+ id: ObjectID.generate().toString(),
611
+ onCallPolicyIds: [],
612
+ },
613
+ ],
614
+ changeMonitorStatus: true,
615
+ createIncidents: true,
616
+ createAlerts: false,
617
+ alerts: [
618
+ {
619
+ title: `${arg.monitorName} domain is expired`,
620
+ description: `${arg.monitorName} domain registration has expired.`,
621
+ alertSeverityId: arg.alertSeverityId,
622
+ autoResolveAlert: true,
623
+ id: ObjectID.generate().toString(),
624
+ onCallPolicyIds: [],
625
+ },
626
+ ],
627
+ name: `Check if ${arg.monitorName} domain is expired`,
628
+ description: `This criteria checks if the ${arg.monitorName} domain registration has expired`,
629
+ };
630
+ }
631
+
565
632
  if (
566
633
  arg.monitorType === MonitorType.API ||
567
634
  arg.monitorType === MonitorType.Website
@@ -32,6 +32,9 @@ import MonitorStepSnmpMonitor, {
32
32
  import MonitorStepDnsMonitor, {
33
33
  MonitorStepDnsMonitorUtil,
34
34
  } from "./MonitorStepDnsMonitor";
35
+ import MonitorStepDomainMonitor, {
36
+ MonitorStepDomainMonitorUtil,
37
+ } from "./MonitorStepDomainMonitor";
35
38
  import Zod, { ZodSchema } from "../../Utils/Schema/Zod";
36
39
 
37
40
  export interface MonitorStepType {
@@ -78,6 +81,9 @@ export interface MonitorStepType {
78
81
 
79
82
  // DNS monitor
80
83
  dnsMonitor?: MonitorStepDnsMonitor | undefined;
84
+
85
+ // Domain monitor
86
+ domainMonitor?: MonitorStepDomainMonitor | undefined;
81
87
  }
82
88
 
83
89
  export default class MonitorStep extends DatabaseProperty {
@@ -105,6 +111,7 @@ export default class MonitorStep extends DatabaseProperty {
105
111
  exceptionMonitor: undefined,
106
112
  snmpMonitor: undefined,
107
113
  dnsMonitor: undefined,
114
+ domainMonitor: undefined,
108
115
  };
109
116
  }
110
117
 
@@ -137,6 +144,7 @@ export default class MonitorStep extends DatabaseProperty {
137
144
  exceptionMonitor: undefined,
138
145
  snmpMonitor: undefined,
139
146
  dnsMonitor: undefined,
147
+ domainMonitor: undefined,
140
148
  };
141
149
 
142
150
  return monitorStep;
@@ -237,6 +245,13 @@ export default class MonitorStep extends DatabaseProperty {
237
245
  return this;
238
246
  }
239
247
 
248
+ public setDomainMonitor(
249
+ domainMonitor: MonitorStepDomainMonitor,
250
+ ): MonitorStep {
251
+ this.data!.domainMonitor = domainMonitor;
252
+ return this;
253
+ }
254
+
240
255
  public setCustomCode(customCode: string): MonitorStep {
241
256
  this.data!.customCode = customCode;
242
257
  return this;
@@ -355,6 +370,16 @@ export default class MonitorStep extends DatabaseProperty {
355
370
  }
356
371
  }
357
372
 
373
+ if (monitorType === MonitorType.Domain) {
374
+ if (!value.data.domainMonitor) {
375
+ return "Domain configuration is required";
376
+ }
377
+
378
+ if (!value.data.domainMonitor.domainName) {
379
+ return "Domain name is required";
380
+ }
381
+ }
382
+
358
383
  return null;
359
384
  }
360
385
 
@@ -403,6 +428,9 @@ export default class MonitorStep extends DatabaseProperty {
403
428
  dnsMonitor: this.data.dnsMonitor
404
429
  ? MonitorStepDnsMonitorUtil.toJSON(this.data.dnsMonitor)
405
430
  : undefined,
431
+ domainMonitor: this.data.domainMonitor
432
+ ? MonitorStepDomainMonitorUtil.toJSON(this.data.domainMonitor)
433
+ : undefined,
406
434
  },
407
435
  });
408
436
  }
@@ -511,6 +539,9 @@ export default class MonitorStep extends DatabaseProperty {
511
539
  dnsMonitor: json["dnsMonitor"]
512
540
  ? (json["dnsMonitor"] as JSONObject)
513
541
  : undefined,
542
+ domainMonitor: json["domainMonitor"]
543
+ ? (json["domainMonitor"] as JSONObject)
544
+ : undefined,
514
545
  }) as any;
515
546
 
516
547
  return monitorStep;
@@ -537,6 +568,7 @@ export default class MonitorStep extends DatabaseProperty {
537
568
  metricMonitor: Zod.any().optional(),
538
569
  snmpMonitor: Zod.any().optional(),
539
570
  dnsMonitor: Zod.any().optional(),
571
+ domainMonitor: Zod.any().optional(),
540
572
  }).openapi({
541
573
  type: "object",
542
574
  example: {
@@ -0,0 +1,33 @@
1
+ import { JSONObject } from "../JSON";
2
+
3
+ export default interface MonitorStepDomainMonitor {
4
+ domainName: string;
5
+ timeout: number;
6
+ retries: number;
7
+ }
8
+
9
+ export class MonitorStepDomainMonitorUtil {
10
+ public static getDefault(): MonitorStepDomainMonitor {
11
+ return {
12
+ domainName: "",
13
+ timeout: 10000,
14
+ retries: 3,
15
+ };
16
+ }
17
+
18
+ public static fromJSON(json: JSONObject): MonitorStepDomainMonitor {
19
+ return {
20
+ domainName: (json["domainName"] as string) || "",
21
+ timeout: (json["timeout"] as number) || 10000,
22
+ retries: (json["retries"] as number) || 3,
23
+ };
24
+ }
25
+
26
+ public static toJSON(monitor: MonitorStepDomainMonitor): JSONObject {
27
+ return {
28
+ domainName: monitor.domainName,
29
+ timeout: monitor.timeout,
30
+ retries: monitor.retries,
31
+ };
32
+ }
33
+ }
@@ -29,6 +29,9 @@ enum MonitorType {
29
29
 
30
30
  // DNS monitoring
31
31
  DNS = "DNS",
32
+
33
+ // Domain registration monitoring
34
+ Domain = "Domain",
32
35
  }
33
36
 
34
37
  export default MonitorType;
@@ -58,6 +61,7 @@ export class MonitorTypeHelper {
58
61
  MonitorType.Port,
59
62
  MonitorType.DNS,
60
63
  MonitorType.SSLCertificate,
64
+ MonitorType.Domain,
61
65
  ],
62
66
  },
63
67
  {
@@ -239,6 +243,13 @@ export class MonitorTypeHelper {
239
243
  "This monitor type lets you monitor DNS resolution for your domains, verify record values, and check DNSSEC validity.",
240
244
  icon: IconProp.GlobeAlt,
241
245
  },
246
+ {
247
+ monitorType: MonitorType.Domain,
248
+ title: "Domain",
249
+ description:
250
+ "This monitor type lets you monitor domain registration health — expiry dates, registrar info, nameserver delegation, and WHOIS status.",
251
+ icon: IconProp.Globe,
252
+ },
242
253
  ];
243
254
 
244
255
  return monitorTypeProps;
@@ -285,7 +296,8 @@ export class MonitorTypeHelper {
285
296
  monitorType === MonitorType.SyntheticMonitor ||
286
297
  monitorType === MonitorType.CustomJavaScriptCode ||
287
298
  monitorType === MonitorType.SNMP ||
288
- monitorType === MonitorType.DNS;
299
+ monitorType === MonitorType.DNS ||
300
+ monitorType === MonitorType.Domain;
289
301
  return isProbeableMonitor;
290
302
  }
291
303
 
@@ -308,6 +320,7 @@ export class MonitorTypeHelper {
308
320
  MonitorType.Exceptions,
309
321
  MonitorType.SNMP,
310
322
  MonitorType.DNS,
323
+ MonitorType.Domain,
311
324
  ];
312
325
  }
313
326
 
@@ -341,7 +354,8 @@ export class MonitorTypeHelper {
341
354
  monitorType === MonitorType.SyntheticMonitor ||
342
355
  monitorType === MonitorType.CustomJavaScriptCode ||
343
356
  monitorType === MonitorType.SNMP ||
344
- monitorType === MonitorType.DNS
357
+ monitorType === MonitorType.DNS ||
358
+ monitorType === MonitorType.Domain
345
359
  ) {
346
360
  return true;
347
361
  }
@@ -8,6 +8,7 @@ import SslMonitorResponse from "../Monitor/SSLMonitor/SslMonitorResponse";
8
8
  import SyntheticMonitorResponse from "../Monitor/SyntheticMonitors/SyntheticMonitorResponse";
9
9
  import SnmpMonitorResponse from "../Monitor/SnmpMonitor/SnmpMonitorResponse";
10
10
  import DnsMonitorResponse from "../Monitor/DnsMonitor/DnsMonitorResponse";
11
+ import DomainMonitorResponse from "../Monitor/DomainMonitor/DomainMonitorResponse";
11
12
  import MonitorEvaluationSummary from "../Monitor/MonitorEvaluationSummary";
12
13
  import ObjectID from "../ObjectID";
13
14
  import Port from "../Port";
@@ -32,6 +33,7 @@ export default interface ProbeMonitorResponse {
32
33
  customCodeMonitorResponse?: CustomCodeMonitorResponse | undefined;
33
34
  snmpResponse?: SnmpMonitorResponse | undefined;
34
35
  dnsResponse?: DnsMonitorResponse | undefined;
36
+ domainResponse?: DomainMonitorResponse | undefined;
35
37
  monitoredAt: Date;
36
38
  isTimeout?: boolean | undefined;
37
39
  ingestedAt?: Date | undefined;
@@ -1,8 +1,11 @@
1
1
  import UserMiddleware from "../Middleware/UserAuthorization";
2
2
  import UserCallService from "../Services/UserCallService";
3
+ import UserNotificationRuleService from "../Services/UserNotificationRuleService";
3
4
  import Response from "../Utils/Response";
5
+ import logger from "../Utils/Logger";
4
6
  import BaseAPI from "./BaseAPI";
5
7
  import BadDataException from "../../Types/Exception/BadDataException";
8
+ import ObjectID from "../../Types/ObjectID";
6
9
  import UserCall from "../../Models/DatabaseModels/UserCall";
7
10
  export default class UserCallAPI extends BaseAPI {
8
11
  constructor() {
@@ -25,6 +28,7 @@ export default class UserCallAPI extends BaseAPI {
25
28
  },
26
29
  select: {
27
30
  userId: true,
31
+ projectId: true,
28
32
  verificationCode: true,
29
33
  },
30
34
  });
@@ -48,6 +52,19 @@ export default class UserCallAPI extends BaseAPI {
48
52
  isVerified: true,
49
53
  },
50
54
  });
55
+ // Create default notification rules for this verified call number
56
+ try {
57
+ await UserNotificationRuleService.addDefaultNotificationRulesForVerifiedMethod({
58
+ projectId: new ObjectID(item.projectId.toString()),
59
+ userId: new ObjectID(item.userId.toString()),
60
+ notificationMethod: {
61
+ userCallId: item.id,
62
+ },
63
+ });
64
+ }
65
+ catch (e) {
66
+ logger.error(e);
67
+ }
51
68
  return Response.sendEmptySuccessResponse(req, res);
52
69
  }
53
70
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"UserCallAPI.js","sourceRoot":"","sources":["../../../../Server/API/UserCallAPI.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UserCallAPI.js","sourceRoot":"","sources":["../../../../Server/API/UserCallAPI.ts"],"names":[],"mappings":"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"}