@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.
Files changed (287) hide show
  1. package/README.md +17 -16
  2. package/dist/connector/developerPortal.d.ts +6 -0
  3. package/{connector → dist/connector}/developerPortal.js +29 -12
  4. package/dist/connector/mock.d.ts +1 -0
  5. package/{connector → dist/connector}/mock.js +33 -17
  6. package/dist/connector/proxy/engine.d.ts +10 -0
  7. package/dist/connector/proxy/engine.js +222 -0
  8. package/dist/connector/proxy/index.d.ts +5 -0
  9. package/dist/connector/proxy/index.js +511 -0
  10. package/dist/connector/registry.d.ts +1 -0
  11. package/dist/connector/registry.js +243 -0
  12. package/dist/handlers/admin.d.ts +1 -0
  13. package/{handlers → dist/handlers}/admin.js +137 -78
  14. package/dist/handlers/appointment.d.ts +9 -0
  15. package/{handlers → dist/handlers}/appointment.js +58 -29
  16. package/dist/handlers/auth.d.ts +9 -0
  17. package/{handlers → dist/handlers}/auth.js +68 -40
  18. package/dist/handlers/calldown.d.ts +10 -0
  19. package/dist/handlers/calldown.js +134 -0
  20. package/dist/handlers/contact.d.ts +1 -0
  21. package/{handlers → dist/handlers}/contact.js +61 -39
  22. package/dist/handlers/disposition.d.ts +1 -0
  23. package/{handlers → dist/handlers}/disposition.js +20 -10
  24. package/dist/handlers/log.d.ts +1 -0
  25. package/{handlers → dist/handlers}/log.js +91 -124
  26. package/dist/handlers/managedAuth.d.ts +1 -0
  27. package/{handlers → dist/handlers}/managedAuth.js +134 -61
  28. package/dist/handlers/managedOAuth.d.ts +13 -0
  29. package/{handlers → dist/handlers}/managedOAuth.js +102 -30
  30. package/dist/handlers/plugin.d.ts +1 -0
  31. package/{handlers → dist/handlers}/plugin.js +59 -27
  32. package/dist/handlers/user.d.ts +1 -0
  33. package/{handlers → dist/handlers}/user.js +45 -27
  34. package/dist/index.d.ts +1 -0
  35. package/{index.js → dist/index.js} +548 -450
  36. package/dist/jest.config.d.ts +1 -0
  37. package/dist/jest.config.js +65 -0
  38. package/dist/lib/analytics.d.ts +4 -0
  39. package/{lib → dist/lib}/analytics.js +8 -6
  40. package/dist/lib/authSession.d.ts +5 -0
  41. package/{lib → dist/lib}/authSession.js +15 -43
  42. package/dist/lib/cacheCleanup.d.ts +4 -0
  43. package/{lib → dist/lib}/cacheCleanup.js +5 -17
  44. package/dist/lib/callLogComposer.d.ts +109 -0
  45. package/{lib → dist/lib}/callLogComposer.js +157 -197
  46. package/dist/lib/callLogLookup.d.ts +6 -0
  47. package/{lib → dist/lib}/callLogLookup.js +12 -34
  48. package/dist/lib/constants.d.ts +6 -0
  49. package/dist/lib/constants.js +9 -0
  50. package/dist/lib/debugTracer.d.ts +17 -0
  51. package/{lib → dist/lib}/debugTracer.js +7 -83
  52. package/dist/lib/encode.d.ts +3 -0
  53. package/dist/lib/encode.js +50 -0
  54. package/dist/lib/errorHandler.d.ts +7 -0
  55. package/dist/lib/errorHandler.js +161 -0
  56. package/dist/lib/generalErrorMessage.d.ts +7 -0
  57. package/{lib → dist/lib}/generalErrorMessage.js +6 -6
  58. package/dist/lib/jwt.d.ts +4 -0
  59. package/dist/lib/jwt.js +18 -0
  60. package/dist/lib/logger.d.ts +24 -0
  61. package/dist/lib/logger.js +126 -0
  62. package/dist/lib/migrateCallLogsSchema.d.ts +32 -0
  63. package/dist/lib/migrateCallLogsSchema.js +339 -0
  64. package/dist/lib/oauth.d.ts +4 -0
  65. package/{lib → dist/lib}/oauth.js +157 -160
  66. package/dist/lib/ringcentral.d.ts +24 -0
  67. package/dist/lib/ringcentral.js +226 -0
  68. package/dist/lib/s3ErrorLogReport.d.ts +4 -0
  69. package/{lib → dist/lib}/s3ErrorLogReport.js +11 -23
  70. package/dist/lib/sharedSMSComposer.d.ts +7 -0
  71. package/{lib → dist/lib}/sharedSMSComposer.js +21 -107
  72. package/dist/lib/util.d.ts +7 -0
  73. package/{lib → dist/lib}/util.js +9 -20
  74. package/dist/mcp/lib/oauthError.d.ts +1 -0
  75. package/dist/mcp/lib/oauthError.js +25 -0
  76. package/dist/mcp/lib/validator.d.ts +1 -0
  77. package/{mcp → dist/mcp}/lib/validator.js +16 -20
  78. package/dist/mcp/lib/widgetSessionToken.d.ts +1 -0
  79. package/dist/mcp/lib/widgetSessionToken.js +46 -0
  80. package/dist/mcp/mcpHandler.d.ts +8 -0
  81. package/{mcp → dist/mcp}/mcpHandler.js +98 -88
  82. package/dist/mcp/tools/cancelAppointment.d.ts +1 -0
  83. package/{mcp → dist/mcp}/tools/cancelAppointment.js +7 -16
  84. package/dist/mcp/tools/checkAuthStatus.d.ts +1 -0
  85. package/{mcp → dist/mcp}/tools/checkAuthStatus.js +21 -14
  86. package/dist/mcp/tools/confirmAppointment.d.ts +1 -0
  87. package/{mcp → dist/mcp}/tools/confirmAppointment.js +7 -16
  88. package/dist/mcp/tools/createAppointment.d.ts +1 -0
  89. package/{mcp → dist/mcp}/tools/createAppointment.js +7 -19
  90. package/dist/mcp/tools/createCallLog.d.ts +1 -0
  91. package/{mcp → dist/mcp}/tools/createCallLog.js +18 -29
  92. package/dist/mcp/tools/createContact.d.ts +1 -0
  93. package/{mcp → dist/mcp}/tools/createContact.js +8 -20
  94. package/dist/mcp/tools/createMessageLog.d.ts +1 -0
  95. package/{mcp → dist/mcp}/tools/createMessageLog.js +14 -26
  96. package/dist/mcp/tools/doAuth.d.ts +1 -0
  97. package/{mcp → dist/mcp}/tools/doAuth.js +17 -13
  98. package/dist/mcp/tools/findContactByName.d.ts +1 -0
  99. package/{mcp → dist/mcp}/tools/findContactByName.js +9 -15
  100. package/dist/mcp/tools/findContactByPhone.d.ts +1 -0
  101. package/{mcp → dist/mcp}/tools/findContactByPhone.js +8 -15
  102. package/dist/mcp/tools/getCallLog.d.ts +1 -0
  103. package/{mcp → dist/mcp}/tools/getCallLog.js +12 -21
  104. package/dist/mcp/tools/getGoogleFilePicker.d.ts +1 -0
  105. package/{mcp → dist/mcp}/tools/getGoogleFilePicker.js +9 -18
  106. package/dist/mcp/tools/getHelp.d.ts +1 -0
  107. package/{mcp → dist/mcp}/tools/getHelp.js +5 -6
  108. package/dist/mcp/tools/getPublicConnectors.d.ts +1 -0
  109. package/{mcp → dist/mcp}/tools/getPublicConnectors.js +19 -18
  110. package/dist/mcp/tools/getSessionInfo.d.ts +1 -0
  111. package/{mcp → dist/mcp}/tools/getSessionInfo.js +10 -16
  112. package/dist/mcp/tools/index.d.ts +8 -0
  113. package/dist/mcp/tools/index.js +50 -0
  114. package/dist/mcp/tools/listAppointments.d.ts +1 -0
  115. package/{mcp → dist/mcp}/tools/listAppointments.js +7 -19
  116. package/dist/mcp/tools/logout.d.ts +1 -0
  117. package/{mcp → dist/mcp}/tools/logout.js +16 -14
  118. package/dist/mcp/tools/rcGetCallLogs.d.ts +1 -0
  119. package/{mcp → dist/mcp}/tools/rcGetCallLogs.js +10 -8
  120. package/dist/mcp/tools/updateAppointment.d.ts +1 -0
  121. package/{mcp → dist/mcp}/tools/updateAppointment.js +17 -22
  122. package/dist/mcp/tools/updateCallLog.d.ts +1 -0
  123. package/{mcp → dist/mcp}/tools/updateCallLog.js +16 -26
  124. package/dist/models/accountDataModel.d.ts +3 -0
  125. package/dist/models/accountDataModel.js +39 -0
  126. package/dist/models/adminConfigModel.d.ts +2 -0
  127. package/dist/models/adminConfigModel.js +39 -0
  128. package/dist/models/cacheModel.d.ts +2 -0
  129. package/{models → dist/models}/cacheModel.js +7 -3
  130. package/dist/models/callDownListModel.d.ts +2 -0
  131. package/{models → dist/models}/callDownListModel.js +8 -4
  132. package/dist/models/callLogModel.d.ts +2 -0
  133. package/dist/models/callLogModel.js +43 -0
  134. package/dist/models/dynamo/connectorSchema.d.ts +2 -0
  135. package/dist/models/dynamo/connectorSchema.js +141 -0
  136. package/dist/models/dynamo/lockSchema.d.ts +2 -0
  137. package/{models → dist/models}/dynamo/lockSchema.js +5 -7
  138. package/dist/models/dynamo/noteCacheSchema.d.ts +2 -0
  139. package/{models → dist/models}/dynamo/noteCacheSchema.js +4 -6
  140. package/dist/models/llmSessionModel.d.ts +2 -0
  141. package/dist/models/llmSessionModel.js +21 -0
  142. package/dist/models/messageLogModel.d.ts +2 -0
  143. package/{models → dist/models}/messageLogModel.js +8 -4
  144. package/dist/models/sequelize.d.ts +2 -0
  145. package/dist/models/sequelize.js +68 -0
  146. package/dist/models/userModel.d.ts +2 -0
  147. package/dist/models/userModel.js +49 -0
  148. package/dist/package.json +100 -0
  149. package/dist/releaseNotes.json +1222 -0
  150. package/dist/tsconfig.json +14 -0
  151. package/dist/types/admin.d.ts +141 -0
  152. package/dist/types/analytics.d.ts +14 -0
  153. package/dist/types/appointment.d.ts +50 -0
  154. package/dist/types/auth.d.ts +137 -0
  155. package/dist/types/authSession.d.ts +35 -0
  156. package/dist/types/cacheCleanup.d.ts +12 -0
  157. package/dist/types/calldown.d.ts +54 -0
  158. package/dist/types/common.d.ts +46 -0
  159. package/dist/types/connector.d.ts +165 -0
  160. package/dist/types/contact.d.ts +125 -0
  161. package/dist/types/errorHandler.d.ts +60 -0
  162. package/dist/types/index.d.ts +76 -0
  163. package/dist/types/json.d.ts +9 -0
  164. package/dist/types/jwt.d.ts +8 -0
  165. package/dist/types/logging.d.ts +224 -0
  166. package/dist/types/managedAuth.d.ts +114 -0
  167. package/dist/types/managedOAuth.d.ts +59 -0
  168. package/dist/types/manifest.d.ts +120 -0
  169. package/dist/types/migration.d.ts +15 -0
  170. package/dist/types/plugin.d.ts +74 -0
  171. package/dist/types/ringcentral.d.ts +61 -0
  172. package/dist/types/s3ErrorLogReport.d.ts +16 -0
  173. package/dist/types/sharedSMSComposer.d.ts +105 -0
  174. package/dist/types/user.d.ts +46 -0
  175. package/dist/types/util.d.ts +7 -0
  176. package/package.json +34 -6
  177. package/releaseNotes.json +13 -1
  178. package/.env.test +0 -5
  179. package/connector/proxy/engine.js +0 -165
  180. package/connector/proxy/index.js +0 -500
  181. package/connector/registry.js +0 -252
  182. package/docs/README.md +0 -50
  183. package/docs/architecture.md +0 -94
  184. package/docs/connectors.md +0 -116
  185. package/docs/handlers.md +0 -128
  186. package/docs/libraries.md +0 -98
  187. package/docs/models.md +0 -146
  188. package/docs/routes.md +0 -119
  189. package/docs/tests.md +0 -73
  190. package/handlers/calldown.js +0 -99
  191. package/jest.config.js +0 -57
  192. package/lib/constants.js +0 -9
  193. package/lib/encode.js +0 -30
  194. package/lib/errorHandler.js +0 -218
  195. package/lib/jwt.js +0 -18
  196. package/lib/logger.js +0 -190
  197. package/lib/migrateCallLogsSchema.js +0 -237
  198. package/lib/ringcentral.js +0 -267
  199. package/mcp/README.md +0 -420
  200. package/mcp/tools/index.js +0 -51
  201. package/mcp/ui/App/App.tsx +0 -358
  202. package/mcp/ui/App/components/AuthInfoForm.tsx +0 -113
  203. package/mcp/ui/App/components/AuthSuccess.tsx +0 -22
  204. package/mcp/ui/App/components/ConnectorList.tsx +0 -82
  205. package/mcp/ui/App/components/DebugPanel.tsx +0 -43
  206. package/mcp/ui/App/components/OAuthConnect.tsx +0 -270
  207. package/mcp/ui/App/lib/callTool.ts +0 -130
  208. package/mcp/ui/App/lib/debugLog.ts +0 -41
  209. package/mcp/ui/App/lib/developerPortal.ts +0 -111
  210. package/mcp/ui/App/main.css +0 -6
  211. package/mcp/ui/App/root.tsx +0 -13
  212. package/mcp/ui/dist/index.html +0 -53
  213. package/mcp/ui/vite.config.ts +0 -16
  214. package/models/accountDataModel.js +0 -34
  215. package/models/adminConfigModel.js +0 -35
  216. package/models/callLogModel.js +0 -39
  217. package/models/dynamo/connectorSchema.js +0 -146
  218. package/models/llmSessionModel.js +0 -17
  219. package/models/sequelize.js +0 -17
  220. package/models/userModel.js +0 -45
  221. package/test/connector/developerPortal.test.js +0 -166
  222. package/test/connector/mock.test.js +0 -131
  223. package/test/connector/proxy/engine.test.js +0 -211
  224. package/test/connector/proxy/index.test.js +0 -525
  225. package/test/connector/proxy/sample.json +0 -162
  226. package/test/connector/registry.test.js +0 -416
  227. package/test/handlers/admin.test.js +0 -960
  228. package/test/handlers/appointment.test.js +0 -260
  229. package/test/handlers/auth.test.js +0 -1096
  230. package/test/handlers/calldown.test.js +0 -310
  231. package/test/handlers/contact.test.js +0 -1014
  232. package/test/handlers/disposition.test.js +0 -396
  233. package/test/handlers/log.test.js +0 -1847
  234. package/test/handlers/managedAuth.test.js +0 -458
  235. package/test/handlers/managedOAuth.test.js +0 -262
  236. package/test/handlers/plugin.test.js +0 -429
  237. package/test/handlers/user.test.js +0 -381
  238. package/test/index.test.js +0 -301
  239. package/test/lib/analytics.test.js +0 -146
  240. package/test/lib/authSession.test.js +0 -173
  241. package/test/lib/cacheCleanup.test.js +0 -127
  242. package/test/lib/callLogComposer.test.js +0 -1231
  243. package/test/lib/debugTracer.test.js +0 -328
  244. package/test/lib/encode.test.js +0 -59
  245. package/test/lib/errorHandler.test.js +0 -246
  246. package/test/lib/generalErrorMessage.test.js +0 -82
  247. package/test/lib/jwt.test.js +0 -176
  248. package/test/lib/logger.test.js +0 -206
  249. package/test/lib/oauth.test.js +0 -359
  250. package/test/lib/ringcentral.test.js +0 -467
  251. package/test/lib/s3ErrorLogReport.test.js +0 -187
  252. package/test/lib/sharedSMSComposer.test.js +0 -1084
  253. package/test/lib/util.test.js +0 -329
  254. package/test/mcp/mcpHandler.test.js +0 -73
  255. package/test/mcp/mcpHandlerMore.test.js +0 -384
  256. package/test/mcp/tools/appointmentTools.test.js +0 -362
  257. package/test/mcp/tools/checkAuthStatus.test.js +0 -83
  258. package/test/mcp/tools/createCallLog.test.js +0 -436
  259. package/test/mcp/tools/createContact.test.js +0 -58
  260. package/test/mcp/tools/createMessageLog.test.js +0 -595
  261. package/test/mcp/tools/doAuth.test.js +0 -113
  262. package/test/mcp/tools/findContactByName.test.js +0 -275
  263. package/test/mcp/tools/findContactByPhone.test.js +0 -296
  264. package/test/mcp/tools/getCallLog.test.js +0 -298
  265. package/test/mcp/tools/getGoogleFilePicker.test.js +0 -281
  266. package/test/mcp/tools/getPublicConnectors.test.js +0 -107
  267. package/test/mcp/tools/getSessionInfo.test.js +0 -127
  268. package/test/mcp/tools/logout.test.js +0 -233
  269. package/test/mcp/tools/rcGetCallLogs.test.js +0 -56
  270. package/test/mcp/tools/updateCallLog.test.js +0 -360
  271. package/test/models/accountDataModel.test.js +0 -98
  272. package/test/models/callDownListModel.test.js +0 -125
  273. package/test/models/dynamo/connectorSchema.test.js +0 -189
  274. package/test/models/dynamo/lockSchema.test.js +0 -37
  275. package/test/models/dynamo/noteCacheSchema.test.js +0 -45
  276. package/test/models/llmSessionModel.test.js +0 -91
  277. package/test/models/models.test.js +0 -660
  278. package/test/routes/calldownRoutes.test.js +0 -224
  279. package/test/routes/coreRouterBroadRoutes.test.js +0 -855
  280. package/test/routes/dispositionRoutes.test.js +0 -192
  281. package/test/routes/managedAuthRoutes.test.js +0 -386
  282. package/test/routes/pluginRoutes.test.js +0 -262
  283. package/test/setup.js +0 -178
  284. /package/{mcp → dist/mcp}/ui/index.html +0 -0
  285. /package/{mcp → dist/mcp}/ui/package-lock.json +0 -0
  286. /package/{mcp → dist/mcp}/ui/package.json +0 -0
  287. /package/{mcp → dist/mcp}/ui/tsconfig.json +0 -0
