@app-connect/core 1.7.24 → 1.7.26
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 -42
- package/connector/mock.js +84 -77
- package/connector/proxy/engine.js +164 -163
- 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 -117
- 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 +296 -296
- package/handlers/calldown.js +99 -99
- package/handlers/contact.js +280 -280
- package/handlers/disposition.js +82 -80
- package/handlers/log.js +984 -973
- package/handlers/managedAuth.js +446 -446
- package/handlers/plugin.js +208 -208
- package/handlers/user.js +142 -142
- package/index.js +3140 -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 +96 -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 +72 -72
- package/releaseNotes.json +1093 -1073
- package/test/connector/proxy/engine.test.js +126 -93
- 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 +1018 -1015
- package/test/handlers/contact.test.js +1014 -1014
- package/test/handlers/log.test.js +1298 -1160
- package/test/handlers/managedAuth.test.js +458 -458
- 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 -82
- 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 +104 -129
- package/test/setup.js +178 -178
package/handlers/plugin.js
CHANGED
|
@@ -1,209 +1,209 @@
|
|
|
1
|
-
const { CacheModel } = require('../models/cacheModel');
|
|
2
|
-
const { Op } = require('sequelize');
|
|
3
|
-
const axios = require('axios');
|
|
4
|
-
const { AccountDataModel } = require('../models/accountDataModel');
|
|
5
|
-
const logger = require('../lib/logger');
|
|
6
|
-
|
|
7
|
-
const PUBLIC_MANIFEST_BASE = 'https://appconnect.labs.ringcentral.com/public-api/connectors';
|
|
8
|
-
|
|
9
|
-
async function getPluginsFromRcAccountId({ rcAccountId }) {
|
|
10
|
-
const accountData = await AccountDataModel.findAll({
|
|
11
|
-
where: {
|
|
12
|
-
rcAccountId,
|
|
13
|
-
dataKey: 'pluginData',
|
|
14
|
-
},
|
|
15
|
-
});
|
|
16
|
-
const workingPlugins = accountData.map(data => ({
|
|
17
|
-
id: data.platformName,
|
|
18
|
-
data: data.data,
|
|
19
|
-
}));
|
|
20
|
-
return workingPlugins;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function getPluginConfigFromUserSettings({ userSettings, pluginId }) {
|
|
24
|
-
if (!userSettings) {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
const targetPluginSettings = userSettings[`plugin_${pluginId}`];
|
|
28
|
-
if (!targetPluginSettings?.value?.config) {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
return targetPluginSettings.value.config;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async function getPluginLicenseStatus({ rcAccountId, pluginId }) {
|
|
35
|
-
const accountData = await AccountDataModel.findOne({
|
|
36
|
-
where: {
|
|
37
|
-
rcAccountId,
|
|
38
|
-
platformName: pluginId,
|
|
39
|
-
dataKey: 'pluginData',
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
if (!accountData) {
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
const licenseStatusUrl = accountData.data.licenseStatusUrl;
|
|
46
|
-
const licenseStatusResponse = await axios.get(licenseStatusUrl, {
|
|
47
|
-
headers: {
|
|
48
|
-
'Authorization': `Bearer ${accountData.data.jwtToken}`
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
return licenseStatusResponse.data;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async function getPluginAsyncTasks({ asyncTaskIds }) {
|
|
55
|
-
const caches = await CacheModel.findAll({
|
|
56
|
-
where: {
|
|
57
|
-
id: {
|
|
58
|
-
[Op.in]: asyncTaskIds
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
const result = caches.map(cache => ({
|
|
63
|
-
cacheKey: cache.cacheKey,
|
|
64
|
-
status: cache.status
|
|
65
|
-
}));
|
|
66
|
-
const toRemoveCaches = caches.filter(cache => cache.status === 'completed' || cache.status === 'failed');
|
|
67
|
-
await CacheModel.destroy({
|
|
68
|
-
where: {
|
|
69
|
-
id: {
|
|
70
|
-
[Op.in]: toRemoveCaches.map(cache => cache.id)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
return result;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function getRefreshedJwtTokenFromHeaders({ headers }) {
|
|
78
|
-
if (!headers) {
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
return headers['x-refreshed-jwt-token'] || headers['X-Refreshed-Jwt-Token'] || null;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async function resolvePluginManifest({ pluginId, pluginAccess, rcAccountId, pluginName }) {
|
|
85
|
-
const manifestFetchers = [];
|
|
86
|
-
if (pluginAccess === 'public') {
|
|
87
|
-
manifestFetchers.push(`${PUBLIC_MANIFEST_BASE}/${pluginId}/manifest?type=plugin`);
|
|
88
|
-
} else if (pluginAccess === 'private' || pluginAccess === 'shared') {
|
|
89
|
-
manifestFetchers.push(`${PUBLIC_MANIFEST_BASE}/${pluginId}/manifest?access=internal&type=plugin&accountId=${rcAccountId}`);
|
|
90
|
-
} else {
|
|
91
|
-
manifestFetchers.push(`${PUBLIC_MANIFEST_BASE}/${pluginId}/manifest?type=plugin`);
|
|
92
|
-
manifestFetchers.push(`${PUBLIC_MANIFEST_BASE}/${pluginId}/manifest?access=internal&type=plugin&accountId=${rcAccountId}`);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
let pluginData = null;
|
|
96
|
-
let lastError = null;
|
|
97
|
-
for (const url of manifestFetchers) {
|
|
98
|
-
try {
|
|
99
|
-
const pluginDataResponse = await axios.get(url);
|
|
100
|
-
pluginData = pluginDataResponse.data;
|
|
101
|
-
break;
|
|
102
|
-
} catch (error) {
|
|
103
|
-
lastError = error;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (!pluginData) {
|
|
108
|
-
throw lastError || new Error(`Unable to resolve manifest for plugin ${pluginId}`);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const platformKey = pluginName || Object.keys(pluginData.platforms || {})[0];
|
|
112
|
-
if (!platformKey || !pluginData.platforms?.[platformKey]) {
|
|
113
|
-
throw new Error(`Unable to resolve platform manifest for plugin ${pluginId}`);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return {
|
|
117
|
-
pluginData,
|
|
118
|
-
pluginManifest: pluginData.platforms[platformKey],
|
|
119
|
-
platformKey,
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
async function persistPluginData({ rcAccountId, pluginId, jwtToken, pluginData = {} }) {
|
|
124
|
-
try {
|
|
125
|
-
const accountData = await AccountDataModel.findOne({
|
|
126
|
-
where: {
|
|
127
|
-
rcAccountId,
|
|
128
|
-
platformName: pluginId
|
|
129
|
-
},
|
|
130
|
-
});
|
|
131
|
-
if (!accountData) {
|
|
132
|
-
await AccountDataModel.create({
|
|
133
|
-
rcAccountId,
|
|
134
|
-
platformName: pluginId,
|
|
135
|
-
dataKey: 'pluginData',
|
|
136
|
-
data: {
|
|
137
|
-
jwtToken,
|
|
138
|
-
...pluginData,
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
} else {
|
|
142
|
-
await accountData.update({
|
|
143
|
-
data: {
|
|
144
|
-
jwtToken,
|
|
145
|
-
...pluginData,
|
|
146
|
-
},
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
} catch (error) {
|
|
150
|
-
logger.error('Failed to persist plugin data', {
|
|
151
|
-
pluginId,
|
|
152
|
-
rcAccountId,
|
|
153
|
-
message: error.message,
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
async function registerPluginAccount({ pluginId, rcAccessToken, rcAccountId, pluginAccess, pluginName }) {
|
|
159
|
-
const { pluginManifest } = await resolvePluginManifest({ pluginId, pluginAccess, rcAccountId, pluginName });
|
|
160
|
-
if (!pluginManifest?.endpointUrl) {
|
|
161
|
-
throw new Error(`Plugin endpoint URL not found for ${pluginId}`);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const registerUrl = pluginManifest.userRegisterEndpointUrl;
|
|
165
|
-
const registerResponse = await axios.post(registerUrl, {
|
|
166
|
-
rcAccessToken,
|
|
167
|
-
rcAccountId: rcAccountId?.toString(),
|
|
168
|
-
});
|
|
169
|
-
const pluginJwtToken = registerResponse.data?.jwtToken;
|
|
170
|
-
if (!pluginJwtToken) {
|
|
171
|
-
throw new Error('Plugin register API did not return jwtToken');
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
await persistPluginData({
|
|
175
|
-
rcAccountId: rcAccountId?.toString(),
|
|
176
|
-
pluginId,
|
|
177
|
-
jwtToken: pluginJwtToken,
|
|
178
|
-
pluginData: pluginManifest,
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
return {
|
|
182
|
-
successful: true,
|
|
183
|
-
registerUrl,
|
|
184
|
-
jwtToken: pluginJwtToken,
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
async function unregisterPluginAccount({ pluginId, rcAccountId }) {
|
|
189
|
-
const accountData = await AccountDataModel.findOne({
|
|
190
|
-
where: {
|
|
191
|
-
rcAccountId,
|
|
192
|
-
platformName: pluginId,
|
|
193
|
-
dataKey: 'pluginData'
|
|
194
|
-
},
|
|
195
|
-
});
|
|
196
|
-
if (accountData) {
|
|
197
|
-
await accountData.destroy();
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
exports.getPluginsFromRcAccountId = getPluginsFromRcAccountId;
|
|
202
|
-
exports.getPluginConfigFromUserSettings = getPluginConfigFromUserSettings;
|
|
203
|
-
exports.getPluginLicenseStatus = getPluginLicenseStatus;
|
|
204
|
-
exports.getPluginAsyncTasks = getPluginAsyncTasks;
|
|
205
|
-
exports.getRefreshedJwtTokenFromHeaders = getRefreshedJwtTokenFromHeaders;
|
|
206
|
-
exports.resolvePluginManifest = resolvePluginManifest;
|
|
207
|
-
exports.persistPluginData = persistPluginData;
|
|
208
|
-
exports.registerPluginAccount = registerPluginAccount;
|
|
1
|
+
const { CacheModel } = require('../models/cacheModel');
|
|
2
|
+
const { Op } = require('sequelize');
|
|
3
|
+
const axios = require('axios');
|
|
4
|
+
const { AccountDataModel } = require('../models/accountDataModel');
|
|
5
|
+
const logger = require('../lib/logger');
|
|
6
|
+
|
|
7
|
+
const PUBLIC_MANIFEST_BASE = 'https://appconnect.labs.ringcentral.com/public-api/connectors';
|
|
8
|
+
|
|
9
|
+
async function getPluginsFromRcAccountId({ rcAccountId }) {
|
|
10
|
+
const accountData = await AccountDataModel.findAll({
|
|
11
|
+
where: {
|
|
12
|
+
rcAccountId,
|
|
13
|
+
dataKey: 'pluginData',
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
const workingPlugins = accountData.map(data => ({
|
|
17
|
+
id: data.platformName,
|
|
18
|
+
data: data.data,
|
|
19
|
+
}));
|
|
20
|
+
return workingPlugins;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getPluginConfigFromUserSettings({ userSettings, pluginId }) {
|
|
24
|
+
if (!userSettings) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const targetPluginSettings = userSettings[`plugin_${pluginId}`];
|
|
28
|
+
if (!targetPluginSettings?.value?.config) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return targetPluginSettings.value.config;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function getPluginLicenseStatus({ rcAccountId, pluginId }) {
|
|
35
|
+
const accountData = await AccountDataModel.findOne({
|
|
36
|
+
where: {
|
|
37
|
+
rcAccountId,
|
|
38
|
+
platformName: pluginId,
|
|
39
|
+
dataKey: 'pluginData',
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
if (!accountData) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const licenseStatusUrl = accountData.data.licenseStatusUrl;
|
|
46
|
+
const licenseStatusResponse = await axios.get(licenseStatusUrl, {
|
|
47
|
+
headers: {
|
|
48
|
+
'Authorization': `Bearer ${accountData.data.jwtToken}`
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
return licenseStatusResponse.data;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function getPluginAsyncTasks({ asyncTaskIds }) {
|
|
55
|
+
const caches = await CacheModel.findAll({
|
|
56
|
+
where: {
|
|
57
|
+
id: {
|
|
58
|
+
[Op.in]: asyncTaskIds
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
const result = caches.map(cache => ({
|
|
63
|
+
cacheKey: cache.cacheKey,
|
|
64
|
+
status: cache.status
|
|
65
|
+
}));
|
|
66
|
+
const toRemoveCaches = caches.filter(cache => cache.status === 'completed' || cache.status === 'failed');
|
|
67
|
+
await CacheModel.destroy({
|
|
68
|
+
where: {
|
|
69
|
+
id: {
|
|
70
|
+
[Op.in]: toRemoveCaches.map(cache => cache.id)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getRefreshedJwtTokenFromHeaders({ headers }) {
|
|
78
|
+
if (!headers) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
return headers['x-refreshed-jwt-token'] || headers['X-Refreshed-Jwt-Token'] || null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function resolvePluginManifest({ pluginId, pluginAccess, rcAccountId, pluginName }) {
|
|
85
|
+
const manifestFetchers = [];
|
|
86
|
+
if (pluginAccess === 'public') {
|
|
87
|
+
manifestFetchers.push(`${PUBLIC_MANIFEST_BASE}/${pluginId}/manifest?type=plugin`);
|
|
88
|
+
} else if (pluginAccess === 'private' || pluginAccess === 'shared') {
|
|
89
|
+
manifestFetchers.push(`${PUBLIC_MANIFEST_BASE}/${pluginId}/manifest?access=internal&type=plugin&accountId=${rcAccountId}`);
|
|
90
|
+
} else {
|
|
91
|
+
manifestFetchers.push(`${PUBLIC_MANIFEST_BASE}/${pluginId}/manifest?type=plugin`);
|
|
92
|
+
manifestFetchers.push(`${PUBLIC_MANIFEST_BASE}/${pluginId}/manifest?access=internal&type=plugin&accountId=${rcAccountId}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let pluginData = null;
|
|
96
|
+
let lastError = null;
|
|
97
|
+
for (const url of manifestFetchers) {
|
|
98
|
+
try {
|
|
99
|
+
const pluginDataResponse = await axios.get(url);
|
|
100
|
+
pluginData = pluginDataResponse.data;
|
|
101
|
+
break;
|
|
102
|
+
} catch (error) {
|
|
103
|
+
lastError = error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!pluginData) {
|
|
108
|
+
throw lastError || new Error(`Unable to resolve manifest for plugin ${pluginId}`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const platformKey = pluginName || Object.keys(pluginData.platforms || {})[0];
|
|
112
|
+
if (!platformKey || !pluginData.platforms?.[platformKey]) {
|
|
113
|
+
throw new Error(`Unable to resolve platform manifest for plugin ${pluginId}`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
pluginData,
|
|
118
|
+
pluginManifest: pluginData.platforms[platformKey],
|
|
119
|
+
platformKey,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async function persistPluginData({ rcAccountId, pluginId, jwtToken, pluginData = {} }) {
|
|
124
|
+
try {
|
|
125
|
+
const accountData = await AccountDataModel.findOne({
|
|
126
|
+
where: {
|
|
127
|
+
rcAccountId,
|
|
128
|
+
platformName: pluginId
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
if (!accountData) {
|
|
132
|
+
await AccountDataModel.create({
|
|
133
|
+
rcAccountId,
|
|
134
|
+
platformName: pluginId,
|
|
135
|
+
dataKey: 'pluginData',
|
|
136
|
+
data: {
|
|
137
|
+
jwtToken,
|
|
138
|
+
...pluginData,
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
} else {
|
|
142
|
+
await accountData.update({
|
|
143
|
+
data: {
|
|
144
|
+
jwtToken,
|
|
145
|
+
...pluginData,
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
} catch (error) {
|
|
150
|
+
logger.error('Failed to persist plugin data', {
|
|
151
|
+
pluginId,
|
|
152
|
+
rcAccountId,
|
|
153
|
+
message: error.message,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function registerPluginAccount({ pluginId, rcAccessToken, rcAccountId, pluginAccess, pluginName }) {
|
|
159
|
+
const { pluginManifest } = await resolvePluginManifest({ pluginId, pluginAccess, rcAccountId, pluginName });
|
|
160
|
+
if (!pluginManifest?.endpointUrl) {
|
|
161
|
+
throw new Error(`Plugin endpoint URL not found for ${pluginId}`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const registerUrl = pluginManifest.userRegisterEndpointUrl;
|
|
165
|
+
const registerResponse = await axios.post(registerUrl, {
|
|
166
|
+
rcAccessToken,
|
|
167
|
+
rcAccountId: rcAccountId?.toString(),
|
|
168
|
+
});
|
|
169
|
+
const pluginJwtToken = registerResponse.data?.jwtToken;
|
|
170
|
+
if (!pluginJwtToken) {
|
|
171
|
+
throw new Error('Plugin register API did not return jwtToken');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
await persistPluginData({
|
|
175
|
+
rcAccountId: rcAccountId?.toString(),
|
|
176
|
+
pluginId,
|
|
177
|
+
jwtToken: pluginJwtToken,
|
|
178
|
+
pluginData: pluginManifest,
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
successful: true,
|
|
183
|
+
registerUrl,
|
|
184
|
+
jwtToken: pluginJwtToken,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async function unregisterPluginAccount({ pluginId, rcAccountId }) {
|
|
189
|
+
const accountData = await AccountDataModel.findOne({
|
|
190
|
+
where: {
|
|
191
|
+
rcAccountId,
|
|
192
|
+
platformName: pluginId,
|
|
193
|
+
dataKey: 'pluginData'
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
if (accountData) {
|
|
197
|
+
await accountData.destroy();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
exports.getPluginsFromRcAccountId = getPluginsFromRcAccountId;
|
|
202
|
+
exports.getPluginConfigFromUserSettings = getPluginConfigFromUserSettings;
|
|
203
|
+
exports.getPluginLicenseStatus = getPluginLicenseStatus;
|
|
204
|
+
exports.getPluginAsyncTasks = getPluginAsyncTasks;
|
|
205
|
+
exports.getRefreshedJwtTokenFromHeaders = getRefreshedJwtTokenFromHeaders;
|
|
206
|
+
exports.resolvePluginManifest = resolvePluginManifest;
|
|
207
|
+
exports.persistPluginData = persistPluginData;
|
|
208
|
+
exports.registerPluginAccount = registerPluginAccount;
|
|
209
209
|
exports.unregisterPluginAccount = unregisterPluginAccount;
|