@sipgate/integration-bridge 1.0.36 → 1.0.40
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/cache/contact-cache-storage.js +79 -97
- package/dist/cache/contact-cache-storage.js.map +1 -1
- package/dist/cache/storage/memory-storage-adapter.js +8 -22
- package/dist/cache/storage/memory-storage-adapter.js.map +1 -1
- package/dist/cache/storage/redis-storage-adapter.js +16 -30
- package/dist/cache/storage/redis-storage-adapter.js.map +1 -1
- package/dist/cache/token-cache-storage.js +30 -43
- package/dist/cache/token-cache-storage.js.map +1 -1
- package/dist/controllers/call-log.controller.js +63 -78
- package/dist/controllers/call-log.controller.js.map +1 -1
- package/dist/controllers/task.controller.js +60 -75
- package/dist/controllers/task.controller.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +38 -21
- package/dist/index.js.map +1 -1
- package/dist/middlewares/error-handler.middleware.js +1 -2
- package/dist/middlewares/error-handler.middleware.js.map +1 -1
- package/dist/middlewares/extract-header.middleware.d.ts +0 -1
- package/dist/middlewares/extract-header.middleware.js +2 -2
- package/dist/middlewares/extract-header.middleware.js.map +1 -1
- package/dist/models/cache-item-state.model.js +1 -1
- package/dist/models/cache-item-state.model.js.map +1 -1
- package/dist/models/call-direction.enum.js +1 -1
- package/dist/models/call-direction.enum.js.map +1 -1
- package/dist/models/call-event.model.js +2 -2
- package/dist/models/call-event.model.js.map +1 -1
- package/dist/models/contact.model.js +3 -3
- package/dist/models/contact.model.js.map +1 -1
- package/dist/models/controller.model.js +579 -622
- package/dist/models/controller.model.js.map +1 -1
- package/dist/models/integration-entity.model.js +1 -1
- package/dist/models/integration-entity.model.js.map +1 -1
- package/dist/models/integration-error.model.js +1 -1
- package/dist/models/integration-error.model.js.map +1 -1
- package/dist/models/integrations-event.model.js +1 -1
- package/dist/models/integrations-event.model.js.map +1 -1
- package/dist/models/pubsub/pubsub-client.model.js +16 -25
- package/dist/models/pubsub/pubsub-client.model.js.map +1 -1
- package/dist/models/pubsub/pubsub-contacts-message.model.js +1 -1
- package/dist/models/pubsub/pubsub-contacts-message.model.js.map +1 -1
- package/dist/models/server-error.model.js +1 -0
- package/dist/models/server-error.model.js.map +1 -1
- package/dist/swagger/openapi-spec.d.ts +972 -0
- package/dist/swagger/openapi-spec.js +787 -0
- package/dist/swagger/openapi-spec.js.map +1 -0
- package/dist/util/anonymize-key.js +1 -2
- package/dist/util/anonymize-key.js.map +1 -1
- package/dist/util/call-comment.js +5 -6
- package/dist/util/call-comment.js.map +1 -1
- package/dist/util/call-event.util.js +1 -2
- package/dist/util/call-event.util.js.map +1 -1
- package/dist/util/callEventHelper.js +4 -4
- package/dist/util/callEventHelper.js.map +1 -1
- package/dist/util/contact.util.js +10 -8
- package/dist/util/contact.util.js.map +1 -1
- package/dist/util/env.js +19 -9
- package/dist/util/env.js.map +1 -1
- package/dist/util/error/delegate-to-frontend.error.js +1 -0
- package/dist/util/error/delegate-to-frontend.error.js.map +1 -1
- package/dist/util/error/error.js +11 -8
- package/dist/util/error/error.js.map +1 -1
- package/dist/util/gdpr/gdprSlackNotification.js +22 -22
- package/dist/util/gdpr/gdprSlackNotification.js.map +1 -1
- package/dist/util/gdpr/index.js +17 -7
- package/dist/util/gdpr/index.js.map +1 -1
- package/dist/util/get-contact-cache.js +1 -2
- package/dist/util/get-contact-cache.js.map +1 -1
- package/dist/util/http/default-axios.js +1 -2
- package/dist/util/http/default-axios.js.map +1 -1
- package/dist/util/http/index.js +17 -7
- package/dist/util/http/index.js.map +1 -1
- package/dist/util/http/pagination.js +32 -85
- package/dist/util/http/pagination.js.map +1 -1
- package/dist/util/http/rate-limited-axios.js +42 -61
- package/dist/util/http/rate-limited-axios.js.map +1 -1
- package/dist/util/http/retrying-axios.js +11 -23
- package/dist/util/http/retrying-axios.js.map +1 -1
- package/dist/util/http/url.js +1 -2
- package/dist/util/http/url.js.map +1 -1
- package/dist/util/index.js +17 -7
- package/dist/util/index.js.map +1 -1
- package/dist/util/lang/delay.js +1 -2
- package/dist/util/lang/delay.js.map +1 -1
- package/dist/util/lang/diff.js +19 -10
- package/dist/util/lang/diff.js.map +1 -1
- package/dist/util/logger.util.js +7 -2
- package/dist/util/logger.util.js.map +1 -1
- package/dist/util/oauth.js +131 -134
- package/dist/util/oauth.js.map +1 -1
- package/dist/util/phone-number-utils.js +4 -5
- package/dist/util/phone-number-utils.js.map +1 -1
- package/dist/util/security/index.js +17 -7
- package/dist/util/security/index.js.map +1 -1
- package/dist/util/security/nonce.js +5 -6
- package/dist/util/security/nonce.js.map +1 -1
- package/dist/util/size-of.js +1 -1
- package/dist/util/size-of.js.map +1 -1
- package/dist/util/token-util.js +46 -62
- package/dist/util/token-util.js.map +1 -1
- package/dist/util/validate.js +1 -2
- package/dist/util/validate.js.map +1 -1
- package/package.json +25 -38
- package/README.md +0 -117
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.Controller = void 0;
|
|
13
4
|
const lodash_1 = require("lodash");
|
|
@@ -23,13 +14,15 @@ const pubsub_contacts_message_model_1 = require("./pubsub/pubsub-contacts-messag
|
|
|
23
14
|
const anonymize_key_1 = require("../util/anonymize-key");
|
|
24
15
|
const CONTACT_FETCH_TIMEOUT = 5000;
|
|
25
16
|
class Controller {
|
|
17
|
+
adapter;
|
|
18
|
+
contactCache;
|
|
19
|
+
pubSubContactStreamingClient = null;
|
|
20
|
+
pubSubIntegrationEventsClient = null;
|
|
21
|
+
additionalPubSubContactStreamingClient = null;
|
|
22
|
+
integrationName = 'UNKNOWN';
|
|
23
|
+
// used for garbage collection reasons, to prevent long running promises from getting canceled
|
|
24
|
+
streamingPromises = new Map();
|
|
26
25
|
constructor(adapter, contactCache) {
|
|
27
|
-
this.pubSubContactStreamingClient = null;
|
|
28
|
-
this.pubSubIntegrationEventsClient = null;
|
|
29
|
-
this.additionalPubSubContactStreamingClient = null;
|
|
30
|
-
this.integrationName = 'UNKNOWN';
|
|
31
|
-
// used for garbage collection reasons, to prevent long running promises from getting canceled
|
|
32
|
-
this.streamingPromises = new Map();
|
|
33
26
|
this.adapter = adapter;
|
|
34
27
|
this.contactCache = contactCache;
|
|
35
28
|
if (this.adapter.streamContacts) {
|
|
@@ -48,7 +41,7 @@ class Controller {
|
|
|
48
41
|
}
|
|
49
42
|
initContactStreaming() {
|
|
50
43
|
const { PUBSUB_TOPIC_NAME: topicNameLegacy, PUBSUB_TOPIC_NAME_CONTACT_STREAMING: topicName, PUBSUB_ADDITIONAL_TOPIC_NAME: additionalTopicName, } = process.env;
|
|
51
|
-
const topicNameProvided = topicName
|
|
44
|
+
const topicNameProvided = topicName ?? topicNameLegacy;
|
|
52
45
|
if (!topicNameProvided) {
|
|
53
46
|
throw new Error('No PUBSUB_TOPIC_NAME_CONTACT_STREAMING provided.');
|
|
54
47
|
}
|
|
@@ -67,388 +60,371 @@ class Controller {
|
|
|
67
60
|
this.pubSubIntegrationEventsClient = new _1.PubSubClient(topicName);
|
|
68
61
|
(0, logger_util_1.infoLogger)('Controller', `Initialized PubSub client for topic ${topicName}`);
|
|
69
62
|
}
|
|
70
|
-
isValidToken(req, res, next) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
63
|
+
async isValidToken(req, res, next) {
|
|
64
|
+
const { providerConfig } = req;
|
|
65
|
+
if (!providerConfig) {
|
|
66
|
+
throw new _1.ServerError(400, 'Missing parameters');
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
(0, logger_util_1.infoLogger)('isValidToken', 'START', providerConfig.apiKey);
|
|
70
|
+
if (!this.adapter.isValidToken) {
|
|
71
|
+
throw new _1.ServerError(501, 'Token validation function is not implemented');
|
|
75
72
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
73
|
+
const isTokenValid = await this.adapter.isValidToken(providerConfig);
|
|
74
|
+
if (!isTokenValid) {
|
|
75
|
+
throw new _1.ServerError(401, 'Token is not valid');
|
|
76
|
+
}
|
|
77
|
+
(0, logger_util_1.infoLogger)('isValidToken', 'END', providerConfig.apiKey);
|
|
78
|
+
res.status(200).send('OK');
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
// prevent logging of refresh errors
|
|
82
|
+
if (error instanceof _1.ServerError &&
|
|
83
|
+
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
84
|
+
next(error);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
(0, logger_util_1.errorLogger)('isValidToken', 'Could not validate token:', providerConfig.apiKey, error);
|
|
88
|
+
next(error);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async getContacts(req, res, next) {
|
|
92
|
+
const { providerConfig } = req;
|
|
93
|
+
if (!providerConfig) {
|
|
94
|
+
throw new _1.ServerError(400, 'Missing parameters');
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
(0, logger_util_1.infoLogger)('getContacts', 'START', providerConfig.apiKey);
|
|
98
|
+
const fetchContacts = async () => {
|
|
99
|
+
if (!this.adapter.getContacts) {
|
|
100
|
+
throw new _1.ServerError(501, 'Fetching contacts is not implemented');
|
|
101
|
+
}
|
|
102
|
+
(0, logger_util_1.infoLogger)('getContacts', `Fetching contacts…`, providerConfig.apiKey);
|
|
103
|
+
const fetchedContacts = await this.adapter.getContacts(providerConfig);
|
|
104
|
+
const { error: parsingError, data: parsedContacts } = schemas_1.contactsGetSchema.safeParse(fetchedContacts);
|
|
105
|
+
if (parsingError)
|
|
106
|
+
throw new _1.ServerError(500, `Invalid contacts received: ${parsingError.message}`);
|
|
107
|
+
return parsedContacts.map((contact) => (0, contact_util_1.sanitizeContact)(contact, providerConfig.locale));
|
|
108
|
+
};
|
|
109
|
+
const fetcherPromise = this.contactCache
|
|
110
|
+
? this.contactCache.get(providerConfig.apiKey, fetchContacts)
|
|
111
|
+
: fetchContacts();
|
|
112
|
+
const timeoutPromise = new Promise((resolve) => setTimeout(() => resolve('TIMEOUT'), CONTACT_FETCH_TIMEOUT));
|
|
113
|
+
const raceResult = await Promise.race([fetcherPromise, timeoutPromise]);
|
|
114
|
+
if (raceResult === 'TIMEOUT') {
|
|
115
|
+
(0, logger_util_1.infoLogger)('getContacts', `Fetching too slow, returning empty array.`, providerConfig.apiKey);
|
|
116
|
+
}
|
|
117
|
+
const responseContacts = Array.isArray(raceResult)
|
|
118
|
+
? raceResult
|
|
119
|
+
: [];
|
|
120
|
+
const contactsCount = responseContacts.length;
|
|
121
|
+
(0, logger_util_1.infoLogger)('getContacts', `Found ${contactsCount} cached contacts`, providerConfig.apiKey);
|
|
122
|
+
if (!Array.isArray(raceResult) &&
|
|
123
|
+
(raceResult === 'TIMEOUT' ||
|
|
124
|
+
raceResult.state === cache_item_state_model_1.CacheItemStateType.FETCHING)) {
|
|
125
|
+
res.header('X-Fetching-State', 'pending');
|
|
126
|
+
}
|
|
127
|
+
if (this.adapter.getToken && req.providerConfig) {
|
|
128
|
+
try {
|
|
129
|
+
const { apiKey } = await this.adapter.getToken(req.providerConfig);
|
|
130
|
+
res.header('X-Provider-Key', apiKey);
|
|
84
131
|
}
|
|
85
|
-
(
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
catch (error) {
|
|
89
|
-
// prevent logging of refresh errors
|
|
90
|
-
if (error instanceof _1.ServerError &&
|
|
91
|
-
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
92
|
-
next(error);
|
|
93
|
-
return;
|
|
132
|
+
catch (error) {
|
|
133
|
+
(0, logger_util_1.errorLogger)('getContacts', 'Could not get and refresh token', providerConfig.apiKey, error);
|
|
94
134
|
}
|
|
95
|
-
|
|
135
|
+
}
|
|
136
|
+
(0, logger_util_1.infoLogger)('getContacts', 'END', providerConfig.apiKey);
|
|
137
|
+
res.status(200).send(responseContacts);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
// prevent logging of refresh errors
|
|
141
|
+
if (error instanceof _1.ServerError &&
|
|
142
|
+
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
96
143
|
next(error);
|
|
144
|
+
return;
|
|
97
145
|
}
|
|
98
|
-
|
|
146
|
+
(0, logger_util_1.errorLogger)('getContacts', 'Could not get contacts:', providerConfig.apiKey, error);
|
|
147
|
+
next(error);
|
|
148
|
+
}
|
|
99
149
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
150
|
+
async streamContacts(req, res, next) {
|
|
151
|
+
const { providerConfig } = req;
|
|
152
|
+
try {
|
|
103
153
|
if (!providerConfig) {
|
|
104
154
|
throw new _1.ServerError(400, 'Missing parameters');
|
|
105
155
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
156
|
+
const { userId } = providerConfig;
|
|
157
|
+
if (!userId) {
|
|
158
|
+
throw new _1.ServerError(400, 'Missing user ID');
|
|
159
|
+
}
|
|
160
|
+
const timestamp = Date.now();
|
|
161
|
+
const orderingKey = `${userId}:${timestamp}`;
|
|
162
|
+
(0, logger_util_1.infoLogger)('streamContacts', `[${orderingKey}] Starting contact streaming`, providerConfig.apiKey);
|
|
163
|
+
const publishContacts = async (contacts) => {
|
|
164
|
+
try {
|
|
165
|
+
const { error: parsingError, data: parsedContacts } = schemas_1.contactsGetSchema.safeParse(contacts);
|
|
166
|
+
if (parsingError) {
|
|
116
167
|
throw new _1.ServerError(500, `Invalid contacts received: ${parsingError.message}`);
|
|
117
|
-
return parsedContacts.map((contact) => (0, contact_util_1.sanitizeContact)(contact, providerConfig.locale));
|
|
118
|
-
});
|
|
119
|
-
const fetcherPromise = this.contactCache
|
|
120
|
-
? this.contactCache.get(providerConfig.apiKey, fetchContacts)
|
|
121
|
-
: fetchContacts();
|
|
122
|
-
const timeoutPromise = new Promise((resolve) => setTimeout(() => resolve('TIMEOUT'), CONTACT_FETCH_TIMEOUT));
|
|
123
|
-
const raceResult = yield Promise.race([fetcherPromise, timeoutPromise]);
|
|
124
|
-
if (raceResult === 'TIMEOUT') {
|
|
125
|
-
(0, logger_util_1.infoLogger)('getContacts', `Fetching too slow, returning empty array.`, providerConfig.apiKey);
|
|
126
|
-
}
|
|
127
|
-
const responseContacts = Array.isArray(raceResult)
|
|
128
|
-
? raceResult
|
|
129
|
-
: [];
|
|
130
|
-
const contactsCount = responseContacts.length;
|
|
131
|
-
(0, logger_util_1.infoLogger)('getContacts', `Found ${contactsCount} cached contacts`, providerConfig.apiKey);
|
|
132
|
-
if (!Array.isArray(raceResult) &&
|
|
133
|
-
(raceResult === 'TIMEOUT' ||
|
|
134
|
-
raceResult.state === cache_item_state_model_1.CacheItemStateType.FETCHING)) {
|
|
135
|
-
res.header('X-Fetching-State', 'pending');
|
|
136
|
-
}
|
|
137
|
-
if (this.adapter.getToken && req.providerConfig) {
|
|
138
|
-
try {
|
|
139
|
-
const { apiKey } = yield this.adapter.getToken(req.providerConfig);
|
|
140
|
-
res.header('X-Provider-Key', apiKey);
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
(0, logger_util_1.errorLogger)('getContacts', 'Could not get and refresh token', providerConfig.apiKey, error);
|
|
144
168
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
res.status(200).send(responseContacts);
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
// prevent logging of refresh errors
|
|
151
|
-
if (error instanceof _1.ServerError &&
|
|
152
|
-
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
153
|
-
next(error);
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
(0, logger_util_1.errorLogger)('getContacts', 'Could not get contacts:', providerConfig.apiKey, error);
|
|
157
|
-
next(error);
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
streamContacts(req, res, next) {
|
|
162
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
163
|
-
const { providerConfig } = req;
|
|
164
|
-
try {
|
|
165
|
-
if (!providerConfig) {
|
|
166
|
-
throw new _1.ServerError(400, 'Missing parameters');
|
|
167
|
-
}
|
|
168
|
-
const { userId } = providerConfig;
|
|
169
|
-
if (!userId) {
|
|
170
|
-
throw new _1.ServerError(400, 'Missing user ID');
|
|
171
|
-
}
|
|
172
|
-
const timestamp = Date.now();
|
|
173
|
-
const orderingKey = `${userId}:${timestamp}`;
|
|
174
|
-
(0, logger_util_1.infoLogger)('streamContacts', `[${orderingKey}] Starting contact streaming`, providerConfig.apiKey);
|
|
175
|
-
const publishContacts = (contacts) => __awaiter(this, void 0, void 0, function* () {
|
|
176
|
-
var _a, _b;
|
|
177
|
-
try {
|
|
178
|
-
const { error: parsingError, data: parsedContacts } = schemas_1.contactsGetSchema.safeParse(contacts);
|
|
179
|
-
if (parsingError) {
|
|
180
|
-
throw new _1.ServerError(500, `Invalid contacts received: ${parsingError.message}`);
|
|
181
|
-
}
|
|
182
|
-
yield ((_a = this.pubSubContactStreamingClient) === null || _a === void 0 ? void 0 : _a.publishMessage({
|
|
183
|
-
userId,
|
|
184
|
-
timestamp,
|
|
185
|
-
contacts: parsedContacts.map((contact) => (0, contact_util_1.sanitizeContact)(contact, providerConfig.locale)),
|
|
186
|
-
state: pubsub_contacts_message_model_1.PubSubContactsState.IN_PROGRESS,
|
|
187
|
-
integrationName: this.integrationName,
|
|
188
|
-
}, orderingKey));
|
|
189
|
-
// todo: remove as soon as platypus goes live
|
|
190
|
-
yield ((_b = this.additionalPubSubContactStreamingClient) === null || _b === void 0 ? void 0 : _b.publishMessage({
|
|
191
|
-
userId,
|
|
192
|
-
timestamp,
|
|
193
|
-
contacts: contacts.map((contact) => (0, contact_util_1.sanitizeContact)(contact, providerConfig.locale)),
|
|
194
|
-
state: pubsub_contacts_message_model_1.PubSubContactsState.IN_PROGRESS,
|
|
195
|
-
integrationName: this.integrationName,
|
|
196
|
-
}, orderingKey));
|
|
197
|
-
}
|
|
198
|
-
catch (error) {
|
|
199
|
-
if (error instanceof _1.ServerError) {
|
|
200
|
-
(0, logger_util_1.errorLogger)('streamContacts', `[${orderingKey}] Could not publish contacts`, providerConfig.apiKey, { message: error.message, status: error.status });
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
(0, logger_util_1.errorLogger)('streamContacts', `[${orderingKey}] Could not publish contacts (${error})`, providerConfig.apiKey);
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
const streamContacts = () => __awaiter(this, void 0, void 0, function* () {
|
|
207
|
-
if (!this.adapter.streamContacts) {
|
|
208
|
-
throw new _1.ServerError(501, 'Streaming contacts is not implemented');
|
|
209
|
-
}
|
|
210
|
-
const iterator = this.adapter.streamContacts(providerConfig);
|
|
211
|
-
let result;
|
|
212
|
-
do {
|
|
213
|
-
result = yield iterator.next();
|
|
214
|
-
const { value: contacts } = result;
|
|
215
|
-
if (contacts && contacts.length > 0)
|
|
216
|
-
yield publishContacts(contacts);
|
|
217
|
-
} while (!result.done);
|
|
218
|
-
});
|
|
219
|
-
const streamingPromise = streamContacts()
|
|
220
|
-
.then(() => {
|
|
221
|
-
var _a, _b;
|
|
222
|
-
(_a = this.additionalPubSubContactStreamingClient) === null || _a === void 0 ? void 0 : _a.publishMessage({
|
|
223
|
-
userId: providerConfig.userId,
|
|
169
|
+
await this.pubSubContactStreamingClient?.publishMessage({
|
|
170
|
+
userId,
|
|
224
171
|
timestamp,
|
|
225
|
-
contacts:
|
|
226
|
-
state: pubsub_contacts_message_model_1.PubSubContactsState.
|
|
172
|
+
contacts: parsedContacts.map((contact) => (0, contact_util_1.sanitizeContact)(contact, providerConfig.locale)),
|
|
173
|
+
state: pubsub_contacts_message_model_1.PubSubContactsState.IN_PROGRESS,
|
|
227
174
|
integrationName: this.integrationName,
|
|
228
175
|
}, orderingKey);
|
|
229
|
-
|
|
230
|
-
|
|
176
|
+
// todo: remove as soon as platypus goes live
|
|
177
|
+
await this.additionalPubSubContactStreamingClient?.publishMessage({
|
|
178
|
+
userId,
|
|
231
179
|
timestamp,
|
|
232
|
-
contacts:
|
|
233
|
-
state: pubsub_contacts_message_model_1.PubSubContactsState.
|
|
180
|
+
contacts: contacts.map((contact) => (0, contact_util_1.sanitizeContact)(contact, providerConfig.locale)),
|
|
181
|
+
state: pubsub_contacts_message_model_1.PubSubContactsState.IN_PROGRESS,
|
|
234
182
|
integrationName: this.integrationName,
|
|
235
183
|
}, orderingKey);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
userId: providerConfig.userId,
|
|
242
|
-
timestamp,
|
|
243
|
-
contacts: [],
|
|
244
|
-
state: pubsub_contacts_message_model_1.PubSubContactsState.FAILED,
|
|
245
|
-
integrationName: this.integrationName,
|
|
246
|
-
}, orderingKey);
|
|
247
|
-
return (_d = this.pubSubContactStreamingClient) === null || _d === void 0 ? void 0 : _d.publishMessage({
|
|
248
|
-
userId: providerConfig.userId,
|
|
249
|
-
timestamp,
|
|
250
|
-
contacts: [],
|
|
251
|
-
state: pubsub_contacts_message_model_1.PubSubContactsState.FAILED,
|
|
252
|
-
integrationName: this.integrationName,
|
|
253
|
-
}, orderingKey);
|
|
254
|
-
}))
|
|
255
|
-
.catch((error) => {
|
|
256
|
-
(0, logger_util_1.errorLogger)('streamContacts', `[${orderingKey}] Could not publish failed message`, providerConfig.apiKey, error);
|
|
257
|
-
})
|
|
258
|
-
.finally(() => this.streamingPromises.delete(`${userId}:${timestamp}`));
|
|
259
|
-
this.streamingPromises.set(`${userId}:${timestamp}`, streamingPromise);
|
|
260
|
-
if (this.adapter.getToken && req.providerConfig) {
|
|
261
|
-
try {
|
|
262
|
-
const { apiKey } = yield this.adapter.getToken(req.providerConfig);
|
|
263
|
-
res.header('X-Provider-Key', apiKey);
|
|
264
|
-
}
|
|
265
|
-
catch (error) {
|
|
266
|
-
(0, logger_util_1.errorLogger)('streamContacts', `[${orderingKey}] Could not get and refresh token`, providerConfig.apiKey, error);
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
if (error instanceof _1.ServerError) {
|
|
187
|
+
(0, logger_util_1.errorLogger)('streamContacts', `[${orderingKey}] Could not publish contacts`, providerConfig.apiKey, { message: error.message, status: error.status });
|
|
188
|
+
return;
|
|
267
189
|
}
|
|
190
|
+
(0, logger_util_1.errorLogger)('streamContacts', `[${orderingKey}] Could not publish contacts (${error})`, providerConfig.apiKey);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
const streamContacts = async () => {
|
|
194
|
+
if (!this.adapter.streamContacts) {
|
|
195
|
+
throw new _1.ServerError(501, 'Streaming contacts is not implemented');
|
|
196
|
+
}
|
|
197
|
+
const iterator = this.adapter.streamContacts(providerConfig);
|
|
198
|
+
let result;
|
|
199
|
+
do {
|
|
200
|
+
result = await iterator.next();
|
|
201
|
+
const { value: contacts } = result;
|
|
202
|
+
if (contacts && contacts.length > 0)
|
|
203
|
+
await publishContacts(contacts);
|
|
204
|
+
} while (!result.done);
|
|
205
|
+
};
|
|
206
|
+
const streamingPromise = streamContacts()
|
|
207
|
+
.then(() => {
|
|
208
|
+
this.additionalPubSubContactStreamingClient?.publishMessage({
|
|
209
|
+
userId: providerConfig.userId,
|
|
210
|
+
timestamp,
|
|
211
|
+
contacts: [],
|
|
212
|
+
state: pubsub_contacts_message_model_1.PubSubContactsState.COMPLETE,
|
|
213
|
+
integrationName: this.integrationName,
|
|
214
|
+
}, orderingKey);
|
|
215
|
+
return this.pubSubContactStreamingClient?.publishMessage({
|
|
216
|
+
userId: providerConfig.userId,
|
|
217
|
+
timestamp,
|
|
218
|
+
contacts: [],
|
|
219
|
+
state: pubsub_contacts_message_model_1.PubSubContactsState.COMPLETE,
|
|
220
|
+
integrationName: this.integrationName,
|
|
221
|
+
}, orderingKey);
|
|
222
|
+
})
|
|
223
|
+
.catch(async (error) => {
|
|
224
|
+
(0, logger_util_1.errorLogger)('streamContacts', `[${orderingKey}] Could not stream contacts`, providerConfig.apiKey, error);
|
|
225
|
+
this.additionalPubSubContactStreamingClient?.publishMessage({
|
|
226
|
+
userId: providerConfig.userId,
|
|
227
|
+
timestamp,
|
|
228
|
+
contacts: [],
|
|
229
|
+
state: pubsub_contacts_message_model_1.PubSubContactsState.FAILED,
|
|
230
|
+
integrationName: this.integrationName,
|
|
231
|
+
}, orderingKey);
|
|
232
|
+
return this.pubSubContactStreamingClient?.publishMessage({
|
|
233
|
+
userId: providerConfig.userId,
|
|
234
|
+
timestamp,
|
|
235
|
+
contacts: [],
|
|
236
|
+
state: pubsub_contacts_message_model_1.PubSubContactsState.FAILED,
|
|
237
|
+
integrationName: this.integrationName,
|
|
238
|
+
}, orderingKey);
|
|
239
|
+
})
|
|
240
|
+
.catch((error) => {
|
|
241
|
+
(0, logger_util_1.errorLogger)('streamContacts', `[${orderingKey}] Could not publish failed message`, providerConfig.apiKey, error);
|
|
242
|
+
})
|
|
243
|
+
.finally(() => this.streamingPromises.delete(`${userId}:${timestamp}`));
|
|
244
|
+
this.streamingPromises.set(`${userId}:${timestamp}`, streamingPromise);
|
|
245
|
+
if (this.adapter.getToken && req.providerConfig) {
|
|
246
|
+
try {
|
|
247
|
+
const { apiKey } = await this.adapter.getToken(req.providerConfig);
|
|
248
|
+
res.header('X-Provider-Key', apiKey);
|
|
268
249
|
}
|
|
269
|
-
(
|
|
270
|
-
|
|
271
|
-
yield streamingPromise;
|
|
272
|
-
}
|
|
273
|
-
catch (error) {
|
|
274
|
-
// prevent logging of refresh errors
|
|
275
|
-
if (error instanceof _1.ServerError &&
|
|
276
|
-
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
277
|
-
next(error);
|
|
278
|
-
return;
|
|
250
|
+
catch (error) {
|
|
251
|
+
(0, logger_util_1.errorLogger)('streamContacts', `[${orderingKey}] Could not get and refresh token`, providerConfig.apiKey, error);
|
|
279
252
|
}
|
|
280
|
-
|
|
253
|
+
}
|
|
254
|
+
(0, logger_util_1.infoLogger)(`streamContacts`, `[${orderingKey}] END`, providerConfig.apiKey);
|
|
255
|
+
res.status(200).send({ timestamp });
|
|
256
|
+
await streamingPromise;
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
// prevent logging of refresh errors
|
|
260
|
+
if (error instanceof _1.ServerError &&
|
|
261
|
+
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
281
262
|
next(error);
|
|
263
|
+
return;
|
|
282
264
|
}
|
|
283
|
-
|
|
265
|
+
(0, logger_util_1.errorLogger)('streamContacts', `Could not stream contacts`, providerConfig?.apiKey, error);
|
|
266
|
+
next(error);
|
|
267
|
+
}
|
|
284
268
|
}
|
|
285
|
-
getContact(req, res, next) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
310
|
-
next(error);
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
(0, logger_util_1.errorLogger)('getContact', 'Could not get contact:', providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.apiKey, error);
|
|
269
|
+
async getContact(req, res, next) {
|
|
270
|
+
const { providerConfig } = req;
|
|
271
|
+
try {
|
|
272
|
+
if (!providerConfig) {
|
|
273
|
+
throw new _1.ServerError(400, 'Missing parameters');
|
|
274
|
+
}
|
|
275
|
+
if (!this.adapter.getContact) {
|
|
276
|
+
throw new _1.ServerError(501, 'Getting single contact is not implemented');
|
|
277
|
+
}
|
|
278
|
+
(0, logger_util_1.infoLogger)('getContact', 'START', providerConfig.apiKey);
|
|
279
|
+
const contactType = Object.values(_1.IntegrationEntityType).find((value) => value === req.query.type?.toString());
|
|
280
|
+
if (!contactType) {
|
|
281
|
+
throw new _1.ServerError(400, 'Missing contact type query parameter');
|
|
282
|
+
}
|
|
283
|
+
const contactId = req.params.id;
|
|
284
|
+
(0, logger_util_1.infoLogger)('getContact', `Fetching contact ${contactId} of type ${contactType}`, providerConfig.apiKey);
|
|
285
|
+
const contact = await this.adapter.getContact(providerConfig, contactId, contactType);
|
|
286
|
+
(0, logger_util_1.infoLogger)('getContact', 'END', providerConfig.apiKey);
|
|
287
|
+
res.status(200).send((0, contact_util_1.sanitizeContact)(contact, providerConfig.locale));
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
// prevent logging of refresh errors
|
|
291
|
+
if (error instanceof _1.ServerError &&
|
|
292
|
+
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
314
293
|
next(error);
|
|
294
|
+
return;
|
|
315
295
|
}
|
|
316
|
-
|
|
296
|
+
(0, logger_util_1.errorLogger)('getContact', 'Could not get contact:', providerConfig?.apiKey, error);
|
|
297
|
+
next(error);
|
|
298
|
+
}
|
|
317
299
|
}
|
|
318
|
-
createContact(req, res, next) {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
356
|
-
next(error);
|
|
357
|
-
return;
|
|
358
|
-
}
|
|
359
|
-
(0, logger_util_1.errorLogger)('createContact', 'Could not create contact:', apiKey, error || 'Unknown');
|
|
360
|
-
(0, logger_util_1.errorLogger)('createContact', 'Entity', apiKey, req.body);
|
|
300
|
+
async createContact(req, res, next) {
|
|
301
|
+
const { providerConfig: { apiKey = '', locale = '' } = {} } = req;
|
|
302
|
+
try {
|
|
303
|
+
(0, logger_util_1.infoLogger)('createContact', 'START', apiKey);
|
|
304
|
+
if (!this.adapter.createContact) {
|
|
305
|
+
throw new _1.ServerError(501, 'Creating contacts is not implemented');
|
|
306
|
+
}
|
|
307
|
+
if (!req.providerConfig) {
|
|
308
|
+
throw new _1.ServerError(400, 'Missing config parameters');
|
|
309
|
+
}
|
|
310
|
+
const parseResultContactCreate = schemas_1.contactCreateSchema.safeParse(req.body);
|
|
311
|
+
if (parseResultContactCreate.error)
|
|
312
|
+
throw new _1.ServerError(400, `Invalid contactCreate received: ${parseResultContactCreate.error.message}`);
|
|
313
|
+
(0, logger_util_1.infoLogger)('createContact', 'Creating contact', apiKey);
|
|
314
|
+
const contact = await this.adapter.createContact(req.providerConfig, parseResultContactCreate.data);
|
|
315
|
+
const parseResultReturnContact = schemas_1.contactSchema.safeParse(contact);
|
|
316
|
+
if (parseResultReturnContact.error)
|
|
317
|
+
throw new _1.ServerError(500, `Invalid contact returned from bridge: ${parseResultReturnContact.error.message}`);
|
|
318
|
+
(0, logger_util_1.infoLogger)('createContact', `Contact with id ${parseResultReturnContact.data.id} created`, apiKey);
|
|
319
|
+
const sanitizedContact = (0, contact_util_1.sanitizeContact)(parseResultReturnContact.data, locale);
|
|
320
|
+
if (this.adapter.getToken && req.providerConfig) {
|
|
321
|
+
const { apiKey } = await this.adapter.getToken(req.providerConfig);
|
|
322
|
+
res.header('X-Provider-Key', apiKey);
|
|
323
|
+
}
|
|
324
|
+
res.status(200).send(sanitizedContact);
|
|
325
|
+
if (this.contactCache) {
|
|
326
|
+
const contacts = await this.contactCache.get(apiKey);
|
|
327
|
+
if (Array.isArray(contacts)) {
|
|
328
|
+
await this.contactCache.set(apiKey, [...contacts, sanitizedContact]);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
(0, logger_util_1.infoLogger)('createContact', 'END', apiKey);
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
// prevent logging of refresh errors
|
|
335
|
+
if (error instanceof _1.ServerError &&
|
|
336
|
+
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
361
337
|
next(error);
|
|
338
|
+
return;
|
|
362
339
|
}
|
|
363
|
-
|
|
340
|
+
(0, logger_util_1.errorLogger)('createContact', 'Could not create contact:', apiKey, error || 'Unknown');
|
|
341
|
+
(0, logger_util_1.errorLogger)('createContact', 'Entity', apiKey, req.body);
|
|
342
|
+
next(error);
|
|
343
|
+
}
|
|
364
344
|
}
|
|
365
|
-
updateContact(req, res, next) {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
403
|
-
next(error);
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
(0, logger_util_1.errorLogger)('updateContact', 'Could not update contact:', apiKey, error || 'Unknown');
|
|
407
|
-
(0, logger_util_1.errorLogger)('updateContact', 'Entity', apiKey, req.body);
|
|
345
|
+
async updateContact(req, res, next) {
|
|
346
|
+
const { providerConfig: { apiKey = '', locale = '' } = {} } = req;
|
|
347
|
+
try {
|
|
348
|
+
if (!this.adapter.updateContact) {
|
|
349
|
+
throw new _1.ServerError(501, 'Updating contacts is not implemented');
|
|
350
|
+
}
|
|
351
|
+
if (!req.providerConfig) {
|
|
352
|
+
throw new _1.ServerError(400, 'Missing config parameters');
|
|
353
|
+
}
|
|
354
|
+
const parseResultContactUpdate = schemas_1.contactCreateSchema.safeParse(req.body);
|
|
355
|
+
if (parseResultContactUpdate.error)
|
|
356
|
+
throw new _1.ServerError(400, `Invalid contactUpdate received: ${parseResultContactUpdate.error.message}`);
|
|
357
|
+
(0, logger_util_1.infoLogger)('updateContact', 'Updating contact', apiKey);
|
|
358
|
+
const contact = await this.adapter.updateContact(req.providerConfig, req.params.id, { ...parseResultContactUpdate.data, id: req.params.id });
|
|
359
|
+
const parseResultReturnContact = schemas_1.contactSchema.safeParse(contact);
|
|
360
|
+
if (parseResultReturnContact.error)
|
|
361
|
+
throw new _1.ServerError(500, `Invalid contact returned from bridge: ${parseResultReturnContact.error.message}`);
|
|
362
|
+
(0, logger_util_1.infoLogger)('updateContact', `Contact with id ${parseResultReturnContact.data.id} updated`, apiKey);
|
|
363
|
+
const sanitizedContact = (0, contact_util_1.sanitizeContact)(parseResultReturnContact.data, locale);
|
|
364
|
+
if (this.adapter.getToken && req.providerConfig) {
|
|
365
|
+
const { apiKey } = await this.adapter.getToken(req.providerConfig);
|
|
366
|
+
res.header('X-Provider-Key', apiKey);
|
|
367
|
+
}
|
|
368
|
+
res.status(200).send(sanitizedContact);
|
|
369
|
+
if (this.contactCache) {
|
|
370
|
+
const contacts = await this.contactCache.get(apiKey);
|
|
371
|
+
if (Array.isArray(contacts)) {
|
|
372
|
+
const updatedCache = contacts.map((entry) => entry.id === sanitizedContact.id ? sanitizedContact : entry);
|
|
373
|
+
await this.contactCache.set(apiKey, updatedCache);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
(0, logger_util_1.infoLogger)('updateContact', 'END', apiKey);
|
|
377
|
+
}
|
|
378
|
+
catch (error) {
|
|
379
|
+
// prevent logging of refresh errors
|
|
380
|
+
if (error instanceof _1.ServerError &&
|
|
381
|
+
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
408
382
|
next(error);
|
|
383
|
+
return;
|
|
409
384
|
}
|
|
410
|
-
|
|
385
|
+
(0, logger_util_1.errorLogger)('updateContact', 'Could not update contact:', apiKey, error || 'Unknown');
|
|
386
|
+
(0, logger_util_1.errorLogger)('updateContact', 'Entity', apiKey, req.body);
|
|
387
|
+
next(error);
|
|
388
|
+
}
|
|
411
389
|
}
|
|
412
|
-
deleteContact(req, res, next) {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
445
|
-
next(error);
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
(0, logger_util_1.errorLogger)('deleteContact', 'Could not delete contact:', apiKey, error || 'Unknown');
|
|
390
|
+
async deleteContact(req, res, next) {
|
|
391
|
+
const { providerConfig: { apiKey = '' } = {} } = req;
|
|
392
|
+
try {
|
|
393
|
+
(0, logger_util_1.infoLogger)('deleteContact', 'START', apiKey);
|
|
394
|
+
if (!this.adapter.deleteContact) {
|
|
395
|
+
throw new _1.ServerError(501, 'Deleting contacts is not implemented');
|
|
396
|
+
}
|
|
397
|
+
if (!req.providerConfig) {
|
|
398
|
+
throw new _1.ServerError(400, 'Missing config parameters');
|
|
399
|
+
}
|
|
400
|
+
(0, logger_util_1.infoLogger)('deleteContact', 'Deleting contact', apiKey);
|
|
401
|
+
const contactId = req.params.id;
|
|
402
|
+
await this.adapter.deleteContact(req.providerConfig, contactId);
|
|
403
|
+
if (this.adapter.getToken && req.providerConfig) {
|
|
404
|
+
const { apiKey } = await this.adapter.getToken(req.providerConfig);
|
|
405
|
+
res.header('X-Provider-Key', apiKey);
|
|
406
|
+
}
|
|
407
|
+
res.status(200).send();
|
|
408
|
+
(0, logger_util_1.infoLogger)('deleteContact', `Contact with id ${contactId} deleted`, apiKey);
|
|
409
|
+
if (this.contactCache) {
|
|
410
|
+
const contacts = await this.contactCache.get(apiKey);
|
|
411
|
+
if (Array.isArray(contacts)) {
|
|
412
|
+
const updatedCache = contacts.filter((entry) => entry.id !== contactId);
|
|
413
|
+
await this.contactCache.set(apiKey, updatedCache);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
(0, logger_util_1.infoLogger)('deleteContact', 'END', apiKey);
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
// prevent logging of refresh errors
|
|
420
|
+
if (error instanceof _1.ServerError &&
|
|
421
|
+
error.message === integration_error_model_1.IntegrationErrorType.INTEGRATION_REFRESH_ERROR) {
|
|
449
422
|
next(error);
|
|
423
|
+
return;
|
|
450
424
|
}
|
|
451
|
-
|
|
425
|
+
(0, logger_util_1.errorLogger)('deleteContact', 'Could not delete contact:', apiKey, error || 'Unknown');
|
|
426
|
+
next(error);
|
|
427
|
+
}
|
|
452
428
|
}
|
|
453
429
|
/**
|
|
454
430
|
* @deprecated Use createOrUpdateCallLogForEntities instead
|
|
@@ -456,82 +432,76 @@ class Controller {
|
|
|
456
432
|
* @param res
|
|
457
433
|
* @param next
|
|
458
434
|
*/
|
|
459
|
-
handleCallEvent(req, res, next) {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
throw new _1.ServerError(400, 'Missing config parameters');
|
|
466
|
-
}
|
|
467
|
-
if (!this.adapter.handleCallEvent) {
|
|
468
|
-
throw new _1.ServerError(501, 'Handling call event is not implemented');
|
|
469
|
-
}
|
|
470
|
-
if ((0, call_event_util_1.shouldSkipCallEvent)(req.body)) {
|
|
471
|
-
(0, logger_util_1.infoLogger)('handleCallEvent', `Skipping call event for call id ${req.body.id}`, providerConfig.apiKey);
|
|
472
|
-
res.status(200).send('Skipping call event');
|
|
473
|
-
return;
|
|
474
|
-
}
|
|
475
|
-
(0, logger_util_1.infoLogger)('handleCallEvent', `Handling call event`, providerConfig.apiKey);
|
|
476
|
-
const integrationCallEventRef = yield this.adapter.handleCallEvent(providerConfig, req.body);
|
|
477
|
-
if (integrationCallEventRef != '')
|
|
478
|
-
(0, logger_util_1.infoLogger)('handleCallEvent', `CallEvent with refId ${integrationCallEventRef} created!`, providerConfig.apiKey);
|
|
479
|
-
else
|
|
480
|
-
(0, logger_util_1.infoLogger)('handleCallEvent', `Did not create callEvent`, providerConfig.apiKey);
|
|
481
|
-
(0, logger_util_1.infoLogger)('handleCallEvent', `END`, providerConfig.apiKey);
|
|
482
|
-
res.status(200).send(integrationCallEventRef);
|
|
483
|
-
}
|
|
484
|
-
catch (error) {
|
|
485
|
-
(0, logger_util_1.errorLogger)('handleCallEvent', 'Could not handle call event:', providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.apiKey, [error || 'Unknown', req.body]);
|
|
486
|
-
next(error);
|
|
435
|
+
async handleCallEvent(req, res, next) {
|
|
436
|
+
const { providerConfig } = req;
|
|
437
|
+
try {
|
|
438
|
+
(0, logger_util_1.infoLogger)('handleCallEvent', `START`, providerConfig?.apiKey);
|
|
439
|
+
if (!providerConfig) {
|
|
440
|
+
throw new _1.ServerError(400, 'Missing config parameters');
|
|
487
441
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
handleConnectedEvent(req, res, next) {
|
|
491
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
492
|
-
const { providerConfig: { apiKey = '' } = {} } = req;
|
|
493
|
-
try {
|
|
494
|
-
(0, logger_util_1.infoLogger)('handleConnectedEvent', `START`, apiKey);
|
|
495
|
-
if (!this.adapter.handleConnectedEvent) {
|
|
496
|
-
throw new _1.ServerError(501, 'Handling connected event is not implemented');
|
|
497
|
-
}
|
|
498
|
-
if (!req.providerConfig) {
|
|
499
|
-
throw new _1.ServerError(400, 'Missing config parameters');
|
|
500
|
-
}
|
|
501
|
-
(0, logger_util_1.infoLogger)('handleConnectedEvent', `Handling connected event`, apiKey);
|
|
502
|
-
yield this.adapter.handleConnectedEvent(req.providerConfig);
|
|
503
|
-
(0, logger_util_1.infoLogger)('handleConnectedEvent', `END`, apiKey);
|
|
504
|
-
res.status(200).send();
|
|
505
|
-
}
|
|
506
|
-
catch (error) {
|
|
507
|
-
(0, logger_util_1.errorLogger)('handleConnectedEvent', `Could not handle connected event:`, apiKey, error || 'Unknown');
|
|
508
|
-
(0, logger_util_1.errorLogger)('handleConnectedEvent', 'Entity', apiKey, req.body);
|
|
509
|
-
next(error);
|
|
442
|
+
if (!this.adapter.handleCallEvent) {
|
|
443
|
+
throw new _1.ServerError(501, 'Handling call event is not implemented');
|
|
510
444
|
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
const { providerConfig: { apiKey = '' } = {} } = req;
|
|
516
|
-
try {
|
|
517
|
-
(0, logger_util_1.infoLogger)('handleDisconnectedEvent', `START`, apiKey);
|
|
518
|
-
if (!this.adapter.handleDisconnectedEvent) {
|
|
519
|
-
throw new _1.ServerError(501, 'Handling disconnected event is not implemented');
|
|
520
|
-
}
|
|
521
|
-
if (!req.providerConfig) {
|
|
522
|
-
throw new _1.ServerError(400, 'Missing config parameters');
|
|
523
|
-
}
|
|
524
|
-
(0, logger_util_1.infoLogger)('handleDisconnectedEvent', `Handling disconnected event`, apiKey);
|
|
525
|
-
yield this.adapter.handleDisconnectedEvent(req.providerConfig);
|
|
526
|
-
(0, logger_util_1.infoLogger)('handleDisconnectedEvent', `END`, apiKey);
|
|
527
|
-
res.status(200).send();
|
|
528
|
-
}
|
|
529
|
-
catch (error) {
|
|
530
|
-
(0, logger_util_1.errorLogger)('handleDisconnectedEvent', `Could not handle connected event:`, apiKey, error || 'Unknown');
|
|
531
|
-
(0, logger_util_1.errorLogger)('handleDisconnectedEvent', 'Entity', apiKey, req.body);
|
|
532
|
-
next(error);
|
|
445
|
+
if ((0, call_event_util_1.shouldSkipCallEvent)(req.body)) {
|
|
446
|
+
(0, logger_util_1.infoLogger)('handleCallEvent', `Skipping call event for call id ${req.body.id}`, providerConfig.apiKey);
|
|
447
|
+
res.status(200).send('Skipping call event');
|
|
448
|
+
return;
|
|
533
449
|
}
|
|
534
|
-
|
|
450
|
+
(0, logger_util_1.infoLogger)('handleCallEvent', `Handling call event`, providerConfig.apiKey);
|
|
451
|
+
const integrationCallEventRef = await this.adapter.handleCallEvent(providerConfig, req.body);
|
|
452
|
+
if (integrationCallEventRef != '')
|
|
453
|
+
(0, logger_util_1.infoLogger)('handleCallEvent', `CallEvent with refId ${integrationCallEventRef} created!`, providerConfig.apiKey);
|
|
454
|
+
else
|
|
455
|
+
(0, logger_util_1.infoLogger)('handleCallEvent', `Did not create callEvent`, providerConfig.apiKey);
|
|
456
|
+
(0, logger_util_1.infoLogger)('handleCallEvent', `END`, providerConfig.apiKey);
|
|
457
|
+
res.status(200).send(integrationCallEventRef);
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
(0, logger_util_1.errorLogger)('handleCallEvent', 'Could not handle call event:', providerConfig?.apiKey, [error || 'Unknown', req.body]);
|
|
461
|
+
next(error);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
async handleConnectedEvent(req, res, next) {
|
|
465
|
+
const { providerConfig: { apiKey = '' } = {} } = req;
|
|
466
|
+
try {
|
|
467
|
+
(0, logger_util_1.infoLogger)('handleConnectedEvent', `START`, apiKey);
|
|
468
|
+
if (!this.adapter.handleConnectedEvent) {
|
|
469
|
+
throw new _1.ServerError(501, 'Handling connected event is not implemented');
|
|
470
|
+
}
|
|
471
|
+
if (!req.providerConfig) {
|
|
472
|
+
throw new _1.ServerError(400, 'Missing config parameters');
|
|
473
|
+
}
|
|
474
|
+
(0, logger_util_1.infoLogger)('handleConnectedEvent', `Handling connected event`, apiKey);
|
|
475
|
+
await this.adapter.handleConnectedEvent(req.providerConfig);
|
|
476
|
+
(0, logger_util_1.infoLogger)('handleConnectedEvent', `END`, apiKey);
|
|
477
|
+
res.status(200).send();
|
|
478
|
+
}
|
|
479
|
+
catch (error) {
|
|
480
|
+
(0, logger_util_1.errorLogger)('handleConnectedEvent', `Could not handle connected event:`, apiKey, error || 'Unknown');
|
|
481
|
+
(0, logger_util_1.errorLogger)('handleConnectedEvent', 'Entity', apiKey, req.body);
|
|
482
|
+
next(error);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
async handleDisconnectedEvent(req, res, next) {
|
|
486
|
+
const { providerConfig: { apiKey = '' } = {} } = req;
|
|
487
|
+
try {
|
|
488
|
+
(0, logger_util_1.infoLogger)('handleDisconnectedEvent', `START`, apiKey);
|
|
489
|
+
if (!this.adapter.handleDisconnectedEvent) {
|
|
490
|
+
throw new _1.ServerError(501, 'Handling disconnected event is not implemented');
|
|
491
|
+
}
|
|
492
|
+
if (!req.providerConfig) {
|
|
493
|
+
throw new _1.ServerError(400, 'Missing config parameters');
|
|
494
|
+
}
|
|
495
|
+
(0, logger_util_1.infoLogger)('handleDisconnectedEvent', `Handling disconnected event`, apiKey);
|
|
496
|
+
await this.adapter.handleDisconnectedEvent(req.providerConfig);
|
|
497
|
+
(0, logger_util_1.infoLogger)('handleDisconnectedEvent', `END`, apiKey);
|
|
498
|
+
res.status(200).send();
|
|
499
|
+
}
|
|
500
|
+
catch (error) {
|
|
501
|
+
(0, logger_util_1.errorLogger)('handleDisconnectedEvent', `Could not handle connected event:`, apiKey, error || 'Unknown');
|
|
502
|
+
(0, logger_util_1.errorLogger)('handleDisconnectedEvent', 'Entity', apiKey, req.body);
|
|
503
|
+
next(error);
|
|
504
|
+
}
|
|
535
505
|
}
|
|
536
506
|
/**
|
|
537
507
|
* @deprecated Use createOrUpdateCallLogForEntities instead
|
|
@@ -539,207 +509,194 @@ class Controller {
|
|
|
539
509
|
* @param res
|
|
540
510
|
* @param next
|
|
541
511
|
*/
|
|
542
|
-
updateCallEvent(req, res, next) {
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
}
|
|
563
|
-
});
|
|
512
|
+
async updateCallEvent(req, res, next) {
|
|
513
|
+
const { providerConfig: { apiKey = '' } = {}, body, params } = req;
|
|
514
|
+
try {
|
|
515
|
+
(0, logger_util_1.infoLogger)('updateCallEvent', `START`, apiKey);
|
|
516
|
+
if (!this.adapter.updateCallEvent) {
|
|
517
|
+
throw new _1.ServerError(501, 'Updating call events is not implemented');
|
|
518
|
+
}
|
|
519
|
+
if (!req.providerConfig) {
|
|
520
|
+
throw new _1.ServerError(400, 'Missing config parameters');
|
|
521
|
+
}
|
|
522
|
+
(0, logger_util_1.infoLogger)('updateCallEvent', `Updating call event`, apiKey);
|
|
523
|
+
await this.adapter.updateCallEvent(req.providerConfig, params.id, body);
|
|
524
|
+
(0, logger_util_1.infoLogger)('updateCallEvent', `END`, apiKey);
|
|
525
|
+
res.status(200).send();
|
|
526
|
+
}
|
|
527
|
+
catch (error) {
|
|
528
|
+
(0, logger_util_1.errorLogger)('updateCallEvent', `Could not update call event:`, apiKey, error || 'Unknown');
|
|
529
|
+
(0, logger_util_1.errorLogger)('updateCallEvent', 'Entity', apiKey, req.body);
|
|
530
|
+
next(error);
|
|
531
|
+
}
|
|
564
532
|
}
|
|
565
|
-
getEntity(req, res, next) {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
throw new _1.ServerError(400, 'Missing parameters');
|
|
572
|
-
}
|
|
573
|
-
if (!this.adapter.getEntity) {
|
|
574
|
-
throw new _1.ServerError(501, 'Fetching Entity is not implemented');
|
|
575
|
-
}
|
|
576
|
-
const fetchedEntity = yield this.adapter.getEntity(providerConfig, req.params.id, req.params.type);
|
|
577
|
-
(0, logger_util_1.infoLogger)('getEntity', `successfully got entity`, providerConfig.apiKey, Object.assign(Object.assign({}, fetchedEntity), { label: (0, anonymize_key_1.anonymizeKey)(fetchedEntity === null || fetchedEntity === void 0 ? void 0 : fetchedEntity.label) }));
|
|
578
|
-
(0, logger_util_1.infoLogger)('getEntity', `END`, providerConfig.apiKey);
|
|
579
|
-
res.status(200).send(fetchedEntity);
|
|
580
|
-
}
|
|
581
|
-
catch (error) {
|
|
582
|
-
(0, logger_util_1.errorLogger)('getEntity', 'Could not get entity:', providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.apiKey, error);
|
|
583
|
-
next(error);
|
|
533
|
+
async getEntity(req, res, next) {
|
|
534
|
+
const { providerConfig } = req;
|
|
535
|
+
try {
|
|
536
|
+
(0, logger_util_1.infoLogger)('getEntity', `START`, providerConfig?.apiKey);
|
|
537
|
+
if (!providerConfig) {
|
|
538
|
+
throw new _1.ServerError(400, 'Missing parameters');
|
|
584
539
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
getEntitiesForContact(req, res, next) {
|
|
588
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
589
|
-
const { providerConfig } = req;
|
|
590
|
-
try {
|
|
591
|
-
(0, logger_util_1.infoLogger)('getEntitiesForContact', `START`, providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.apiKey);
|
|
592
|
-
if (!providerConfig) {
|
|
593
|
-
throw new _1.ServerError(400, 'Missing parameters');
|
|
594
|
-
}
|
|
595
|
-
if (!this.adapter.getEntitiesForContact) {
|
|
596
|
-
throw new _1.ServerError(501, 'Fetching Entities for contact is not implemented');
|
|
597
|
-
}
|
|
598
|
-
const fetchedEntities = yield this.adapter.getEntitiesForContact(providerConfig, req.params.id);
|
|
599
|
-
(0, logger_util_1.infoLogger)('getEntitiesForContact', `successfully fetched ${fetchedEntities.length} entities`, providerConfig.apiKey, {
|
|
600
|
-
count: fetchedEntities.length,
|
|
601
|
-
});
|
|
602
|
-
(0, logger_util_1.infoLogger)('getEntitiesForContact', `END`, providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.apiKey);
|
|
603
|
-
res.status(200).send(fetchedEntities);
|
|
604
|
-
}
|
|
605
|
-
catch (error) {
|
|
606
|
-
(0, logger_util_1.errorLogger)('getEntitiesForContact', 'Could not get entities for contact', providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.apiKey, error);
|
|
607
|
-
next(error);
|
|
540
|
+
if (!this.adapter.getEntity) {
|
|
541
|
+
throw new _1.ServerError(501, 'Fetching Entity is not implemented');
|
|
608
542
|
}
|
|
609
|
-
|
|
543
|
+
const fetchedEntity = await this.adapter.getEntity(providerConfig, req.params.id, req.params.type);
|
|
544
|
+
(0, logger_util_1.infoLogger)('getEntity', `successfully got entity`, providerConfig.apiKey, {
|
|
545
|
+
...fetchedEntity,
|
|
546
|
+
label: (0, anonymize_key_1.anonymizeKey)(fetchedEntity?.label),
|
|
547
|
+
});
|
|
548
|
+
(0, logger_util_1.infoLogger)('getEntity', `END`, providerConfig.apiKey);
|
|
549
|
+
res.status(200).send(fetchedEntity);
|
|
550
|
+
}
|
|
551
|
+
catch (error) {
|
|
552
|
+
(0, logger_util_1.errorLogger)('getEntity', 'Could not get entity:', providerConfig?.apiKey, error);
|
|
553
|
+
next(error);
|
|
554
|
+
}
|
|
610
555
|
}
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
res.sendStatus(200);
|
|
556
|
+
async getEntitiesForContact(req, res, next) {
|
|
557
|
+
const { providerConfig } = req;
|
|
558
|
+
try {
|
|
559
|
+
(0, logger_util_1.infoLogger)('getEntitiesForContact', `START`, providerConfig?.apiKey);
|
|
560
|
+
if (!providerConfig) {
|
|
561
|
+
throw new _1.ServerError(400, 'Missing parameters');
|
|
618
562
|
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
next(error || 'Internal Server Error');
|
|
563
|
+
if (!this.adapter.getEntitiesForContact) {
|
|
564
|
+
throw new _1.ServerError(501, 'Fetching Entities for contact is not implemented');
|
|
622
565
|
}
|
|
623
|
-
|
|
566
|
+
const fetchedEntities = await this.adapter.getEntitiesForContact(providerConfig, req.params.id);
|
|
567
|
+
(0, logger_util_1.infoLogger)('getEntitiesForContact', `successfully fetched ${fetchedEntities.length} entities`, providerConfig.apiKey, {
|
|
568
|
+
count: fetchedEntities.length,
|
|
569
|
+
});
|
|
570
|
+
(0, logger_util_1.infoLogger)('getEntitiesForContact', `END`, providerConfig?.apiKey);
|
|
571
|
+
res.status(200).send(fetchedEntities);
|
|
572
|
+
}
|
|
573
|
+
catch (error) {
|
|
574
|
+
(0, logger_util_1.errorLogger)('getEntitiesForContact', 'Could not get entities for contact', providerConfig?.apiKey, error);
|
|
575
|
+
next(error);
|
|
576
|
+
}
|
|
624
577
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
throw new _1.ServerError(501, 'OAuth2 flow not implemented');
|
|
630
|
-
}
|
|
631
|
-
const redirectUrl = yield this.adapter.getOAuth2RedirectUrl(req, res);
|
|
632
|
-
res.status(200).send({ redirectUrl });
|
|
633
|
-
}
|
|
634
|
-
catch (error) {
|
|
635
|
-
(0, logger_util_1.errorLogger)('oAuth2Redirect', 'Could not get OAuth2 redirect URL:', '', error || 'Unknown');
|
|
636
|
-
next(error);
|
|
578
|
+
async getHealth(req, res, next) {
|
|
579
|
+
try {
|
|
580
|
+
if (this.adapter.getHealth) {
|
|
581
|
+
await this.adapter.getHealth();
|
|
637
582
|
}
|
|
638
|
-
|
|
583
|
+
res.sendStatus(200);
|
|
584
|
+
}
|
|
585
|
+
catch (error) {
|
|
586
|
+
(0, logger_util_1.errorLogger)('getHealth', 'Health check failed:', '', error || 'Unknown');
|
|
587
|
+
next(error || 'Internal Server Error');
|
|
588
|
+
}
|
|
639
589
|
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
(0, logger_util_1.errorLogger)('oAuth2Callback', 'OAuth2 Redirect URL not configured!', '');
|
|
645
|
-
res.status(500).send('OAuth2 Redirect URL not configured!');
|
|
646
|
-
return;
|
|
590
|
+
async oAuth2Redirect(req, res, next) {
|
|
591
|
+
try {
|
|
592
|
+
if (!this.adapter.getOAuth2RedirectUrl) {
|
|
593
|
+
throw new _1.ServerError(501, 'OAuth2 flow not implemented');
|
|
647
594
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
key: apiKey,
|
|
656
|
-
url: apiUrl,
|
|
657
|
-
});
|
|
658
|
-
res.redirect(`${redirectUrl}?${params}`);
|
|
659
|
-
}
|
|
660
|
-
catch (error) {
|
|
661
|
-
(0, logger_util_1.errorLogger)('oAuth2Callback', 'Unable to save OAuth2 token:', '', error || 'Unknown');
|
|
662
|
-
res.redirect(redirectUrl);
|
|
663
|
-
}
|
|
664
|
-
});
|
|
595
|
+
const redirectUrl = await this.adapter.getOAuth2RedirectUrl(req, res);
|
|
596
|
+
res.status(200).send({ redirectUrl });
|
|
597
|
+
}
|
|
598
|
+
catch (error) {
|
|
599
|
+
(0, logger_util_1.errorLogger)('oAuth2Redirect', 'Could not get OAuth2 redirect URL:', '', error || 'Unknown');
|
|
600
|
+
next(error);
|
|
601
|
+
}
|
|
665
602
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
603
|
+
async oAuth2Callback(req, res) {
|
|
604
|
+
const { OAUTH2_REDIRECT_URL: redirectUrl, OAUTH2_IDENTIFIER: oAuth2Identifier = 'UNKNOWN', } = process.env;
|
|
605
|
+
if (!redirectUrl) {
|
|
606
|
+
(0, logger_util_1.errorLogger)('oAuth2Callback', 'OAuth2 Redirect URL not configured!', '');
|
|
607
|
+
res.status(500).send('OAuth2 Redirect URL not configured!');
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
try {
|
|
611
|
+
if (!this.adapter.handleOAuth2Callback) {
|
|
612
|
+
throw new _1.ServerError(501, 'OAuth2 flow not implemented');
|
|
613
|
+
}
|
|
614
|
+
const { apiKey, apiUrl } = await this.adapter.handleOAuth2Callback(req, res);
|
|
615
|
+
const params = (0, querystring_1.stringify)({
|
|
616
|
+
name: oAuth2Identifier,
|
|
617
|
+
key: apiKey,
|
|
618
|
+
url: apiUrl,
|
|
619
|
+
});
|
|
620
|
+
res.redirect(`${redirectUrl}?${params}`);
|
|
621
|
+
}
|
|
622
|
+
catch (error) {
|
|
623
|
+
(0, logger_util_1.errorLogger)('oAuth2Callback', 'Unable to save OAuth2 token:', '', error || 'Unknown');
|
|
624
|
+
res.redirect(redirectUrl);
|
|
625
|
+
}
|
|
680
626
|
}
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
if (!providerConfig) {
|
|
686
|
-
throw new _1.ServerError(400, 'Missing parameters');
|
|
687
|
-
}
|
|
688
|
-
if (!this.adapter.getAccountId) {
|
|
689
|
-
throw new _1.ServerError(501, 'Fetching account id is not implemented');
|
|
690
|
-
}
|
|
691
|
-
(0, logger_util_1.infoLogger)('getAccountId', 'START', providerConfig.apiKey);
|
|
692
|
-
const accountId = yield this.adapter.getAccountId(providerConfig);
|
|
693
|
-
if (!accountId) {
|
|
694
|
-
throw new _1.ServerError(500, 'AccountID not found');
|
|
695
|
-
}
|
|
696
|
-
(0, logger_util_1.infoLogger)('getAccountId', 'END', providerConfig.apiKey);
|
|
697
|
-
res.status(200).json(accountId.toString());
|
|
698
|
-
}
|
|
699
|
-
catch (error) {
|
|
700
|
-
(0, logger_util_1.errorLogger)('getAccountId', 'Could not get AccountId', providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.apiKey, error);
|
|
701
|
-
next(error);
|
|
627
|
+
async oAuth2Token(req, res) {
|
|
628
|
+
try {
|
|
629
|
+
if (!this.adapter.handleOAuth2Callback) {
|
|
630
|
+
throw new _1.ServerError(501, 'OAuth2 flow not implemented');
|
|
702
631
|
}
|
|
703
|
-
|
|
632
|
+
const credentials = await this.adapter.handleOAuth2Callback(req, res);
|
|
633
|
+
res.json(credentials);
|
|
634
|
+
}
|
|
635
|
+
catch (error) {
|
|
636
|
+
(0, logger_util_1.errorLogger)('oAuth2Callback', 'Unable to save OAuth2 token:', '', error || 'Unknown');
|
|
637
|
+
throw error;
|
|
638
|
+
}
|
|
704
639
|
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
}
|
|
711
|
-
if (!this.adapter.verifyWebhookRequest) {
|
|
712
|
-
throw new _1.ServerError(501, 'Webhook verification not implemented');
|
|
713
|
-
}
|
|
714
|
-
const verified = yield this.adapter.verifyWebhookRequest(req);
|
|
715
|
-
if (!verified) {
|
|
716
|
-
(0, logger_util_1.errorLogger)('handleWebhook', 'Webhook verification failed');
|
|
717
|
-
throw new _1.ServerError(403, 'Webhook verification failed');
|
|
718
|
-
}
|
|
719
|
-
(0, logger_util_1.infoLogger)('handleWebhook', 'START');
|
|
720
|
-
const events = yield this.adapter.handleWebhook(req);
|
|
721
|
-
(0, logger_util_1.infoLogger)('handleWebhook', `Got ${events.length} events`);
|
|
722
|
-
const deduplicatedEvents = (0, lodash_1.uniqWith)(events, lodash_1.isEqual);
|
|
723
|
-
const publishResults = yield Promise.allSettled(deduplicatedEvents
|
|
724
|
-
.map((event) => (Object.assign({ integrationName: this.integrationName }, event)))
|
|
725
|
-
.map((message) => {
|
|
726
|
-
var _a;
|
|
727
|
-
(0, logger_util_1.infoLogger)('handleWebhook', `Publishing event ${message.type} with accountId ${message.accountId}`);
|
|
728
|
-
return (_a = this.pubSubIntegrationEventsClient) === null || _a === void 0 ? void 0 : _a.publishMessage(message);
|
|
729
|
-
}));
|
|
730
|
-
publishResults.forEach((result) => {
|
|
731
|
-
if (result.status === 'rejected') {
|
|
732
|
-
(0, logger_util_1.errorLogger)('handleWebhook', `Could not publish event ${result.reason.type} with accountId ${result.reason.accountId}`, '', result.reason);
|
|
733
|
-
}
|
|
734
|
-
});
|
|
735
|
-
(0, logger_util_1.infoLogger)('handleWebhook', 'END', '');
|
|
736
|
-
res.sendStatus(200);
|
|
640
|
+
async getAccountId(req, res, next) {
|
|
641
|
+
const { providerConfig } = req;
|
|
642
|
+
try {
|
|
643
|
+
if (!providerConfig) {
|
|
644
|
+
throw new _1.ServerError(400, 'Missing parameters');
|
|
737
645
|
}
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
646
|
+
if (!this.adapter.getAccountId) {
|
|
647
|
+
throw new _1.ServerError(501, 'Fetching account id is not implemented');
|
|
648
|
+
}
|
|
649
|
+
(0, logger_util_1.infoLogger)('getAccountId', 'START', providerConfig.apiKey);
|
|
650
|
+
const accountId = await this.adapter.getAccountId(providerConfig);
|
|
651
|
+
if (!accountId) {
|
|
652
|
+
throw new _1.ServerError(500, 'AccountID not found');
|
|
741
653
|
}
|
|
742
|
-
|
|
654
|
+
(0, logger_util_1.infoLogger)('getAccountId', 'END', providerConfig.apiKey);
|
|
655
|
+
res.status(200).json(accountId.toString());
|
|
656
|
+
}
|
|
657
|
+
catch (error) {
|
|
658
|
+
(0, logger_util_1.errorLogger)('getAccountId', 'Could not get AccountId', providerConfig?.apiKey, error);
|
|
659
|
+
next(error);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
async handleWebhook(req, res, next) {
|
|
663
|
+
try {
|
|
664
|
+
if (!this.adapter.handleWebhook) {
|
|
665
|
+
throw new _1.ServerError(501, 'Webhook handling not implemented');
|
|
666
|
+
}
|
|
667
|
+
if (!this.adapter.verifyWebhookRequest) {
|
|
668
|
+
throw new _1.ServerError(501, 'Webhook verification not implemented');
|
|
669
|
+
}
|
|
670
|
+
const verified = await this.adapter.verifyWebhookRequest(req);
|
|
671
|
+
if (!verified) {
|
|
672
|
+
(0, logger_util_1.errorLogger)('handleWebhook', 'Webhook verification failed');
|
|
673
|
+
throw new _1.ServerError(403, 'Webhook verification failed');
|
|
674
|
+
}
|
|
675
|
+
(0, logger_util_1.infoLogger)('handleWebhook', 'START');
|
|
676
|
+
const events = await this.adapter.handleWebhook(req);
|
|
677
|
+
(0, logger_util_1.infoLogger)('handleWebhook', `Got ${events.length} events`);
|
|
678
|
+
const deduplicatedEvents = (0, lodash_1.uniqWith)(events, lodash_1.isEqual);
|
|
679
|
+
const publishResults = await Promise.allSettled(deduplicatedEvents
|
|
680
|
+
.map((event) => ({
|
|
681
|
+
integrationName: this.integrationName,
|
|
682
|
+
...event,
|
|
683
|
+
}))
|
|
684
|
+
.map((message) => {
|
|
685
|
+
(0, logger_util_1.infoLogger)('handleWebhook', `Publishing event ${message.type} with accountId ${message.accountId}`);
|
|
686
|
+
return this.pubSubIntegrationEventsClient?.publishMessage(message);
|
|
687
|
+
}));
|
|
688
|
+
publishResults.forEach((result) => {
|
|
689
|
+
if (result.status === 'rejected') {
|
|
690
|
+
(0, logger_util_1.errorLogger)('handleWebhook', `Could not publish event ${result.reason.type} with accountId ${result.reason.accountId}`, '', result.reason);
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
(0, logger_util_1.infoLogger)('handleWebhook', 'END', '');
|
|
694
|
+
res.sendStatus(200);
|
|
695
|
+
}
|
|
696
|
+
catch (error) {
|
|
697
|
+
(0, logger_util_1.errorLogger)('handleWebhook', 'Could not handle webhook:', '', error || 'Unknown');
|
|
698
|
+
next(error);
|
|
699
|
+
}
|
|
743
700
|
}
|
|
744
701
|
}
|
|
745
702
|
exports.Controller = Controller;
|