@@ -1,192 +0,0 @@
1
- const express = require('express');
2
- const request = require('supertest');
3
-
4
- jest.mock('../../handlers/disposition', () => ({
5
- upsertCallDisposition: jest.fn(),
6
- }));
7
- jest.mock('../../lib/analytics', () => ({
8
- init: jest.fn(),
9
- track: jest.fn(),
10
- }));
11
- jest.mock('../../lib/jwt', () => ({
12
- decodeJwt: jest.fn(),
13
- generateJwt: jest.fn().mockReturnValue('refreshed-crm-jwt'),
14
- }));
15
-
16
- const disposition = require('../../handlers/disposition');
17
- const analytics = require('../../lib/analytics');
18
- const jwt = require('../../lib/jwt');
19
- const { createCoreRouter } = require('../../index');
20
-
21
- describe('Disposition Routes', () => {
22
- let app;
23
-
24
- beforeEach(() => {
25
- jest.clearAllMocks();
26
- jwt.decodeJwt.mockReturnValue({
27
- id: 'crm-user-id',
28
- platform: 'testCRM',
29
- });
30
- app = express();
31
- app.use(express.json());
32
- app.use('/', createCoreRouter());
33
- });
34
-
35
- test('PUT /callDisposition delegates decoded CRM identity and request body', async () => {
36
- disposition.upsertCallDisposition.mockResolvedValue({
37
- successful: true,
38
- returnMessage: {
39
- message: 'Disposition saved',
40
- messageType: 'success',
41
- ttl: 2000,
42
- },
43
- extraDataTracking: {
44
- statusCode: 204,
45
- },
46
- });
47
-
48
- const response = await request(app)
49
- .put('/callDisposition')
50
- .query({ jwtToken: 'crm-jwt' })
51
- .send({
52
- sessionId: 'session-1',
53
- extensionNumber: '101',
54
- hashedExtensionId: 'hashed-extension-1',
55
- dispositions: [{ id: 'disp-1' }],
56
- additionalSubmission: { note: 'extra' },
57
- });
58
-
59
- expect(response.status).toBe(200);
60
- expect(response.body).toEqual({
61
- successful: true,
62
- returnMessage: {
63
- message: 'Disposition saved',
64
- messageType: 'success',
65
- ttl: 2000,
66
- },
67
- });
68
- expect(disposition.upsertCallDisposition).toHaveBeenCalledWith({
69
- platform: 'testCRM',
70
- userId: 'crm-user-id',
71
- sessionId: 'session-1',
72
- extensionNumber: '101',
73
- hashedExtensionId: 'hashed-extension-1',
74
- dispositions: [{ id: 'disp-1' }],
75
- additionalSubmission: { note: 'extra' },
76
- });
77
- expect(analytics.track).toHaveBeenCalledWith(expect.objectContaining({
78
- eventName: 'Disposition call log',
79
- interfaceName: 'dispositionCallLog',
80
- connectorName: 'testCRM',
81
- success: true,
82
- extras: {
83
- statusCode: 204,
84
- },
85
- }));
86
- });
87
-
88
- test('PUT /callDisposition rejects missing CRM auth token', async () => {
89
- const response = await request(app)
90
- .put('/callDisposition')
91
- .send({
92
- sessionId: 'session-1',
93
- });
94
-
95
- expect(response.status).toBe(400);
96
- expect(response.text).toBe('Please go to Settings and authorize CRM platform');
97
- expect(disposition.upsertCallDisposition).not.toHaveBeenCalled();
98
- expect(analytics.track).toHaveBeenCalledWith(expect.objectContaining({
99
- eventName: 'Disposition call log',
100
- success: false,
101
- }));
102
- });
103
-
104
- test('PUT /callDisposition rejects invalid JWT token', async () => {
105
- jwt.decodeJwt.mockReturnValue(null);
106
-
107
- const response = await request(app)
108
- .put('/callDisposition')
109
- .query({ jwtToken: 'invalid-jwt' })
110
- .send({
111
- sessionId: 'session-1',
112
- });
113
-
114
- expect(response.status).toBe(400);
115
- expect(response.text).toBe('Invalid JWT token');
116
- expect(disposition.upsertCallDisposition).not.toHaveBeenCalled();
117
- });
118
-
119
- test('PUT /callDisposition rejects decoded token without user id', async () => {
120
- jwt.decodeJwt.mockReturnValue({
121
- platform: 'testCRM',
122
- });
123
-
124
- const response = await request(app)
125
- .put('/callDisposition')
126
- .query({ jwtToken: 'crm-jwt' })
127
- .send({
128
- sessionId: 'session-1',
129
- });
130
-
131
- expect(response.status).toBe(400);
132
- expect(response.text).toBe('Please go to Settings and authorize CRM platform');
133
- expect(disposition.upsertCallDisposition).not.toHaveBeenCalled();
134
- });
135
-
136
- test('PUT /callDisposition returns 401 when handler asks to revoke user session', async () => {
137
- disposition.upsertCallDisposition.mockResolvedValue({
138
- successful: false,
139
- returnMessage: {
140
- message: 'User session expired. Please connect again.',
141
- messageType: 'warning',
142
- ttl: 5000,
143
- },
144
- isRevokeUserSession: true,
145
- });
146
-
147
- const response = await request(app)
148
- .put('/callDisposition')
149
- .query({ jwtToken: 'crm-jwt' })
150
- .send({
151
- sessionId: 'session-1',
152
- });
153
-
154
- expect(response.status).toBe(401);
155
- expect(response.body).toEqual({
156
- successful: false,
157
- returnMessage: {
158
- message: 'User session expired. Please connect again.',
159
- messageType: 'warning',
160
- ttl: 5000,
161
- },
162
- });
163
- expect(analytics.track).toHaveBeenCalledWith(expect.objectContaining({
164
- eventName: 'Disposition call log',
165
- success: false,
166
- }));
167
- });
168
-
169
- test('PUT /callDisposition maps handler exceptions to 400 error response', async () => {
170
- disposition.upsertCallDisposition.mockRejectedValue(new Error('provider failed'));
171
-
172
- const response = await request(app)
173
- .put('/callDisposition')
174
- .query({ jwtToken: 'crm-jwt' })
175
- .send({
176
- sessionId: 'session-1',
177
- });
178
-
179
- expect(response.status).toBe(400);
180
- expect(response.body).toEqual({
181
- error: 'provider failed',
182
- });
183
- expect(analytics.track).toHaveBeenCalledWith(expect.objectContaining({
184
- eventName: 'Disposition call log',
185
- success: false,
186
- extras: {
187
- statusCode: 'unknown',
188
- },
189
- }));
190
- });
191
- });
192
-
@@ -1,386 +0,0 @@
1
- const express = require('express');
2
- const request = require('supertest');
3
-
4
- jest.mock('../../handlers/admin', () => ({
5
- validateRcUserToken: jest.fn(),
6
- validateAdminRole: jest.fn(),
7
- }));
8
- jest.mock('../../handlers/managedAuth', () => ({
9
- getManagedAuthState: jest.fn(),
10
- getManagedAuthAdminSettings: jest.fn(),
11
- upsertOrgManagedAuthValues: jest.fn(),
12
- upsertUserManagedAuthValues: jest.fn(),
13
- }));
14
- jest.mock('../../handlers/managedOAuth', () => ({
15
- getManagedOAuthState: jest.fn(),
16
- upsertPendingManagedOAuth: jest.fn(),
17
- clearPendingManagedOAuth: jest.fn(),
18
- resetManagedOAuth: jest.fn(),
19
- }));
20
- jest.mock('../../handlers/auth', () => ({
21
- onApiKeyLogin: jest.fn(),
22
- }));
23
- jest.mock('../../lib/jwt', () => ({
24
- generateJwt: jest.fn().mockReturnValue('jwt-token'),
25
- decodeJwt: jest.fn(),
26
- }));
27
- jest.mock('../../models/userModel', () => ({
28
- UserModel: {
29
- findByPk: jest.fn(),
30
- },
31
- }));
32
-
33
- const adminCore = require('../../handlers/admin');
34
- const managedAuthCore = require('../../handlers/managedAuth');
35
- const managedOAuthCore = require('../../handlers/managedOAuth');
36
- const authCore = require('../../handlers/auth');
37
- const jwt = require('../../lib/jwt');
38
- const { UserModel } = require('../../models/userModel');
39
- const { createCoreRouter } = require('../../index');
40
-
41
- describe('Managed Auth Routes', () => {
42
- let app;
43
-
44
- beforeEach(() => {
45
- jest.clearAllMocks();
46
- app = express();
47
- app.use(express.json());
48
- app.use('/', createCoreRouter());
49
- });
50
-
51
- describe('GET /apiKeyManagedAuthState', () => {
52
- test('should validate rcAccessToken and use validated identity', async () => {
53
- adminCore.validateRcUserToken.mockResolvedValue({
54
- rcAccountId: 'validated-account-id',
55
- rcExtensionId: 'validated-extension-id',
56
- });
57
- managedAuthCore.getManagedAuthState.mockResolvedValue({
58
- hasManagedAuth: true,
59
- allRequiredFieldsSatisfied: true,
60
- visibleFieldConsts: [],
61
- missingRequiredFieldConsts: [],
62
- });
63
-
64
- const response = await request(app)
65
- .get('/apiKeyManagedAuthState')
66
- .query({
67
- platform: 'testCRM',
68
- rcAccessToken: 'valid-rc-token',
69
- rcAccountId: 'spoofed-account-id',
70
- rcExtensionId: 'spoofed-extension-id',
71
- });
72
-
73
- expect(response.status).toBe(200);
74
- expect(adminCore.validateRcUserToken).toHaveBeenCalledWith({ rcAccessToken: 'valid-rc-token' });
75
- expect(managedAuthCore.getManagedAuthState).toHaveBeenCalledWith(expect.objectContaining({
76
- platform: 'testCRM',
77
- rcAccountId: 'validated-account-id',
78
- rcExtensionId: 'validated-extension-id',
79
- }));
80
- });
81
- });
82
-
83
- describe('GET /oauthManagedAuthState', () => {
84
- test('should validate rcAccessToken and return managed OAuth state for validated account', async () => {
85
- adminCore.validateRcUserToken.mockResolvedValue({
86
- rcAccountId: 'validated-account-id',
87
- rcExtensionId: 'validated-extension-id',
88
- });
89
- adminCore.validateAdminRole.mockResolvedValue({
90
- isValidated: true,
91
- rcAccountId: 'validated-account-id',
92
- });
93
- managedOAuthCore.getManagedOAuthState.mockResolvedValue({
94
- isAdmin: true,
95
- hasAccountOAuth: false,
96
- hasPendingOAuth: true,
97
- pendingValues: {
98
- clientId: 'client-id',
99
- clientSecret: 'client-secret',
100
- },
101
- });
102
-
103
- const response = await request(app)
104
- .get('/oauthManagedAuthState')
105
- .query({
106
- platform: 'testCRM',
107
- rcAccessToken: 'valid-rc-token',
108
- rcAccountId: 'spoofed-account-id',
109
- });
110
-
111
- expect(response.status).toBe(200);
112
- expect(adminCore.validateRcUserToken).toHaveBeenCalledWith({ rcAccessToken: 'valid-rc-token' });
113
- expect(adminCore.validateAdminRole).toHaveBeenCalledWith({ rcAccessToken: 'valid-rc-token' });
114
- expect(managedOAuthCore.getManagedOAuthState).toHaveBeenCalledWith({
115
- platform: 'testCRM',
116
- rcAccountId: 'validated-account-id',
117
- isAdmin: true,
118
- });
119
- expect(response.body.pendingValues.clientSecret).toBe('client-secret');
120
- });
121
- });
122
-
123
- describe('POST /admin/managedOAuth/cache', () => {
124
- test('should require admin role and write pending managed OAuth values for validated account', async () => {
125
- adminCore.validateAdminRole.mockResolvedValue({
126
- isValidated: true,
127
- rcAccountId: 'validated-account-id',
128
- });
129
- managedOAuthCore.upsertPendingManagedOAuth.mockResolvedValue({});
130
-
131
- const values = {
132
- clientId: 'client-id',
133
- clientSecret: 'client-secret',
134
- };
135
-
136
- const response = await request(app)
137
- .post('/admin/managedOAuth/cache')
138
- .query({ rcAccessToken: 'valid-rc-token' })
139
- .send({ values });
140
-
141
- expect(response.status).toBe(200);
142
- expect(managedOAuthCore.upsertPendingManagedOAuth).toHaveBeenCalledWith({
143
- rcAccountId: 'validated-account-id',
144
- values,
145
- });
146
- });
147
-
148
- test('should reject non-admin users', async () => {
149
- adminCore.validateAdminRole.mockResolvedValue({
150
- isValidated: false,
151
- rcAccountId: 'validated-account-id',
152
- });
153
-
154
- const response = await request(app)
155
- .post('/admin/managedOAuth/cache')
156
- .query({ rcAccessToken: 'valid-rc-token' })
157
- .send({ values: { clientId: 'client-id' } });
158
-
159
- expect(response.status).toBe(403);
160
- expect(managedOAuthCore.upsertPendingManagedOAuth).not.toHaveBeenCalled();
161
- });
162
- });
163
-
164
- describe('DELETE /admin/managedOAuth/account', () => {
165
- test('should require admin role and delete managed OAuth account for validated account', async () => {
166
- adminCore.validateAdminRole.mockResolvedValue({
167
- isValidated: true,
168
- rcAccountId: 'validated-account-id',
169
- });
170
- managedOAuthCore.resetManagedOAuth.mockResolvedValue({
171
- deletedAccountCount: 1,
172
- deletedPendingCount: 1,
173
- });
174
-
175
- const response = await request(app)
176
- .delete('/admin/managedOAuth/account')
177
- .query({
178
- rcAccessToken: 'valid-rc-token',
179
- platform: 'testCRM',
180
- });
181
-
182
- expect(response.status).toBe(200);
183
- expect(managedOAuthCore.resetManagedOAuth).toHaveBeenCalledWith({
184
- rcAccountId: 'validated-account-id',
185
- platform: 'testCRM',
186
- });
187
- });
188
-
189
- test('should reject non-admin users', async () => {
190
- adminCore.validateAdminRole.mockResolvedValue({
191
- isValidated: false,
192
- rcAccountId: 'validated-account-id',
193
- });
194
-
195
- const response = await request(app)
196
- .delete('/admin/managedOAuth/account')
197
- .query({
198
- rcAccessToken: 'valid-rc-token',
199
- platform: 'testCRM',
200
- });
201
-
202
- expect(response.status).toBe(403);
203
- expect(managedOAuthCore.resetManagedOAuth).not.toHaveBeenCalled();
204
- });
205
- });
206
-
207
-
208
- describe('GET /admin/managedAuth', () => {
209
- test('should use CRM jwt platform and validated admin account for settings lookup', async () => {
210
- jwt.decodeJwt.mockReturnValue({ id: 'crm-user-id' });
211
- UserModel.findByPk.mockResolvedValue({
212
- id: 'crm-user-id',
213
- platform: 'salesforce',
214
- });
215
- adminCore.validateAdminRole.mockResolvedValue({
216
- isValidated: true,
217
- rcAccountId: 'validated-account-id',
218
- });
219
- managedAuthCore.getManagedAuthAdminSettings.mockResolvedValue({
220
- orgFields: [{ const: 'apiKey' }],
221
- userFields: [{ const: 'userToken' }],
222
- orgValues: {},
223
- userValues: [],
224
- });
225
-
226
- const response = await request(app)
227
- .get('/admin/managedAuth')
228
- .query({
229
- jwtToken: 'crm-jwt',
230
- rcAccessToken: 'valid-rc-token',
231
- connectorId: 'shared-connector',
232
- isPrivate: 'true',
233
- });
234
-
235
- expect(response.status).toBe(200);
236
- expect(jwt.decodeJwt).toHaveBeenCalledWith('crm-jwt');
237
- expect(UserModel.findByPk).toHaveBeenCalledWith('crm-user-id');
238
- expect(adminCore.validateAdminRole).toHaveBeenCalledWith({ rcAccessToken: 'valid-rc-token' });
239
- expect(managedAuthCore.getManagedAuthAdminSettings).toHaveBeenCalledWith({
240
- platform: 'salesforce',
241
- rcAccountId: 'validated-account-id',
242
- connectorId: 'shared-connector',
243
- isPrivate: true,
244
- });
245
- expect(response.body.orgFields).toEqual([{ const: 'apiKey' }]);
246
- });
247
-
248
- test('should reject non-admin users before reading managed auth settings', async () => {
249
- jwt.decodeJwt.mockReturnValue({ id: 'crm-user-id' });
250
- UserModel.findByPk.mockResolvedValue({
251
- id: 'crm-user-id',
252
- platform: 'salesforce',
253
- });
254
- adminCore.validateAdminRole.mockResolvedValue({
255
- isValidated: false,
256
- rcAccountId: 'validated-account-id',
257
- });
258
-
259
- const response = await request(app)
260
- .get('/admin/managedAuth')
261
- .query({
262
- jwtToken: 'crm-jwt',
263
- rcAccessToken: 'valid-rc-token',
264
- });
265
-
266
- expect(response.status).toBe(403);
267
- expect(response.text).toBe('Admin validation failed');
268
- expect(managedAuthCore.getManagedAuthAdminSettings).not.toHaveBeenCalled();
269
- });
270
- });
271
-
272
- describe('POST /admin/managedAuth', () => {
273
- test('should save org scoped values under the validated admin account and CRM platform', async () => {
274
- jwt.decodeJwt.mockReturnValue({ id: 'crm-user-id' });
275
- UserModel.findByPk.mockResolvedValue({
276
- id: 'crm-user-id',
277
- platform: 'salesforce',
278
- });
279
- adminCore.validateAdminRole.mockResolvedValue({
280
- isValidated: true,
281
- rcAccountId: 'validated-account-id',
282
- });
283
- managedAuthCore.upsertOrgManagedAuthValues.mockResolvedValue({});
284
-
285
- const response = await request(app)
286
- .post('/admin/managedAuth')
287
- .query({
288
- jwtToken: 'crm-jwt',
289
- rcAccessToken: 'valid-rc-token',
290
- connectorId: 'private-connector',
291
- isPrivate: 'true',
292
- })
293
- .send({
294
- scope: 'org',
295
- values: { apiKey: 'api-key' },
296
- fieldsToRemove: ['oldApiKey'],
297
- });
298
-
299
- expect(response.status).toBe(200);
300
- expect(response.text).toBe('Shared authentication updated');
301
- expect(managedAuthCore.upsertOrgManagedAuthValues).toHaveBeenCalledWith({
302
- rcAccountId: 'validated-account-id',
303
- platform: 'salesforce',
304
- values: { apiKey: 'api-key' },
305
- fieldsToRemove: ['oldApiKey'],
306
- });
307
- expect(managedAuthCore.upsertUserManagedAuthValues).not.toHaveBeenCalled();
308
- });
309
-
310
- test('should save user scoped values with selected RingCentral extension details', async () => {
311
- jwt.decodeJwt.mockReturnValue({ id: 'crm-user-id' });
312
- UserModel.findByPk.mockResolvedValue({
313
- id: 'crm-user-id',
314
- platform: 'salesforce',
315
- });
316
- adminCore.validateAdminRole.mockResolvedValue({
317
- isValidated: true,
318
- rcAccountId: 'validated-account-id',
319
- });
320
- managedAuthCore.upsertUserManagedAuthValues.mockResolvedValue({});
321
-
322
- const response = await request(app)
323
- .post('/admin/managedAuth')
324
- .query({
325
- jwtToken: 'crm-jwt',
326
- rcAccessToken: 'valid-rc-token',
327
- })
328
- .send({
329
- scope: 'user',
330
- rcExtensionId: '101',
331
- rcUserName: 'Ada Lovelace',
332
- values: { userToken: 'token-101' },
333
- fieldsToRemove: ['oldUserToken'],
334
- });
335
-
336
- expect(response.status).toBe(200);
337
- expect(managedAuthCore.upsertUserManagedAuthValues).toHaveBeenCalledWith({
338
- rcAccountId: 'validated-account-id',
339
- platform: 'salesforce',
340
- rcExtensionId: '101',
341
- rcUserName: 'Ada Lovelace',
342
- values: { userToken: 'token-101' },
343
- fieldsToRemove: ['oldUserToken'],
344
- });
345
- expect(managedAuthCore.upsertOrgManagedAuthValues).not.toHaveBeenCalled();
346
- });
347
- });
348
- describe('POST /apiKeyLogin', () => {
349
-
350
- test('should validate rcAccessToken and ignore spoofed rc ids in body', async () => {
351
- adminCore.validateRcUserToken.mockResolvedValue({
352
- rcAccountId: 'validated-account-id',
353
- rcExtensionId: 'validated-extension-id',
354
- });
355
- authCore.onApiKeyLogin.mockResolvedValue({
356
- userInfo: {
357
- id: 'crm-user-id',
358
- name: 'CRM User',
359
- },
360
- returnMessage: {
361
- messageType: 'success',
362
- message: 'ok',
363
- },
364
- });
365
-
366
- const response = await request(app)
367
- .post('/apiKeyLogin')
368
- .send({
369
- platform: 'testCRM',
370
- apiKey: 'api-key',
371
- hostname: 'test.example.com',
372
- rcAccessToken: 'valid-rc-token',
373
- rcAccountId: 'spoofed-account-id',
374
- rcExtensionId: 'spoofed-extension-id',
375
- });
376
-
377
- expect(response.status).toBe(200);
378
- expect(adminCore.validateRcUserToken).toHaveBeenCalledWith({ rcAccessToken: 'valid-rc-token' });
379
- expect(authCore.onApiKeyLogin).toHaveBeenCalledWith(expect.objectContaining({
380
- platform: 'testCRM',
381
- rcAccountId: 'validated-account-id',
382
- rcExtensionId: 'validated-extension-id',
383
- }));
384
- });
385
- });
386
- });