@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/user.js
CHANGED
|
@@ -1,143 +1,143 @@
|
|
|
1
|
-
const axios = require('axios');
|
|
2
|
-
const { AdminConfigModel } = require('../models/adminConfigModel');
|
|
3
|
-
const { getHashValue } = require('../lib/util');
|
|
4
|
-
const connectorRegistry = require('../connector/registry');
|
|
5
|
-
const logger = require('../lib/logger');
|
|
6
|
-
const { handleDatabaseError } = require('../lib/errorHandler');
|
|
7
|
-
|
|
8
|
-
async function getUserSettingsByAdmin({ rcAccessToken, rcAccountId }) {
|
|
9
|
-
let hashedRcAccountId = null;
|
|
10
|
-
if (rcAccountId) {
|
|
11
|
-
hashedRcAccountId = rcAccountId;
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
const rcExtensionResponse = await axios.get(
|
|
15
|
-
'https://platform.ringcentral.com/restapi/v1.0/account/~/extension/~',
|
|
16
|
-
{
|
|
17
|
-
headers: {
|
|
18
|
-
Authorization: `Bearer ${rcAccessToken}`,
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
hashedRcAccountId = getHashValue(rcExtensionResponse.data.account.id, process.env.HASH_KEY);
|
|
22
|
-
}
|
|
23
|
-
const adminConfig = await AdminConfigModel.findByPk(hashedRcAccountId);
|
|
24
|
-
return {
|
|
25
|
-
userSettings: adminConfig?.userSettings
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async function getUserSettings({ user, rcAccessToken, rcAccountId }) {
|
|
30
|
-
let userSettingsByAdmin = [];
|
|
31
|
-
if (rcAccessToken || rcAccountId) {
|
|
32
|
-
try {
|
|
33
|
-
userSettingsByAdmin = await getUserSettingsByAdmin({ rcAccessToken, rcAccountId });
|
|
34
|
-
}
|
|
35
|
-
catch (e) {
|
|
36
|
-
logger.error('Error getting user settings by admin', { stack: e.stack });
|
|
37
|
-
userSettingsByAdmin = [];
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// For non-readonly admin settings, user use its own setting
|
|
42
|
-
let userSettings = await user?.userSettings;
|
|
43
|
-
let result = {};
|
|
44
|
-
if (!userSettingsByAdmin?.userSettings) {
|
|
45
|
-
result = userSettings;
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
if (!!userSettingsByAdmin?.userSettings && !!userSettings) {
|
|
49
|
-
const keys = Object.keys(userSettingsByAdmin.userSettings).concat(Object.keys(userSettings));
|
|
50
|
-
// distinct keys
|
|
51
|
-
for (const key of new Set(keys)) {
|
|
52
|
-
// marked as removed
|
|
53
|
-
if (userSettingsByAdmin.userSettings[key]?.isRemoved) {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
if ((userSettingsByAdmin.userSettings[key] === undefined || userSettingsByAdmin.userSettings[key].customizable) && userSettings[key] !== undefined) {
|
|
57
|
-
result[key] = {
|
|
58
|
-
customizable: true,
|
|
59
|
-
value: userSettings[key].value,
|
|
60
|
-
defaultValue: userSettings[key].defaultValue,
|
|
61
|
-
options: userSettings[key].options
|
|
62
|
-
};
|
|
63
|
-
// Special case: plugins
|
|
64
|
-
if (key.startsWith('plugin_')) {
|
|
65
|
-
const config = Object.keys(result[key].value.config)?.length === 0 ? null : result[key].value.config;
|
|
66
|
-
if (config) {
|
|
67
|
-
const configFromadminSettings = userSettingsByAdmin.userSettings[key].value.config ?? {};
|
|
68
|
-
for (const k in config) {
|
|
69
|
-
// use admin setting to replace, if not customizable
|
|
70
|
-
if (configFromadminSettings[k] && !configFromadminSettings[k].customizable || !config[k].value && configFromadminSettings[k].value) {
|
|
71
|
-
config[k] = configFromadminSettings[k];
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
config[k].customizable = configFromadminSettings[k]?.customizable ?? true;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
result[key].value.config = config;
|
|
78
|
-
}
|
|
79
|
-
//Case: no config at all, use admin setting directly
|
|
80
|
-
else {
|
|
81
|
-
result[key].value.config = userSettingsByAdmin.userSettings[key].value.config;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
// from admin settings
|
|
86
|
-
else {
|
|
87
|
-
result[key] = userSettingsByAdmin.userSettings[key];
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return result;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
async function updateUserSettings({ user, userSettings, settingKeysToRemove, platformName }) {
|
|
96
|
-
const keys = Object.keys(userSettings || {});
|
|
97
|
-
let updatedSettings = {
|
|
98
|
-
...(user.userSettings || {})
|
|
99
|
-
};
|
|
100
|
-
for (const k of keys) {
|
|
101
|
-
updatedSettings[k] = userSettings[k];
|
|
102
|
-
}
|
|
103
|
-
for (const k of settingKeysToRemove) {
|
|
104
|
-
if (updatedSettings[k]) {
|
|
105
|
-
delete updatedSettings[k];
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
const platformModule = connectorRegistry.getConnector(platformName);
|
|
109
|
-
if (platformModule.onUpdateUserSettings) {
|
|
110
|
-
const { successful, returnMessage } = await platformModule.onUpdateUserSettings({ user, userSettings, updatedSettings });
|
|
111
|
-
if (successful) {
|
|
112
|
-
try {
|
|
113
|
-
await user.update({
|
|
114
|
-
userSettings: updatedSettings
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
catch (error) {
|
|
118
|
-
return handleDatabaseError(error, 'Error updating user settings');
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
return {
|
|
122
|
-
successful,
|
|
123
|
-
returnMessage
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
try {
|
|
128
|
-
await user.update({
|
|
129
|
-
userSettings: updatedSettings
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
catch (error) {
|
|
133
|
-
return handleDatabaseError(error, 'Error updating user settings');
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return {
|
|
137
|
-
userSettings: user.userSettings
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
exports.getUserSettingsByAdmin = getUserSettingsByAdmin;
|
|
142
|
-
exports.getUserSettings = getUserSettings;
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const { AdminConfigModel } = require('../models/adminConfigModel');
|
|
3
|
+
const { getHashValue } = require('../lib/util');
|
|
4
|
+
const connectorRegistry = require('../connector/registry');
|
|
5
|
+
const logger = require('../lib/logger');
|
|
6
|
+
const { handleDatabaseError } = require('../lib/errorHandler');
|
|
7
|
+
|
|
8
|
+
async function getUserSettingsByAdmin({ rcAccessToken, rcAccountId }) {
|
|
9
|
+
let hashedRcAccountId = null;
|
|
10
|
+
if (rcAccountId) {
|
|
11
|
+
hashedRcAccountId = rcAccountId;
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
const rcExtensionResponse = await axios.get(
|
|
15
|
+
'https://platform.ringcentral.com/restapi/v1.0/account/~/extension/~',
|
|
16
|
+
{
|
|
17
|
+
headers: {
|
|
18
|
+
Authorization: `Bearer ${rcAccessToken}`,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
hashedRcAccountId = getHashValue(rcExtensionResponse.data.account.id, process.env.HASH_KEY);
|
|
22
|
+
}
|
|
23
|
+
const adminConfig = await AdminConfigModel.findByPk(hashedRcAccountId);
|
|
24
|
+
return {
|
|
25
|
+
userSettings: adminConfig?.userSettings
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function getUserSettings({ user, rcAccessToken, rcAccountId }) {
|
|
30
|
+
let userSettingsByAdmin = [];
|
|
31
|
+
if (rcAccessToken || rcAccountId) {
|
|
32
|
+
try {
|
|
33
|
+
userSettingsByAdmin = await getUserSettingsByAdmin({ rcAccessToken, rcAccountId });
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
logger.error('Error getting user settings by admin', { stack: e.stack });
|
|
37
|
+
userSettingsByAdmin = [];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// For non-readonly admin settings, user use its own setting
|
|
42
|
+
let userSettings = await user?.userSettings;
|
|
43
|
+
let result = {};
|
|
44
|
+
if (!userSettingsByAdmin?.userSettings) {
|
|
45
|
+
result = userSettings;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
if (!!userSettingsByAdmin?.userSettings && !!userSettings) {
|
|
49
|
+
const keys = Object.keys(userSettingsByAdmin.userSettings).concat(Object.keys(userSettings));
|
|
50
|
+
// distinct keys
|
|
51
|
+
for (const key of new Set(keys)) {
|
|
52
|
+
// marked as removed
|
|
53
|
+
if (userSettingsByAdmin.userSettings[key]?.isRemoved) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if ((userSettingsByAdmin.userSettings[key] === undefined || userSettingsByAdmin.userSettings[key].customizable) && userSettings[key] !== undefined) {
|
|
57
|
+
result[key] = {
|
|
58
|
+
customizable: true,
|
|
59
|
+
value: userSettings[key].value,
|
|
60
|
+
defaultValue: userSettings[key].defaultValue,
|
|
61
|
+
options: userSettings[key].options
|
|
62
|
+
};
|
|
63
|
+
// Special case: plugins
|
|
64
|
+
if (key.startsWith('plugin_')) {
|
|
65
|
+
const config = Object.keys(result[key].value.config)?.length === 0 ? null : result[key].value.config;
|
|
66
|
+
if (config) {
|
|
67
|
+
const configFromadminSettings = userSettingsByAdmin.userSettings[key].value.config ?? {};
|
|
68
|
+
for (const k in config) {
|
|
69
|
+
// use admin setting to replace, if not customizable
|
|
70
|
+
if (configFromadminSettings[k] && !configFromadminSettings[k].customizable || !config[k].value && configFromadminSettings[k].value) {
|
|
71
|
+
config[k] = configFromadminSettings[k];
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
config[k].customizable = configFromadminSettings[k]?.customizable ?? true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
result[key].value.config = config;
|
|
78
|
+
}
|
|
79
|
+
//Case: no config at all, use admin setting directly
|
|
80
|
+
else {
|
|
81
|
+
result[key].value.config = userSettingsByAdmin.userSettings[key].value.config;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// from admin settings
|
|
86
|
+
else {
|
|
87
|
+
result[key] = userSettingsByAdmin.userSettings[key];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function updateUserSettings({ user, userSettings, settingKeysToRemove, platformName }) {
|
|
96
|
+
const keys = Object.keys(userSettings || {});
|
|
97
|
+
let updatedSettings = {
|
|
98
|
+
...(user.userSettings || {})
|
|
99
|
+
};
|
|
100
|
+
for (const k of keys) {
|
|
101
|
+
updatedSettings[k] = userSettings[k];
|
|
102
|
+
}
|
|
103
|
+
for (const k of settingKeysToRemove) {
|
|
104
|
+
if (updatedSettings[k]) {
|
|
105
|
+
delete updatedSettings[k];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const platformModule = connectorRegistry.getConnector(platformName);
|
|
109
|
+
if (platformModule.onUpdateUserSettings) {
|
|
110
|
+
const { successful, returnMessage } = await platformModule.onUpdateUserSettings({ user, userSettings, updatedSettings });
|
|
111
|
+
if (successful) {
|
|
112
|
+
try {
|
|
113
|
+
await user.update({
|
|
114
|
+
userSettings: updatedSettings
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
return handleDatabaseError(error, 'Error updating user settings');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
successful,
|
|
123
|
+
returnMessage
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
try {
|
|
128
|
+
await user.update({
|
|
129
|
+
userSettings: updatedSettings
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
return handleDatabaseError(error, 'Error updating user settings');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
userSettings: user.userSettings
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
exports.getUserSettingsByAdmin = getUserSettingsByAdmin;
|
|
142
|
+
exports.getUserSettings = getUserSettings;
|
|
143
143
|
exports.updateUserSettings = updateUserSettings;
|