@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.
- package/Server/API/UserCallAPI.ts +19 -0
- package/Server/API/UserEmailAPI.ts +19 -0
- package/Server/API/UserPushAPI.ts +66 -22
- package/Server/API/UserSmsAPI.ts +19 -0
- package/Server/API/UserWhatsAppAPI.ts +19 -0
- package/Server/EnvironmentConfig.ts +15 -0
- package/Server/Services/PushNotificationService.ts +136 -12
- package/Server/Services/UserNotificationRuleService.ts +153 -111
- package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +142 -0
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +13 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +21 -0
- package/Server/Utils/VM/VMRunner.ts +214 -37
- package/Types/Monitor/CriteriaFilter.ts +9 -1
- package/Types/Monitor/DomainMonitor/DomainMonitorResponse.ts +15 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +67 -0
- package/Types/Monitor/MonitorStep.ts +32 -0
- package/Types/Monitor/MonitorStepDomainMonitor.ts +33 -0
- package/Types/Monitor/MonitorType.ts +16 -2
- package/Types/Probe/ProbeMonitorResponse.ts +2 -0
- package/build/dist/Server/API/UserCallAPI.js +17 -0
- package/build/dist/Server/API/UserCallAPI.js.map +1 -1
- package/build/dist/Server/API/UserEmailAPI.js +17 -0
- package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
- package/build/dist/Server/API/UserPushAPI.js +50 -12
- package/build/dist/Server/API/UserPushAPI.js.map +1 -1
- package/build/dist/Server/API/UserSmsAPI.js +17 -0
- package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
- package/build/dist/Server/API/UserWhatsAppAPI.js +17 -0
- package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +5 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +74 -12
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +96 -109
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +113 -0
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +10 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +16 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +182 -20
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +8 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/DomainMonitor/DomainMonitorResponse.js +2 -0
- package/build/dist/Types/Monitor/DomainMonitor/DomainMonitorResponse.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +62 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +22 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +24 -0
- package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorType.js +14 -2
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/package.json +2 -1
|
@@ -2,6 +2,7 @@ import UserMiddleware from "../Middleware/UserAuthorization";
|
|
|
2
2
|
import UserCallService, {
|
|
3
3
|
Service as UserCallServiceType,
|
|
4
4
|
} from "../Services/UserCallService";
|
|
5
|
+
import UserNotificationRuleService from "../Services/UserNotificationRuleService";
|
|
5
6
|
import {
|
|
6
7
|
ExpressRequest,
|
|
7
8
|
ExpressResponse,
|
|
@@ -9,8 +10,10 @@ import {
|
|
|
9
10
|
OneUptimeRequest,
|
|
10
11
|
} from "../Utils/Express";
|
|
11
12
|
import Response from "../Utils/Response";
|
|
13
|
+
import logger from "../Utils/Logger";
|
|
12
14
|
import BaseAPI from "./BaseAPI";
|
|
13
15
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
16
|
+
import ObjectID from "../../Types/ObjectID";
|
|
14
17
|
import UserCall from "../../Models/DatabaseModels/UserCall";
|
|
15
18
|
import UserSMS from "../../Models/DatabaseModels/UserSMS";
|
|
16
19
|
|
|
@@ -52,6 +55,7 @@ export default class UserCallAPI extends BaseAPI<
|
|
|
52
55
|
},
|
|
53
56
|
select: {
|
|
54
57
|
userId: true,
|
|
58
|
+
projectId: true,
|
|
55
59
|
verificationCode: true,
|
|
56
60
|
},
|
|
57
61
|
});
|
|
@@ -95,6 +99,21 @@ export default class UserCallAPI extends BaseAPI<
|
|
|
95
99
|
},
|
|
96
100
|
});
|
|
97
101
|
|
|
102
|
+
// Create default notification rules for this verified call number
|
|
103
|
+
try {
|
|
104
|
+
await UserNotificationRuleService.addDefaultNotificationRulesForVerifiedMethod(
|
|
105
|
+
{
|
|
106
|
+
projectId: new ObjectID(item.projectId!.toString()),
|
|
107
|
+
userId: new ObjectID(item.userId!.toString()),
|
|
108
|
+
notificationMethod: {
|
|
109
|
+
userCallId: item.id!,
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
);
|
|
113
|
+
} catch (e) {
|
|
114
|
+
logger.error(e);
|
|
115
|
+
}
|
|
116
|
+
|
|
98
117
|
return Response.sendEmptySuccessResponse(req, res);
|
|
99
118
|
} catch (err) {
|
|
100
119
|
return next(err);
|
|
@@ -2,6 +2,7 @@ import UserMiddleware from "../Middleware/UserAuthorization";
|
|
|
2
2
|
import UserEmailService, {
|
|
3
3
|
Service as UserEmailServiceType,
|
|
4
4
|
} from "../Services/UserEmailService";
|
|
5
|
+
import UserNotificationRuleService from "../Services/UserNotificationRuleService";
|
|
5
6
|
import {
|
|
6
7
|
ExpressRequest,
|
|
7
8
|
ExpressResponse,
|
|
@@ -9,8 +10,10 @@ import {
|
|
|
9
10
|
OneUptimeRequest,
|
|
10
11
|
} from "../Utils/Express";
|
|
11
12
|
import Response from "../Utils/Response";
|
|
13
|
+
import logger from "../Utils/Logger";
|
|
12
14
|
import BaseAPI from "./BaseAPI";
|
|
13
15
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
16
|
+
import ObjectID from "../../Types/ObjectID";
|
|
14
17
|
import UserEmail from "../../Models/DatabaseModels/UserEmail";
|
|
15
18
|
|
|
16
19
|
export default class UserEmailAPI extends BaseAPI<
|
|
@@ -51,6 +54,7 @@ export default class UserEmailAPI extends BaseAPI<
|
|
|
51
54
|
},
|
|
52
55
|
select: {
|
|
53
56
|
userId: true,
|
|
57
|
+
projectId: true,
|
|
54
58
|
verificationCode: true,
|
|
55
59
|
},
|
|
56
60
|
});
|
|
@@ -94,6 +98,21 @@ export default class UserEmailAPI extends BaseAPI<
|
|
|
94
98
|
},
|
|
95
99
|
});
|
|
96
100
|
|
|
101
|
+
// Create default notification rules for this verified email
|
|
102
|
+
try {
|
|
103
|
+
await UserNotificationRuleService.addDefaultNotificationRulesForVerifiedMethod(
|
|
104
|
+
{
|
|
105
|
+
projectId: new ObjectID(item.projectId!.toString()),
|
|
106
|
+
userId: new ObjectID(item.userId!.toString()),
|
|
107
|
+
notificationMethod: {
|
|
108
|
+
userEmailId: item.id!,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
);
|
|
112
|
+
} catch (e) {
|
|
113
|
+
logger.error(e);
|
|
114
|
+
}
|
|
115
|
+
|
|
97
116
|
return Response.sendEmptySuccessResponse(req, res);
|
|
98
117
|
} catch (err) {
|
|
99
118
|
return next(err);
|
|
@@ -2,8 +2,10 @@ import UserMiddleware from "../Middleware/UserAuthorization";
|
|
|
2
2
|
import UserPushService, {
|
|
3
3
|
Service as UserPushServiceType,
|
|
4
4
|
} from "../Services/UserPushService";
|
|
5
|
+
import UserNotificationRuleService from "../Services/UserNotificationRuleService";
|
|
5
6
|
import PushNotificationService from "../Services/PushNotificationService";
|
|
6
7
|
import PushNotificationUtil from "../Utils/PushNotificationUtil";
|
|
8
|
+
import logger from "../Utils/Logger";
|
|
7
9
|
import {
|
|
8
10
|
ExpressRequest,
|
|
9
11
|
ExpressResponse,
|
|
@@ -13,11 +15,23 @@ import {
|
|
|
13
15
|
import Response from "../Utils/Response";
|
|
14
16
|
import BaseAPI from "./BaseAPI";
|
|
15
17
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
18
|
+
import NotAuthenticatedException from "../../Types/Exception/NotAuthenticatedException";
|
|
16
19
|
import ObjectID from "../../Types/ObjectID";
|
|
17
20
|
import PushDeviceType from "../../Types/PushNotification/PushDeviceType";
|
|
18
21
|
import UserPush from "../../Models/DatabaseModels/UserPush";
|
|
19
22
|
import PushNotificationMessage from "../../Types/PushNotification/PushNotificationMessage";
|
|
20
23
|
|
|
24
|
+
function getAuthenticatedUserId(req: ExpressRequest): ObjectID {
|
|
25
|
+
const userId: ObjectID | undefined = (req as OneUptimeRequest)
|
|
26
|
+
.userAuthorization?.userId;
|
|
27
|
+
if (!userId) {
|
|
28
|
+
throw new NotAuthenticatedException(
|
|
29
|
+
"You must be logged in to perform this action.",
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
return userId;
|
|
33
|
+
}
|
|
34
|
+
|
|
21
35
|
export default class UserPushAPI extends BaseAPI<
|
|
22
36
|
UserPush,
|
|
23
37
|
UserPushServiceType
|
|
@@ -32,6 +46,8 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
32
46
|
try {
|
|
33
47
|
req = req as OneUptimeRequest;
|
|
34
48
|
|
|
49
|
+
const userId: ObjectID = getAuthenticatedUserId(req);
|
|
50
|
+
|
|
35
51
|
if (!req.body.deviceToken) {
|
|
36
52
|
return Response.sendErrorResponse(
|
|
37
53
|
req,
|
|
@@ -65,7 +81,7 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
65
81
|
// Check if device is already registered
|
|
66
82
|
const existingDevice: UserPush | null = await this.service.findOneBy({
|
|
67
83
|
query: {
|
|
68
|
-
userId:
|
|
84
|
+
userId: userId,
|
|
69
85
|
projectId: new ObjectID(req.body.projectId),
|
|
70
86
|
deviceToken: req.body.deviceToken,
|
|
71
87
|
},
|
|
@@ -78,17 +94,18 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
78
94
|
});
|
|
79
95
|
|
|
80
96
|
if (existingDevice) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
97
|
+
return Response.sendErrorResponse(
|
|
98
|
+
req,
|
|
99
|
+
res,
|
|
100
|
+
new BadDataException(
|
|
101
|
+
"This device is already registered for push notifications",
|
|
102
|
+
),
|
|
84
103
|
);
|
|
85
104
|
}
|
|
86
105
|
|
|
87
106
|
// Create new device registration
|
|
88
107
|
const userPush: UserPush = new UserPush();
|
|
89
|
-
userPush.userId =
|
|
90
|
-
req as OneUptimeRequest
|
|
91
|
-
).userAuthorization!.userId!;
|
|
108
|
+
userPush.userId = userId;
|
|
92
109
|
userPush.projectId = new ObjectID(req.body.projectId);
|
|
93
110
|
userPush.deviceToken = req.body.deviceToken;
|
|
94
111
|
userPush.deviceType = req.body.deviceType;
|
|
@@ -102,6 +119,21 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
102
119
|
},
|
|
103
120
|
});
|
|
104
121
|
|
|
122
|
+
// Create default notification rules for this registered push device
|
|
123
|
+
try {
|
|
124
|
+
await UserNotificationRuleService.addDefaultNotificationRulesForVerifiedMethod(
|
|
125
|
+
{
|
|
126
|
+
projectId: new ObjectID(req.body.projectId),
|
|
127
|
+
userId,
|
|
128
|
+
notificationMethod: {
|
|
129
|
+
userPushId: savedDevice.id!,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
);
|
|
133
|
+
} catch (e) {
|
|
134
|
+
logger.error(e);
|
|
135
|
+
}
|
|
136
|
+
|
|
105
137
|
return Response.sendJsonObjectResponse(req, res, {
|
|
106
138
|
success: true,
|
|
107
139
|
deviceId: savedDevice._id!.toString(),
|
|
@@ -119,6 +151,8 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
119
151
|
try {
|
|
120
152
|
req = req as OneUptimeRequest;
|
|
121
153
|
|
|
154
|
+
const userId: ObjectID = getAuthenticatedUserId(req);
|
|
155
|
+
|
|
122
156
|
if (!req.body.deviceToken) {
|
|
123
157
|
return Response.sendErrorResponse(
|
|
124
158
|
req,
|
|
@@ -127,9 +161,6 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
127
161
|
);
|
|
128
162
|
}
|
|
129
163
|
|
|
130
|
-
const userId: ObjectID = (req as OneUptimeRequest).userAuthorization!
|
|
131
|
-
.userId!;
|
|
132
|
-
|
|
133
164
|
await this.service.deleteBy({
|
|
134
165
|
query: {
|
|
135
166
|
userId: userId,
|
|
@@ -159,6 +190,8 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
159
190
|
try {
|
|
160
191
|
req = req as OneUptimeRequest;
|
|
161
192
|
|
|
193
|
+
const userId: ObjectID = getAuthenticatedUserId(req);
|
|
194
|
+
|
|
162
195
|
if (!req.params["deviceId"]) {
|
|
163
196
|
return Response.sendErrorResponse(
|
|
164
197
|
req,
|
|
@@ -192,10 +225,7 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
192
225
|
}
|
|
193
226
|
|
|
194
227
|
// Check if the device belongs to the current user
|
|
195
|
-
if (
|
|
196
|
-
device.userId?.toString() !==
|
|
197
|
-
(req as OneUptimeRequest).userAuthorization!.userId!.toString()
|
|
198
|
-
) {
|
|
228
|
+
if (device.userId?.toString() !== userId.toString()) {
|
|
199
229
|
return Response.sendErrorResponse(
|
|
200
230
|
req,
|
|
201
231
|
res,
|
|
@@ -264,6 +294,8 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
264
294
|
try {
|
|
265
295
|
req = req as OneUptimeRequest;
|
|
266
296
|
|
|
297
|
+
const userId: ObjectID = getAuthenticatedUserId(req);
|
|
298
|
+
|
|
267
299
|
if (!req.params["deviceId"]) {
|
|
268
300
|
return Response.sendErrorResponse(
|
|
269
301
|
req,
|
|
@@ -279,6 +311,7 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
279
311
|
},
|
|
280
312
|
select: {
|
|
281
313
|
userId: true,
|
|
314
|
+
projectId: true,
|
|
282
315
|
},
|
|
283
316
|
});
|
|
284
317
|
|
|
@@ -291,10 +324,7 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
291
324
|
}
|
|
292
325
|
|
|
293
326
|
// Check if the device belongs to the current user
|
|
294
|
-
if (
|
|
295
|
-
device.userId?.toString() !==
|
|
296
|
-
(req as OneUptimeRequest).userAuthorization!.userId!.toString()
|
|
297
|
-
) {
|
|
327
|
+
if (device.userId?.toString() !== userId.toString()) {
|
|
298
328
|
return Response.sendErrorResponse(
|
|
299
329
|
req,
|
|
300
330
|
res,
|
|
@@ -304,6 +334,21 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
304
334
|
|
|
305
335
|
await this.service.verifyDevice(device._id!.toString());
|
|
306
336
|
|
|
337
|
+
// Create default notification rules for this verified push device
|
|
338
|
+
try {
|
|
339
|
+
await UserNotificationRuleService.addDefaultNotificationRulesForVerifiedMethod(
|
|
340
|
+
{
|
|
341
|
+
projectId: new ObjectID(device.projectId!.toString()),
|
|
342
|
+
userId,
|
|
343
|
+
notificationMethod: {
|
|
344
|
+
userPushId: device.id!,
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
);
|
|
348
|
+
} catch (e) {
|
|
349
|
+
logger.error(e);
|
|
350
|
+
}
|
|
351
|
+
|
|
307
352
|
return Response.sendEmptySuccessResponse(req, res);
|
|
308
353
|
} catch (error) {
|
|
309
354
|
return next(error);
|
|
@@ -318,6 +363,8 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
318
363
|
try {
|
|
319
364
|
req = req as OneUptimeRequest;
|
|
320
365
|
|
|
366
|
+
const userId: ObjectID = getAuthenticatedUserId(req);
|
|
367
|
+
|
|
321
368
|
if (!req.params["deviceId"]) {
|
|
322
369
|
return Response.sendErrorResponse(
|
|
323
370
|
req,
|
|
@@ -345,10 +392,7 @@ export default class UserPushAPI extends BaseAPI<
|
|
|
345
392
|
}
|
|
346
393
|
|
|
347
394
|
// Check if the device belongs to the current user
|
|
348
|
-
if (
|
|
349
|
-
device.userId?.toString() !==
|
|
350
|
-
(req as OneUptimeRequest).userAuthorization!.userId!.toString()
|
|
351
|
-
) {
|
|
395
|
+
if (device.userId?.toString() !== userId.toString()) {
|
|
352
396
|
return Response.sendErrorResponse(
|
|
353
397
|
req,
|
|
354
398
|
res,
|
package/Server/API/UserSmsAPI.ts
CHANGED
|
@@ -2,6 +2,7 @@ import UserMiddleware from "../Middleware/UserAuthorization";
|
|
|
2
2
|
import UserSMSService, {
|
|
3
3
|
Service as UserSMSServiceType,
|
|
4
4
|
} from "../Services/UserSmsService";
|
|
5
|
+
import UserNotificationRuleService from "../Services/UserNotificationRuleService";
|
|
5
6
|
import {
|
|
6
7
|
ExpressRequest,
|
|
7
8
|
ExpressResponse,
|
|
@@ -9,8 +10,10 @@ import {
|
|
|
9
10
|
OneUptimeRequest,
|
|
10
11
|
} from "../Utils/Express";
|
|
11
12
|
import Response from "../Utils/Response";
|
|
13
|
+
import logger from "../Utils/Logger";
|
|
12
14
|
import BaseAPI from "./BaseAPI";
|
|
13
15
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
16
|
+
import ObjectID from "../../Types/ObjectID";
|
|
14
17
|
import UserSMS from "../../Models/DatabaseModels/UserSMS";
|
|
15
18
|
|
|
16
19
|
export default class UserSMSAPI extends BaseAPI<UserSMS, UserSMSServiceType> {
|
|
@@ -48,6 +51,7 @@ export default class UserSMSAPI extends BaseAPI<UserSMS, UserSMSServiceType> {
|
|
|
48
51
|
},
|
|
49
52
|
select: {
|
|
50
53
|
userId: true,
|
|
54
|
+
projectId: true,
|
|
51
55
|
verificationCode: true,
|
|
52
56
|
},
|
|
53
57
|
});
|
|
@@ -91,6 +95,21 @@ export default class UserSMSAPI extends BaseAPI<UserSMS, UserSMSServiceType> {
|
|
|
91
95
|
},
|
|
92
96
|
});
|
|
93
97
|
|
|
98
|
+
// Create default notification rules for this verified SMS
|
|
99
|
+
try {
|
|
100
|
+
await UserNotificationRuleService.addDefaultNotificationRulesForVerifiedMethod(
|
|
101
|
+
{
|
|
102
|
+
projectId: new ObjectID(item.projectId!.toString()),
|
|
103
|
+
userId: new ObjectID(item.userId!.toString()),
|
|
104
|
+
notificationMethod: {
|
|
105
|
+
userSmsId: item.id!,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
logger.error(e);
|
|
111
|
+
}
|
|
112
|
+
|
|
94
113
|
return Response.sendEmptySuccessResponse(req, res);
|
|
95
114
|
} catch (err) {
|
|
96
115
|
return next(err);
|
|
@@ -2,6 +2,7 @@ import UserMiddleware from "../Middleware/UserAuthorization";
|
|
|
2
2
|
import UserWhatsAppService, {
|
|
3
3
|
Service as UserWhatsAppServiceType,
|
|
4
4
|
} from "../Services/UserWhatsAppService";
|
|
5
|
+
import UserNotificationRuleService from "../Services/UserNotificationRuleService";
|
|
5
6
|
import {
|
|
6
7
|
ExpressRequest,
|
|
7
8
|
ExpressResponse,
|
|
@@ -9,8 +10,10 @@ import {
|
|
|
9
10
|
OneUptimeRequest,
|
|
10
11
|
} from "../Utils/Express";
|
|
11
12
|
import Response from "../Utils/Response";
|
|
13
|
+
import logger from "../Utils/Logger";
|
|
12
14
|
import BaseAPI from "./BaseAPI";
|
|
13
15
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
16
|
+
import ObjectID from "../../Types/ObjectID";
|
|
14
17
|
import UserWhatsApp from "../../Models/DatabaseModels/UserWhatsApp";
|
|
15
18
|
|
|
16
19
|
export default class UserWhatsAppAPI extends BaseAPI<
|
|
@@ -50,6 +53,7 @@ export default class UserWhatsAppAPI extends BaseAPI<
|
|
|
50
53
|
},
|
|
51
54
|
select: {
|
|
52
55
|
userId: true,
|
|
56
|
+
projectId: true,
|
|
53
57
|
verificationCode: true,
|
|
54
58
|
isVerified: true,
|
|
55
59
|
},
|
|
@@ -100,6 +104,21 @@ export default class UserWhatsAppAPI extends BaseAPI<
|
|
|
100
104
|
},
|
|
101
105
|
});
|
|
102
106
|
|
|
107
|
+
// Create default notification rules for this verified WhatsApp number
|
|
108
|
+
try {
|
|
109
|
+
await UserNotificationRuleService.addDefaultNotificationRulesForVerifiedMethod(
|
|
110
|
+
{
|
|
111
|
+
projectId: new ObjectID(item.projectId!.toString()),
|
|
112
|
+
userId: new ObjectID(item.userId!.toString()),
|
|
113
|
+
notificationMethod: {
|
|
114
|
+
userWhatsAppId: item.id!,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
);
|
|
118
|
+
} catch (e) {
|
|
119
|
+
logger.error(e);
|
|
120
|
+
}
|
|
121
|
+
|
|
103
122
|
return Response.sendEmptySuccessResponse(req, res);
|
|
104
123
|
} catch (err) {
|
|
105
124
|
return next(err);
|
|
@@ -161,6 +161,14 @@ export const ClusterKey: ObjectID = new ObjectID(
|
|
|
161
161
|
|
|
162
162
|
export const HasClusterKey: boolean = Boolean(process.env["ONEUPTIME_SECRET"]);
|
|
163
163
|
|
|
164
|
+
export const RegisterProbeKey: ObjectID = new ObjectID(
|
|
165
|
+
process.env["REGISTER_PROBE_KEY"] || "secret",
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
export const HasRegisterProbeKey: boolean = Boolean(
|
|
169
|
+
process.env["REGISTER_PROBE_KEY"],
|
|
170
|
+
);
|
|
171
|
+
|
|
164
172
|
export const AppApiHostname: Hostname = Hostname.fromString(
|
|
165
173
|
`${process.env["SERVER_APP_HOSTNAME"] || "localhost"}:${
|
|
166
174
|
process.env["APP_PORT"] || 80
|
|
@@ -529,6 +537,13 @@ export const VapidPrivateKey: string | undefined =
|
|
|
529
537
|
export const VapidSubject: string =
|
|
530
538
|
process.env["VAPID_SUBJECT"] || "mailto:support@oneuptime.com";
|
|
531
539
|
|
|
540
|
+
export const ExpoAccessToken: string | undefined =
|
|
541
|
+
process.env["EXPO_ACCESS_TOKEN"] || undefined;
|
|
542
|
+
|
|
543
|
+
export const PushNotificationRelayUrl: string =
|
|
544
|
+
process.env["PUSH_NOTIFICATION_RELAY_URL"] ||
|
|
545
|
+
"https://oneuptime.com/api/notification/push-relay/send";
|
|
546
|
+
|
|
532
547
|
export const EnterpriseLicenseValidationUrl: URL = URL.fromString(
|
|
533
548
|
"https://oneuptime.com/api/enterprise-license/validate",
|
|
534
549
|
);
|
|
@@ -10,9 +10,16 @@ import {
|
|
|
10
10
|
VapidPublicKey,
|
|
11
11
|
VapidPrivateKey,
|
|
12
12
|
VapidSubject,
|
|
13
|
+
ExpoAccessToken,
|
|
14
|
+
PushNotificationRelayUrl,
|
|
13
15
|
} from "../EnvironmentConfig";
|
|
14
16
|
import webpush from "web-push";
|
|
15
17
|
import { Expo, ExpoPushMessage, ExpoPushTicket } from "expo-server-sdk";
|
|
18
|
+
import API from "../../Utils/API";
|
|
19
|
+
import URL from "../../Types/API/URL";
|
|
20
|
+
import HTTPErrorResponse from "../../Types/API/HTTPErrorResponse";
|
|
21
|
+
import HTTPResponse from "../../Types/API/HTTPResponse";
|
|
22
|
+
import { JSONObject } from "../../Types/JSON";
|
|
16
23
|
import PushNotificationUtil from "../Utils/PushNotificationUtil";
|
|
17
24
|
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
18
25
|
import UserPush from "../../Models/DatabaseModels/UserPush";
|
|
@@ -43,7 +50,9 @@ export interface PushNotificationOptions {
|
|
|
43
50
|
|
|
44
51
|
export default class PushNotificationService {
|
|
45
52
|
public static isWebPushInitialized = false;
|
|
46
|
-
private static expoClient: Expo = new Expo(
|
|
53
|
+
private static expoClient: Expo = new Expo(
|
|
54
|
+
ExpoAccessToken ? { accessToken: ExpoAccessToken } : undefined,
|
|
55
|
+
);
|
|
47
56
|
|
|
48
57
|
public static initializeWebPush(): void {
|
|
49
58
|
if (this.isWebPushInitialized) {
|
|
@@ -340,20 +349,33 @@ export default class PushNotificationService {
|
|
|
340
349
|
);
|
|
341
350
|
}
|
|
342
351
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
dataPayload[key] = String(message.data[key]);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
if (message.url || message.clickAction) {
|
|
351
|
-
dataPayload["url"] = message.url || message.clickAction || "";
|
|
352
|
+
const dataPayload: { [key: string]: string } = {};
|
|
353
|
+
if (message.data) {
|
|
354
|
+
for (const key of Object.keys(message.data)) {
|
|
355
|
+
dataPayload[key] = String(message.data[key]);
|
|
352
356
|
}
|
|
357
|
+
}
|
|
358
|
+
if (message.url || message.clickAction) {
|
|
359
|
+
dataPayload["url"] = message.url || message.clickAction || "";
|
|
360
|
+
}
|
|
353
361
|
|
|
354
|
-
|
|
355
|
-
|
|
362
|
+
const channelId: string =
|
|
363
|
+
deviceType === PushDeviceType.Android ? "oncall_high" : "default";
|
|
364
|
+
|
|
365
|
+
// If EXPO_ACCESS_TOKEN is not set, relay through the push notification gateway
|
|
366
|
+
if (!ExpoAccessToken) {
|
|
367
|
+
await this.sendViaRelay(
|
|
368
|
+
expoPushToken,
|
|
369
|
+
message,
|
|
370
|
+
dataPayload,
|
|
371
|
+
channelId,
|
|
372
|
+
deviceType,
|
|
373
|
+
);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
356
376
|
|
|
377
|
+
// Send directly via Expo SDK
|
|
378
|
+
try {
|
|
357
379
|
const expoPushMessage: ExpoPushMessage = {
|
|
358
380
|
to: expoPushToken,
|
|
359
381
|
title: message.title,
|
|
@@ -403,6 +425,108 @@ export default class PushNotificationService {
|
|
|
403
425
|
}
|
|
404
426
|
}
|
|
405
427
|
|
|
428
|
+
private static async sendViaRelay(
|
|
429
|
+
expoPushToken: string,
|
|
430
|
+
message: PushNotificationMessage,
|
|
431
|
+
dataPayload: { [key: string]: string },
|
|
432
|
+
channelId: string,
|
|
433
|
+
deviceType: PushDeviceType,
|
|
434
|
+
): Promise<void> {
|
|
435
|
+
logger.info(
|
|
436
|
+
`Sending ${deviceType} push notification via relay: ${PushNotificationRelayUrl}`,
|
|
437
|
+
);
|
|
438
|
+
|
|
439
|
+
try {
|
|
440
|
+
const response: HTTPErrorResponse | HTTPResponse<JSONObject> =
|
|
441
|
+
await API.post<JSONObject>({
|
|
442
|
+
url: URL.fromString(PushNotificationRelayUrl),
|
|
443
|
+
data: {
|
|
444
|
+
to: expoPushToken,
|
|
445
|
+
title: message.title || "",
|
|
446
|
+
body: message.body || "",
|
|
447
|
+
data: dataPayload,
|
|
448
|
+
sound: "default",
|
|
449
|
+
priority: "high",
|
|
450
|
+
channelId: channelId,
|
|
451
|
+
},
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
if (response instanceof HTTPErrorResponse) {
|
|
455
|
+
throw new Error(
|
|
456
|
+
`Push relay error: ${JSON.stringify(response.jsonData)}`,
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
logger.info(
|
|
461
|
+
`Push notification sent via relay successfully to ${deviceType} device`,
|
|
462
|
+
);
|
|
463
|
+
} catch (error: any) {
|
|
464
|
+
logger.error(
|
|
465
|
+
`Failed to send push notification via relay to ${deviceType} device: ${error.message}`,
|
|
466
|
+
);
|
|
467
|
+
throw error;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
public static isValidExpoPushToken(token: string): boolean {
|
|
472
|
+
return Expo.isExpoPushToken(token);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
public static hasExpoAccessToken(): boolean {
|
|
476
|
+
return Boolean(ExpoAccessToken);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
public static async sendRelayPushNotification(data: {
|
|
480
|
+
to: string;
|
|
481
|
+
title?: string;
|
|
482
|
+
body?: string;
|
|
483
|
+
data?: { [key: string]: string };
|
|
484
|
+
sound?: string;
|
|
485
|
+
priority?: string;
|
|
486
|
+
channelId?: string;
|
|
487
|
+
}): Promise<void> {
|
|
488
|
+
if (!ExpoAccessToken) {
|
|
489
|
+
throw new Error(
|
|
490
|
+
"Push relay is not configured. EXPO_ACCESS_TOKEN is not set on this server.",
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const expoPushMessage: ExpoPushMessage = {
|
|
495
|
+
to: data.to,
|
|
496
|
+
title: data.title || "",
|
|
497
|
+
body: data.body || "",
|
|
498
|
+
data: data.data || {},
|
|
499
|
+
sound: (data.sound as "default" | null) || "default",
|
|
500
|
+
priority: (data.priority as "default" | "normal" | "high") || "high",
|
|
501
|
+
channelId: data.channelId || "default",
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
const tickets: ExpoPushTicket[] =
|
|
505
|
+
await this.expoClient.sendPushNotificationsAsync([expoPushMessage]);
|
|
506
|
+
|
|
507
|
+
const ticket: ExpoPushTicket | undefined = tickets[0];
|
|
508
|
+
|
|
509
|
+
if (ticket && ticket.status === "error") {
|
|
510
|
+
const errorTicket: ExpoPushTicket & {
|
|
511
|
+
message?: string;
|
|
512
|
+
details?: { error?: string };
|
|
513
|
+
} = ticket as ExpoPushTicket & {
|
|
514
|
+
message?: string;
|
|
515
|
+
details?: { error?: string };
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
logger.error(
|
|
519
|
+
`Push relay: Expo push notification error: ${errorTicket.message}`,
|
|
520
|
+
);
|
|
521
|
+
|
|
522
|
+
throw new Error(
|
|
523
|
+
`Failed to send push notification: ${errorTicket.message}`,
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
logger.info(`Push relay: notification sent successfully to ${data.to}`);
|
|
528
|
+
}
|
|
529
|
+
|
|
406
530
|
public static async sendPushNotificationToUser(
|
|
407
531
|
userId: ObjectID,
|
|
408
532
|
projectId: ObjectID,
|