@app-connect/core 1.7.19 → 1.7.20

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.
@@ -36,6 +36,9 @@ exports.UserModel = sequelize.define('users', {
36
36
  platformAdditionalInfo: {
37
37
  type: Sequelize.JSON
38
38
  },
39
+ hashedRcExtensionId: {
40
+ type: Sequelize.STRING,
41
+ },
39
42
  userSettings: {
40
43
  type: Sequelize.JSON
41
44
  }
package/package.json CHANGED
@@ -1,72 +1,72 @@
1
- {
2
- "name": "@app-connect/core",
3
- "version": "1.7.19",
4
- "description": "RingCentral App Connect Core",
5
- "main": "index.js",
6
- "repository": {
7
- "type": "git",
8
- "url": "git+https://github.com/ringcentral/rc-unified-crm-extension.git"
9
- },
10
- "keywords": [
11
- "RingCentral",
12
- "App Connect"
13
- ],
14
- "author": "RingCentral Labs",
15
- "license": "MIT",
16
- "peerDependencies": {
17
- "axios": "^1.12.2",
18
- "express": "^4.22.1",
19
- "moment": "^2.29.4",
20
- "moment-timezone": "^0.5.39",
21
- "pg": "^8.8.0",
22
- "sequelize": "^6.29.0"
23
- },
24
- "dependencies": {
25
- "@aws-sdk/client-dynamodb": "^3.751.0",
26
- "@aws-sdk/client-s3": "^3.947.0",
27
- "@aws-sdk/s3-request-presigner": "^3.947.0",
28
- "@modelcontextprotocol/sdk": "^1.26.0",
29
- "awesome-phonenumber": "^5.6.0",
30
- "body-parser": "^1.20.4",
31
- "body-parser-xml": "^2.0.5",
32
- "client-oauth2": "^4.3.3",
33
- "cors": "^2.8.5",
34
- "country-state-city": "^3.2.1",
35
- "dotenv": "^16.0.3",
36
- "dynamoose": "^4.0.3",
37
- "jsonwebtoken": "^9.0.0",
38
- "mixpanel": "^0.18.0",
39
- "shortid": "^2.2.17",
40
- "tz-lookup": "^6.1.25",
41
- "ua-parser-js": "^1.0.38"
42
- },
43
- "scripts": {
44
- "test": "jest",
45
- "test:watch": "jest --watch",
46
- "test:coverage": "jest --coverage",
47
- "test:ci": "jest --ci --coverage --watchAll=false"
48
- },
49
- "devDependencies": {
50
- "@eslint/js": "^9.22.0",
51
- "@octokit/rest": "^19.0.5",
52
- "axios": "^1.12.2",
53
- "eslint": "^9.22.0",
54
- "express": "^4.22.1",
55
- "globals": "^16.0.0",
56
- "jest": "^29.3.1",
57
- "moment": "^2.29.4",
58
- "moment-timezone": "^0.5.39",
59
- "nock": "^13.2.9",
60
- "pg": "^8.8.0",
61
- "sequelize": "^6.29.0",
62
- "sqlite3": "^5.1.2",
63
- "supertest": "^6.3.1"
64
- },
65
- "overrides": {
66
- "js-object-utilities": "2.2.1"
67
- },
68
- "bugs": {
69
- "url": "https://github.com/ringcentral/rc-unified-crm-extension/issues"
70
- },
71
- "homepage": "https://github.com/ringcentral/rc-unified-crm-extension#readme"
72
- }
1
+ {
2
+ "name": "@app-connect/core",
3
+ "version": "1.7.20",
4
+ "description": "RingCentral App Connect Core",
5
+ "main": "index.js",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/ringcentral/rc-unified-crm-extension.git"
9
+ },
10
+ "keywords": [
11
+ "RingCentral",
12
+ "App Connect"
13
+ ],
14
+ "author": "RingCentral Labs",
15
+ "license": "MIT",
16
+ "peerDependencies": {
17
+ "axios": "^1.12.2",
18
+ "express": "^4.22.1",
19
+ "moment": "^2.29.4",
20
+ "moment-timezone": "^0.5.39",
21
+ "pg": "^8.8.0",
22
+ "sequelize": "^6.29.0"
23
+ },
24
+ "dependencies": {
25
+ "@aws-sdk/client-dynamodb": "^3.751.0",
26
+ "@aws-sdk/client-s3": "^3.947.0",
27
+ "@aws-sdk/s3-request-presigner": "^3.947.0",
28
+ "@modelcontextprotocol/sdk": "^1.26.0",
29
+ "awesome-phonenumber": "^5.6.0",
30
+ "body-parser": "^1.20.4",
31
+ "body-parser-xml": "^2.0.5",
32
+ "client-oauth2": "^4.3.3",
33
+ "cors": "^2.8.5",
34
+ "country-state-city": "^3.2.1",
35
+ "dotenv": "^16.0.3",
36
+ "dynamoose": "^4.0.3",
37
+ "jsonwebtoken": "^9.0.0",
38
+ "mixpanel": "^0.18.0",
39
+ "shortid": "^2.2.17",
40
+ "tz-lookup": "^6.1.25",
41
+ "ua-parser-js": "^1.0.38"
42
+ },
43
+ "scripts": {
44
+ "test": "jest",
45
+ "test:watch": "jest --watch",
46
+ "test:coverage": "jest --coverage",
47
+ "test:ci": "jest --ci --coverage --watchAll=false"
48
+ },
49
+ "devDependencies": {
50
+ "@eslint/js": "^9.22.0",
51
+ "@octokit/rest": "^19.0.5",
52
+ "axios": "^1.12.2",
53
+ "eslint": "^9.22.0",
54
+ "express": "^4.22.1",
55
+ "globals": "^16.0.0",
56
+ "jest": "^29.3.1",
57
+ "moment": "^2.29.4",
58
+ "moment-timezone": "^0.5.39",
59
+ "nock": "^13.2.9",
60
+ "pg": "^8.8.0",
61
+ "sequelize": "^6.29.0",
62
+ "sqlite3": "^5.1.2",
63
+ "supertest": "^6.3.1"
64
+ },
65
+ "overrides": {
66
+ "js-object-utilities": "2.2.1"
67
+ },
68
+ "bugs": {
69
+ "url": "https://github.com/ringcentral/rc-unified-crm-extension/issues"
70
+ },
71
+ "homepage": "https://github.com/ringcentral/rc-unified-crm-extension#readme"
72
+ }
package/releaseNotes.json CHANGED
@@ -1,4 +1,16 @@
1
1
  {
2
+ "1.7.20": {
3
+ "global": [
4
+ {
5
+ "type": "Fix",
6
+ "description": "Click-to-dial not detecting numbers in input fields"
7
+ },
8
+ {
9
+ "type": "Fix",
10
+ "description": "Warm transfer call logging issue"
11
+ }
12
+ ]
13
+ },
2
14
  "1.7.19": {
3
15
  "global": [
4
16
  {
@@ -501,6 +501,7 @@ describe('Auth Handler', () => {
501
501
  describe('getLicenseStatus', () => {
502
502
  test('should return license status from platform module', async () => {
503
503
  // Arrange
504
+ const mockUser = global.testUtils.createMockUser({ id: 'user-123' });
504
505
  const mockLicenseStatus = {
505
506
  isValid: true,
506
507
  expiresAt: '2025-12-31',
@@ -513,6 +514,9 @@ describe('Auth Handler', () => {
513
514
 
514
515
  connectorRegistry.getConnector.mockReturnValue(mockConnector);
515
516
 
517
+ const { UserModel } = require('../../models/userModel');
518
+ jest.spyOn(UserModel, 'findByPk').mockResolvedValue(mockUser);
519
+
516
520
  // Act
517
521
  const result = await authHandler.getLicenseStatus({
518
522
  userId: 'user-123',
@@ -523,8 +527,35 @@ describe('Auth Handler', () => {
523
527
  expect(result).toEqual(mockLicenseStatus);
524
528
  expect(mockConnector.getLicenseStatus).toHaveBeenCalledWith({
525
529
  userId: 'user-123',
530
+ platform: 'testCRM',
531
+ user: mockUser
532
+ });
533
+ });
534
+
535
+ test('should return invalid license status when user not found', async () => {
536
+ // Arrange
537
+ const mockConnector = global.testUtils.createMockConnector({
538
+ getLicenseStatus: jest.fn()
539
+ });
540
+ connectorRegistry.getConnector.mockReturnValue(mockConnector);
541
+
542
+ const { UserModel } = require('../../models/userModel');
543
+ jest.spyOn(UserModel, 'findByPk').mockResolvedValue(null);
544
+
545
+ // Act
546
+ const result = await authHandler.getLicenseStatus({
547
+ userId: 'missing-user',
526
548
  platform: 'testCRM'
527
549
  });
550
+
551
+ // Assert
552
+ expect(result).toEqual({
553
+ isLicenseValid: false,
554
+ licenseStatus: 'Invalid (User not found)',
555
+ licenseStatusDescription: ''
556
+ });
557
+ expect(connectorRegistry.getConnector).not.toHaveBeenCalled();
558
+ expect(mockConnector.getLicenseStatus).not.toHaveBeenCalled();
528
559
  });
529
560
  });
530
561
 
@@ -94,8 +94,9 @@ describe('MCP Tool: logout', () => {
94
94
  });
95
95
  });
96
96
 
97
- test('should handle logout errors gracefully', async () => {
97
+ test('should treat CRM unAuthorize failure as non-fatal and still succeed', async () => {
98
98
  // Arrange
99
+ const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
99
100
  const mockUser = {
100
101
  id: 'test-user-id',
101
102
  platform: 'testCRM'
@@ -120,10 +121,12 @@ describe('MCP Tool: logout', () => {
120
121
  jwtToken: 'mock-jwt-token'
121
122
  });
122
123
 
123
- // Assert
124
- expect(result.success).toBe(false);
125
- expect(result.error).toBe('Logout API failed');
126
- expect(result.errorDetails).toBeDefined();
124
+ // Assert — local session is cleared; CRM revoke errors are logged only
125
+ expect(result.success).toBe(true);
126
+ expect(result.data.message).toContain('IMPORTANT');
127
+ expect(mockConnector.unAuthorize).toHaveBeenCalled();
128
+ expect(consoleSpy).toHaveBeenCalled();
129
+ consoleSpy.mockRestore();
127
130
  });
128
131
 
129
132
  test('should handle invalid JWT token', async () => {
@@ -140,8 +143,9 @@ describe('MCP Tool: logout', () => {
140
143
  expect(result.error).toBeDefined();
141
144
  });
142
145
 
143
- test('should handle missing platform connector', async () => {
146
+ test('should succeed when platform connector is missing (unAuthorize skipped)', async () => {
144
147
  // Arrange
148
+ const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
145
149
  const mockUser = {
146
150
  id: 'test-user-id',
147
151
  platform: 'unknownCRM'
@@ -160,9 +164,11 @@ describe('MCP Tool: logout', () => {
160
164
  jwtToken: 'mock-jwt-token'
161
165
  });
162
166
 
163
- // Assert
164
- expect(result.success).toBe(false);
165
- expect(result.error).toBeDefined();
167
+ // Assert — null connector throws on unAuthorize; error is caught, logout still succeeds locally
168
+ expect(result.success).toBe(true);
169
+ expect(result.data.message).toContain('IMPORTANT');
170
+ expect(consoleSpy).toHaveBeenCalled();
171
+ consoleSpy.mockRestore();
166
172
  });
167
173
  });
168
174
  });