@app-connect/core 1.7.36 → 1.7.38
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/README.md +17 -16
- package/dist/connector/developerPortal.d.ts +6 -0
- package/{connector → dist/connector}/developerPortal.js +29 -12
- package/dist/connector/mock.d.ts +1 -0
- package/{connector → dist/connector}/mock.js +33 -17
- package/dist/connector/proxy/engine.d.ts +10 -0
- package/dist/connector/proxy/engine.js +222 -0
- package/dist/connector/proxy/index.d.ts +5 -0
- package/dist/connector/proxy/index.js +511 -0
- package/dist/connector/registry.d.ts +1 -0
- package/dist/connector/registry.js +243 -0
- package/dist/handlers/admin.d.ts +1 -0
- package/{handlers → dist/handlers}/admin.js +137 -78
- package/dist/handlers/appointment.d.ts +9 -0
- package/{handlers → dist/handlers}/appointment.js +58 -29
- package/dist/handlers/auth.d.ts +9 -0
- package/{handlers → dist/handlers}/auth.js +68 -40
- package/dist/handlers/calldown.d.ts +10 -0
- package/dist/handlers/calldown.js +134 -0
- package/dist/handlers/contact.d.ts +1 -0
- package/{handlers → dist/handlers}/contact.js +61 -39
- package/dist/handlers/disposition.d.ts +1 -0
- package/{handlers → dist/handlers}/disposition.js +20 -10
- package/dist/handlers/log.d.ts +1 -0
- package/{handlers → dist/handlers}/log.js +91 -124
- package/dist/handlers/managedAuth.d.ts +1 -0
- package/{handlers → dist/handlers}/managedAuth.js +134 -61
- package/dist/handlers/managedOAuth.d.ts +13 -0
- package/{handlers → dist/handlers}/managedOAuth.js +102 -30
- package/dist/handlers/plugin.d.ts +1 -0
- package/{handlers → dist/handlers}/plugin.js +59 -27
- package/dist/handlers/user.d.ts +1 -0
- package/{handlers → dist/handlers}/user.js +45 -27
- package/dist/index.d.ts +1 -0
- package/{index.js → dist/index.js} +548 -450
- package/dist/jest.config.d.ts +1 -0
- package/dist/jest.config.js +65 -0
- package/dist/lib/analytics.d.ts +4 -0
- package/{lib → dist/lib}/analytics.js +8 -6
- package/dist/lib/authSession.d.ts +5 -0
- package/{lib → dist/lib}/authSession.js +15 -43
- package/dist/lib/cacheCleanup.d.ts +4 -0
- package/{lib → dist/lib}/cacheCleanup.js +5 -17
- package/dist/lib/callLogComposer.d.ts +109 -0
- package/{lib → dist/lib}/callLogComposer.js +157 -197
- package/dist/lib/callLogLookup.d.ts +6 -0
- package/{lib → dist/lib}/callLogLookup.js +12 -34
- package/dist/lib/constants.d.ts +6 -0
- package/dist/lib/constants.js +9 -0
- package/dist/lib/debugTracer.d.ts +17 -0
- package/{lib → dist/lib}/debugTracer.js +7 -83
- package/dist/lib/encode.d.ts +3 -0
- package/dist/lib/encode.js +50 -0
- package/dist/lib/errorHandler.d.ts +7 -0
- package/dist/lib/errorHandler.js +161 -0
- package/dist/lib/generalErrorMessage.d.ts +7 -0
- package/{lib → dist/lib}/generalErrorMessage.js +6 -6
- package/dist/lib/jwt.d.ts +4 -0
- package/dist/lib/jwt.js +18 -0
- package/dist/lib/logger.d.ts +24 -0
- package/dist/lib/logger.js +126 -0
- package/dist/lib/migrateCallLogsSchema.d.ts +32 -0
- package/dist/lib/migrateCallLogsSchema.js +339 -0
- package/dist/lib/oauth.d.ts +4 -0
- package/{lib → dist/lib}/oauth.js +157 -160
- package/dist/lib/ringcentral.d.ts +24 -0
- package/dist/lib/ringcentral.js +226 -0
- package/dist/lib/s3ErrorLogReport.d.ts +4 -0
- package/{lib → dist/lib}/s3ErrorLogReport.js +11 -23
- package/dist/lib/sharedSMSComposer.d.ts +7 -0
- package/{lib → dist/lib}/sharedSMSComposer.js +21 -107
- package/dist/lib/util.d.ts +7 -0
- package/{lib → dist/lib}/util.js +9 -20
- package/dist/mcp/lib/oauthError.d.ts +1 -0
- package/dist/mcp/lib/oauthError.js +25 -0
- package/dist/mcp/lib/validator.d.ts +1 -0
- package/{mcp → dist/mcp}/lib/validator.js +16 -20
- package/dist/mcp/lib/widgetSessionToken.d.ts +1 -0
- package/dist/mcp/lib/widgetSessionToken.js +46 -0
- package/dist/mcp/mcpHandler.d.ts +8 -0
- package/{mcp → dist/mcp}/mcpHandler.js +98 -88
- package/dist/mcp/tools/cancelAppointment.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/cancelAppointment.js +7 -16
- package/dist/mcp/tools/checkAuthStatus.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/checkAuthStatus.js +21 -14
- package/dist/mcp/tools/confirmAppointment.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/confirmAppointment.js +7 -16
- package/dist/mcp/tools/createAppointment.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/createAppointment.js +7 -19
- package/dist/mcp/tools/createCallLog.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/createCallLog.js +18 -29
- package/dist/mcp/tools/createContact.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/createContact.js +8 -20
- package/dist/mcp/tools/createMessageLog.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/createMessageLog.js +14 -26
- package/dist/mcp/tools/doAuth.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/doAuth.js +17 -13
- package/dist/mcp/tools/findContactByName.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/findContactByName.js +9 -15
- package/dist/mcp/tools/findContactByPhone.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/findContactByPhone.js +8 -15
- package/dist/mcp/tools/getCallLog.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getCallLog.js +12 -21
- package/dist/mcp/tools/getGoogleFilePicker.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getGoogleFilePicker.js +9 -18
- package/dist/mcp/tools/getHelp.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getHelp.js +5 -6
- package/dist/mcp/tools/getPublicConnectors.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getPublicConnectors.js +19 -18
- package/dist/mcp/tools/getSessionInfo.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getSessionInfo.js +10 -16
- package/dist/mcp/tools/index.d.ts +8 -0
- package/dist/mcp/tools/index.js +50 -0
- package/dist/mcp/tools/listAppointments.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/listAppointments.js +7 -19
- package/dist/mcp/tools/logout.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/logout.js +16 -14
- package/dist/mcp/tools/rcGetCallLogs.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/rcGetCallLogs.js +10 -8
- package/dist/mcp/tools/updateAppointment.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/updateAppointment.js +17 -22
- package/dist/mcp/tools/updateCallLog.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/updateCallLog.js +16 -26
- package/dist/models/accountDataModel.d.ts +3 -0
- package/dist/models/accountDataModel.js +39 -0
- package/dist/models/adminConfigModel.d.ts +2 -0
- package/dist/models/adminConfigModel.js +39 -0
- package/dist/models/cacheModel.d.ts +2 -0
- package/{models → dist/models}/cacheModel.js +7 -3
- package/dist/models/callDownListModel.d.ts +2 -0
- package/{models → dist/models}/callDownListModel.js +8 -4
- package/dist/models/callLogModel.d.ts +2 -0
- package/dist/models/callLogModel.js +43 -0
- package/dist/models/dynamo/connectorSchema.d.ts +2 -0
- package/dist/models/dynamo/connectorSchema.js +141 -0
- package/dist/models/dynamo/lockSchema.d.ts +2 -0
- package/{models → dist/models}/dynamo/lockSchema.js +5 -7
- package/dist/models/dynamo/noteCacheSchema.d.ts +2 -0
- package/{models → dist/models}/dynamo/noteCacheSchema.js +4 -6
- package/dist/models/llmSessionModel.d.ts +2 -0
- package/dist/models/llmSessionModel.js +21 -0
- package/dist/models/messageLogModel.d.ts +2 -0
- package/{models → dist/models}/messageLogModel.js +8 -4
- package/dist/models/sequelize.d.ts +2 -0
- package/dist/models/sequelize.js +68 -0
- package/dist/models/userModel.d.ts +2 -0
- package/dist/models/userModel.js +49 -0
- package/dist/package.json +100 -0
- package/dist/releaseNotes.json +1222 -0
- package/dist/tsconfig.json +14 -0
- package/dist/types/admin.d.ts +141 -0
- package/dist/types/analytics.d.ts +14 -0
- package/dist/types/appointment.d.ts +50 -0
- package/dist/types/auth.d.ts +137 -0
- package/dist/types/authSession.d.ts +35 -0
- package/dist/types/cacheCleanup.d.ts +12 -0
- package/dist/types/calldown.d.ts +54 -0
- package/dist/types/common.d.ts +46 -0
- package/dist/types/connector.d.ts +165 -0
- package/dist/types/contact.d.ts +125 -0
- package/dist/types/errorHandler.d.ts +60 -0
- package/dist/types/index.d.ts +76 -0
- package/dist/types/json.d.ts +9 -0
- package/dist/types/jwt.d.ts +8 -0
- package/dist/types/logging.d.ts +224 -0
- package/dist/types/managedAuth.d.ts +114 -0
- package/dist/types/managedOAuth.d.ts +59 -0
- package/dist/types/manifest.d.ts +120 -0
- package/dist/types/migration.d.ts +15 -0
- package/dist/types/plugin.d.ts +74 -0
- package/dist/types/ringcentral.d.ts +61 -0
- package/dist/types/s3ErrorLogReport.d.ts +16 -0
- package/dist/types/sharedSMSComposer.d.ts +105 -0
- package/dist/types/user.d.ts +46 -0
- package/dist/types/util.d.ts +7 -0
- package/package.json +34 -6
- package/releaseNotes.json +13 -1
- package/.env.test +0 -5
- package/connector/proxy/engine.js +0 -165
- package/connector/proxy/index.js +0 -500
- package/connector/registry.js +0 -252
- package/docs/README.md +0 -50
- package/docs/architecture.md +0 -94
- package/docs/connectors.md +0 -116
- package/docs/handlers.md +0 -128
- package/docs/libraries.md +0 -98
- package/docs/models.md +0 -146
- package/docs/routes.md +0 -119
- package/docs/tests.md +0 -73
- package/handlers/calldown.js +0 -99
- package/jest.config.js +0 -57
- package/lib/constants.js +0 -9
- package/lib/encode.js +0 -30
- package/lib/errorHandler.js +0 -218
- package/lib/jwt.js +0 -18
- package/lib/logger.js +0 -190
- package/lib/migrateCallLogsSchema.js +0 -237
- package/lib/ringcentral.js +0 -267
- package/mcp/README.md +0 -420
- package/mcp/tools/index.js +0 -51
- package/mcp/ui/App/App.tsx +0 -358
- package/mcp/ui/App/components/AuthInfoForm.tsx +0 -113
- package/mcp/ui/App/components/AuthSuccess.tsx +0 -22
- package/mcp/ui/App/components/ConnectorList.tsx +0 -82
- package/mcp/ui/App/components/DebugPanel.tsx +0 -43
- package/mcp/ui/App/components/OAuthConnect.tsx +0 -270
- package/mcp/ui/App/lib/callTool.ts +0 -130
- package/mcp/ui/App/lib/debugLog.ts +0 -41
- package/mcp/ui/App/lib/developerPortal.ts +0 -111
- package/mcp/ui/App/main.css +0 -6
- package/mcp/ui/App/root.tsx +0 -13
- package/mcp/ui/dist/index.html +0 -53
- package/mcp/ui/vite.config.ts +0 -16
- package/models/accountDataModel.js +0 -34
- package/models/adminConfigModel.js +0 -35
- package/models/callLogModel.js +0 -39
- package/models/dynamo/connectorSchema.js +0 -146
- package/models/llmSessionModel.js +0 -17
- package/models/sequelize.js +0 -17
- package/models/userModel.js +0 -45
- package/test/connector/developerPortal.test.js +0 -166
- package/test/connector/mock.test.js +0 -131
- package/test/connector/proxy/engine.test.js +0 -211
- package/test/connector/proxy/index.test.js +0 -525
- package/test/connector/proxy/sample.json +0 -162
- package/test/connector/registry.test.js +0 -416
- package/test/handlers/admin.test.js +0 -960
- package/test/handlers/appointment.test.js +0 -260
- package/test/handlers/auth.test.js +0 -1096
- package/test/handlers/calldown.test.js +0 -310
- package/test/handlers/contact.test.js +0 -1014
- package/test/handlers/disposition.test.js +0 -396
- package/test/handlers/log.test.js +0 -1847
- package/test/handlers/managedAuth.test.js +0 -458
- package/test/handlers/managedOAuth.test.js +0 -262
- package/test/handlers/plugin.test.js +0 -429
- package/test/handlers/user.test.js +0 -381
- package/test/index.test.js +0 -301
- package/test/lib/analytics.test.js +0 -146
- package/test/lib/authSession.test.js +0 -173
- package/test/lib/cacheCleanup.test.js +0 -127
- package/test/lib/callLogComposer.test.js +0 -1231
- package/test/lib/debugTracer.test.js +0 -328
- package/test/lib/encode.test.js +0 -59
- package/test/lib/errorHandler.test.js +0 -246
- package/test/lib/generalErrorMessage.test.js +0 -82
- package/test/lib/jwt.test.js +0 -176
- package/test/lib/logger.test.js +0 -206
- package/test/lib/oauth.test.js +0 -359
- package/test/lib/ringcentral.test.js +0 -467
- package/test/lib/s3ErrorLogReport.test.js +0 -187
- package/test/lib/sharedSMSComposer.test.js +0 -1084
- package/test/lib/util.test.js +0 -329
- package/test/mcp/mcpHandler.test.js +0 -73
- package/test/mcp/mcpHandlerMore.test.js +0 -384
- package/test/mcp/tools/appointmentTools.test.js +0 -362
- package/test/mcp/tools/checkAuthStatus.test.js +0 -83
- package/test/mcp/tools/createCallLog.test.js +0 -436
- package/test/mcp/tools/createContact.test.js +0 -58
- package/test/mcp/tools/createMessageLog.test.js +0 -595
- package/test/mcp/tools/doAuth.test.js +0 -113
- package/test/mcp/tools/findContactByName.test.js +0 -275
- package/test/mcp/tools/findContactByPhone.test.js +0 -296
- package/test/mcp/tools/getCallLog.test.js +0 -298
- package/test/mcp/tools/getGoogleFilePicker.test.js +0 -281
- package/test/mcp/tools/getPublicConnectors.test.js +0 -107
- package/test/mcp/tools/getSessionInfo.test.js +0 -127
- package/test/mcp/tools/logout.test.js +0 -233
- package/test/mcp/tools/rcGetCallLogs.test.js +0 -56
- package/test/mcp/tools/updateCallLog.test.js +0 -360
- package/test/models/accountDataModel.test.js +0 -98
- package/test/models/callDownListModel.test.js +0 -125
- package/test/models/dynamo/connectorSchema.test.js +0 -189
- package/test/models/dynamo/lockSchema.test.js +0 -37
- package/test/models/dynamo/noteCacheSchema.test.js +0 -45
- package/test/models/llmSessionModel.test.js +0 -91
- package/test/models/models.test.js +0 -660
- package/test/routes/calldownRoutes.test.js +0 -224
- package/test/routes/coreRouterBroadRoutes.test.js +0 -855
- package/test/routes/dispositionRoutes.test.js +0 -192
- package/test/routes/managedAuthRoutes.test.js +0 -386
- package/test/routes/pluginRoutes.test.js +0 -262
- package/test/setup.js +0 -178
- /package/{mcp → dist/mcp}/ui/index.html +0 -0
- /package/{mcp → dist/mcp}/ui/package-lock.json +0 -0
- /package/{mcp → dist/mcp}/ui/package.json +0 -0
- /package/{mcp → dist/mcp}/ui/tsconfig.json +0 -0
|
@@ -1,54 +1,58 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
// @ts-check
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const express = /** @type {any} */ (require('express'));
|
|
5
|
+
const cors = /** @type {any} */ (require('cors'));
|
|
6
|
+
const bodyParser = /** @type {any} */ (require('body-parser'));
|
|
4
7
|
require('body-parser-xml')(bodyParser);
|
|
5
|
-
const dynamoose = require('dynamoose');
|
|
6
|
-
const { DynamoDB } = require('@aws-sdk/client-dynamodb');
|
|
7
|
-
const axios = require('axios');
|
|
8
|
-
const { UserModel } = require('./models/userModel');
|
|
9
|
-
const { LlmSessionModel } = require('./models/llmSessionModel');
|
|
10
|
-
const { CallDownListModel } = require('./models/callDownListModel');
|
|
11
|
-
const { CallLogModel } = require('./models/callLogModel');
|
|
12
|
-
const { MessageLogModel } = require('./models/messageLogModel');
|
|
13
|
-
const { AdminConfigModel } = require('./models/adminConfigModel');
|
|
14
|
-
const { CacheModel } = require('./models/cacheModel');
|
|
15
|
-
const { AccountDataModel } = require('./models/accountDataModel');
|
|
16
|
-
const jwt = require('./lib/jwt');
|
|
17
|
-
const logCore = require('./handlers/log');
|
|
18
|
-
const contactCore = require('./handlers/contact');
|
|
19
|
-
const appointmentCore = require('./handlers/appointment');
|
|
20
|
-
const authCore = require('./handlers/auth');
|
|
21
|
-
const adminCore = require('./handlers/admin');
|
|
22
|
-
const userCore = require('./handlers/user');
|
|
23
|
-
const dispositionCore = require('./handlers/disposition');
|
|
24
|
-
const mock = require('./connector/mock');
|
|
25
|
-
const proxyConnector = require('./connector/proxy');
|
|
8
|
+
const dynamoose = /** @type {any} */ (require('dynamoose'));
|
|
9
|
+
const { DynamoDB } = /** @type {any} */ (require('@aws-sdk/client-dynamodb'));
|
|
10
|
+
const axios = /** @type {any} */ (require('axios'));
|
|
11
|
+
const { UserModel } = /** @type {any} */ (require('./models/userModel'));
|
|
12
|
+
const { LlmSessionModel } = /** @type {any} */ (require('./models/llmSessionModel'));
|
|
13
|
+
const { CallDownListModel } = /** @type {any} */ (require('./models/callDownListModel'));
|
|
14
|
+
const { CallLogModel } = /** @type {any} */ (require('./models/callLogModel'));
|
|
15
|
+
const { MessageLogModel } = /** @type {any} */ (require('./models/messageLogModel'));
|
|
16
|
+
const { AdminConfigModel } = /** @type {any} */ (require('./models/adminConfigModel'));
|
|
17
|
+
const { CacheModel } = /** @type {any} */ (require('./models/cacheModel'));
|
|
18
|
+
const { AccountDataModel } = /** @type {any} */ (require('./models/accountDataModel'));
|
|
19
|
+
const jwt = /** @type {any} */ (require('./lib/jwt'));
|
|
20
|
+
const logCore = /** @type {any} */ (require('./handlers/log'));
|
|
21
|
+
const contactCore = /** @type {any} */ (require('./handlers/contact'));
|
|
22
|
+
const appointmentCore = /** @type {any} */ (require('./handlers/appointment'));
|
|
23
|
+
const authCore = /** @type {any} */ (require('./handlers/auth'));
|
|
24
|
+
const adminCore = /** @type {any} */ (require('./handlers/admin'));
|
|
25
|
+
const userCore = /** @type {any} */ (require('./handlers/user'));
|
|
26
|
+
const dispositionCore = /** @type {any} */ (require('./handlers/disposition'));
|
|
27
|
+
const mock = /** @type {any} */ (require('./connector/mock'));
|
|
28
|
+
const proxyConnector = /** @type {any} */ (require('./connector/proxy'));
|
|
26
29
|
const releaseNotes = require('./releaseNotes.json');
|
|
27
|
-
const analytics = require('./lib/analytics');
|
|
28
|
-
const util = require('./lib/util');
|
|
29
|
-
const connectorRegistry = require('./connector/registry');
|
|
30
|
-
const calldown = require('./handlers/calldown');
|
|
31
|
-
const mcpHandler = require('./mcp/mcpHandler');
|
|
32
|
-
const logger = require('./lib/logger');
|
|
33
|
-
const { DebugTracer } = require('./lib/debugTracer');
|
|
34
|
-
const s3ErrorLogReport = require('./lib/s3ErrorLogReport');
|
|
35
|
-
const pluginCore = require('./handlers/plugin');
|
|
36
|
-
const { sequelize } = require('./models/sequelize');
|
|
37
|
-
const {
|
|
38
|
-
const { handleDatabaseError } = require('./lib/errorHandler');
|
|
39
|
-
const { updateAuthSession } = require('./lib/authSession');
|
|
40
|
-
const managedAuthCore = require('./handlers/managedAuth');
|
|
41
|
-
const managedOAuthCore = require('./handlers/managedOAuth');
|
|
42
|
-
|
|
30
|
+
const analytics = /** @type {any} */ (require('./lib/analytics'));
|
|
31
|
+
const util = /** @type {any} */ (require('./lib/util'));
|
|
32
|
+
const connectorRegistry = /** @type {any} */ (require('./connector/registry'));
|
|
33
|
+
const calldown = /** @type {any} */ (require('./handlers/calldown'));
|
|
34
|
+
const mcpHandler = /** @type {any} */ (require('./mcp/mcpHandler'));
|
|
35
|
+
const logger = /** @type {any} */ (require('./lib/logger'));
|
|
36
|
+
const { DebugTracer } = /** @type {any} */ (require('./lib/debugTracer'));
|
|
37
|
+
const s3ErrorLogReport = /** @type {any} */ (require('./lib/s3ErrorLogReport'));
|
|
38
|
+
const pluginCore = /** @type {any} */ (require('./handlers/plugin'));
|
|
39
|
+
const { sequelize } = /** @type {any} */ (require('./models/sequelize'));
|
|
40
|
+
const { runCallLogsSchemaMigration } = /** @type {any} */ (require('./lib/migrateCallLogsSchema'));
|
|
41
|
+
const { handleDatabaseError } = /** @type {any} */ (require('./lib/errorHandler'));
|
|
42
|
+
const { updateAuthSession } = /** @type {any} */ (require('./lib/authSession'));
|
|
43
|
+
const managedAuthCore = /** @type {any} */ (require('./handlers/managedAuth'));
|
|
44
|
+
const managedOAuthCore = /** @type {any} */ (require('./handlers/managedOAuth'));
|
|
45
|
+
const { MCP_OAUTH_REQUIRED_MESSAGE, MCP_OAUTH_STALE_CLIENT_MESSAGE, getMcpOAuthChallengeHeader, buildMcpOAuthError, } = /** @type {any} */ (require('./mcp/lib/oauthError'));
|
|
46
|
+
/** @type {any} */
|
|
43
47
|
let packageJson = null;
|
|
44
48
|
try {
|
|
45
49
|
packageJson = require('./package.json');
|
|
46
50
|
}
|
|
47
51
|
catch (e) {
|
|
48
52
|
logger.error('Error loading package.json', { stack: e.stack });
|
|
49
|
-
|
|
53
|
+
const fallbackPackageJsonPath = '../package.json';
|
|
54
|
+
packageJson = require(fallbackPackageJsonPath);
|
|
50
55
|
}
|
|
51
|
-
|
|
52
56
|
// For using dynamodb in local env
|
|
53
57
|
// AWS SDK v3 requires a region even for local; ddb.local() omits it, so set manually.
|
|
54
58
|
if (process.env.DYNAMODB_LOCALHOST) {
|
|
@@ -66,14 +70,12 @@ if (process.env.IS_PROD === 'false') {
|
|
|
66
70
|
});
|
|
67
71
|
}
|
|
68
72
|
axios.defaults.headers.common['Unified-CRM-Extension-Version'] = packageJson.version;
|
|
69
|
-
|
|
70
73
|
async function initDB() {
|
|
71
74
|
if (!process.env.DISABLE_SYNC_DB_TABLE) {
|
|
72
75
|
logger.info('creating db tables if not exist...');
|
|
73
76
|
await UserModel.sync();
|
|
74
77
|
await LlmSessionModel.sync();
|
|
75
78
|
await CallLogModel.sync();
|
|
76
|
-
await ensureCallLogsHashedExtensionIdSchema(sequelize);
|
|
77
79
|
await MessageLogModel.sync();
|
|
78
80
|
await AdminConfigModel.sync();
|
|
79
81
|
await CacheModel.sync();
|
|
@@ -81,7 +83,6 @@ async function initDB() {
|
|
|
81
83
|
await AccountDataModel.sync();
|
|
82
84
|
}
|
|
83
85
|
}
|
|
84
|
-
|
|
85
86
|
function getAnalyticsVariablesInReqHeaders({ headers }) {
|
|
86
87
|
const hashedExtensionId = headers['rc-extension-id'];
|
|
87
88
|
const hashedAccountId = headers['rc-account-id'];
|
|
@@ -96,12 +97,10 @@ function getAnalyticsVariablesInReqHeaders({ headers }) {
|
|
|
96
97
|
userAgent,
|
|
97
98
|
author,
|
|
98
99
|
eventAddedVia
|
|
99
|
-
}
|
|
100
|
+
};
|
|
100
101
|
}
|
|
101
|
-
|
|
102
102
|
const JWT_REFRESH_THRESHOLD_SECONDS = 7 * 24 * 60 * 60; // 1 week
|
|
103
103
|
const JWT_LEGACY_LONG_LIVED_THRESHOLD_SECONDS = 365 * 24 * 60 * 60; // 1 year
|
|
104
|
-
|
|
105
104
|
function getBearerTokenFromRequest(req) {
|
|
106
105
|
const authHeader = req.headers?.authorization || req.headers?.Authorization;
|
|
107
106
|
if (!authHeader || typeof authHeader !== 'string') {
|
|
@@ -113,7 +112,49 @@ function getBearerTokenFromRequest(req) {
|
|
|
113
112
|
}
|
|
114
113
|
return token;
|
|
115
114
|
}
|
|
116
|
-
|
|
115
|
+
function normalizeTokenValue(value) {
|
|
116
|
+
const token = Array.isArray(value) ? value[0] : value;
|
|
117
|
+
if (typeof token !== 'string') {
|
|
118
|
+
return token || null;
|
|
119
|
+
}
|
|
120
|
+
const trimmedToken = token.trim();
|
|
121
|
+
return trimmedToken.toLowerCase().startsWith('bearer ')
|
|
122
|
+
? trimmedToken.slice('bearer '.length).trim()
|
|
123
|
+
: trimmedToken;
|
|
124
|
+
}
|
|
125
|
+
function wrapDebugResponse(tracer, payload) {
|
|
126
|
+
if (tracer) {
|
|
127
|
+
return tracer.wrapResponse(payload);
|
|
128
|
+
}
|
|
129
|
+
return payload;
|
|
130
|
+
}
|
|
131
|
+
function getErrorResponse(e) {
|
|
132
|
+
if (e && e.message) {
|
|
133
|
+
return e.message;
|
|
134
|
+
}
|
|
135
|
+
return e;
|
|
136
|
+
}
|
|
137
|
+
function getRcAccessTokenFromRequest(req) {
|
|
138
|
+
return normalizeTokenValue(req.get?.('X-RC-Access-Token')
|
|
139
|
+
|| req.headers?.['x-rc-access-token']
|
|
140
|
+
|| req.body?.rcAccessToken
|
|
141
|
+
|| req.query?.rcAccessToken);
|
|
142
|
+
}
|
|
143
|
+
function getFirstQueryValue(value) {
|
|
144
|
+
if (Array.isArray(value)) {
|
|
145
|
+
return value[0];
|
|
146
|
+
}
|
|
147
|
+
if (value === undefined || value === null) {
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
return value.toString();
|
|
151
|
+
}
|
|
152
|
+
function appendOAuthQueryParam(params, name, value) {
|
|
153
|
+
const normalizedValue = getFirstQueryValue(value);
|
|
154
|
+
if (normalizedValue) {
|
|
155
|
+
params.set(name, normalizedValue);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
117
158
|
function normalizeJwtFromRequest(req, res, next) {
|
|
118
159
|
if (req.path?.startsWith('/mcp')) {
|
|
119
160
|
return next();
|
|
@@ -122,19 +163,15 @@ function normalizeJwtFromRequest(req, res, next) {
|
|
|
122
163
|
const queryToken = req.query?.jwtToken;
|
|
123
164
|
let bearerToken = originalBearerToken;
|
|
124
165
|
const isQueryAuth = !originalBearerToken && !!queryToken;
|
|
125
|
-
|
|
126
166
|
// Backward compatibility: promote query jwtToken to Authorization Bearer.
|
|
127
167
|
if (isQueryAuth) {
|
|
128
168
|
req.headers.authorization = `Bearer ${queryToken}`;
|
|
129
169
|
bearerToken = queryToken;
|
|
130
170
|
}
|
|
131
|
-
|
|
132
171
|
const token = bearerToken;
|
|
133
|
-
|
|
134
172
|
if (!token) {
|
|
135
173
|
return next();
|
|
136
174
|
}
|
|
137
|
-
|
|
138
175
|
const decodedToken = jwt.decodeJwt(token);
|
|
139
176
|
if (!decodedToken?.id) {
|
|
140
177
|
req.invalidJwtToken = true;
|
|
@@ -143,10 +180,8 @@ function normalizeJwtFromRequest(req, res, next) {
|
|
|
143
180
|
}
|
|
144
181
|
return next();
|
|
145
182
|
}
|
|
146
|
-
|
|
147
183
|
req.jwtToken = token;
|
|
148
184
|
req.jwtAuth = decodedToken;
|
|
149
|
-
|
|
150
185
|
if (typeof decodedToken.exp === 'number') {
|
|
151
186
|
const now = Math.floor(Date.now() / 1000);
|
|
152
187
|
const timeLeft = decodedToken.exp - now;
|
|
@@ -167,12 +202,10 @@ function normalizeJwtFromRequest(req, res, next) {
|
|
|
167
202
|
}
|
|
168
203
|
return next();
|
|
169
204
|
}
|
|
170
|
-
|
|
171
205
|
// Create a router with all core routes
|
|
172
206
|
function createCoreRouter() {
|
|
173
207
|
const router = express.Router();
|
|
174
208
|
router.use(normalizeJwtFromRequest);
|
|
175
|
-
|
|
176
209
|
// Move all app.get, app.post, etc. to router.get, router.post, etc.
|
|
177
210
|
router.get('/releaseNotes', async function (req, res) {
|
|
178
211
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
@@ -187,7 +220,7 @@ function createCoreRouter() {
|
|
|
187
220
|
...connectorReleaseNotes[version] ?? {}
|
|
188
221
|
};
|
|
189
222
|
}
|
|
190
|
-
res.json(tracer
|
|
223
|
+
res.json(wrapDebugResponse(tracer, mergedReleaseNotes ?? {}));
|
|
191
224
|
});
|
|
192
225
|
// Obsolete
|
|
193
226
|
router.get('/crmManifest', (req, res) => {
|
|
@@ -265,17 +298,17 @@ function createCoreRouter() {
|
|
|
265
298
|
result.getLogFormatType = !!platformModule.getLogFormatType;
|
|
266
299
|
result.refreshUserInfo = !!platformModule.refreshUserInfo;
|
|
267
300
|
result.cacheCallNote = !!process.env.USE_CACHE;
|
|
268
|
-
res.status(200).send(tracer
|
|
301
|
+
res.status(200).send(wrapDebugResponse(tracer, result));
|
|
269
302
|
}
|
|
270
303
|
else {
|
|
271
304
|
tracer?.trace('implementedInterfaces:noPlatform', {});
|
|
272
|
-
res.status(400).send(tracer
|
|
305
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please provide platform.'));
|
|
273
306
|
return;
|
|
274
307
|
}
|
|
275
308
|
}
|
|
276
309
|
catch (e) {
|
|
277
310
|
tracer?.traceError('implementedInterfaces:error', e);
|
|
278
|
-
res.status(400).send(tracer
|
|
311
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
279
312
|
}
|
|
280
313
|
});
|
|
281
314
|
router.get('/licenseStatus', async (req, res) => {
|
|
@@ -285,14 +318,14 @@ function createCoreRouter() {
|
|
|
285
318
|
let platformName = null;
|
|
286
319
|
let success = false;
|
|
287
320
|
let extraData = {};
|
|
288
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
321
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
289
322
|
try {
|
|
290
323
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
291
324
|
if (jwtToken) {
|
|
292
325
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
293
326
|
if (!decodedToken) {
|
|
294
327
|
tracer?.trace('licenseStatus:invalidJwtToken', {});
|
|
295
|
-
res.status(400).send(tracer
|
|
328
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Invalid JWT token'));
|
|
296
329
|
success = false;
|
|
297
330
|
return;
|
|
298
331
|
}
|
|
@@ -300,36 +333,28 @@ function createCoreRouter() {
|
|
|
300
333
|
platformName = platform;
|
|
301
334
|
if (!userId) {
|
|
302
335
|
tracer?.trace('licenseStatus:noUserId', {});
|
|
303
|
-
res.status(400).send(tracer
|
|
336
|
+
res.status(400).send(wrapDebugResponse(tracer, 'No user ID'));
|
|
304
337
|
success = true;
|
|
305
338
|
}
|
|
306
339
|
const licenseStatus = await authCore.getLicenseStatus({ userId, platform });
|
|
307
|
-
res.status(200).send(tracer
|
|
340
|
+
res.status(200).send(wrapDebugResponse(tracer, licenseStatus));
|
|
308
341
|
success = true;
|
|
309
342
|
}
|
|
310
343
|
else {
|
|
311
|
-
res.status(200).send(tracer
|
|
312
|
-
isLicenseValid: false,
|
|
313
|
-
licenseStatus: 'Invalid (Invalid user session)',
|
|
314
|
-
licenseStatusDescription: ''
|
|
315
|
-
}) : {
|
|
344
|
+
res.status(200).send(wrapDebugResponse(tracer, {
|
|
316
345
|
isLicenseValid: false,
|
|
317
346
|
licenseStatus: 'Invalid (Invalid user session)',
|
|
318
347
|
licenseStatusDescription: ''
|
|
319
|
-
});
|
|
348
|
+
}));
|
|
320
349
|
success = true;
|
|
321
350
|
}
|
|
322
351
|
}
|
|
323
352
|
catch (e) {
|
|
324
|
-
res.status(200).send(tracer
|
|
353
|
+
res.status(200).send(wrapDebugResponse(tracer, {
|
|
325
354
|
isLicenseValid: false,
|
|
326
355
|
licenseStatus: 'Invalid (Connect to get license status)',
|
|
327
356
|
licenseStatusDescription: ''
|
|
328
|
-
})
|
|
329
|
-
isLicenseValid: false,
|
|
330
|
-
licenseStatus: 'Invalid (Connect to get license status)',
|
|
331
|
-
licenseStatusDescription: ''
|
|
332
|
-
});
|
|
357
|
+
}));
|
|
333
358
|
success = false;
|
|
334
359
|
}
|
|
335
360
|
const requestEndTime = new Date().getTime();
|
|
@@ -359,14 +384,14 @@ function createCoreRouter() {
|
|
|
359
384
|
let validationPass = false;
|
|
360
385
|
let reason = '';
|
|
361
386
|
let statusCode = 200;
|
|
362
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
387
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
363
388
|
try {
|
|
364
389
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
365
390
|
if (jwtToken) {
|
|
366
391
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
367
392
|
if (!decodedToken) {
|
|
368
393
|
tracer?.trace('authValidation:invalidJwtToken', {});
|
|
369
|
-
res.status(400).send(tracer
|
|
394
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Invalid JWT token'));
|
|
370
395
|
return;
|
|
371
396
|
}
|
|
372
397
|
const { id: userId, platform } = decodedToken;
|
|
@@ -376,11 +401,11 @@ function createCoreRouter() {
|
|
|
376
401
|
validationPass = successful;
|
|
377
402
|
reason = failReason;
|
|
378
403
|
statusCode = status;
|
|
379
|
-
res.status(200).send(tracer
|
|
404
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
380
405
|
}
|
|
381
406
|
else {
|
|
382
407
|
tracer?.trace('authValidation:noToken', {});
|
|
383
|
-
res.status(400).send(tracer
|
|
408
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
384
409
|
success = false;
|
|
385
410
|
}
|
|
386
411
|
}
|
|
@@ -388,7 +413,7 @@ function createCoreRouter() {
|
|
|
388
413
|
logger.error('Auth validation failed', { platform: platformName, stack: e.stack });
|
|
389
414
|
tracer?.traceError('authValidation:error', e);
|
|
390
415
|
statusCode = e.response?.status ?? 'unknown';
|
|
391
|
-
res.status(400).send(tracer
|
|
416
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
392
417
|
success = false;
|
|
393
418
|
}
|
|
394
419
|
const requestEndTime = new Date().getTime();
|
|
@@ -416,13 +441,13 @@ function createCoreRouter() {
|
|
|
416
441
|
tracer?.trace('apiKeyManagedAuthState:start', { query: req.query });
|
|
417
442
|
try {
|
|
418
443
|
const platform = req.query.platform;
|
|
419
|
-
const rcAccessToken = req
|
|
444
|
+
const rcAccessToken = getRcAccessTokenFromRequest(req);
|
|
420
445
|
if (!platform) {
|
|
421
|
-
res.status(400).send(tracer
|
|
446
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Missing platform name'));
|
|
422
447
|
return;
|
|
423
448
|
}
|
|
424
449
|
if (!rcAccessToken) {
|
|
425
|
-
res.status(400).send(tracer
|
|
450
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Missing RingCentral access token'));
|
|
426
451
|
return;
|
|
427
452
|
}
|
|
428
453
|
const { rcAccountId, rcExtensionId } = await adminCore.validateRcUserToken({ rcAccessToken });
|
|
@@ -433,12 +458,12 @@ function createCoreRouter() {
|
|
|
433
458
|
connectorId: req.query.connectorId,
|
|
434
459
|
isPrivate: req.query.isPrivate === 'true'
|
|
435
460
|
});
|
|
436
|
-
res.status(200).send(tracer
|
|
461
|
+
res.status(200).send(wrapDebugResponse(tracer, managedAuthState));
|
|
437
462
|
}
|
|
438
463
|
catch (e) {
|
|
439
464
|
logger.error('Get API key managed auth state failed', { stack: e.stack });
|
|
440
465
|
tracer?.traceError('apiKeyManagedAuthState:error', e);
|
|
441
|
-
res.status(400).send(tracer
|
|
466
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
442
467
|
}
|
|
443
468
|
});
|
|
444
469
|
router.get('/oauthManagedAuthState', async function (req, res) {
|
|
@@ -446,13 +471,13 @@ function createCoreRouter() {
|
|
|
446
471
|
tracer?.trace('oauthManagedAuthState:start', { query: req.query });
|
|
447
472
|
try {
|
|
448
473
|
const platform = req.query.platform;
|
|
449
|
-
const rcAccessToken = req
|
|
474
|
+
const rcAccessToken = getRcAccessTokenFromRequest(req);
|
|
450
475
|
if (!platform) {
|
|
451
|
-
res.status(400).send(tracer
|
|
476
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Missing platform name'));
|
|
452
477
|
return;
|
|
453
478
|
}
|
|
454
479
|
if (!rcAccessToken) {
|
|
455
|
-
res.status(400).send(tracer
|
|
480
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Missing RingCentral access token'));
|
|
456
481
|
return;
|
|
457
482
|
}
|
|
458
483
|
const { rcAccountId } = await adminCore.validateRcUserToken({ rcAccessToken });
|
|
@@ -462,12 +487,12 @@ function createCoreRouter() {
|
|
|
462
487
|
rcAccountId,
|
|
463
488
|
isAdmin: !!adminValidation.isValidated
|
|
464
489
|
});
|
|
465
|
-
res.status(200).send(tracer
|
|
490
|
+
res.status(200).send(wrapDebugResponse(tracer, state));
|
|
466
491
|
}
|
|
467
492
|
catch (e) {
|
|
468
493
|
logger.error('Get managed OAuth state failed', { stack: e.stack });
|
|
469
494
|
tracer?.traceError('oauthManagedAuthState:error', e);
|
|
470
|
-
res.status(400).send(tracer
|
|
495
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
471
496
|
}
|
|
472
497
|
});
|
|
473
498
|
// Obsolete
|
|
@@ -480,25 +505,25 @@ function createCoreRouter() {
|
|
|
480
505
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
481
506
|
tracer?.trace('setAdminSettings:start', { body: req.body });
|
|
482
507
|
let success = false;
|
|
483
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
508
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
484
509
|
try {
|
|
485
|
-
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: req
|
|
510
|
+
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: getRcAccessTokenFromRequest(req) });
|
|
486
511
|
const hashedRcAccountId = util.getHashValue(rcAccountId, process.env.HASH_KEY);
|
|
487
512
|
if (isValidated) {
|
|
488
513
|
await adminCore.upsertAdminSettings({ hashedRcAccountId, adminSettings: req.body.adminSettings });
|
|
489
|
-
res.status(200).send(tracer
|
|
514
|
+
res.status(200).send(wrapDebugResponse(tracer, 'Admin settings updated'));
|
|
490
515
|
success = true;
|
|
491
516
|
}
|
|
492
517
|
else {
|
|
493
518
|
tracer?.trace('setAdminSettings:adminValidationFailed', {});
|
|
494
|
-
res.status(403).send(tracer
|
|
519
|
+
res.status(403).send(wrapDebugResponse(tracer, 'Admin validation failed'));
|
|
495
520
|
success = false;
|
|
496
521
|
}
|
|
497
522
|
}
|
|
498
523
|
catch (e) {
|
|
499
524
|
logger.error('Set admin settings failed', { stack: e.stack });
|
|
500
525
|
tracer?.traceError('setAdminSettings:error', e);
|
|
501
|
-
res.status(400).send(tracer
|
|
526
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
502
527
|
success = false;
|
|
503
528
|
}
|
|
504
529
|
const requestEndTime = new Date().getTime();
|
|
@@ -521,7 +546,7 @@ function createCoreRouter() {
|
|
|
521
546
|
tracer?.trace('getAdminSettings:start', { query: req.query });
|
|
522
547
|
let platformName = null;
|
|
523
548
|
let success = false;
|
|
524
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
549
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
525
550
|
try {
|
|
526
551
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
527
552
|
if (jwtToken) {
|
|
@@ -530,43 +555,40 @@ function createCoreRouter() {
|
|
|
530
555
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
531
556
|
if (!user) {
|
|
532
557
|
tracer?.trace('getAdminSettings:userNotFound', {});
|
|
533
|
-
res.status(400).send(tracer
|
|
558
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
534
559
|
return;
|
|
535
560
|
}
|
|
536
|
-
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: req
|
|
561
|
+
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: getRcAccessTokenFromRequest(req) });
|
|
537
562
|
const hashedRcAccountId = util.getHashValue(rcAccountId, process.env.HASH_KEY);
|
|
538
563
|
if (isValidated) {
|
|
539
564
|
const adminSettings = await adminCore.getAdminSettings({ hashedRcAccountId });
|
|
540
565
|
if (adminSettings) {
|
|
541
|
-
res.status(200).send(tracer
|
|
566
|
+
res.status(200).send(wrapDebugResponse(tracer, adminSettings));
|
|
542
567
|
}
|
|
543
568
|
else {
|
|
544
|
-
res.status(200).send(tracer
|
|
569
|
+
res.status(200).send(wrapDebugResponse(tracer, {
|
|
545
570
|
customConnector: null,
|
|
546
571
|
userSettings: {}
|
|
547
|
-
})
|
|
548
|
-
customConnector: null,
|
|
549
|
-
userSettings: {}
|
|
550
|
-
});
|
|
572
|
+
}));
|
|
551
573
|
}
|
|
552
574
|
success = true;
|
|
553
575
|
}
|
|
554
576
|
else {
|
|
555
577
|
tracer?.trace('getAdminSettings:adminValidationFailed', {});
|
|
556
|
-
res.status(403).send(tracer
|
|
578
|
+
res.status(403).send(wrapDebugResponse(tracer, 'Admin validation failed'));
|
|
557
579
|
success = true;
|
|
558
580
|
}
|
|
559
581
|
}
|
|
560
582
|
else {
|
|
561
583
|
tracer?.trace('getAdminSettings:noToken', {});
|
|
562
|
-
res.status(400).send(tracer
|
|
584
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
563
585
|
success = false;
|
|
564
586
|
}
|
|
565
587
|
}
|
|
566
588
|
catch (e) {
|
|
567
589
|
console.log(`${e.stack}`);
|
|
568
590
|
tracer?.traceError('getAdminSettings:error', e);
|
|
569
|
-
res.status(400).send(tracer
|
|
591
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
570
592
|
}
|
|
571
593
|
const requestEndTime = new Date().getTime();
|
|
572
594
|
analytics.track({
|
|
@@ -589,18 +611,18 @@ function createCoreRouter() {
|
|
|
589
611
|
try {
|
|
590
612
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
591
613
|
if (!jwtToken) {
|
|
592
|
-
res.status(400).send(tracer
|
|
614
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
593
615
|
return;
|
|
594
616
|
}
|
|
595
617
|
const unAuthData = jwt.decodeJwt(jwtToken);
|
|
596
618
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
597
619
|
if (!user) {
|
|
598
|
-
res.status(400).send(tracer
|
|
620
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
599
621
|
return;
|
|
600
622
|
}
|
|
601
|
-
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: req
|
|
623
|
+
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: getRcAccessTokenFromRequest(req) });
|
|
602
624
|
if (!isValidated) {
|
|
603
|
-
res.status(403).send(tracer
|
|
625
|
+
res.status(403).send(wrapDebugResponse(tracer, 'Admin validation failed'));
|
|
604
626
|
return;
|
|
605
627
|
}
|
|
606
628
|
const managedAuthSettings = await managedAuthCore.getManagedAuthAdminSettings({
|
|
@@ -609,12 +631,12 @@ function createCoreRouter() {
|
|
|
609
631
|
connectorId: req.query.connectorId,
|
|
610
632
|
isPrivate: req.query.isPrivate === 'true'
|
|
611
633
|
});
|
|
612
|
-
res.status(200).send(tracer
|
|
634
|
+
res.status(200).send(wrapDebugResponse(tracer, managedAuthSettings));
|
|
613
635
|
}
|
|
614
636
|
catch (e) {
|
|
615
637
|
logger.error('Get managed auth settings failed', { stack: e.stack });
|
|
616
638
|
tracer?.traceError('getAdminManagedAuth:error', e);
|
|
617
|
-
res.status(400).send(tracer
|
|
639
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
618
640
|
}
|
|
619
641
|
});
|
|
620
642
|
router.post('/admin/managedAuth', async function (req, res) {
|
|
@@ -623,18 +645,18 @@ function createCoreRouter() {
|
|
|
623
645
|
try {
|
|
624
646
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
625
647
|
if (!jwtToken) {
|
|
626
|
-
res.status(400).send(tracer
|
|
648
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
627
649
|
return;
|
|
628
650
|
}
|
|
629
651
|
const unAuthData = jwt.decodeJwt(jwtToken);
|
|
630
652
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
631
653
|
if (!user) {
|
|
632
|
-
res.status(400).send(tracer
|
|
654
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
633
655
|
return;
|
|
634
656
|
}
|
|
635
|
-
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: req
|
|
657
|
+
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: getRcAccessTokenFromRequest(req) });
|
|
636
658
|
if (!isValidated) {
|
|
637
|
-
res.status(403).send(tracer
|
|
659
|
+
res.status(403).send(wrapDebugResponse(tracer, 'Admin validation failed'));
|
|
638
660
|
return;
|
|
639
661
|
}
|
|
640
662
|
if (req.body?.scope === 'user') {
|
|
@@ -655,12 +677,12 @@ function createCoreRouter() {
|
|
|
655
677
|
fieldsToRemove: req.body?.fieldsToRemove ?? []
|
|
656
678
|
});
|
|
657
679
|
}
|
|
658
|
-
res.status(200).send(tracer
|
|
680
|
+
res.status(200).send(wrapDebugResponse(tracer, 'Shared authentication updated'));
|
|
659
681
|
}
|
|
660
682
|
catch (e) {
|
|
661
683
|
logger.error('Set managed auth settings failed', { stack: e.stack });
|
|
662
684
|
tracer?.traceError('setAdminManagedAuth:error', e);
|
|
663
|
-
res.status(400).send(tracer
|
|
685
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
664
686
|
}
|
|
665
687
|
});
|
|
666
688
|
router.post('/admin/managedOAuth/cache', async function (req, res) {
|
|
@@ -672,64 +694,64 @@ function createCoreRouter() {
|
|
|
672
694
|
}
|
|
673
695
|
});
|
|
674
696
|
try {
|
|
675
|
-
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: req
|
|
697
|
+
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: getRcAccessTokenFromRequest(req) });
|
|
676
698
|
if (!isValidated) {
|
|
677
|
-
res.status(403).send(tracer
|
|
699
|
+
res.status(403).send(wrapDebugResponse(tracer, 'Admin validation failed'));
|
|
678
700
|
return;
|
|
679
701
|
}
|
|
680
702
|
await managedOAuthCore.upsertPendingManagedOAuth({
|
|
681
703
|
rcAccountId: rcAccountId?.toString(),
|
|
682
704
|
values: req.body?.values ?? {}
|
|
683
705
|
});
|
|
684
|
-
res.status(200).send(tracer
|
|
706
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful: true }));
|
|
685
707
|
}
|
|
686
708
|
catch (e) {
|
|
687
709
|
logger.error('Set managed OAuth pending cache failed', { stack: e.stack });
|
|
688
710
|
tracer?.traceError('setAdminManagedOAuthCache:error', e);
|
|
689
|
-
res.status(400).send(tracer
|
|
711
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
690
712
|
}
|
|
691
713
|
});
|
|
692
714
|
router.delete('/admin/managedOAuth/cache', async function (req, res) {
|
|
693
715
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
694
716
|
tracer?.trace('deleteAdminManagedOAuthCache:start', {});
|
|
695
717
|
try {
|
|
696
|
-
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: req
|
|
718
|
+
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: getRcAccessTokenFromRequest(req) });
|
|
697
719
|
if (!isValidated) {
|
|
698
|
-
res.status(403).send(tracer
|
|
720
|
+
res.status(403).send(wrapDebugResponse(tracer, 'Admin validation failed'));
|
|
699
721
|
return;
|
|
700
722
|
}
|
|
701
723
|
await managedOAuthCore.clearPendingManagedOAuth({ rcAccountId: rcAccountId?.toString() });
|
|
702
|
-
res.status(200).send(tracer
|
|
724
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful: true }));
|
|
703
725
|
}
|
|
704
726
|
catch (e) {
|
|
705
727
|
logger.error('Delete managed OAuth pending cache failed', { stack: e.stack });
|
|
706
728
|
tracer?.traceError('deleteAdminManagedOAuthCache:error', e);
|
|
707
|
-
res.status(400).send(tracer
|
|
729
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
708
730
|
}
|
|
709
731
|
});
|
|
710
732
|
router.delete('/admin/managedOAuth/account', async function (req, res) {
|
|
711
733
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
712
734
|
tracer?.trace('deleteAdminManagedOAuthAccount:start', { query: req.query });
|
|
713
735
|
try {
|
|
714
|
-
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: req
|
|
736
|
+
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: getRcAccessTokenFromRequest(req) });
|
|
715
737
|
if (!isValidated) {
|
|
716
|
-
res.status(403).send(tracer
|
|
738
|
+
res.status(403).send(wrapDebugResponse(tracer, 'Admin validation failed'));
|
|
717
739
|
return;
|
|
718
740
|
}
|
|
719
741
|
if (!req.query.platform) {
|
|
720
|
-
res.status(400).send(tracer
|
|
742
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Missing platform name'));
|
|
721
743
|
return;
|
|
722
744
|
}
|
|
723
745
|
await managedOAuthCore.resetManagedOAuth({
|
|
724
746
|
rcAccountId: rcAccountId?.toString(),
|
|
725
747
|
platform: req.query.platform
|
|
726
748
|
});
|
|
727
|
-
res.status(200).send(tracer
|
|
749
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful: true }));
|
|
728
750
|
}
|
|
729
751
|
catch (e) {
|
|
730
752
|
logger.error('Delete managed OAuth account failed', { stack: e.stack });
|
|
731
753
|
tracer?.traceError('deleteAdminManagedOAuthAccount:error', e);
|
|
732
|
-
res.status(400).send(tracer
|
|
754
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
733
755
|
}
|
|
734
756
|
});
|
|
735
757
|
router.post('/admin/userMapping', async function (req, res) {
|
|
@@ -738,7 +760,7 @@ function createCoreRouter() {
|
|
|
738
760
|
tracer?.trace('getUserMapping:start', { query: req.query });
|
|
739
761
|
let platformName = null;
|
|
740
762
|
let success = false;
|
|
741
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
763
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
742
764
|
try {
|
|
743
765
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
744
766
|
if (jwtToken) {
|
|
@@ -747,38 +769,38 @@ function createCoreRouter() {
|
|
|
747
769
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
748
770
|
if (!user) {
|
|
749
771
|
tracer?.trace('getUserMapping:userNotFound', {});
|
|
750
|
-
res.status(400).send(tracer
|
|
772
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
751
773
|
return;
|
|
752
774
|
}
|
|
753
|
-
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: req
|
|
775
|
+
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: getRcAccessTokenFromRequest(req) });
|
|
754
776
|
const hashedRcAccountId = util.getHashValue(rcAccountId, process.env.HASH_KEY);
|
|
755
777
|
if (isValidated) {
|
|
756
778
|
const userMapping = await adminCore.getUserMapping({ user, hashedRcAccountId, rcExtensionList: req.body.rcExtensionList });
|
|
757
779
|
if (userMapping?.isRevokeUserSession) {
|
|
758
|
-
res.status(401).send(tracer
|
|
780
|
+
res.status(401).send(wrapDebugResponse(tracer, userMapping));
|
|
759
781
|
success = false;
|
|
760
782
|
}
|
|
761
783
|
else {
|
|
762
|
-
res.status(200).send(tracer
|
|
784
|
+
res.status(200).send(wrapDebugResponse(tracer, userMapping));
|
|
763
785
|
success = true;
|
|
764
786
|
}
|
|
765
787
|
}
|
|
766
788
|
else {
|
|
767
789
|
tracer?.trace('getUserMapping:adminValidationFailed', {});
|
|
768
|
-
res.status(403).send(tracer
|
|
790
|
+
res.status(403).send(wrapDebugResponse(tracer, 'Admin validation failed'));
|
|
769
791
|
success = true;
|
|
770
792
|
}
|
|
771
793
|
}
|
|
772
794
|
else {
|
|
773
795
|
tracer?.trace('getUserMapping:noToken', {});
|
|
774
|
-
res.status(400).send(tracer
|
|
796
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
775
797
|
success = false;
|
|
776
798
|
}
|
|
777
799
|
}
|
|
778
800
|
catch (e) {
|
|
779
801
|
logger.error('Get user mapping failed', { stack: e.stack });
|
|
780
802
|
tracer?.traceError('getUserMapping:error', e);
|
|
781
|
-
res.status(400).send(tracer
|
|
803
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
782
804
|
}
|
|
783
805
|
const requestEndTime = new Date().getTime();
|
|
784
806
|
analytics.track({
|
|
@@ -801,7 +823,7 @@ function createCoreRouter() {
|
|
|
801
823
|
tracer?.trace('reinitializeUserMapping:start', { body: req.body });
|
|
802
824
|
let platformName = null;
|
|
803
825
|
let success = false;
|
|
804
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
826
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
805
827
|
try {
|
|
806
828
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
807
829
|
if (jwtToken) {
|
|
@@ -810,38 +832,38 @@ function createCoreRouter() {
|
|
|
810
832
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
811
833
|
if (!user) {
|
|
812
834
|
tracer?.trace('reinitializeUserMapping:userNotFound', {});
|
|
813
|
-
res.status(400).send(tracer
|
|
835
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
814
836
|
return;
|
|
815
837
|
}
|
|
816
|
-
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: req
|
|
838
|
+
const { isValidated, rcAccountId } = await adminCore.validateAdminRole({ rcAccessToken: getRcAccessTokenFromRequest(req) });
|
|
817
839
|
const hashedRcAccountId = util.getHashValue(rcAccountId, process.env.HASH_KEY);
|
|
818
840
|
if (isValidated) {
|
|
819
841
|
const userMapping = await adminCore.reinitializeUserMapping({ user, hashedRcAccountId, rcExtensionList: req.body.rcExtensionList });
|
|
820
842
|
if (userMapping?.isRevokeUserSession) {
|
|
821
|
-
res.status(401).send(tracer
|
|
843
|
+
res.status(401).send(wrapDebugResponse(tracer, userMapping));
|
|
822
844
|
success = false;
|
|
823
845
|
}
|
|
824
846
|
else {
|
|
825
|
-
res.status(200).send(tracer
|
|
847
|
+
res.status(200).send(wrapDebugResponse(tracer, userMapping));
|
|
826
848
|
success = true;
|
|
827
849
|
}
|
|
828
850
|
}
|
|
829
851
|
else {
|
|
830
852
|
tracer?.trace('reinitializeUserMapping:adminValidationFailed', {});
|
|
831
|
-
res.status(403).send(tracer
|
|
853
|
+
res.status(403).send(wrapDebugResponse(tracer, 'Admin validation failed'));
|
|
832
854
|
success = true;
|
|
833
855
|
}
|
|
834
856
|
}
|
|
835
857
|
else {
|
|
836
858
|
tracer?.trace('reinitializeUserMapping:noToken', {});
|
|
837
|
-
res.status(400).send(tracer
|
|
859
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
838
860
|
success = false;
|
|
839
861
|
}
|
|
840
862
|
}
|
|
841
863
|
catch (e) {
|
|
842
864
|
logger.error('Reinitialize user mapping failed', { stack: e.stack });
|
|
843
865
|
tracer?.traceError('reinitializeUserMapping:error', e);
|
|
844
|
-
res.status(400).send(tracer
|
|
866
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
845
867
|
}
|
|
846
868
|
const requestEndTime = new Date().getTime();
|
|
847
869
|
analytics.track({
|
|
@@ -867,32 +889,32 @@ function createCoreRouter() {
|
|
|
867
889
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
868
890
|
if (!jwtToken) {
|
|
869
891
|
tracer?.trace('getServerLoggingSettings:noToken', {});
|
|
870
|
-
res.status(400).send(tracer
|
|
892
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
871
893
|
return;
|
|
872
894
|
}
|
|
873
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
895
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
874
896
|
try {
|
|
875
897
|
const unAuthData = jwt.decodeJwt(jwtToken);
|
|
876
898
|
if (!unAuthData?.id) {
|
|
877
899
|
tracer?.trace('getServerLoggingSettings:noToken', {});
|
|
878
|
-
res.status(400).send(tracer
|
|
900
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
879
901
|
return;
|
|
880
902
|
}
|
|
881
903
|
platformName = unAuthData?.platform ?? 'Unknown';
|
|
882
904
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
883
905
|
if (!user) {
|
|
884
906
|
tracer?.trace('getServerLoggingSettings:userNotFound', {});
|
|
885
|
-
res.status(400).send(tracer
|
|
907
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
886
908
|
return;
|
|
887
909
|
}
|
|
888
910
|
const serverLoggingSettings = await adminCore.getServerLoggingSettings({ user });
|
|
889
|
-
res.status(200).send(tracer
|
|
911
|
+
res.status(200).send(wrapDebugResponse(tracer, serverLoggingSettings));
|
|
890
912
|
success = true;
|
|
891
913
|
}
|
|
892
914
|
catch (e) {
|
|
893
915
|
logger.error('Get server logging settings failed', { stack: e.stack });
|
|
894
916
|
tracer?.traceError('getServerLoggingSettings:error', e);
|
|
895
|
-
res.status(400).send(tracer
|
|
917
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
896
918
|
}
|
|
897
919
|
const requestEndTime = new Date().getTime();
|
|
898
920
|
analytics.track({
|
|
@@ -918,37 +940,37 @@ function createCoreRouter() {
|
|
|
918
940
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
919
941
|
if (!jwtToken) {
|
|
920
942
|
tracer?.trace('setServerLoggingSettings:noToken', {});
|
|
921
|
-
res.status(400).send(tracer
|
|
943
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
922
944
|
return;
|
|
923
945
|
}
|
|
924
946
|
if (!req.body.additionalFieldValues) {
|
|
925
947
|
tracer?.trace('setServerLoggingSettings:missingAdditionalFieldValues', {});
|
|
926
|
-
res.status(400).send(tracer
|
|
948
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Missing additionalFieldValues'));
|
|
927
949
|
return;
|
|
928
950
|
}
|
|
929
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
951
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
930
952
|
try {
|
|
931
953
|
const unAuthData = jwt.decodeJwt(jwtToken);
|
|
932
954
|
if (!unAuthData?.id) {
|
|
933
955
|
tracer?.trace('setServerLoggingSettings:noToken', {});
|
|
934
|
-
res.status(400).send(tracer
|
|
956
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
935
957
|
return;
|
|
936
958
|
}
|
|
937
959
|
platformName = unAuthData?.platform ?? 'Unknown';
|
|
938
960
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
939
961
|
if (!user) {
|
|
940
962
|
tracer?.trace('setServerLoggingSettings:userNotFound', {});
|
|
941
|
-
res.status(400).send(tracer
|
|
963
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
942
964
|
return;
|
|
943
965
|
}
|
|
944
966
|
const { successful, returnMessage } = await adminCore.updateServerLoggingSettings({ user, additionalFieldValues: req.body.additionalFieldValues });
|
|
945
|
-
res.status(200).send(tracer
|
|
967
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
946
968
|
success = true;
|
|
947
969
|
}
|
|
948
970
|
catch (e) {
|
|
949
971
|
logger.error('Set server logging settings failed', { stack: e.stack });
|
|
950
972
|
tracer?.traceError('setServerLoggingSettings:error', e);
|
|
951
|
-
res.status(400).send(tracer
|
|
973
|
+
res.status(400).send(wrapDebugResponse(tracer, { successful: false, returnMessage: { messageType: 'warning', message: 'Server logging settings update failed', ttl: 5000 } }));
|
|
952
974
|
success = false;
|
|
953
975
|
}
|
|
954
976
|
const requestEndTime = new Date().getTime();
|
|
@@ -965,36 +987,35 @@ function createCoreRouter() {
|
|
|
965
987
|
author,
|
|
966
988
|
eventAddedVia
|
|
967
989
|
});
|
|
968
|
-
})
|
|
990
|
+
});
|
|
969
991
|
router.get('/user/preloadSettings', async function (req, res) {
|
|
970
992
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
971
993
|
tracer?.trace('getUserSettingsByAdmin:start', { query: req.query });
|
|
972
994
|
try {
|
|
973
|
-
const rcAccessToken = req
|
|
995
|
+
const rcAccessToken = getRcAccessTokenFromRequest(req);
|
|
974
996
|
const rcAccountId = req.query.rcAccountId;
|
|
975
997
|
if (rcAccessToken || rcAccountId) {
|
|
976
998
|
const userSettings = await userCore.getUserSettingsByAdmin({ rcAccessToken, rcAccountId });
|
|
977
|
-
res.status(200).send(tracer
|
|
999
|
+
res.status(200).send(wrapDebugResponse(tracer, userSettings));
|
|
978
1000
|
}
|
|
979
1001
|
else {
|
|
980
1002
|
tracer?.trace('getUserSettingsByAdmin:noRcAccessTokenOrRcAccountId', {});
|
|
981
|
-
res.status(400).send(tracer
|
|
1003
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Cannot find rc user login'));
|
|
982
1004
|
}
|
|
983
1005
|
}
|
|
984
1006
|
catch (e) {
|
|
985
1007
|
logger.error('Get user preload settings failed', { stack: e.stack });
|
|
986
1008
|
tracer?.traceError('getUserSettingsByAdmin:error', e);
|
|
987
|
-
res.status(400).send(tracer
|
|
1009
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
988
1010
|
}
|
|
989
|
-
}
|
|
990
|
-
);
|
|
1011
|
+
});
|
|
991
1012
|
router.post('/user/refreshInfo', async function (req, res) {
|
|
992
1013
|
const requestStartTime = new Date().getTime();
|
|
993
1014
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
994
1015
|
tracer?.trace('refreshUserInfo:start', { body: req.body });
|
|
995
1016
|
let platformName = null;
|
|
996
1017
|
let success = false;
|
|
997
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1018
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
998
1019
|
try {
|
|
999
1020
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1000
1021
|
if (jwtToken) {
|
|
@@ -1002,19 +1023,19 @@ function createCoreRouter() {
|
|
|
1002
1023
|
platformName = unAuthData?.platform ?? 'Unknown';
|
|
1003
1024
|
const userId = unAuthData?.id;
|
|
1004
1025
|
const { successful, returnMessage } = await userCore.refreshUserInfo({ platform: platformName, userId, tracer });
|
|
1005
|
-
res.status(200).send(tracer
|
|
1026
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
1006
1027
|
success = true;
|
|
1007
1028
|
}
|
|
1008
1029
|
else {
|
|
1009
1030
|
tracer?.trace('refreshUserInfo:noToken', {});
|
|
1010
|
-
res.status(400).send(tracer
|
|
1031
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1011
1032
|
success = false;
|
|
1012
1033
|
}
|
|
1013
1034
|
}
|
|
1014
1035
|
catch (e) {
|
|
1015
1036
|
logger.error('Refresh user info failed', { platform: platformName, stack: e.stack });
|
|
1016
1037
|
tracer?.traceError('refreshUserInfo:error', e, { platform: platformName });
|
|
1017
|
-
res.status(400).send(tracer
|
|
1038
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1018
1039
|
}
|
|
1019
1040
|
const requestEndTime = new Date().getTime();
|
|
1020
1041
|
analytics.track({
|
|
@@ -1030,14 +1051,14 @@ function createCoreRouter() {
|
|
|
1030
1051
|
author,
|
|
1031
1052
|
eventAddedVia
|
|
1032
1053
|
});
|
|
1033
|
-
})
|
|
1054
|
+
});
|
|
1034
1055
|
router.get('/user/settings', async function (req, res) {
|
|
1035
1056
|
const requestStartTime = new Date().getTime();
|
|
1036
1057
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
1037
1058
|
tracer?.trace('getUserSettings:start', { query: req.query });
|
|
1038
1059
|
let platformName = null;
|
|
1039
1060
|
let success = false;
|
|
1040
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1061
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1041
1062
|
try {
|
|
1042
1063
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1043
1064
|
if (jwtToken) {
|
|
@@ -1045,33 +1066,33 @@ function createCoreRouter() {
|
|
|
1045
1066
|
platformName = unAuthData?.platform ?? 'Unknown';
|
|
1046
1067
|
if (!unAuthData || !unAuthData?.id) {
|
|
1047
1068
|
tracer?.trace('getUserSettings:noToken', {});
|
|
1048
|
-
res.status(400).send(tracer
|
|
1069
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1049
1070
|
return;
|
|
1050
1071
|
}
|
|
1051
1072
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
1052
1073
|
if (!user) {
|
|
1053
1074
|
tracer?.trace('getUserSettings:userNotFound', {});
|
|
1054
|
-
res.status(400).send(tracer
|
|
1075
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
1055
1076
|
return;
|
|
1056
1077
|
}
|
|
1057
1078
|
else {
|
|
1058
|
-
const rcAccessToken = req
|
|
1079
|
+
const rcAccessToken = getRcAccessTokenFromRequest(req);
|
|
1059
1080
|
const rcAccountId = req.query.rcAccountId;
|
|
1060
1081
|
const userSettings = await userCore.getUserSettings({ user, rcAccessToken, rcAccountId });
|
|
1061
1082
|
success = true;
|
|
1062
|
-
res.status(200).send(tracer
|
|
1083
|
+
res.status(200).send(wrapDebugResponse(tracer, userSettings));
|
|
1063
1084
|
}
|
|
1064
1085
|
}
|
|
1065
1086
|
else {
|
|
1066
1087
|
success = false;
|
|
1067
1088
|
tracer?.trace('getUserSettings:noToken', {});
|
|
1068
|
-
res.status(400).send(tracer
|
|
1089
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1069
1090
|
}
|
|
1070
1091
|
}
|
|
1071
1092
|
catch (e) {
|
|
1072
1093
|
logger.error('Get user settings failed', { platform: platformName, stack: e.stack });
|
|
1073
1094
|
tracer?.traceError('getUserSettings:error', e, { platform: platformName });
|
|
1074
|
-
res.status(400).send(tracer
|
|
1095
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1075
1096
|
}
|
|
1076
1097
|
const requestEndTime = new Date().getTime();
|
|
1077
1098
|
analytics.track({
|
|
@@ -1094,7 +1115,7 @@ function createCoreRouter() {
|
|
|
1094
1115
|
tracer?.trace('setUserSettings:start', { body: req.body });
|
|
1095
1116
|
let platformName = null;
|
|
1096
1117
|
let success = false;
|
|
1097
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1118
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1098
1119
|
try {
|
|
1099
1120
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1100
1121
|
if (jwtToken) {
|
|
@@ -1102,29 +1123,29 @@ function createCoreRouter() {
|
|
|
1102
1123
|
platformName = unAuthData?.platform;
|
|
1103
1124
|
if (!platformName) {
|
|
1104
1125
|
tracer?.trace('setUserSettings:unknownPlatform', {});
|
|
1105
|
-
res.status(400).send(tracer
|
|
1126
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Unknown platform'));
|
|
1106
1127
|
return;
|
|
1107
1128
|
}
|
|
1108
1129
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
1109
1130
|
if (!user) {
|
|
1110
1131
|
tracer?.trace('setUserSettings:userNotFound', {});
|
|
1111
|
-
res.status(400).send(tracer
|
|
1132
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
1112
1133
|
return;
|
|
1113
1134
|
}
|
|
1114
1135
|
const { userSettings } = await userCore.updateUserSettings({ user, userSettings: req.body.userSettings, settingKeysToRemove: req.body.settingKeysToRemove || [], platformName });
|
|
1115
|
-
res.status(200).send(tracer
|
|
1136
|
+
res.status(200).send(wrapDebugResponse(tracer, { userSettings }));
|
|
1116
1137
|
success = true;
|
|
1117
1138
|
}
|
|
1118
1139
|
else {
|
|
1119
1140
|
tracer?.trace('setUserSettings:noToken', {});
|
|
1120
|
-
res.status(400).send(tracer
|
|
1141
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1121
1142
|
success = false;
|
|
1122
1143
|
}
|
|
1123
1144
|
}
|
|
1124
1145
|
catch (e) {
|
|
1125
1146
|
logger.error('Set user settings failed', { platform: platformName, stack: e.stack });
|
|
1126
1147
|
tracer?.traceError('setUserSettings:error', e, { platform: platformName });
|
|
1127
|
-
res.status(400).send(tracer
|
|
1148
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1128
1149
|
}
|
|
1129
1150
|
const requestEndTime = new Date().getTime();
|
|
1130
1151
|
analytics.track({
|
|
@@ -1151,22 +1172,22 @@ function createCoreRouter() {
|
|
|
1151
1172
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
1152
1173
|
if (!user) {
|
|
1153
1174
|
tracer?.trace('hostname:userNotFound', {});
|
|
1154
|
-
res.status(400).send(tracer
|
|
1175
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
1155
1176
|
return;
|
|
1156
1177
|
}
|
|
1157
|
-
res.status(200).send(tracer
|
|
1178
|
+
res.status(200).send(wrapDebugResponse(tracer, user.hostname));
|
|
1158
1179
|
}
|
|
1159
1180
|
else {
|
|
1160
1181
|
tracer?.trace('hostname:noToken', {});
|
|
1161
|
-
res.status(400).send(tracer
|
|
1182
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1162
1183
|
}
|
|
1163
1184
|
}
|
|
1164
1185
|
catch (e) {
|
|
1165
1186
|
logger.error('Get hostname failed', { stack: e.stack });
|
|
1166
1187
|
tracer?.traceError('hostname:error', e);
|
|
1167
|
-
res.status(500).send(tracer
|
|
1188
|
+
res.status(500).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1168
1189
|
}
|
|
1169
|
-
})
|
|
1190
|
+
});
|
|
1170
1191
|
router.get('/oauth-callback', async function (req, res) {
|
|
1171
1192
|
const requestStartTime = new Date().getTime();
|
|
1172
1193
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
@@ -1174,7 +1195,7 @@ function createCoreRouter() {
|
|
|
1174
1195
|
let platformName = null;
|
|
1175
1196
|
let success = false;
|
|
1176
1197
|
let sessionId = null;
|
|
1177
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1198
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1178
1199
|
try {
|
|
1179
1200
|
if (!req.query?.callbackUri || req.query.callbackUri === 'undefined') {
|
|
1180
1201
|
// case: from mcp
|
|
@@ -1184,7 +1205,7 @@ function createCoreRouter() {
|
|
|
1184
1205
|
}
|
|
1185
1206
|
else {
|
|
1186
1207
|
tracer?.trace('oauth-callback:missingCallbackUri', {});
|
|
1187
|
-
res.status(400).send(tracer
|
|
1208
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Missing callbackUri'));
|
|
1188
1209
|
return;
|
|
1189
1210
|
}
|
|
1190
1211
|
}
|
|
@@ -1202,7 +1223,7 @@ function createCoreRouter() {
|
|
|
1202
1223
|
const tokenUrl = req.query.tokenUrl;
|
|
1203
1224
|
if (!platformName) {
|
|
1204
1225
|
tracer?.trace('oauth-callback:missingPlatformName', {});
|
|
1205
|
-
res.status(400).send(tracer
|
|
1226
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Missing platform name'));
|
|
1206
1227
|
return;
|
|
1207
1228
|
}
|
|
1208
1229
|
const hasAuthCodeInCallbackUri = req.query.callbackUri.includes('code=');
|
|
@@ -1238,12 +1259,12 @@ function createCoreRouter() {
|
|
|
1238
1259
|
success = true;
|
|
1239
1260
|
}
|
|
1240
1261
|
else {
|
|
1241
|
-
res.status(200).send(tracer
|
|
1262
|
+
res.status(200).send(wrapDebugResponse(tracer, { jwtToken, name: userInfo.name, returnMessage }));
|
|
1242
1263
|
success = true;
|
|
1243
1264
|
}
|
|
1244
1265
|
}
|
|
1245
1266
|
else {
|
|
1246
|
-
res.status(200).send(tracer
|
|
1267
|
+
res.status(200).send(wrapDebugResponse(tracer, { returnMessage }));
|
|
1247
1268
|
await updateAuthSession(sessionId, {
|
|
1248
1269
|
status: 'failed',
|
|
1249
1270
|
errorMessage: returnMessage?.message || 'Authentication failed'
|
|
@@ -1254,14 +1275,13 @@ function createCoreRouter() {
|
|
|
1254
1275
|
catch (e) {
|
|
1255
1276
|
logger.error('OAuth callback failed', { platform: platformName, stack: e.stack });
|
|
1256
1277
|
tracer?.traceError('oauth-callback:error', e, { platform: platformName });
|
|
1257
|
-
res.status(400).send(tracer
|
|
1278
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1258
1279
|
if (sessionId) {
|
|
1259
1280
|
await updateAuthSession(sessionId, {
|
|
1260
1281
|
status: 'failed',
|
|
1261
|
-
errorMessage: e.
|
|
1282
|
+
errorMessage: getErrorResponse(e).toString()
|
|
1262
1283
|
});
|
|
1263
1284
|
}
|
|
1264
|
-
|
|
1265
1285
|
success = false;
|
|
1266
1286
|
}
|
|
1267
1287
|
const requestEndTime = new Date().getTime();
|
|
@@ -1292,7 +1312,7 @@ function createCoreRouter() {
|
|
|
1292
1312
|
});
|
|
1293
1313
|
let platformName = null;
|
|
1294
1314
|
let success = false;
|
|
1295
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1315
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1296
1316
|
try {
|
|
1297
1317
|
const platform = req.body.platform;
|
|
1298
1318
|
platformName = platform;
|
|
@@ -1300,12 +1320,12 @@ function createCoreRouter() {
|
|
|
1300
1320
|
const hostname = req.body.hostname;
|
|
1301
1321
|
const proxyId = req.body.proxyId;
|
|
1302
1322
|
const additionalInfo = req.body.additionalInfo;
|
|
1303
|
-
const rcAccessToken = req
|
|
1323
|
+
const rcAccessToken = getRcAccessTokenFromRequest(req);
|
|
1304
1324
|
const connectorId = req.body.connectorId;
|
|
1305
1325
|
const isPrivate = !!req.body.isPrivate;
|
|
1306
1326
|
if (!platform) {
|
|
1307
1327
|
tracer?.trace('apiKeyLogin:missingPlatform', {});
|
|
1308
|
-
res.status(400).send(tracer
|
|
1328
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Missing platform name'));
|
|
1309
1329
|
return;
|
|
1310
1330
|
}
|
|
1311
1331
|
let rcAccountId = null;
|
|
@@ -1332,18 +1352,18 @@ function createCoreRouter() {
|
|
|
1332
1352
|
id: userInfo.id.toString(),
|
|
1333
1353
|
platform: platform
|
|
1334
1354
|
});
|
|
1335
|
-
res.status(200).send(tracer
|
|
1355
|
+
res.status(200).send(wrapDebugResponse(tracer, { jwtToken, name: userInfo.name, returnMessage }));
|
|
1336
1356
|
success = true;
|
|
1337
1357
|
}
|
|
1338
1358
|
else {
|
|
1339
|
-
res.status(400).send(tracer
|
|
1359
|
+
res.status(400).send(wrapDebugResponse(tracer, { returnMessage }));
|
|
1340
1360
|
success = false;
|
|
1341
1361
|
}
|
|
1342
1362
|
}
|
|
1343
1363
|
catch (e) {
|
|
1344
1364
|
logger.error('API key login failed', { platform: platformName, stack: e.stack });
|
|
1345
1365
|
tracer?.traceError('apiKeyLogin:error', e, { platform: platformName });
|
|
1346
|
-
res.status(400).send(tracer
|
|
1366
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1347
1367
|
success = false;
|
|
1348
1368
|
}
|
|
1349
1369
|
const requestEndTime = new Date().getTime();
|
|
@@ -1360,14 +1380,14 @@ function createCoreRouter() {
|
|
|
1360
1380
|
author,
|
|
1361
1381
|
eventAddedVia
|
|
1362
1382
|
});
|
|
1363
|
-
})
|
|
1383
|
+
});
|
|
1364
1384
|
router.post('/unAuthorize', async function (req, res) {
|
|
1365
1385
|
const requestStartTime = new Date().getTime();
|
|
1366
1386
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
1367
1387
|
tracer?.trace('unAuthorize:start', { query: req.query });
|
|
1368
1388
|
let platformName = null;
|
|
1369
1389
|
let success = false;
|
|
1370
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1390
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1371
1391
|
try {
|
|
1372
1392
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1373
1393
|
if (jwtToken) {
|
|
@@ -1376,24 +1396,24 @@ function createCoreRouter() {
|
|
|
1376
1396
|
const userToLogout = await UserModel.findByPk(unAuthData?.id);
|
|
1377
1397
|
if (!userToLogout) {
|
|
1378
1398
|
tracer?.trace('unAuthorize:userNotFound', {});
|
|
1379
|
-
res.status(400).send(tracer
|
|
1399
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
1380
1400
|
return;
|
|
1381
1401
|
}
|
|
1382
1402
|
const platformModule = connectorRegistry.getConnector(unAuthData?.platform ?? 'Unknown');
|
|
1383
1403
|
const { returnMessage } = await platformModule.unAuthorize({ user: userToLogout });
|
|
1384
|
-
res.status(200).send(tracer
|
|
1404
|
+
res.status(200).send(wrapDebugResponse(tracer, returnMessage));
|
|
1385
1405
|
success = true;
|
|
1386
1406
|
}
|
|
1387
1407
|
else {
|
|
1388
1408
|
tracer?.trace('unAuthorize:noToken', {});
|
|
1389
|
-
res.status(400).send(tracer
|
|
1409
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1390
1410
|
success = false;
|
|
1391
1411
|
}
|
|
1392
1412
|
}
|
|
1393
1413
|
catch (e) {
|
|
1394
1414
|
logger.error('Unauthorize failed', { platform: platformName, stack: e.stack });
|
|
1395
1415
|
tracer?.traceError('unAuthorize:error', e, { platform: platformName });
|
|
1396
|
-
res.status(400).send(tracer
|
|
1416
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1397
1417
|
success = false;
|
|
1398
1418
|
}
|
|
1399
1419
|
const requestEndTime = new Date().getTime();
|
|
@@ -1417,24 +1437,23 @@ function createCoreRouter() {
|
|
|
1417
1437
|
tracer?.trace('userInfoHash:start', { query: req.query });
|
|
1418
1438
|
const extensionId = util.getHashValue(req.query.extensionId, process.env.HASH_KEY);
|
|
1419
1439
|
const accountId = util.getHashValue(req.query.accountId, process.env.HASH_KEY);
|
|
1420
|
-
res.status(200).send(tracer
|
|
1440
|
+
res.status(200).send(wrapDebugResponse(tracer, { extensionId, accountId }));
|
|
1421
1441
|
}
|
|
1422
1442
|
catch (e) {
|
|
1423
1443
|
logger.error('Get user info hash failed', { stack: e.stack });
|
|
1424
|
-
res.status(400).send(tracer
|
|
1444
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1425
1445
|
tracer?.traceError('userInfoHash:error', e);
|
|
1426
1446
|
}
|
|
1427
|
-
})
|
|
1447
|
+
});
|
|
1428
1448
|
router.get('/contact', async function (req, res) {
|
|
1429
1449
|
const requestStartTime = new Date().getTime();
|
|
1430
1450
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
1431
1451
|
tracer?.trace('findContact:start', { query: req.query });
|
|
1432
|
-
|
|
1433
1452
|
let platformName = null;
|
|
1434
1453
|
let success = false;
|
|
1435
1454
|
let resultCount = 0;
|
|
1436
1455
|
let extraData = {};
|
|
1437
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1456
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1438
1457
|
try {
|
|
1439
1458
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1440
1459
|
if (jwtToken) {
|
|
@@ -1442,7 +1461,7 @@ function createCoreRouter() {
|
|
|
1442
1461
|
tracer?.trace('findContact:jwtDecoded', { decodedToken });
|
|
1443
1462
|
if (!decodedToken) {
|
|
1444
1463
|
tracer?.trace('findContact:invalidToken', {});
|
|
1445
|
-
res.status(400).send(tracer
|
|
1464
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1446
1465
|
return;
|
|
1447
1466
|
}
|
|
1448
1467
|
const { id: userId, platform } = decodedToken;
|
|
@@ -1457,12 +1476,12 @@ function createCoreRouter() {
|
|
|
1457
1476
|
isForceRefreshAccountData: req.query?.isForceRefreshAccountData === 'true'
|
|
1458
1477
|
});
|
|
1459
1478
|
if (isRevokeUserSession) {
|
|
1460
|
-
res.status(401).send(tracer
|
|
1479
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
1461
1480
|
success = false;
|
|
1462
1481
|
}
|
|
1463
1482
|
else {
|
|
1464
1483
|
tracer?.trace('findContact:result', { successful, returnMessage, contact });
|
|
1465
|
-
res.status(200).send(tracer
|
|
1484
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, returnMessage, contact }));
|
|
1466
1485
|
if (successful) {
|
|
1467
1486
|
const nonNewContact = contact?.filter(c => !c.isNewContact) ?? [];
|
|
1468
1487
|
resultCount = nonNewContact.length;
|
|
@@ -1475,7 +1494,7 @@ function createCoreRouter() {
|
|
|
1475
1494
|
}
|
|
1476
1495
|
else {
|
|
1477
1496
|
tracer?.trace('findContact:noToken', {});
|
|
1478
|
-
res.status(400).send(tracer
|
|
1497
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1479
1498
|
success = false;
|
|
1480
1499
|
}
|
|
1481
1500
|
}
|
|
@@ -1483,7 +1502,7 @@ function createCoreRouter() {
|
|
|
1483
1502
|
logger.error('Find contact failed', { platform: platformName, stack: e.stack });
|
|
1484
1503
|
tracer?.traceError('findContact:error', e, { platform: platformName });
|
|
1485
1504
|
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
1486
|
-
res.status(400).send(tracer
|
|
1505
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1487
1506
|
success = false;
|
|
1488
1507
|
}
|
|
1489
1508
|
const requestEndTime = new Date().getTime();
|
|
@@ -1512,25 +1531,25 @@ function createCoreRouter() {
|
|
|
1512
1531
|
let platformName = null;
|
|
1513
1532
|
let success = false;
|
|
1514
1533
|
let extraData = {};
|
|
1515
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1534
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1516
1535
|
try {
|
|
1517
1536
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1518
1537
|
if (jwtToken) {
|
|
1519
1538
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
1520
1539
|
if (!decodedToken) {
|
|
1521
1540
|
tracer?.trace('createContact:invalidToken', {});
|
|
1522
|
-
res.status(400).send(tracer
|
|
1541
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1523
1542
|
return;
|
|
1524
1543
|
}
|
|
1525
1544
|
const { id: userId, platform } = decodedToken;
|
|
1526
1545
|
platformName = platform;
|
|
1527
1546
|
const { successful, returnMessage, contact, extraDataTracking, isRevokeUserSession } = await contactCore.createContact({ platform, userId, phoneNumber: req.body.phoneNumber, newContactName: req.body.newContactName, newContactType: req.body.newContactType, additionalSubmission: req.body.additionalSubmission });
|
|
1528
1547
|
if (isRevokeUserSession) {
|
|
1529
|
-
res.status(401).send(tracer
|
|
1548
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
1530
1549
|
success = false;
|
|
1531
1550
|
}
|
|
1532
1551
|
else {
|
|
1533
|
-
res.status(200).send(tracer
|
|
1552
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, returnMessage, contact }));
|
|
1534
1553
|
success = true;
|
|
1535
1554
|
if (extraDataTracking) {
|
|
1536
1555
|
extraData = extraDataTracking;
|
|
@@ -1539,7 +1558,7 @@ function createCoreRouter() {
|
|
|
1539
1558
|
}
|
|
1540
1559
|
else {
|
|
1541
1560
|
tracer?.trace('createContact:noToken', {});
|
|
1542
|
-
res.status(400).send(tracer
|
|
1561
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1543
1562
|
success = false;
|
|
1544
1563
|
}
|
|
1545
1564
|
}
|
|
@@ -1547,7 +1566,7 @@ function createCoreRouter() {
|
|
|
1547
1566
|
logger.error('Create contact failed', { platform: platformName, stack: e.stack });
|
|
1548
1567
|
tracer?.traceError('createContact:error', e, { platform: platformName });
|
|
1549
1568
|
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
1550
|
-
res.status(400).send(tracer
|
|
1569
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1551
1570
|
success = false;
|
|
1552
1571
|
}
|
|
1553
1572
|
const requestEndTime = new Date().getTime();
|
|
@@ -1568,7 +1587,6 @@ function createCoreRouter() {
|
|
|
1568
1587
|
eventAddedVia
|
|
1569
1588
|
});
|
|
1570
1589
|
});
|
|
1571
|
-
|
|
1572
1590
|
router.get('/appointments', async function (req, res) {
|
|
1573
1591
|
const requestStartTime = new Date().getTime();
|
|
1574
1592
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
@@ -1576,14 +1594,14 @@ function createCoreRouter() {
|
|
|
1576
1594
|
let platformName = null;
|
|
1577
1595
|
let success = false;
|
|
1578
1596
|
let extraData = {};
|
|
1579
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1597
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1580
1598
|
try {
|
|
1581
|
-
const jwtToken = req.query.jwtToken;
|
|
1599
|
+
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1582
1600
|
if (jwtToken) {
|
|
1583
1601
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
1584
1602
|
if (!decodedToken) {
|
|
1585
1603
|
tracer?.trace('listAppointments:invalidToken', {});
|
|
1586
|
-
res.status(400).send(tracer
|
|
1604
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1587
1605
|
return;
|
|
1588
1606
|
}
|
|
1589
1607
|
const { id: userId, platform } = decodedToken;
|
|
@@ -1593,11 +1611,11 @@ function createCoreRouter() {
|
|
|
1593
1611
|
const forceSync = req.query.forceSync === 'true';
|
|
1594
1612
|
const { successful, appointments, returnMessage, extraDataTracking, isRevokeUserSession } = await appointmentCore.listAppointments({ platform, userId, range, mineOnly, forceSync });
|
|
1595
1613
|
if (isRevokeUserSession) {
|
|
1596
|
-
res.status(401).send(tracer
|
|
1614
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
1597
1615
|
success = false;
|
|
1598
1616
|
}
|
|
1599
1617
|
else {
|
|
1600
|
-
res.status(200).send(tracer
|
|
1618
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, appointments, returnMessage }));
|
|
1601
1619
|
success = true;
|
|
1602
1620
|
if (extraDataTracking) {
|
|
1603
1621
|
extraData = extraDataTracking;
|
|
@@ -1610,7 +1628,7 @@ function createCoreRouter() {
|
|
|
1610
1628
|
}
|
|
1611
1629
|
else {
|
|
1612
1630
|
tracer?.trace('listAppointments:noToken', {});
|
|
1613
|
-
res.status(400).send(tracer
|
|
1631
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1614
1632
|
success = false;
|
|
1615
1633
|
}
|
|
1616
1634
|
}
|
|
@@ -1618,7 +1636,7 @@ function createCoreRouter() {
|
|
|
1618
1636
|
logger.error('List appointments failed', { platform: platformName, stack: e.stack });
|
|
1619
1637
|
tracer?.traceError('listAppointments:error', e, { platform: platformName });
|
|
1620
1638
|
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
1621
|
-
res.status(400).send(tracer
|
|
1639
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1622
1640
|
success = false;
|
|
1623
1641
|
}
|
|
1624
1642
|
const requestEndTime = new Date().getTime();
|
|
@@ -1639,7 +1657,6 @@ function createCoreRouter() {
|
|
|
1639
1657
|
eventAddedVia
|
|
1640
1658
|
});
|
|
1641
1659
|
});
|
|
1642
|
-
|
|
1643
1660
|
router.post('/appointments', async function (req, res) {
|
|
1644
1661
|
const requestStartTime = new Date().getTime();
|
|
1645
1662
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
@@ -1647,14 +1664,14 @@ function createCoreRouter() {
|
|
|
1647
1664
|
let platformName = null;
|
|
1648
1665
|
let success = false;
|
|
1649
1666
|
let extraData = {};
|
|
1650
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1667
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1651
1668
|
try {
|
|
1652
|
-
const jwtToken = req.query.jwtToken;
|
|
1669
|
+
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1653
1670
|
if (jwtToken) {
|
|
1654
1671
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
1655
1672
|
if (!decodedToken) {
|
|
1656
1673
|
tracer?.trace('createAppointment:invalidToken', {});
|
|
1657
|
-
res.status(400).send(tracer
|
|
1674
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1658
1675
|
return;
|
|
1659
1676
|
}
|
|
1660
1677
|
const { id: userId, platform } = decodedToken;
|
|
@@ -1662,20 +1679,20 @@ function createCoreRouter() {
|
|
|
1662
1679
|
const payload = req.body?.payload ?? req.body;
|
|
1663
1680
|
const { successful, appointmentId, appointment, returnMessage, extraDataTracking, isRevokeUserSession } = await appointmentCore.createAppointment({ platform, userId, payload });
|
|
1664
1681
|
if (isRevokeUserSession) {
|
|
1665
|
-
res.status(401).send(tracer
|
|
1682
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
1666
1683
|
success = false;
|
|
1667
1684
|
}
|
|
1668
1685
|
else {
|
|
1669
1686
|
if (extraDataTracking) {
|
|
1670
1687
|
extraData = extraDataTracking;
|
|
1671
1688
|
}
|
|
1672
|
-
res.status(200).send(tracer
|
|
1689
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, appointmentId, appointment, returnMessage }));
|
|
1673
1690
|
success = true;
|
|
1674
1691
|
}
|
|
1675
1692
|
}
|
|
1676
1693
|
else {
|
|
1677
1694
|
tracer?.trace('createAppointment:noToken', {});
|
|
1678
|
-
res.status(400).send(tracer
|
|
1695
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1679
1696
|
success = false;
|
|
1680
1697
|
}
|
|
1681
1698
|
}
|
|
@@ -1683,7 +1700,7 @@ function createCoreRouter() {
|
|
|
1683
1700
|
logger.error('Create appointment failed', { platform: platformName, stack: e.stack });
|
|
1684
1701
|
tracer?.traceError('createAppointment:error', e, { platform: platformName });
|
|
1685
1702
|
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
1686
|
-
res.status(400).send(tracer
|
|
1703
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1687
1704
|
success = false;
|
|
1688
1705
|
}
|
|
1689
1706
|
const requestEndTime = new Date().getTime();
|
|
@@ -1704,7 +1721,6 @@ function createCoreRouter() {
|
|
|
1704
1721
|
eventAddedVia
|
|
1705
1722
|
});
|
|
1706
1723
|
});
|
|
1707
|
-
|
|
1708
1724
|
router.patch('/appointments/:appointmentId', async function (req, res) {
|
|
1709
1725
|
const requestStartTime = new Date().getTime();
|
|
1710
1726
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
@@ -1712,14 +1728,14 @@ function createCoreRouter() {
|
|
|
1712
1728
|
let platformName = null;
|
|
1713
1729
|
let success = false;
|
|
1714
1730
|
let extraData = {};
|
|
1715
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1731
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1716
1732
|
try {
|
|
1717
|
-
const jwtToken = req.query.jwtToken;
|
|
1733
|
+
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1718
1734
|
if (jwtToken) {
|
|
1719
1735
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
1720
1736
|
if (!decodedToken) {
|
|
1721
1737
|
tracer?.trace('updateAppointment:invalidToken', {});
|
|
1722
|
-
res.status(400).send(tracer
|
|
1738
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1723
1739
|
return;
|
|
1724
1740
|
}
|
|
1725
1741
|
const { id: userId, platform } = decodedToken;
|
|
@@ -1728,20 +1744,20 @@ function createCoreRouter() {
|
|
|
1728
1744
|
const patchBody = req.body?.patch ?? req.body;
|
|
1729
1745
|
const { successful, appointment, returnMessage, extraDataTracking, isRevokeUserSession } = await appointmentCore.updateAppointment({ platform, userId, appointmentId, patchBody });
|
|
1730
1746
|
if (isRevokeUserSession) {
|
|
1731
|
-
res.status(401).send(tracer
|
|
1747
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
1732
1748
|
success = false;
|
|
1733
1749
|
}
|
|
1734
1750
|
else {
|
|
1735
1751
|
if (extraDataTracking) {
|
|
1736
1752
|
extraData = extraDataTracking;
|
|
1737
1753
|
}
|
|
1738
|
-
res.status(200).send(tracer
|
|
1754
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, appointmentId, appointment, returnMessage }));
|
|
1739
1755
|
success = true;
|
|
1740
1756
|
}
|
|
1741
1757
|
}
|
|
1742
1758
|
else {
|
|
1743
1759
|
tracer?.trace('updateAppointment:noToken', {});
|
|
1744
|
-
res.status(400).send(tracer
|
|
1760
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1745
1761
|
success = false;
|
|
1746
1762
|
}
|
|
1747
1763
|
}
|
|
@@ -1749,7 +1765,7 @@ function createCoreRouter() {
|
|
|
1749
1765
|
logger.error('Update appointment failed', { platform: platformName, stack: e.stack });
|
|
1750
1766
|
tracer?.traceError('updateAppointment:error', e, { platform: platformName });
|
|
1751
1767
|
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
1752
|
-
res.status(400).send(tracer
|
|
1768
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1753
1769
|
success = false;
|
|
1754
1770
|
}
|
|
1755
1771
|
const requestEndTime = new Date().getTime();
|
|
@@ -1770,7 +1786,81 @@ function createCoreRouter() {
|
|
|
1770
1786
|
eventAddedVia
|
|
1771
1787
|
});
|
|
1772
1788
|
});
|
|
1773
|
-
|
|
1789
|
+
router.post('/appointments/:appointmentId/status', async function (req, res) {
|
|
1790
|
+
const requestStartTime = new Date().getTime();
|
|
1791
|
+
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
1792
|
+
tracer?.trace('updateAppointmentStatus:start', { query: req.query, params: req.params });
|
|
1793
|
+
let platformName = null;
|
|
1794
|
+
let success = false;
|
|
1795
|
+
let extraData = {};
|
|
1796
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1797
|
+
try {
|
|
1798
|
+
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1799
|
+
if (jwtToken) {
|
|
1800
|
+
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
1801
|
+
if (!decodedToken) {
|
|
1802
|
+
tracer?.trace('updateAppointmentStatus:invalidToken', {});
|
|
1803
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1804
|
+
return;
|
|
1805
|
+
}
|
|
1806
|
+
const status = String(req.body?.status || '').trim().toLowerCase();
|
|
1807
|
+
if (!status) {
|
|
1808
|
+
tracer?.trace('updateAppointmentStatus:noStatus', {});
|
|
1809
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Appointment status is required'));
|
|
1810
|
+
return;
|
|
1811
|
+
}
|
|
1812
|
+
const { id: userId, platform } = decodedToken;
|
|
1813
|
+
platformName = platform;
|
|
1814
|
+
const appointmentId = req.params.appointmentId;
|
|
1815
|
+
const { successful, appointment, returnMessage, extraDataTracking, isRevokeUserSession } = await appointmentCore.updateAppointment({
|
|
1816
|
+
platform,
|
|
1817
|
+
userId,
|
|
1818
|
+
appointmentId,
|
|
1819
|
+
patchBody: { status }
|
|
1820
|
+
});
|
|
1821
|
+
if (isRevokeUserSession) {
|
|
1822
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
1823
|
+
success = false;
|
|
1824
|
+
}
|
|
1825
|
+
else {
|
|
1826
|
+
if (extraDataTracking) {
|
|
1827
|
+
extraData = extraDataTracking;
|
|
1828
|
+
}
|
|
1829
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, appointmentId, appointment, returnMessage }));
|
|
1830
|
+
success = true;
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
else {
|
|
1834
|
+
tracer?.trace('updateAppointmentStatus:noToken', {});
|
|
1835
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1836
|
+
success = false;
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
catch (e) {
|
|
1840
|
+
logger.error('Update appointment status failed', { platform: platformName, stack: e.stack });
|
|
1841
|
+
tracer?.traceError('updateAppointmentStatus:error', e, { platform: platformName });
|
|
1842
|
+
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
1843
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1844
|
+
success = false;
|
|
1845
|
+
}
|
|
1846
|
+
const requestEndTime = new Date().getTime();
|
|
1847
|
+
analytics.track({
|
|
1848
|
+
eventName: 'Update appointment status',
|
|
1849
|
+
interfaceName: 'updateAppointmentStatus',
|
|
1850
|
+
connectorName: platformName,
|
|
1851
|
+
accountId: hashedAccountId,
|
|
1852
|
+
extensionId: hashedExtensionId,
|
|
1853
|
+
success,
|
|
1854
|
+
requestDuration: (requestEndTime - requestStartTime) / 1000,
|
|
1855
|
+
userAgent,
|
|
1856
|
+
ip,
|
|
1857
|
+
author,
|
|
1858
|
+
extras: {
|
|
1859
|
+
...extraData
|
|
1860
|
+
},
|
|
1861
|
+
eventAddedVia
|
|
1862
|
+
});
|
|
1863
|
+
});
|
|
1774
1864
|
router.get('/appointments/:appointmentId/refresh', async function (req, res) {
|
|
1775
1865
|
const requestStartTime = new Date().getTime();
|
|
1776
1866
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
@@ -1778,14 +1868,14 @@ function createCoreRouter() {
|
|
|
1778
1868
|
let platformName = null;
|
|
1779
1869
|
let success = false;
|
|
1780
1870
|
let extraData = {};
|
|
1781
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1871
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1782
1872
|
try {
|
|
1783
|
-
const jwtToken = req.query.jwtToken;
|
|
1873
|
+
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1784
1874
|
if (jwtToken) {
|
|
1785
1875
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
1786
1876
|
if (!decodedToken) {
|
|
1787
1877
|
tracer?.trace('refreshAppointment:invalidToken', {});
|
|
1788
|
-
res.status(400).send(tracer
|
|
1878
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1789
1879
|
return;
|
|
1790
1880
|
}
|
|
1791
1881
|
const { id: userId, platform } = decodedToken;
|
|
@@ -1793,20 +1883,20 @@ function createCoreRouter() {
|
|
|
1793
1883
|
const appointmentId = req.params.appointmentId;
|
|
1794
1884
|
const { successful, appointment, returnMessage, extraDataTracking, isRevokeUserSession } = await appointmentCore.refreshAppointment({ platform, userId, appointmentId });
|
|
1795
1885
|
if (isRevokeUserSession) {
|
|
1796
|
-
res.status(401).send(tracer
|
|
1886
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
1797
1887
|
success = false;
|
|
1798
1888
|
}
|
|
1799
1889
|
else {
|
|
1800
1890
|
if (extraDataTracking) {
|
|
1801
1891
|
extraData = extraDataTracking;
|
|
1802
1892
|
}
|
|
1803
|
-
res.status(200).send(tracer
|
|
1893
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, appointmentId, appointment, returnMessage }));
|
|
1804
1894
|
success = true;
|
|
1805
1895
|
}
|
|
1806
1896
|
}
|
|
1807
1897
|
else {
|
|
1808
1898
|
tracer?.trace('refreshAppointment:noToken', {});
|
|
1809
|
-
res.status(400).send(tracer
|
|
1899
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1810
1900
|
success = false;
|
|
1811
1901
|
}
|
|
1812
1902
|
}
|
|
@@ -1814,7 +1904,7 @@ function createCoreRouter() {
|
|
|
1814
1904
|
logger.error('Refresh appointment failed', { platform: platformName, stack: e.stack });
|
|
1815
1905
|
tracer?.traceError('refreshAppointment:error', e, { platform: platformName });
|
|
1816
1906
|
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
1817
|
-
res.status(400).send(tracer
|
|
1907
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1818
1908
|
success = false;
|
|
1819
1909
|
}
|
|
1820
1910
|
const requestEndTime = new Date().getTime();
|
|
@@ -1835,7 +1925,6 @@ function createCoreRouter() {
|
|
|
1835
1925
|
eventAddedVia
|
|
1836
1926
|
});
|
|
1837
1927
|
});
|
|
1838
|
-
|
|
1839
1928
|
router.post('/appointments/:appointmentId/confirm', async function (req, res) {
|
|
1840
1929
|
const requestStartTime = new Date().getTime();
|
|
1841
1930
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
@@ -1843,14 +1932,14 @@ function createCoreRouter() {
|
|
|
1843
1932
|
let platformName = null;
|
|
1844
1933
|
let success = false;
|
|
1845
1934
|
let extraData = {};
|
|
1846
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1935
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1847
1936
|
try {
|
|
1848
|
-
const jwtToken = req.query.jwtToken;
|
|
1937
|
+
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1849
1938
|
if (jwtToken) {
|
|
1850
1939
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
1851
1940
|
if (!decodedToken) {
|
|
1852
1941
|
tracer?.trace('confirmAppointment:invalidToken', {});
|
|
1853
|
-
res.status(400).send(tracer
|
|
1942
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1854
1943
|
return;
|
|
1855
1944
|
}
|
|
1856
1945
|
const { id: userId, platform } = decodedToken;
|
|
@@ -1858,20 +1947,20 @@ function createCoreRouter() {
|
|
|
1858
1947
|
const appointmentId = req.params.appointmentId;
|
|
1859
1948
|
const { successful, appointment, returnMessage, extraDataTracking, isRevokeUserSession } = await appointmentCore.confirmAppointment({ platform, userId, appointmentId });
|
|
1860
1949
|
if (isRevokeUserSession) {
|
|
1861
|
-
res.status(401).send(tracer
|
|
1950
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
1862
1951
|
success = false;
|
|
1863
1952
|
}
|
|
1864
1953
|
else {
|
|
1865
1954
|
if (extraDataTracking) {
|
|
1866
1955
|
extraData = extraDataTracking;
|
|
1867
1956
|
}
|
|
1868
|
-
res.status(200).send(tracer
|
|
1957
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, appointmentId, appointment, returnMessage }));
|
|
1869
1958
|
success = true;
|
|
1870
1959
|
}
|
|
1871
1960
|
}
|
|
1872
1961
|
else {
|
|
1873
1962
|
tracer?.trace('confirmAppointment:noToken', {});
|
|
1874
|
-
res.status(400).send(tracer
|
|
1963
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1875
1964
|
success = false;
|
|
1876
1965
|
}
|
|
1877
1966
|
}
|
|
@@ -1879,7 +1968,7 @@ function createCoreRouter() {
|
|
|
1879
1968
|
logger.error('Confirm appointment failed', { platform: platformName, stack: e.stack });
|
|
1880
1969
|
tracer?.traceError('confirmAppointment:error', e, { platform: platformName });
|
|
1881
1970
|
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
1882
|
-
res.status(400).send(tracer
|
|
1971
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1883
1972
|
success = false;
|
|
1884
1973
|
}
|
|
1885
1974
|
const requestEndTime = new Date().getTime();
|
|
@@ -1900,7 +1989,6 @@ function createCoreRouter() {
|
|
|
1900
1989
|
eventAddedVia
|
|
1901
1990
|
});
|
|
1902
1991
|
});
|
|
1903
|
-
|
|
1904
1992
|
router.post('/appointments/:appointmentId/cancel', async function (req, res) {
|
|
1905
1993
|
const requestStartTime = new Date().getTime();
|
|
1906
1994
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
@@ -1908,14 +1996,14 @@ function createCoreRouter() {
|
|
|
1908
1996
|
let platformName = null;
|
|
1909
1997
|
let success = false;
|
|
1910
1998
|
let extraData = {};
|
|
1911
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
1999
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1912
2000
|
try {
|
|
1913
|
-
const jwtToken = req.query.jwtToken;
|
|
2001
|
+
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1914
2002
|
if (jwtToken) {
|
|
1915
2003
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
1916
2004
|
if (!decodedToken) {
|
|
1917
2005
|
tracer?.trace('cancelAppointment:invalidToken', {});
|
|
1918
|
-
res.status(400).send(tracer
|
|
2006
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1919
2007
|
return;
|
|
1920
2008
|
}
|
|
1921
2009
|
const { id: userId, platform } = decodedToken;
|
|
@@ -1923,20 +2011,20 @@ function createCoreRouter() {
|
|
|
1923
2011
|
const appointmentId = req.params.appointmentId;
|
|
1924
2012
|
const { successful, appointment, returnMessage, extraDataTracking, isRevokeUserSession } = await appointmentCore.cancelAppointment({ platform, userId, appointmentId });
|
|
1925
2013
|
if (isRevokeUserSession) {
|
|
1926
|
-
res.status(401).send(tracer
|
|
2014
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
1927
2015
|
success = false;
|
|
1928
2016
|
}
|
|
1929
2017
|
else {
|
|
1930
2018
|
if (extraDataTracking) {
|
|
1931
2019
|
extraData = extraDataTracking;
|
|
1932
2020
|
}
|
|
1933
|
-
res.status(200).send(tracer
|
|
2021
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, appointmentId, appointment, returnMessage }));
|
|
1934
2022
|
success = true;
|
|
1935
2023
|
}
|
|
1936
2024
|
}
|
|
1937
2025
|
else {
|
|
1938
2026
|
tracer?.trace('cancelAppointment:noToken', {});
|
|
1939
|
-
res.status(400).send(tracer
|
|
2027
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1940
2028
|
success = false;
|
|
1941
2029
|
}
|
|
1942
2030
|
}
|
|
@@ -1944,7 +2032,7 @@ function createCoreRouter() {
|
|
|
1944
2032
|
logger.error('Cancel appointment failed', { platform: platformName, stack: e.stack });
|
|
1945
2033
|
tracer?.traceError('cancelAppointment:error', e, { platform: platformName });
|
|
1946
2034
|
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
1947
|
-
res.status(400).send(tracer
|
|
2035
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1948
2036
|
success = false;
|
|
1949
2037
|
}
|
|
1950
2038
|
const requestEndTime = new Date().getTime();
|
|
@@ -1972,30 +2060,31 @@ function createCoreRouter() {
|
|
|
1972
2060
|
let platformName = null;
|
|
1973
2061
|
let success = false;
|
|
1974
2062
|
let extraData = {};
|
|
1975
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2063
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
1976
2064
|
try {
|
|
1977
2065
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
1978
2066
|
if (jwtToken) {
|
|
1979
2067
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
1980
2068
|
if (!decodedToken) {
|
|
1981
2069
|
tracer?.trace('saveNoteCache:invalidToken', {});
|
|
1982
|
-
res.status(400).send(tracer
|
|
2070
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
1983
2071
|
return;
|
|
1984
2072
|
}
|
|
1985
2073
|
const { id: userId, platform } = decodedToken;
|
|
1986
2074
|
platformName = platform;
|
|
1987
2075
|
const { successful, returnMessage, extraDataTracking } = await logCore.saveNoteCache({ platform, userId, sessionId: req.body.sessionId, note: req.body.note });
|
|
1988
|
-
res.status(200).send(tracer
|
|
2076
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
1989
2077
|
success = true;
|
|
1990
2078
|
if (extraDataTracking) {
|
|
1991
2079
|
extraData = extraDataTracking;
|
|
1992
2080
|
}
|
|
1993
2081
|
}
|
|
1994
|
-
}
|
|
2082
|
+
}
|
|
2083
|
+
catch (e) {
|
|
1995
2084
|
logger.error('Save note cache failed', { platform: platformName, stack: e.stack });
|
|
1996
2085
|
tracer?.traceError('saveNoteCache:error', e, { platform: platformName });
|
|
1997
2086
|
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
1998
|
-
res.status(400).send(tracer
|
|
2087
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
1999
2088
|
success = false;
|
|
2000
2089
|
}
|
|
2001
2090
|
const requestEndTime = new Date().getTime();
|
|
@@ -2015,7 +2104,7 @@ function createCoreRouter() {
|
|
|
2015
2104
|
...extraData
|
|
2016
2105
|
}
|
|
2017
2106
|
});
|
|
2018
|
-
})
|
|
2107
|
+
});
|
|
2019
2108
|
router.get('/callLog', async function (req, res) {
|
|
2020
2109
|
const requestStartTime = new Date().getTime();
|
|
2021
2110
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
@@ -2023,14 +2112,14 @@ function createCoreRouter() {
|
|
|
2023
2112
|
let platformName = null;
|
|
2024
2113
|
let success = false;
|
|
2025
2114
|
let extraData = {};
|
|
2026
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2115
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2027
2116
|
try {
|
|
2028
2117
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2029
2118
|
if (jwtToken) {
|
|
2030
2119
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
2031
2120
|
if (!decodedToken) {
|
|
2032
2121
|
tracer?.trace('getCallLog:invalidToken', {});
|
|
2033
|
-
res.status(400).send(tracer
|
|
2122
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2034
2123
|
return;
|
|
2035
2124
|
}
|
|
2036
2125
|
const { id: userId, platform } = decodedToken;
|
|
@@ -2044,11 +2133,11 @@ function createCoreRouter() {
|
|
|
2044
2133
|
requireDetails: req.query.requireDetails === 'true'
|
|
2045
2134
|
});
|
|
2046
2135
|
if (isRevokeUserSession) {
|
|
2047
|
-
res.status(401).send(tracer
|
|
2136
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
2048
2137
|
success = false;
|
|
2049
2138
|
}
|
|
2050
2139
|
else {
|
|
2051
|
-
res.status(200).send(tracer
|
|
2140
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, logs, returnMessage }));
|
|
2052
2141
|
success = true;
|
|
2053
2142
|
if (extraDataTracking) {
|
|
2054
2143
|
extraData = extraDataTracking;
|
|
@@ -2058,14 +2147,14 @@ function createCoreRouter() {
|
|
|
2058
2147
|
}
|
|
2059
2148
|
else {
|
|
2060
2149
|
tracer?.trace('getCallLog:noToken', {});
|
|
2061
|
-
res.status(400).send(tracer
|
|
2150
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2062
2151
|
success = false;
|
|
2063
2152
|
}
|
|
2064
2153
|
}
|
|
2065
2154
|
catch (e) {
|
|
2066
2155
|
logger.error('Get call log failed', { platform: platformName, stack: e.stack });
|
|
2067
2156
|
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
2068
|
-
res.status(400).send(tracer
|
|
2157
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
2069
2158
|
tracer?.traceError('getCallLog:error', e, { platform: platformName });
|
|
2070
2159
|
success = false;
|
|
2071
2160
|
}
|
|
@@ -2094,41 +2183,41 @@ function createCoreRouter() {
|
|
|
2094
2183
|
let platformName = null;
|
|
2095
2184
|
let success = false;
|
|
2096
2185
|
let extraData = {};
|
|
2097
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2186
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2098
2187
|
try {
|
|
2099
2188
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2100
2189
|
if (jwtToken) {
|
|
2101
2190
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
2102
2191
|
if (!decodedToken) {
|
|
2103
2192
|
tracer?.trace('createCallLog:invalidToken', {});
|
|
2104
|
-
res.status(400).send(tracer
|
|
2193
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2105
2194
|
return;
|
|
2106
2195
|
}
|
|
2107
2196
|
const { id: userId, platform } = decodedToken;
|
|
2108
2197
|
platformName = platform;
|
|
2109
2198
|
const { successful, logId, returnMessage, extraDataTracking, isRevokeUserSession } = await logCore.createCallLog({ jwtToken, platform, userId, incomingData: req.body, hashedAccountId: hashedAccountId ?? util.getHashValue(req.body.logInfo?.accountId, process.env.HASH_KEY), isFromSSCL: userAgent === 'SSCL' });
|
|
2110
2199
|
if (isRevokeUserSession) {
|
|
2111
|
-
res.status(401).send(tracer
|
|
2200
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
2112
2201
|
success = false;
|
|
2113
2202
|
}
|
|
2114
2203
|
else {
|
|
2115
2204
|
if (extraDataTracking) {
|
|
2116
2205
|
extraData = extraDataTracking;
|
|
2117
2206
|
}
|
|
2118
|
-
res.status(200).send(tracer
|
|
2207
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, logId, returnMessage }));
|
|
2119
2208
|
success = true;
|
|
2120
2209
|
}
|
|
2121
2210
|
}
|
|
2122
2211
|
else {
|
|
2123
2212
|
tracer?.trace('createCallLog:noToken', {});
|
|
2124
|
-
res.status(400).send(tracer
|
|
2213
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2125
2214
|
success = false;
|
|
2126
2215
|
}
|
|
2127
2216
|
}
|
|
2128
2217
|
catch (e) {
|
|
2129
2218
|
logger.error('Create call log failed', { platform: platformName, stack: e.stack });
|
|
2130
2219
|
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
2131
|
-
res.status(400).send(tracer
|
|
2220
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
2132
2221
|
tracer?.traceError('createCallLog:error', e, { platform: platformName });
|
|
2133
2222
|
success = false;
|
|
2134
2223
|
}
|
|
@@ -2157,14 +2246,14 @@ function createCoreRouter() {
|
|
|
2157
2246
|
let platformName = null;
|
|
2158
2247
|
let success = false;
|
|
2159
2248
|
let extraData = {};
|
|
2160
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2249
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2161
2250
|
try {
|
|
2162
2251
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2163
2252
|
if (jwtToken) {
|
|
2164
2253
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
2165
2254
|
if (!decodedToken) {
|
|
2166
2255
|
tracer?.trace('updateCallLog:invalidToken', {});
|
|
2167
|
-
res.status(400).send(tracer
|
|
2256
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2168
2257
|
return;
|
|
2169
2258
|
}
|
|
2170
2259
|
const { id: userId, platform } = decodedToken;
|
|
@@ -2173,19 +2262,19 @@ function createCoreRouter() {
|
|
|
2173
2262
|
if (extraDataTracking) {
|
|
2174
2263
|
extraData = extraDataTracking;
|
|
2175
2264
|
}
|
|
2176
|
-
res.status(200).send(tracer
|
|
2265
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, logId, updatedNote, returnMessage }));
|
|
2177
2266
|
success = true;
|
|
2178
2267
|
}
|
|
2179
2268
|
else {
|
|
2180
2269
|
tracer?.trace('updateCallLog:noToken', {});
|
|
2181
|
-
res.status(400).send(tracer
|
|
2270
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2182
2271
|
success = false;
|
|
2183
2272
|
}
|
|
2184
2273
|
}
|
|
2185
2274
|
catch (e) {
|
|
2186
2275
|
logger.error('Update call log failed', { platform: platformName, stack: e.stack });
|
|
2187
2276
|
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
2188
|
-
res.status(400).send(tracer
|
|
2277
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
2189
2278
|
tracer?.traceError('updateCallLog:error', e, { platform: platformName });
|
|
2190
2279
|
success = false;
|
|
2191
2280
|
}
|
|
@@ -2214,21 +2303,21 @@ function createCoreRouter() {
|
|
|
2214
2303
|
let platformName = null;
|
|
2215
2304
|
let success = false;
|
|
2216
2305
|
let extraData = {};
|
|
2217
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2306
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2218
2307
|
try {
|
|
2219
2308
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2220
2309
|
if (jwtToken) {
|
|
2221
2310
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
2222
2311
|
if (!decodedToken) {
|
|
2223
2312
|
tracer?.trace('upsertCallDisposition:invalidJwtToken', {});
|
|
2224
|
-
res.status(400).send(tracer
|
|
2313
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Invalid JWT token'));
|
|
2225
2314
|
return;
|
|
2226
2315
|
}
|
|
2227
2316
|
const { id: userId, platform } = decodedToken;
|
|
2228
2317
|
platformName = platform;
|
|
2229
2318
|
if (!userId) {
|
|
2230
2319
|
tracer?.trace('upsertCallDisposition:invalidToken', {});
|
|
2231
|
-
res.status(400).send(tracer
|
|
2320
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2232
2321
|
return;
|
|
2233
2322
|
}
|
|
2234
2323
|
const { successful, returnMessage, extraDataTracking, isRevokeUserSession } = await dispositionCore.upsertCallDisposition({
|
|
@@ -2241,27 +2330,27 @@ function createCoreRouter() {
|
|
|
2241
2330
|
additionalSubmission: req.body.additionalSubmission
|
|
2242
2331
|
});
|
|
2243
2332
|
if (isRevokeUserSession) {
|
|
2244
|
-
res.status(401).send(tracer
|
|
2333
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
2245
2334
|
success = false;
|
|
2246
2335
|
}
|
|
2247
2336
|
else {
|
|
2248
2337
|
if (extraDataTracking) {
|
|
2249
2338
|
extraData = extraDataTracking;
|
|
2250
2339
|
}
|
|
2251
|
-
res.status(200).send(tracer
|
|
2340
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
2252
2341
|
success = true;
|
|
2253
2342
|
}
|
|
2254
2343
|
}
|
|
2255
2344
|
else {
|
|
2256
2345
|
tracer?.trace('upsertCallDisposition:noToken', {});
|
|
2257
|
-
res.status(400).send(tracer
|
|
2346
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2258
2347
|
success = false;
|
|
2259
2348
|
}
|
|
2260
2349
|
}
|
|
2261
2350
|
catch (e) {
|
|
2262
2351
|
logger.error('Upsert call disposition failed', { platform: platformName, stack: e.stack });
|
|
2263
2352
|
extraData.statusCode = e.response?.status ?? 'unknown';
|
|
2264
|
-
res.status(400).send(tracer
|
|
2353
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
2265
2354
|
tracer?.traceError('upsertCallDisposition:error', e, { platform: platformName });
|
|
2266
2355
|
success = false;
|
|
2267
2356
|
}
|
|
@@ -2291,41 +2380,41 @@ function createCoreRouter() {
|
|
|
2291
2380
|
let success = false;
|
|
2292
2381
|
let statusCode = 200;
|
|
2293
2382
|
let extraData = {};
|
|
2294
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2383
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2295
2384
|
try {
|
|
2296
2385
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2297
2386
|
if (jwtToken) {
|
|
2298
2387
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
2299
2388
|
if (!decodedToken) {
|
|
2300
2389
|
tracer?.trace('createMessageLog:invalidToken', {});
|
|
2301
|
-
res.status(400).send(tracer
|
|
2390
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2302
2391
|
return;
|
|
2303
2392
|
}
|
|
2304
2393
|
const { id: userId, platform } = decodedToken;
|
|
2305
2394
|
platformName = platform;
|
|
2306
2395
|
const { successful, returnMessage, logIds, extraDataTracking, isRevokeUserSession } = await logCore.createMessageLog({ platform, userId, incomingData: req.body });
|
|
2307
2396
|
if (isRevokeUserSession) {
|
|
2308
|
-
res.status(401).send(tracer
|
|
2397
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
2309
2398
|
success = false;
|
|
2310
2399
|
}
|
|
2311
2400
|
else {
|
|
2312
2401
|
if (extraDataTracking) {
|
|
2313
2402
|
extraData = extraDataTracking;
|
|
2314
2403
|
}
|
|
2315
|
-
res.status(200).send(tracer
|
|
2404
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, returnMessage, logIds }));
|
|
2316
2405
|
success = true;
|
|
2317
2406
|
}
|
|
2318
2407
|
}
|
|
2319
2408
|
else {
|
|
2320
2409
|
tracer?.trace('createMessageLog:noToken', {});
|
|
2321
|
-
res.status(400).send(tracer
|
|
2410
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2322
2411
|
success = false;
|
|
2323
2412
|
}
|
|
2324
2413
|
}
|
|
2325
2414
|
catch (e) {
|
|
2326
2415
|
logger.error('Create message log failed', { platform: platformName, stack: e.stack });
|
|
2327
2416
|
statusCode = e.response?.status ?? 'unknown';
|
|
2328
|
-
res.status(400).send(tracer
|
|
2417
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
2329
2418
|
tracer?.traceError('createMessageLog:error', e, { platform: platformName });
|
|
2330
2419
|
success = false;
|
|
2331
2420
|
}
|
|
@@ -2355,26 +2444,27 @@ function createCoreRouter() {
|
|
|
2355
2444
|
let platformName = null;
|
|
2356
2445
|
let success = false;
|
|
2357
2446
|
let statusCode = 200;
|
|
2358
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2447
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2359
2448
|
try {
|
|
2360
2449
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2361
2450
|
if (!jwtToken) {
|
|
2362
2451
|
tracer?.trace('scheduleCallDown:noToken', {});
|
|
2363
|
-
res.status(400).send(tracer
|
|
2452
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2364
2453
|
return;
|
|
2365
2454
|
}
|
|
2366
2455
|
try {
|
|
2367
|
-
const { id } = await calldown.schedule({ jwtToken, rcAccessToken: req
|
|
2456
|
+
const { id } = await calldown.schedule({ jwtToken, rcAccessToken: getRcAccessTokenFromRequest(req), body: req.body });
|
|
2368
2457
|
success = true;
|
|
2369
|
-
res.status(200).send(tracer
|
|
2458
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful: true, id }));
|
|
2370
2459
|
}
|
|
2371
2460
|
catch (e) {
|
|
2372
2461
|
return handleDatabaseError(e, 'Error scheduling call down');
|
|
2373
2462
|
}
|
|
2374
|
-
}
|
|
2463
|
+
}
|
|
2464
|
+
catch (e) {
|
|
2375
2465
|
logger.error('Schedule call down failed', { platform: platformName, stack: e.stack });
|
|
2376
2466
|
statusCode = e.response?.status ?? 'unknown';
|
|
2377
|
-
res.status(400).send(tracer
|
|
2467
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
2378
2468
|
tracer?.traceError('scheduleCallDown:error', e, { platform: platformName });
|
|
2379
2469
|
success = false;
|
|
2380
2470
|
}
|
|
@@ -2403,21 +2493,22 @@ function createCoreRouter() {
|
|
|
2403
2493
|
let platformName = null;
|
|
2404
2494
|
let success = false;
|
|
2405
2495
|
let statusCode = 200;
|
|
2406
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2496
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2407
2497
|
try {
|
|
2408
2498
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2409
2499
|
if (!jwtToken) {
|
|
2410
2500
|
tracer?.trace('getCallDownList:noToken', {});
|
|
2411
|
-
res.status(400).send(tracer
|
|
2501
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2412
2502
|
return;
|
|
2413
2503
|
}
|
|
2414
2504
|
const { items } = await calldown.list({ jwtToken, status: req.query.status });
|
|
2415
2505
|
success = true;
|
|
2416
|
-
res.status(200).send(tracer
|
|
2417
|
-
}
|
|
2506
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful: true, items }));
|
|
2507
|
+
}
|
|
2508
|
+
catch (e) {
|
|
2418
2509
|
logger.error('Get call down list failed', { platform: platformName, stack: e.stack });
|
|
2419
2510
|
statusCode = e.response?.status ?? 'unknown';
|
|
2420
|
-
res.status(400).send(tracer
|
|
2511
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
2421
2512
|
tracer?.traceError('getCallDownList:error', e, { platform: platformName });
|
|
2422
2513
|
success = false;
|
|
2423
2514
|
}
|
|
@@ -2444,28 +2535,29 @@ function createCoreRouter() {
|
|
|
2444
2535
|
let platformName = null;
|
|
2445
2536
|
let success = false;
|
|
2446
2537
|
let statusCode = 200;
|
|
2447
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2538
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2448
2539
|
try {
|
|
2449
2540
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2450
2541
|
const id = req.query.id;
|
|
2451
2542
|
if (!jwtToken) {
|
|
2452
2543
|
tracer?.trace('deleteCallDownItem:noToken', {});
|
|
2453
|
-
res.status(400).send(tracer
|
|
2544
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2454
2545
|
return;
|
|
2455
2546
|
}
|
|
2456
2547
|
const rid = req.params.id || id;
|
|
2457
2548
|
if (!rid) {
|
|
2458
2549
|
tracer?.trace('deleteCallDownItem:missingId', {});
|
|
2459
|
-
res.status(400).send(tracer
|
|
2550
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Missing id'));
|
|
2460
2551
|
return;
|
|
2461
2552
|
}
|
|
2462
2553
|
await calldown.remove({ jwtToken, id: rid });
|
|
2463
2554
|
success = true;
|
|
2464
|
-
res.status(200).send(tracer
|
|
2465
|
-
}
|
|
2555
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful: true }));
|
|
2556
|
+
}
|
|
2557
|
+
catch (e) {
|
|
2466
2558
|
logger.error('Delete call down item failed', { platform: platformName, stack: e.stack });
|
|
2467
2559
|
statusCode = e.response?.status ?? 'unknown';
|
|
2468
|
-
res.status(400).send(tracer
|
|
2560
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
2469
2561
|
tracer?.traceError('deleteCallDownItem:error', e, { platform: platformName });
|
|
2470
2562
|
success = false;
|
|
2471
2563
|
}
|
|
@@ -2492,27 +2584,28 @@ function createCoreRouter() {
|
|
|
2492
2584
|
let platformName = null;
|
|
2493
2585
|
let success = false;
|
|
2494
2586
|
let statusCode = 200;
|
|
2495
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2587
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2496
2588
|
try {
|
|
2497
2589
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2498
2590
|
if (!jwtToken) {
|
|
2499
2591
|
tracer?.trace('markCallDownCalled:noToken', {});
|
|
2500
|
-
res.status(400).send(tracer
|
|
2592
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2501
2593
|
return;
|
|
2502
2594
|
}
|
|
2503
2595
|
const id = req.params.id || req.body?.id;
|
|
2504
2596
|
if (!id) {
|
|
2505
2597
|
tracer?.trace('markCallDownCalled:missingId', {});
|
|
2506
|
-
res.status(400).send(tracer
|
|
2598
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Missing id'));
|
|
2507
2599
|
return;
|
|
2508
2600
|
}
|
|
2509
2601
|
await calldown.update({ jwtToken, id, updateData: req.body });
|
|
2510
2602
|
success = true;
|
|
2511
|
-
res.status(200).send(tracer
|
|
2512
|
-
}
|
|
2603
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful: true }));
|
|
2604
|
+
}
|
|
2605
|
+
catch (e) {
|
|
2513
2606
|
logger.error('Mark call down called failed', { platform: platformName, stack: e.stack });
|
|
2514
2607
|
statusCode = e.response?.status ?? 'unknown';
|
|
2515
|
-
res.status(400).send(tracer
|
|
2608
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
2516
2609
|
tracer?.traceError('markCallDownCalled:error', e, { platform: platformName });
|
|
2517
2610
|
success = false;
|
|
2518
2611
|
}
|
|
@@ -2539,14 +2632,14 @@ function createCoreRouter() {
|
|
|
2539
2632
|
let platformName = null;
|
|
2540
2633
|
let success = false;
|
|
2541
2634
|
let statusCode = 200;
|
|
2542
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2635
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2543
2636
|
try {
|
|
2544
2637
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2545
2638
|
if (jwtToken) {
|
|
2546
2639
|
const decodedToken = jwt.decodeJwt(jwtToken);
|
|
2547
2640
|
if (!decodedToken) {
|
|
2548
2641
|
tracer?.trace('findContactWithName:invalidJwtToken', {});
|
|
2549
|
-
res.status(400).send(tracer
|
|
2642
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Invalid JWT token'));
|
|
2550
2643
|
success = false;
|
|
2551
2644
|
return;
|
|
2552
2645
|
}
|
|
@@ -2554,25 +2647,24 @@ function createCoreRouter() {
|
|
|
2554
2647
|
platformName = platform;
|
|
2555
2648
|
const { successful, returnMessage, contact, isRevokeUserSession } = await contactCore.findContactWithName({ platform, userId, name: req.query.name });
|
|
2556
2649
|
if (isRevokeUserSession) {
|
|
2557
|
-
res.status(401).send(tracer
|
|
2650
|
+
res.status(401).send(wrapDebugResponse(tracer, { successful, returnMessage }));
|
|
2558
2651
|
success = false;
|
|
2559
2652
|
}
|
|
2560
2653
|
else {
|
|
2561
|
-
res.status(200).send(tracer
|
|
2654
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful, returnMessage, contact }));
|
|
2562
2655
|
success = successful;
|
|
2563
2656
|
}
|
|
2564
2657
|
}
|
|
2565
2658
|
else {
|
|
2566
2659
|
tracer?.trace('contactSearchByName:noToken', {});
|
|
2567
|
-
res.status(400).send(tracer
|
|
2660
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2568
2661
|
success = false;
|
|
2569
2662
|
}
|
|
2570
|
-
|
|
2571
2663
|
}
|
|
2572
2664
|
catch (e) {
|
|
2573
2665
|
logger.error('Contact search by name failed', { platform: platformName, stack: e.stack });
|
|
2574
2666
|
statusCode = e.response?.status ?? 'unknown';
|
|
2575
|
-
res.status(400).send(tracer
|
|
2667
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
2576
2668
|
tracer?.traceError('contactSearchByName:error', e, { platform: platformName });
|
|
2577
2669
|
success = false;
|
|
2578
2670
|
}
|
|
@@ -2599,7 +2691,7 @@ function createCoreRouter() {
|
|
|
2599
2691
|
tracer?.trace('getAdminReport:start', { query: req.query });
|
|
2600
2692
|
let platformName = null;
|
|
2601
2693
|
let success = false;
|
|
2602
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2694
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2603
2695
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2604
2696
|
try {
|
|
2605
2697
|
if (jwtToken) {
|
|
@@ -2607,21 +2699,21 @@ function createCoreRouter() {
|
|
|
2607
2699
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
2608
2700
|
if (!user) {
|
|
2609
2701
|
tracer?.trace('getAdminReport:userNotFound', {});
|
|
2610
|
-
res.status(400).send(tracer
|
|
2702
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
2611
2703
|
return;
|
|
2612
2704
|
}
|
|
2613
2705
|
const report = await adminCore.getAdminReport({ rcAccountId: user.rcAccountId, timezone: req.query.timezone, timeFrom: req.query.timeFrom, timeTo: req.query.timeTo, groupBy: req.query.groupBy });
|
|
2614
|
-
res.status(200).send(tracer
|
|
2706
|
+
res.status(200).send(wrapDebugResponse(tracer, report));
|
|
2615
2707
|
success = true;
|
|
2616
2708
|
return;
|
|
2617
2709
|
}
|
|
2618
2710
|
tracer?.trace('getAdminReport:invalidRequest', {});
|
|
2619
|
-
res.status(400).send(tracer
|
|
2711
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Invalid request'));
|
|
2620
2712
|
success = false;
|
|
2621
2713
|
}
|
|
2622
2714
|
catch (e) {
|
|
2623
2715
|
logger.error('Get admin report failed', { stack: e.stack });
|
|
2624
|
-
res.status(400).send(tracer
|
|
2716
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
2625
2717
|
tracer?.traceError('getAdminReport:error', e, { platform: platformName });
|
|
2626
2718
|
}
|
|
2627
2719
|
const requestEndTime = new Date().getTime();
|
|
@@ -2645,7 +2737,7 @@ function createCoreRouter() {
|
|
|
2645
2737
|
tracer?.trace('getUserReport:start', { query: req.query });
|
|
2646
2738
|
let platformName = null;
|
|
2647
2739
|
let success = false;
|
|
2648
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2740
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2649
2741
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2650
2742
|
try {
|
|
2651
2743
|
if (jwtToken) {
|
|
@@ -2653,20 +2745,20 @@ function createCoreRouter() {
|
|
|
2653
2745
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
2654
2746
|
if (!user) {
|
|
2655
2747
|
tracer?.trace('getUserReport:userNotFound', {});
|
|
2656
|
-
res.status(400).send(tracer
|
|
2748
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
2657
2749
|
return;
|
|
2658
2750
|
}
|
|
2659
2751
|
const report = await adminCore.getUserReport({ rcAccountId: user.rcAccountId, rcExtensionId: req.query.rcExtensionId, timezone: req.query.timezone, timeFrom: req.query.timeFrom, timeTo: req.query.timeTo });
|
|
2660
|
-
res.status(200).send(tracer
|
|
2752
|
+
res.status(200).send(wrapDebugResponse(tracer, report));
|
|
2661
2753
|
return;
|
|
2662
2754
|
}
|
|
2663
2755
|
tracer?.trace('getUserReport:invalidRequest', {});
|
|
2664
|
-
res.status(400).send(tracer
|
|
2756
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Invalid request'));
|
|
2665
2757
|
success = false;
|
|
2666
2758
|
}
|
|
2667
2759
|
catch (e) {
|
|
2668
2760
|
logger.error('Get user report failed', { stack: e.stack });
|
|
2669
|
-
res.status(400).send(tracer
|
|
2761
|
+
res.status(400).send(wrapDebugResponse(tracer, { error: getErrorResponse(e) }));
|
|
2670
2762
|
tracer?.traceError('getUserReport:error', e, { platform: platformName });
|
|
2671
2763
|
}
|
|
2672
2764
|
const requestEndTime = new Date().getTime();
|
|
@@ -2694,15 +2786,15 @@ function createCoreRouter() {
|
|
|
2694
2786
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
2695
2787
|
if (!user) {
|
|
2696
2788
|
tracer?.trace('onRingcentralOAuthCallback:userNotFound', {});
|
|
2697
|
-
res.status(400).send(tracer
|
|
2789
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
2698
2790
|
return;
|
|
2699
2791
|
}
|
|
2700
2792
|
await authCore.onRingcentralOAuthCallback({ code, rcAccountId: user.rcAccountId });
|
|
2701
|
-
res.status(200).send(tracer
|
|
2793
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful: true }));
|
|
2702
2794
|
return;
|
|
2703
2795
|
}
|
|
2704
2796
|
tracer?.trace('onRingcentralOAuthCallback:invalidRequest', {});
|
|
2705
|
-
res.status(400).send(tracer
|
|
2797
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Invalid request'));
|
|
2706
2798
|
});
|
|
2707
2799
|
router.get('/debug/report/url', async function (req, res) {
|
|
2708
2800
|
const requestStartTime = new Date().getTime();
|
|
@@ -2710,17 +2802,17 @@ function createCoreRouter() {
|
|
|
2710
2802
|
tracer?.trace('getErrorLogReportURL:start', { query: req.query });
|
|
2711
2803
|
let platformName = null;
|
|
2712
2804
|
let success = false;
|
|
2713
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2805
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2714
2806
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2715
2807
|
if (jwtToken) {
|
|
2716
2808
|
const unAuthData = jwt.decodeJwt(jwtToken);
|
|
2717
2809
|
const uploadUrl = await s3ErrorLogReport.getUploadUrl({ userId: unAuthData?.id, platform: unAuthData?.platform });
|
|
2718
|
-
res.status(200).send(tracer
|
|
2810
|
+
res.status(200).send(wrapDebugResponse(tracer, { presignedUrl: uploadUrl }));
|
|
2719
2811
|
success = true;
|
|
2720
2812
|
}
|
|
2721
2813
|
else {
|
|
2722
2814
|
tracer?.trace('getErrorLogReportURL:invalidRequest', {});
|
|
2723
|
-
res.status(400).send(tracer
|
|
2815
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Invalid request'));
|
|
2724
2816
|
success = false;
|
|
2725
2817
|
}
|
|
2726
2818
|
const requestEndTime = new Date().getTime();
|
|
@@ -2738,7 +2830,6 @@ function createCoreRouter() {
|
|
|
2738
2830
|
eventAddedVia
|
|
2739
2831
|
});
|
|
2740
2832
|
});
|
|
2741
|
-
|
|
2742
2833
|
router.post('/plugin/async-callback/:taskId', async function (req, res) {
|
|
2743
2834
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
2744
2835
|
tracer?.trace('pluginAsyncCallback:start', { taskId: req.params.taskId, body: req.body });
|
|
@@ -2747,42 +2838,40 @@ function createCoreRouter() {
|
|
|
2747
2838
|
taskId: req.params.taskId,
|
|
2748
2839
|
body: req.body || {},
|
|
2749
2840
|
});
|
|
2750
|
-
res.status(result.statusCode).send(tracer
|
|
2841
|
+
res.status(result.statusCode).send(wrapDebugResponse(tracer, result.body));
|
|
2751
2842
|
}
|
|
2752
2843
|
catch (e) {
|
|
2753
2844
|
logger.error('Plugin async callback failed', { taskId: req.params.taskId, stack: e.stack });
|
|
2754
2845
|
tracer?.traceError('pluginAsyncCallback:error', e);
|
|
2755
|
-
res.status(500).send(tracer
|
|
2846
|
+
res.status(500).send(wrapDebugResponse(tracer, { successful: false, message: getErrorResponse(e) }));
|
|
2756
2847
|
}
|
|
2757
2848
|
});
|
|
2758
|
-
|
|
2759
2849
|
router.post('/plugin/register', async function (req, res) {
|
|
2760
2850
|
const requestStartTime = new Date().getTime();
|
|
2761
2851
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
2762
2852
|
tracer?.trace('pluginRegister:start', { body: req.body });
|
|
2763
2853
|
let success = false;
|
|
2764
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2854
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2765
2855
|
try {
|
|
2766
2856
|
const { pluginId, rcAccountId, pluginAccess, pluginName, ownerRcAccountId } = req.body || {};
|
|
2767
|
-
const rcAccessToken = req
|
|
2857
|
+
const rcAccessToken = getRcAccessTokenFromRequest(req);
|
|
2768
2858
|
if (!pluginId || !rcAccountId) {
|
|
2769
|
-
res.status(400).send(tracer
|
|
2859
|
+
res.status(400).send(wrapDebugResponse(tracer, { successful: false, returnMessage: 'pluginId and rcAccountId are required' }));
|
|
2770
2860
|
return;
|
|
2771
2861
|
}
|
|
2772
2862
|
if (!rcAccessToken) {
|
|
2773
|
-
res.status(400).send(tracer
|
|
2863
|
+
res.status(400).send(wrapDebugResponse(tracer, { successful: false, returnMessage: 'Missing RingCentral access token' }));
|
|
2774
2864
|
return;
|
|
2775
2865
|
}
|
|
2776
2866
|
const { isValidated, rcAccountId: validatedRcAccountId } = await adminCore.validateAdminRole({ rcAccessToken });
|
|
2777
2867
|
if (!isValidated) {
|
|
2778
|
-
res.status(403).send(tracer
|
|
2868
|
+
res.status(403).send(wrapDebugResponse(tracer, { successful: false, returnMessage: 'Admin validation failed' }));
|
|
2779
2869
|
return;
|
|
2780
2870
|
}
|
|
2781
2871
|
if (validatedRcAccountId?.toString() !== rcAccountId?.toString()) {
|
|
2782
|
-
res.status(403).send(tracer
|
|
2872
|
+
res.status(403).send(wrapDebugResponse(tracer, { successful: false, returnMessage: 'rcAccountId mismatch' }));
|
|
2783
2873
|
return;
|
|
2784
2874
|
}
|
|
2785
|
-
|
|
2786
2875
|
await pluginCore.registerPluginAccount({
|
|
2787
2876
|
pluginId,
|
|
2788
2877
|
rcAccessToken,
|
|
@@ -2791,15 +2880,15 @@ function createCoreRouter() {
|
|
|
2791
2880
|
pluginAccess,
|
|
2792
2881
|
pluginName,
|
|
2793
2882
|
});
|
|
2794
|
-
res.status(200).send(tracer
|
|
2883
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful: true }));
|
|
2795
2884
|
success = true;
|
|
2796
|
-
}
|
|
2885
|
+
}
|
|
2886
|
+
catch (e) {
|
|
2797
2887
|
logger.error('Plugin register failed', { stack: e.stack });
|
|
2798
|
-
res.status(400).send(tracer
|
|
2888
|
+
res.status(400).send(wrapDebugResponse(tracer, { successful: false, returnMessage: getErrorResponse(e) }));
|
|
2799
2889
|
tracer?.traceError('pluginRegister:error', e);
|
|
2800
2890
|
success = false;
|
|
2801
2891
|
}
|
|
2802
|
-
|
|
2803
2892
|
const requestEndTime = new Date().getTime();
|
|
2804
2893
|
analytics.track({
|
|
2805
2894
|
eventName: 'Plugin Register',
|
|
@@ -2814,44 +2903,43 @@ function createCoreRouter() {
|
|
|
2814
2903
|
eventAddedVia
|
|
2815
2904
|
});
|
|
2816
2905
|
});
|
|
2817
|
-
|
|
2818
2906
|
router.delete('/plugin/unregister', async function (req, res) {
|
|
2819
2907
|
const requestStartTime = new Date().getTime();
|
|
2820
2908
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
2821
2909
|
tracer?.trace('pluginUnregister:start', { query: req.query });
|
|
2822
2910
|
let success = false;
|
|
2823
|
-
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers })
|
|
2911
|
+
const { hashedExtensionId, hashedAccountId, userAgent, ip, author, eventAddedVia } = getAnalyticsVariablesInReqHeaders({ headers: req.headers });
|
|
2824
2912
|
try {
|
|
2825
2913
|
const { pluginId, rcAccountId, pluginName } = req.query || {};
|
|
2826
|
-
const rcAccessToken = req
|
|
2914
|
+
const rcAccessToken = getRcAccessTokenFromRequest(req);
|
|
2827
2915
|
if (!pluginId || !rcAccountId) {
|
|
2828
|
-
res.status(400).send(tracer
|
|
2916
|
+
res.status(400).send(wrapDebugResponse(tracer, { successful: false, returnMessage: 'pluginId and rcAccountId are required' }));
|
|
2829
2917
|
return;
|
|
2830
2918
|
}
|
|
2831
2919
|
if (!rcAccessToken) {
|
|
2832
|
-
res.status(400).send(tracer
|
|
2920
|
+
res.status(400).send(wrapDebugResponse(tracer, { successful: false, returnMessage: 'Missing RingCentral access token' }));
|
|
2833
2921
|
return;
|
|
2834
2922
|
}
|
|
2835
2923
|
const { isValidated, rcAccountId: validatedRcAccountId } = await adminCore.validateAdminRole({ rcAccessToken });
|
|
2836
2924
|
if (!isValidated) {
|
|
2837
|
-
res.status(403).send(tracer
|
|
2925
|
+
res.status(403).send(wrapDebugResponse(tracer, { successful: false, returnMessage: 'Admin validation failed' }));
|
|
2838
2926
|
return;
|
|
2839
2927
|
}
|
|
2840
2928
|
if (validatedRcAccountId?.toString() !== rcAccountId?.toString()) {
|
|
2841
|
-
res.status(403).send(tracer
|
|
2929
|
+
res.status(403).send(wrapDebugResponse(tracer, { successful: false, returnMessage: 'rcAccountId mismatch' }));
|
|
2842
2930
|
return;
|
|
2843
2931
|
}
|
|
2844
|
-
|
|
2845
2932
|
await pluginCore.unregisterPluginAccount({
|
|
2846
2933
|
pluginId,
|
|
2847
2934
|
rcAccountId: rcAccountId?.toString(),
|
|
2848
2935
|
pluginName,
|
|
2849
2936
|
});
|
|
2850
|
-
res.status(200).send(tracer
|
|
2937
|
+
res.status(200).send(wrapDebugResponse(tracer, { successful: true }));
|
|
2851
2938
|
success = true;
|
|
2852
|
-
}
|
|
2939
|
+
}
|
|
2940
|
+
catch (e) {
|
|
2853
2941
|
logger.error('Plugin unregister failed', { stack: e.stack });
|
|
2854
|
-
res.status(400).send(tracer
|
|
2942
|
+
res.status(400).send(wrapDebugResponse(tracer, { successful: false, returnMessage: getErrorResponse(e) }));
|
|
2855
2943
|
tracer?.traceError('pluginUnregister:error', e);
|
|
2856
2944
|
success = false;
|
|
2857
2945
|
}
|
|
@@ -2869,7 +2957,6 @@ function createCoreRouter() {
|
|
|
2869
2957
|
eventAddedVia
|
|
2870
2958
|
});
|
|
2871
2959
|
});
|
|
2872
|
-
|
|
2873
2960
|
router.get('/plugin/licenseStatus', async function (req, res) {
|
|
2874
2961
|
const tracer = req.headers['is-debug'] === 'true' ? DebugTracer.fromRequest(req) : null;
|
|
2875
2962
|
tracer?.trace('getPluginLicenseStatus:start', { query: req.query });
|
|
@@ -2877,31 +2964,30 @@ function createCoreRouter() {
|
|
|
2877
2964
|
const jwtToken = req.jwtToken || req.query.jwtToken;
|
|
2878
2965
|
if (!jwtToken) {
|
|
2879
2966
|
tracer?.trace('getPluginLicenseStatus:noToken', {});
|
|
2880
|
-
res.status(400).send(tracer
|
|
2967
|
+
res.status(400).send(wrapDebugResponse(tracer, 'Please go to Settings and authorize CRM platform'));
|
|
2881
2968
|
return;
|
|
2882
2969
|
}
|
|
2883
2970
|
const unAuthData = jwt.decodeJwt(jwtToken);
|
|
2884
2971
|
const user = await UserModel.findByPk(unAuthData?.id);
|
|
2885
2972
|
if (!user) {
|
|
2886
2973
|
tracer?.trace('getPluginLicenseStatus:userNotFound', {});
|
|
2887
|
-
res.status(400).send(tracer
|
|
2974
|
+
res.status(400).send(wrapDebugResponse(tracer, 'User not found'));
|
|
2888
2975
|
return;
|
|
2889
2976
|
}
|
|
2890
2977
|
const { rcAccountId, pluginId } = req.query;
|
|
2891
2978
|
if (!rcAccountId || !pluginId) {
|
|
2892
|
-
res.status(400).send(tracer
|
|
2979
|
+
res.status(400).send(wrapDebugResponse(tracer, 'rcAccountId and pluginId are required'));
|
|
2893
2980
|
return;
|
|
2894
2981
|
}
|
|
2895
2982
|
const licenseStatus = await pluginCore.getPluginLicenseStatus({ rcAccountId, pluginId });
|
|
2896
|
-
res.status(200).send(tracer
|
|
2983
|
+
res.status(200).send(wrapDebugResponse(tracer, licenseStatus));
|
|
2897
2984
|
}
|
|
2898
2985
|
catch (e) {
|
|
2899
2986
|
logger.error('Get plugin license status failed', { stack: e.stack });
|
|
2900
|
-
res.status(200).send(tracer
|
|
2987
|
+
res.status(200).send(wrapDebugResponse(tracer, { licenseStatus: false, licenseStatusDescription: getErrorResponse(e) }));
|
|
2901
2988
|
tracer?.traceError('getPluginLicenseStatus:error', e);
|
|
2902
2989
|
}
|
|
2903
2990
|
});
|
|
2904
|
-
|
|
2905
2991
|
if (process.env.IS_PROD === 'false') {
|
|
2906
2992
|
router.post('/registerMockUser', async function (req, res) {
|
|
2907
2993
|
const secretKey = req.query.secretKey;
|
|
@@ -2958,7 +3044,6 @@ function createCoreRouter() {
|
|
|
2958
3044
|
router.get('/.well-known/openai-apps-challenge', (req, res) => {
|
|
2959
3045
|
res.send(process.env.CHATGPT_VERIFICATION_CODE);
|
|
2960
3046
|
});
|
|
2961
|
-
|
|
2962
3047
|
// --- METADATA ENDPOINT 1: Resource Metadata ---
|
|
2963
3048
|
// Tells the client "I am protected" and "Here is who protects me"
|
|
2964
3049
|
router.get('/.well-known/oauth-protected-resource', (req, res) => {
|
|
@@ -2969,7 +3054,6 @@ function createCoreRouter() {
|
|
|
2969
3054
|
scopes_supported: ["ReadAccounts"]
|
|
2970
3055
|
});
|
|
2971
3056
|
});
|
|
2972
|
-
|
|
2973
3057
|
// --- METADATA ENDPOINT 2: Auth Server Metadata ---
|
|
2974
3058
|
// Usually, you can redirect to your provider's configuration.
|
|
2975
3059
|
// If your provider supports OIDC discovery, this is often sufficient.
|
|
@@ -2977,54 +3061,68 @@ function createCoreRouter() {
|
|
|
2977
3061
|
res.json({
|
|
2978
3062
|
issuer: process.env.APP_SERVER,
|
|
2979
3063
|
registration_endpoint: `${process.env.APP_SERVER}/oauth/register`,
|
|
2980
|
-
|
|
2981
|
-
// CHANGE THIS: Don't point to RingCentral. Point to your own Shim.
|
|
3064
|
+
// Keep the shim so unsupported metadata params are stripped before RingCentral.
|
|
2982
3065
|
authorization_endpoint: `${process.env.APP_SERVER}/oauth/authorize_shim`,
|
|
2983
|
-
|
|
2984
|
-
// Keep the token endpoint pointing to RingCentral (that usually works fine)
|
|
3066
|
+
// MCP clients exchange the authorization code with RingCentral directly using PKCE.
|
|
2985
3067
|
token_endpoint: `${process.env.RINGCENTRAL_SERVER}/restapi/oauth/token`,
|
|
2986
|
-
token_endpoint_auth_methods_supported: ["
|
|
2987
|
-
response_types_supported: ["code"]
|
|
3068
|
+
token_endpoint_auth_methods_supported: ["none"],
|
|
3069
|
+
response_types_supported: ["code"],
|
|
3070
|
+
grant_types_supported: ["authorization_code", "refresh_token"],
|
|
3071
|
+
code_challenge_methods_supported: ["S256"]
|
|
2988
3072
|
});
|
|
2989
3073
|
});
|
|
2990
|
-
|
|
2991
3074
|
router.get('/oauth/authorize_shim', (req, res) => {
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
const
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3075
|
+
const mcpClientId = process.env.RINGCENTRAL_MCP_CLIENT_ID;
|
|
3076
|
+
if (!mcpClientId) {
|
|
3077
|
+
return res.status(500).send('RINGCENTRAL_MCP_CLIENT_ID is not configured');
|
|
3078
|
+
}
|
|
3079
|
+
const { response_type, client_id, redirect_uri, state, scope, code_challenge, code_challenge_method, } = req.query;
|
|
3080
|
+
const requestedClientId = getFirstQueryValue(client_id);
|
|
3081
|
+
const requestedCodeChallenge = getFirstQueryValue(code_challenge);
|
|
3082
|
+
const requestedCodeChallengeMethod = getFirstQueryValue(code_challenge_method);
|
|
3083
|
+
if (requestedClientId && requestedClientId !== mcpClientId) {
|
|
3084
|
+
return res.status(400).send(buildMcpOAuthError({
|
|
3085
|
+
error: 'mcp_oauth_client_mismatch',
|
|
3086
|
+
message: MCP_OAUTH_STALE_CLIENT_MESSAGE,
|
|
3087
|
+
}));
|
|
3088
|
+
}
|
|
3089
|
+
if (!getFirstQueryValue(response_type) || !getFirstQueryValue(redirect_uri)) {
|
|
3090
|
+
return res.status(400).send('Missing OAuth authorization parameters');
|
|
3091
|
+
}
|
|
3092
|
+
if (!requestedCodeChallenge || requestedCodeChallengeMethod !== 'S256') {
|
|
3093
|
+
return res.status(400).send('PKCE S256 code_challenge is required');
|
|
3094
|
+
}
|
|
3095
|
+
const params = new URLSearchParams();
|
|
3096
|
+
appendOAuthQueryParam(params, 'response_type', response_type);
|
|
3097
|
+
params.set('client_id', mcpClientId);
|
|
3098
|
+
appendOAuthQueryParam(params, 'redirect_uri', redirect_uri);
|
|
3099
|
+
appendOAuthQueryParam(params, 'state', state);
|
|
3100
|
+
appendOAuthQueryParam(params, 'scope', scope);
|
|
3101
|
+
appendOAuthQueryParam(params, 'code_challenge', code_challenge);
|
|
3102
|
+
appendOAuthQueryParam(params, 'code_challenge_method', code_challenge_method);
|
|
3006
3103
|
const rcUrl = `${process.env.RINGCENTRAL_SERVER}/restapi/oauth/authorize?${params.toString()}`;
|
|
3007
|
-
|
|
3008
3104
|
console.log("Proxying OAuth request to:", rcUrl); // Helpful for debugging
|
|
3009
3105
|
res.redirect(rcUrl);
|
|
3010
3106
|
});
|
|
3011
|
-
|
|
3012
3107
|
router.post('/oauth/register', (req, res) => {
|
|
3013
|
-
|
|
3014
|
-
|
|
3108
|
+
const mcpClientId = process.env.RINGCENTRAL_MCP_CLIENT_ID;
|
|
3109
|
+
if (!mcpClientId) {
|
|
3110
|
+
return res.status(500).send('RINGCENTRAL_MCP_CLIENT_ID is not configured');
|
|
3111
|
+
}
|
|
3112
|
+
// Dynamic registration for MCP public clients. No client secret is issued.
|
|
3015
3113
|
res.json({
|
|
3016
|
-
client_id:
|
|
3017
|
-
|
|
3114
|
+
client_id: mcpClientId,
|
|
3115
|
+
token_endpoint_auth_method: 'none',
|
|
3116
|
+
grant_types: ['authorization_code', 'refresh_token'],
|
|
3117
|
+
response_types: ['code']
|
|
3018
3118
|
});
|
|
3019
3119
|
});
|
|
3020
|
-
|
|
3021
3120
|
router.use('/mcp', (req, res, next) => {
|
|
3022
3121
|
// Widget tool calls are unauthenticated — they come from the iframe
|
|
3023
3122
|
// which has no access to the RC bearer token.
|
|
3024
3123
|
if (req.path === '/widget-tool-call') {
|
|
3025
3124
|
return next();
|
|
3026
3125
|
}
|
|
3027
|
-
|
|
3028
3126
|
const authHeader = req.headers.authorization;
|
|
3029
3127
|
const token = authHeader?.split(' ')[1]; // Remove "Bearer "
|
|
3030
3128
|
// Allow GET and OPTIONS (CORS preflight) to pass freely.
|
|
@@ -3046,16 +3144,23 @@ function createCoreRouter() {
|
|
|
3046
3144
|
}
|
|
3047
3145
|
// SCENARIO 1: No Token provided. Kick off the OAuth flow.
|
|
3048
3146
|
if (!token) {
|
|
3049
|
-
res.setHeader('WWW-Authenticate',
|
|
3050
|
-
|
|
3147
|
+
res.setHeader('WWW-Authenticate', getMcpOAuthChallengeHeader({
|
|
3148
|
+
appServer: process.env.APP_SERVER,
|
|
3149
|
+
errorDescription: MCP_OAUTH_REQUIRED_MESSAGE,
|
|
3150
|
+
}));
|
|
3151
|
+
return res.status(401).json(buildMcpOAuthError({
|
|
3152
|
+
message: MCP_OAUTH_REQUIRED_MESSAGE,
|
|
3153
|
+
}));
|
|
3051
3154
|
}
|
|
3052
|
-
|
|
3053
3155
|
// SCENARIO 2: Token provided. Verify it.
|
|
3054
3156
|
try {
|
|
3055
3157
|
next();
|
|
3056
|
-
}
|
|
3057
|
-
|
|
3058
|
-
|
|
3158
|
+
}
|
|
3159
|
+
catch {
|
|
3160
|
+
res.setHeader('WWW-Authenticate', getMcpOAuthChallengeHeader({
|
|
3161
|
+
appServer: process.env.APP_SERVER,
|
|
3162
|
+
}));
|
|
3163
|
+
return res.status(401).json(buildMcpOAuthError());
|
|
3059
3164
|
}
|
|
3060
3165
|
});
|
|
3061
3166
|
// Handle OPTIONS for CORS preflight
|
|
@@ -3066,21 +3171,18 @@ function createCoreRouter() {
|
|
|
3066
3171
|
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
3067
3172
|
res.status(200).end();
|
|
3068
3173
|
});
|
|
3069
|
-
|
|
3070
3174
|
// Dedicated endpoint for all MCP traffic
|
|
3071
3175
|
router.post('/mcp', async (req, res) => {
|
|
3072
3176
|
// Set CORS headers
|
|
3073
3177
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
3074
3178
|
res.setHeader('Content-Type', 'application/json');
|
|
3075
|
-
|
|
3076
3179
|
await mcpHandler.handleMcpRequest(req, res);
|
|
3077
3180
|
});
|
|
3078
|
-
|
|
3079
3181
|
// Lightweight endpoint for widget tool calls (bypasses MCP protocol)
|
|
3080
3182
|
router.options('/mcp/widget-tool-call', (req, res) => {
|
|
3081
3183
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
3082
3184
|
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
|
|
3083
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
3185
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-App-Connect-Widget-Token');
|
|
3084
3186
|
res.status(200).end();
|
|
3085
3187
|
});
|
|
3086
3188
|
router.post('/mcp/widget-tool-call', async (req, res) => {
|
|
@@ -3088,10 +3190,8 @@ function createCoreRouter() {
|
|
|
3088
3190
|
res.setHeader('Content-Type', 'application/json');
|
|
3089
3191
|
await mcpHandler.handleWidgetToolCall(req, res);
|
|
3090
3192
|
});
|
|
3091
|
-
|
|
3092
3193
|
return router;
|
|
3093
3194
|
}
|
|
3094
|
-
|
|
3095
3195
|
// Create middleware for core functionality
|
|
3096
3196
|
function createCoreMiddleware() {
|
|
3097
3197
|
return [
|
|
@@ -3111,23 +3211,26 @@ function createCoreMiddleware() {
|
|
|
3111
3211
|
})
|
|
3112
3212
|
];
|
|
3113
3213
|
}
|
|
3114
|
-
|
|
3115
3214
|
// Initialize core services
|
|
3116
3215
|
async function initializeCore(options = {}) {
|
|
3117
|
-
const {
|
|
3118
|
-
skipDatabaseInit = false,
|
|
3119
|
-
skipAnalyticsInit = false,
|
|
3120
|
-
} = options;
|
|
3121
|
-
|
|
3216
|
+
const { skipDatabaseInit = false, skipAnalyticsInit = false, } = options;
|
|
3122
3217
|
if (!skipAnalyticsInit) {
|
|
3123
3218
|
analytics.init();
|
|
3124
3219
|
}
|
|
3125
|
-
|
|
3126
3220
|
if (!skipDatabaseInit) {
|
|
3127
3221
|
await initDB();
|
|
3222
|
+
// Run the heavy callLogs primary-key migration in the BACKGROUND, off the
|
|
3223
|
+
// readiness critical path. It must not gate coreInit: on a large production
|
|
3224
|
+
// table the index rebuild takes minutes, and blocking here would stall every
|
|
3225
|
+
// request (including the load-balancer health check) and fail the deploy.
|
|
3226
|
+
// The runner is self-guarding (advisory-locked across instances, idempotent,
|
|
3227
|
+
// never throws) and uses online DDL on Postgres so live traffic is unaffected.
|
|
3228
|
+
// Gated on the same flag as the schema sync so operators have one switch.
|
|
3229
|
+
if (!process.env.DISABLE_SYNC_DB_TABLE) {
|
|
3230
|
+
runCallLogsSchemaMigration(sequelize, logger);
|
|
3231
|
+
}
|
|
3128
3232
|
}
|
|
3129
3233
|
}
|
|
3130
|
-
|
|
3131
3234
|
// Create a complete app with core functionality
|
|
3132
3235
|
function createCoreApp(options = {}) {
|
|
3133
3236
|
const coreInit = initializeCore(options).catch((err) => {
|
|
@@ -3138,14 +3241,14 @@ function createCoreApp(options = {}) {
|
|
|
3138
3241
|
throw err;
|
|
3139
3242
|
});
|
|
3140
3243
|
const app = express();
|
|
3141
|
-
|
|
3142
3244
|
// Block routing until DB sync/migrations finish so traffic never hits a half-ready DB,
|
|
3143
3245
|
// and ensure init failures are logged instead of only as unhandled rejections.
|
|
3144
3246
|
app.use(async (req, res, next) => {
|
|
3145
3247
|
try {
|
|
3146
3248
|
await coreInit;
|
|
3147
3249
|
next();
|
|
3148
|
-
}
|
|
3250
|
+
}
|
|
3251
|
+
catch (e) {
|
|
3149
3252
|
logger.error('Request rejected: core initialization failed', {
|
|
3150
3253
|
message: e?.message,
|
|
3151
3254
|
stack: e?.stack,
|
|
@@ -3155,22 +3258,17 @@ function createCoreApp(options = {}) {
|
|
|
3155
3258
|
.json({ error: 'Service unavailable', detail: e?.message });
|
|
3156
3259
|
}
|
|
3157
3260
|
});
|
|
3158
|
-
|
|
3159
3261
|
// Allow bigger POST body size
|
|
3160
3262
|
app.use(express.json({ limit: '50mb' }));
|
|
3161
3263
|
app.use(express.urlencoded({ limit: '50mb', extended: true }));
|
|
3162
|
-
|
|
3163
3264
|
// Apply core middleware
|
|
3164
3265
|
const coreMiddleware = createCoreMiddleware();
|
|
3165
3266
|
coreMiddleware.forEach(middleware => app.use(middleware));
|
|
3166
|
-
|
|
3167
3267
|
// Apply core routes
|
|
3168
3268
|
const coreRouter = createCoreRouter();
|
|
3169
3269
|
app.use('/', coreRouter);
|
|
3170
|
-
|
|
3171
3270
|
return app;
|
|
3172
3271
|
}
|
|
3173
|
-
|
|
3174
3272
|
exports.createCoreRouter = createCoreRouter;
|
|
3175
3273
|
exports.createCoreMiddleware = createCoreMiddleware;
|
|
3176
3274
|
exports.createCoreApp = createCoreApp;
|