@app-connect/core 1.7.25 → 1.7.27
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/.env.test +5 -5
- package/README.md +441 -441
- package/connector/developerPortal.js +31 -31
- package/connector/mock.js +84 -77
- package/connector/proxy/engine.js +164 -164
- package/connector/proxy/index.js +500 -500
- package/connector/registry.js +252 -252
- package/docs/README.md +50 -50
- package/docs/architecture.md +93 -93
- package/docs/connectors.md +116 -116
- package/docs/handlers.md +125 -125
- package/docs/libraries.md +101 -101
- package/docs/models.md +144 -144
- package/docs/routes.md +115 -115
- package/docs/tests.md +73 -73
- package/handlers/admin.js +523 -523
- package/handlers/appointment.js +193 -0
- package/handlers/auth.js +320 -296
- package/handlers/calldown.js +99 -99
- package/handlers/contact.js +280 -280
- package/handlers/disposition.js +82 -80
- package/handlers/log.js +990 -973
- package/handlers/managedAuth.js +446 -446
- package/handlers/managedOAuth.js +247 -0
- package/handlers/plugin.js +208 -208
- package/handlers/user.js +142 -142
- package/index.js +3162 -2652
- package/jest.config.js +56 -56
- package/lib/analytics.js +54 -54
- package/lib/authSession.js +109 -109
- package/lib/cacheCleanup.js +21 -0
- package/lib/callLogComposer.js +898 -898
- package/lib/callLogLookup.js +34 -0
- package/lib/constants.js +8 -8
- package/lib/debugTracer.js +177 -177
- package/lib/encode.js +30 -30
- package/lib/errorHandler.js +218 -206
- package/lib/generalErrorMessage.js +41 -41
- package/lib/jwt.js +18 -18
- package/lib/logger.js +190 -190
- package/lib/migrateCallLogsSchema.js +116 -0
- package/lib/ringcentral.js +266 -266
- package/lib/s3ErrorLogReport.js +65 -65
- package/lib/sharedSMSComposer.js +471 -471
- package/lib/util.js +67 -67
- package/mcp/README.md +412 -395
- package/mcp/lib/validator.js +91 -91
- package/mcp/mcpHandler.js +425 -425
- package/mcp/tools/cancelAppointment.js +101 -0
- package/mcp/tools/checkAuthStatus.js +105 -105
- package/mcp/tools/confirmAppointment.js +101 -0
- package/mcp/tools/createAppointment.js +157 -0
- package/mcp/tools/createCallLog.js +327 -316
- package/mcp/tools/createContact.js +117 -117
- package/mcp/tools/createMessageLog.js +287 -287
- package/mcp/tools/doAuth.js +60 -60
- package/mcp/tools/findContactByName.js +93 -93
- package/mcp/tools/findContactByPhone.js +101 -101
- package/mcp/tools/getCallLog.js +111 -102
- package/mcp/tools/getGoogleFilePicker.js +99 -99
- package/mcp/tools/getHelp.js +43 -43
- package/mcp/tools/getPublicConnectors.js +94 -94
- package/mcp/tools/getSessionInfo.js +90 -90
- package/mcp/tools/index.js +51 -41
- package/mcp/tools/listAppointments.js +163 -0
- package/mcp/tools/logout.js +99 -96
- package/mcp/tools/rcGetCallLogs.js +65 -65
- package/mcp/tools/updateAppointment.js +154 -0
- package/mcp/tools/updateCallLog.js +130 -126
- package/mcp/ui/App/App.tsx +358 -358
- package/mcp/ui/App/components/AuthInfoForm.tsx +113 -113
- package/mcp/ui/App/components/AuthSuccess.tsx +22 -22
- package/mcp/ui/App/components/ConnectorList.tsx +82 -82
- package/mcp/ui/App/components/DebugPanel.tsx +43 -43
- package/mcp/ui/App/components/OAuthConnect.tsx +270 -270
- package/mcp/ui/App/lib/callTool.ts +130 -130
- package/mcp/ui/App/lib/debugLog.ts +41 -41
- package/mcp/ui/App/lib/developerPortal.ts +111 -111
- package/mcp/ui/App/main.css +5 -5
- package/mcp/ui/App/root.tsx +13 -13
- package/mcp/ui/index.html +13 -13
- package/mcp/ui/package-lock.json +6356 -6356
- package/mcp/ui/package.json +25 -25
- package/mcp/ui/tsconfig.json +26 -26
- package/mcp/ui/vite.config.ts +16 -16
- package/models/accountDataModel.js +33 -33
- package/models/adminConfigModel.js +35 -35
- package/models/cacheModel.js +30 -26
- package/models/callDownListModel.js +34 -34
- package/models/callLogModel.js +33 -27
- package/models/dynamo/connectorSchema.js +146 -146
- package/models/dynamo/lockSchema.js +24 -24
- package/models/dynamo/noteCacheSchema.js +29 -29
- package/models/llmSessionModel.js +17 -17
- package/models/messageLogModel.js +25 -25
- package/models/sequelize.js +16 -16
- package/models/userModel.js +45 -45
- package/package.json +1 -1
- package/releaseNotes.json +1101 -1081
- package/test/connector/proxy/engine.test.js +126 -126
- package/test/connector/proxy/index.test.js +279 -279
- package/test/connector/proxy/sample.json +161 -161
- package/test/connector/registry.test.js +415 -415
- package/test/handlers/admin.test.js +616 -616
- package/test/handlers/auth.test.js +1092 -1018
- package/test/handlers/contact.test.js +1014 -1014
- package/test/handlers/log.test.js +1298 -1160
- package/test/handlers/managedAuth.test.js +457 -457
- package/test/handlers/plugin.test.js +380 -380
- package/test/index.test.js +105 -105
- package/test/lib/cacheCleanup.test.js +42 -0
- package/test/lib/callLogComposer.test.js +1231 -1231
- package/test/lib/debugTracer.test.js +328 -328
- package/test/lib/jwt.test.js +176 -176
- package/test/lib/logger.test.js +206 -206
- package/test/lib/oauth.test.js +359 -359
- package/test/lib/ringcentral.test.js +467 -467
- package/test/lib/sharedSMSComposer.test.js +1084 -1084
- package/test/lib/util.test.js +329 -329
- package/test/mcp/tools/checkAuthStatus.test.js +83 -83
- package/test/mcp/tools/createCallLog.test.js +436 -436
- package/test/mcp/tools/createContact.test.js +58 -58
- package/test/mcp/tools/createMessageLog.test.js +595 -595
- package/test/mcp/tools/doAuth.test.js +113 -113
- package/test/mcp/tools/findContactByName.test.js +275 -275
- package/test/mcp/tools/findContactByPhone.test.js +296 -296
- package/test/mcp/tools/getCallLog.test.js +298 -298
- package/test/mcp/tools/getGoogleFilePicker.test.js +281 -281
- package/test/mcp/tools/getPublicConnectors.test.js +107 -107
- package/test/mcp/tools/getSessionInfo.test.js +127 -127
- package/test/mcp/tools/logout.test.js +233 -233
- package/test/mcp/tools/rcGetCallLogs.test.js +56 -56
- package/test/mcp/tools/updateCallLog.test.js +360 -360
- package/test/models/accountDataModel.test.js +98 -98
- package/test/models/dynamo/connectorSchema.test.js +189 -189
- package/test/models/models.test.js +568 -539
- package/test/routes/managedAuthRoutes.test.js +235 -104
- package/test/setup.js +178 -178
package/handlers/auth.js
CHANGED
|
@@ -1,296 +1,320 @@
|
|
|
1
|
-
const oauth = require('../lib/oauth');
|
|
2
|
-
const { UserModel } = require('../models/userModel');
|
|
3
|
-
const connectorRegistry = require('../connector/registry');
|
|
4
|
-
const Op = require('sequelize').Op;
|
|
5
|
-
const { RingCentral } = require('../lib/ringcentral');
|
|
6
|
-
const adminCore = require('./admin');
|
|
7
|
-
const { Connector } = require('../models/dynamo/connectorSchema');
|
|
8
|
-
const { handleDatabaseError } = require('../lib/errorHandler');
|
|
9
|
-
const managedAuthCore = require('./managedAuth');
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
1
|
+
const oauth = require('../lib/oauth');
|
|
2
|
+
const { UserModel } = require('../models/userModel');
|
|
3
|
+
const connectorRegistry = require('../connector/registry');
|
|
4
|
+
const Op = require('sequelize').Op;
|
|
5
|
+
const { RingCentral } = require('../lib/ringcentral');
|
|
6
|
+
const adminCore = require('./admin');
|
|
7
|
+
const { Connector } = require('../models/dynamo/connectorSchema');
|
|
8
|
+
const { handleDatabaseError } = require('../lib/errorHandler');
|
|
9
|
+
const managedAuthCore = require('./managedAuth');
|
|
10
|
+
const managedOAuthCore = require('./managedOAuth');
|
|
11
|
+
const { getHashValue } = require('../lib/util');
|
|
12
|
+
|
|
13
|
+
async function onOAuthCallback({ platform, hostname, tokenUrl, query, hashedRcExtensionId, isFromMCP = false }) {
|
|
14
|
+
const callbackUri = query.callbackUri;
|
|
15
|
+
const apiUrl = query.apiUrl;
|
|
16
|
+
const username = query.username;
|
|
17
|
+
const proxyId = query.proxyId;
|
|
18
|
+
const userEmail = query.userEmail;
|
|
19
|
+
const platformModule = connectorRegistry.getConnector(platform);
|
|
20
|
+
let proxyConfig = null;
|
|
21
|
+
if (proxyId) {
|
|
22
|
+
proxyConfig = await Connector.getProxyConfig(proxyId);
|
|
23
|
+
}
|
|
24
|
+
let managedOAuthSource = null;
|
|
25
|
+
let oauthInfo = null;
|
|
26
|
+
if (query.rcAccountId) {
|
|
27
|
+
const managedOAuthResult = await managedOAuthCore.resolveManagedOAuthInfo({
|
|
28
|
+
rcAccountId: query.rcAccountId,
|
|
29
|
+
platform
|
|
30
|
+
});
|
|
31
|
+
managedOAuthSource = managedOAuthResult.source;
|
|
32
|
+
oauthInfo = managedOAuthResult.oauthInfo;
|
|
33
|
+
}
|
|
34
|
+
if (!oauthInfo) {
|
|
35
|
+
oauthInfo = await platformModule.getOauthInfo({ tokenUrl, hostname, rcAccountId: query.rcAccountId, proxyId, proxyConfig, userEmail, isFromMCP });
|
|
36
|
+
}
|
|
37
|
+
if (oauthInfo.failMessage) {
|
|
38
|
+
return {
|
|
39
|
+
userInfo: null,
|
|
40
|
+
returnMessage: {
|
|
41
|
+
messageType: 'danger',
|
|
42
|
+
message: oauthInfo.failMessage
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Some platforms require different oauth queries, this won't affect normal OAuth process unless CRM module implements getOverridingOAuthOption() method
|
|
48
|
+
let overridingOAuthOption = null;
|
|
49
|
+
if (platformModule.getOverridingOAuthOption != null) {
|
|
50
|
+
const code = new URL(callbackUri).searchParams.get('code');
|
|
51
|
+
overridingOAuthOption = platformModule.getOverridingOAuthOption({ code });
|
|
52
|
+
}
|
|
53
|
+
const oauthApp = oauth.getOAuthApp(oauthInfo);
|
|
54
|
+
const { accessToken, refreshToken, expires, data } = await oauthApp.code.getToken(callbackUri, overridingOAuthOption);
|
|
55
|
+
const authHeader = `Bearer ${accessToken}`;
|
|
56
|
+
const { successful, platformUserInfo, returnMessage } = await platformModule.getUserInfo({ authHeader, tokenUrl, apiUrl, hostname, platform, username, callbackUri, query, proxyId, proxyConfig, userEmail, data });
|
|
57
|
+
|
|
58
|
+
if (successful) {
|
|
59
|
+
let userInfo = null;
|
|
60
|
+
try {
|
|
61
|
+
userInfo = await saveUserInfo({
|
|
62
|
+
platformUserInfo,
|
|
63
|
+
platform,
|
|
64
|
+
tokenUrl,
|
|
65
|
+
apiUrl,
|
|
66
|
+
username,
|
|
67
|
+
hostname: platformUserInfo?.overridingHostname ? platformUserInfo.overridingHostname : hostname,
|
|
68
|
+
accessToken,
|
|
69
|
+
refreshToken,
|
|
70
|
+
tokenExpiry: isNaN(expires) ? null : expires,
|
|
71
|
+
rcAccountId: query?.rcAccountId,
|
|
72
|
+
hashedRcExtensionId,
|
|
73
|
+
proxyId
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return handleDatabaseError(error, 'Error saving user info');
|
|
78
|
+
}
|
|
79
|
+
if (platformModule.postSaveUserInfo) {
|
|
80
|
+
userInfo = await platformModule.postSaveUserInfo({ userInfo, oauthApp });
|
|
81
|
+
}
|
|
82
|
+
if (managedOAuthSource === 'pending') {
|
|
83
|
+
await managedOAuthCore.migratePendingManagedOAuth({
|
|
84
|
+
rcAccountId: query.rcAccountId,
|
|
85
|
+
platform
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
userInfo,
|
|
90
|
+
returnMessage
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
return {
|
|
95
|
+
userInfo: null,
|
|
96
|
+
returnMessage
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function onApiKeyLogin({ platform, hostname, apiKey, proxyId, rcAccountId, rcExtensionId, connectorId, isPrivate, hashedRcExtensionId, additionalInfo }) {
|
|
102
|
+
const platformModule = connectorRegistry.getConnector(platform);
|
|
103
|
+
let resolvedAdditionalInfo = {
|
|
104
|
+
...(additionalInfo ?? {})
|
|
105
|
+
};
|
|
106
|
+
if (resolvedAdditionalInfo.apiKey === undefined && apiKey !== undefined) {
|
|
107
|
+
resolvedAdditionalInfo.apiKey = apiKey;
|
|
108
|
+
}
|
|
109
|
+
let resolvedApiKey = apiKey;
|
|
110
|
+
let managedFieldDefinitions = [];
|
|
111
|
+
if (rcAccountId) {
|
|
112
|
+
managedFieldDefinitions = await managedAuthCore.getManagedFieldDefinitions({ rcAccountId, platform, connectorId, isPrivate });
|
|
113
|
+
const shouldFallbackToManualAuth = managedFieldDefinitions.length > 0
|
|
114
|
+
&& await managedAuthCore.hasManagedAuthLoginFailure({ rcAccountId, platform, rcExtensionId });
|
|
115
|
+
const managedAuthResult = await managedAuthCore.resolveApiKeyLoginFields({
|
|
116
|
+
platform,
|
|
117
|
+
rcAccountId,
|
|
118
|
+
rcExtensionId,
|
|
119
|
+
connectorId,
|
|
120
|
+
isPrivate,
|
|
121
|
+
apiKey,
|
|
122
|
+
additionalInfo: resolvedAdditionalInfo,
|
|
123
|
+
preferSubmittedValuesForManagedFields: shouldFallbackToManualAuth
|
|
124
|
+
});
|
|
125
|
+
resolvedAdditionalInfo = managedAuthResult.resolvedAdditionalInfo;
|
|
126
|
+
resolvedApiKey = managedAuthResult.resolvedApiKey;
|
|
127
|
+
const missingRequiredFieldConsts = managedAuthResult.missingRequiredFieldConsts;
|
|
128
|
+
if (missingRequiredFieldConsts.length > 0) {
|
|
129
|
+
return {
|
|
130
|
+
userInfo: null,
|
|
131
|
+
returnMessage: {
|
|
132
|
+
messageType: 'warning',
|
|
133
|
+
message: 'Missing required authentication fields.',
|
|
134
|
+
ttl: 3000,
|
|
135
|
+
missingRequiredFieldConsts
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const basicAuth = platformModule.getBasicAuth({ apiKey: resolvedApiKey });
|
|
141
|
+
const { successful, platformUserInfo, returnMessage } = await platformModule.getUserInfo({
|
|
142
|
+
authHeader: `Basic ${basicAuth}`,
|
|
143
|
+
hostname,
|
|
144
|
+
platform,
|
|
145
|
+
additionalInfo: resolvedAdditionalInfo,
|
|
146
|
+
apiKey: resolvedApiKey,
|
|
147
|
+
proxyId
|
|
148
|
+
});
|
|
149
|
+
if (successful) {
|
|
150
|
+
await managedAuthCore.clearManagedAuthLoginFailure({ rcAccountId, platform, rcExtensionId });
|
|
151
|
+
let userInfo = null;
|
|
152
|
+
try {
|
|
153
|
+
userInfo = await saveUserInfo({
|
|
154
|
+
platformUserInfo,
|
|
155
|
+
platform,
|
|
156
|
+
hostname,
|
|
157
|
+
proxyId,
|
|
158
|
+
hashedRcExtensionId,
|
|
159
|
+
rcAccountId,
|
|
160
|
+
accessToken: platformUserInfo.overridingApiKey ?? resolvedApiKey
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
return handleDatabaseError(error, 'Error saving user info');
|
|
165
|
+
}
|
|
166
|
+
if (platformModule.postSaveUserInfo) {
|
|
167
|
+
userInfo = await platformModule.postSaveUserInfo({ userInfo });
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
userInfo,
|
|
171
|
+
returnMessage
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
if (managedFieldDefinitions.length > 0) {
|
|
175
|
+
await managedAuthCore.markManagedAuthLoginFailure({ rcAccountId, platform, rcExtensionId });
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
userInfo: null,
|
|
179
|
+
returnMessage
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async function saveUserInfo({ platformUserInfo, platform, hostname, accessToken, refreshToken, tokenExpiry, rcAccountId, hashedRcExtensionId, proxyId }) {
|
|
184
|
+
const id = platformUserInfo.id;
|
|
185
|
+
const name = platformUserInfo.name;
|
|
186
|
+
const existingUser = await UserModel.findByPk(id);
|
|
187
|
+
const timezoneName = platformUserInfo.timezoneName;
|
|
188
|
+
const timezoneOffset = platformUserInfo.timezoneOffset;
|
|
189
|
+
const platformAdditionalInfo = platformUserInfo.platformAdditionalInfo || {};
|
|
190
|
+
platformAdditionalInfo.proxyId = proxyId;
|
|
191
|
+
if (existingUser) {
|
|
192
|
+
try {
|
|
193
|
+
await existingUser.update(
|
|
194
|
+
{
|
|
195
|
+
platform,
|
|
196
|
+
hostname,
|
|
197
|
+
timezoneName,
|
|
198
|
+
timezoneOffset,
|
|
199
|
+
accessToken,
|
|
200
|
+
refreshToken,
|
|
201
|
+
tokenExpiry,
|
|
202
|
+
rcAccountId,
|
|
203
|
+
hashedRcExtensionId,
|
|
204
|
+
platformAdditionalInfo: {
|
|
205
|
+
...existingUser.platformAdditionalInfo, // keep existing platformAdditionalInfo
|
|
206
|
+
...platformAdditionalInfo,
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
return handleDatabaseError(error, 'Error saving user info');
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
try {
|
|
217
|
+
await UserModel.create({
|
|
218
|
+
id,
|
|
219
|
+
hostname,
|
|
220
|
+
timezoneName,
|
|
221
|
+
timezoneOffset,
|
|
222
|
+
platform,
|
|
223
|
+
accessToken,
|
|
224
|
+
refreshToken,
|
|
225
|
+
tokenExpiry,
|
|
226
|
+
rcAccountId,
|
|
227
|
+
hashedRcExtensionId,
|
|
228
|
+
platformAdditionalInfo,
|
|
229
|
+
userSettings: {}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
return handleDatabaseError(error, 'Error saving user info');
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
id,
|
|
238
|
+
name
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async function getLicenseStatus({ userId, platform }) {
|
|
243
|
+
const user = await UserModel.findByPk(userId);
|
|
244
|
+
if (!user) {
|
|
245
|
+
return {
|
|
246
|
+
isLicenseValid: false,
|
|
247
|
+
licenseStatus: 'Invalid (User not found)',
|
|
248
|
+
licenseStatusDescription: ''
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
const platformModule = connectorRegistry.getConnector(platform);
|
|
252
|
+
const licenseStatus = await platformModule.getLicenseStatus({ userId, platform, user });
|
|
253
|
+
return licenseStatus;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Just for oauth ATM
|
|
257
|
+
async function authValidation({ platform, userId }) {
|
|
258
|
+
let existingUser = await UserModel.findOne({
|
|
259
|
+
where: {
|
|
260
|
+
[Op.and]: [
|
|
261
|
+
{
|
|
262
|
+
id: userId,
|
|
263
|
+
platform
|
|
264
|
+
}
|
|
265
|
+
]
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
if (existingUser) {
|
|
269
|
+
const platformModule = connectorRegistry.getConnector(platform);
|
|
270
|
+
const proxyId = existingUser?.platformAdditionalInfo?.proxyId;
|
|
271
|
+
const managedOAuthResult = await managedOAuthCore.resolveManagedOAuthInfo({
|
|
272
|
+
rcAccountId: existingUser.rcAccountId,
|
|
273
|
+
platform
|
|
274
|
+
});
|
|
275
|
+
const oauthInfo = managedOAuthResult.oauthInfo ?? await platformModule.getOauthInfo({ tokenUrl: existingUser?.platformAdditionalInfo?.tokenUrl, hostname: existingUser?.hostname, proxyId });
|
|
276
|
+
const oauthApp = oauth.getOAuthApp(oauthInfo);
|
|
277
|
+
existingUser = await oauth.checkAndRefreshAccessToken(oauthApp, existingUser);
|
|
278
|
+
const { successful, returnMessage, status } = await platformModule.authValidation({ user: existingUser });
|
|
279
|
+
return {
|
|
280
|
+
successful,
|
|
281
|
+
returnMessage,
|
|
282
|
+
status,
|
|
283
|
+
failReason: successful ? '' : 'CRM. API failed'
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
return {
|
|
288
|
+
successful: false,
|
|
289
|
+
status: 404,
|
|
290
|
+
failReason: 'App Connect. User not found in database'
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Ringcentral
|
|
296
|
+
async function onRingcentralOAuthCallback({ code, rcAccountId }) {
|
|
297
|
+
if (!process.env.RINGCENTRAL_SERVER || !process.env.RINGCENTRAL_CLIENT_ID || !process.env.RINGCENTRAL_CLIENT_SECRET) {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
const rcSDK = new RingCentral({
|
|
301
|
+
server: process.env.RINGCENTRAL_SERVER,
|
|
302
|
+
clientId: process.env.RINGCENTRAL_CLIENT_ID,
|
|
303
|
+
clientSecret: process.env.RINGCENTRAL_CLIENT_SECRET,
|
|
304
|
+
redirectUri: `${process.env.APP_SERVER}/ringcentral/oauth/callback`
|
|
305
|
+
});
|
|
306
|
+
const { access_token, refresh_token, expire_time } = await rcSDK.generateToken({ code });
|
|
307
|
+
const hashedRcAccountId = getHashValue(rcAccountId, process.env.HASH_KEY);
|
|
308
|
+
await adminCore.updateAdminRcTokens({
|
|
309
|
+
hashedRcAccountId,
|
|
310
|
+
adminAccessToken: access_token,
|
|
311
|
+
adminRefreshToken: refresh_token,
|
|
312
|
+
adminTokenExpiry: expire_time
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
exports.onOAuthCallback = onOAuthCallback;
|
|
317
|
+
exports.onApiKeyLogin = onApiKeyLogin;
|
|
318
|
+
exports.authValidation = authValidation;
|
|
319
|
+
exports.getLicenseStatus = getLicenseStatus;
|
|
320
|
+
exports.onRingcentralOAuthCallback = onRingcentralOAuthCallback;
|