@webex/plugin-meetings 3.0.0-beta.247 → 3.0.0-beta.249

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.
@@ -384,7 +384,8 @@ export default class Meeting extends StatelessWebexPlugin {
384
384
  meetingJoinUrl: any;
385
385
  meetingNumber: any;
386
386
  meetingState: any;
387
- permissionToken: any;
387
+ permissionToken: string;
388
+ permissionTokenPayload: any;
388
389
  resourceId: any;
389
390
  resourceUrl: string;
390
391
  selfId: string;
@@ -757,10 +758,16 @@ export default class Meeting extends StatelessWebexPlugin {
757
758
  private updateMeetingActions;
758
759
  /**
759
760
  * Sets the self user policies based on the contents of the permission token
761
+ * @returns {void}
762
+ */
763
+ setSelfUserPolicies(): void;
764
+ /**
765
+ * Sets the permission token payload on the class instance
766
+ *
760
767
  * @param {String} permissionToken
761
768
  * @returns {void}
762
769
  */
763
- setSelfUserPolicies(permissionToken: string): void;
770
+ setPermissionTokenPayload(permissionToken: string): void;
764
771
  /**
765
772
  * Sets the sip uri on the class instance
766
773
  * uses meeting info as precedence
@@ -1509,4 +1516,11 @@ export default class Meeting extends StatelessWebexPlugin {
1509
1516
  * @returns {Promise}
1510
1517
  */
1511
1518
  unpublishTracks(tracks: LocalTrack[]): Promise<void>;
1519
+ /**
1520
+ * Gets the time left in seconds till the permission token expires
1521
+ * (from the time the function has been fired)
1522
+ *
1523
+ * @returns {number} time left in seconds
1524
+ */
1525
+ getPermissionTokenTimeLeftInSec(): number | undefined;
1512
1526
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/plugin-meetings",
3
- "version": "3.0.0-beta.247",
3
+ "version": "3.0.0-beta.249",
4
4
  "description": "",
5
5
  "license": "Cisco EULA (https://www.cisco.com/c/en/us/products/end-user-license-agreement.html)",
6
6
  "contributors": [
@@ -32,12 +32,12 @@
32
32
  "build": "yarn run -T tsc --declaration true --declarationDir ./dist/types"
33
33
  },
34
34
  "devDependencies": {
35
- "@webex/plugin-meetings": "3.0.0-beta.247",
36
- "@webex/test-helper-chai": "3.0.0-beta.247",
37
- "@webex/test-helper-mocha": "3.0.0-beta.247",
38
- "@webex/test-helper-mock-webex": "3.0.0-beta.247",
39
- "@webex/test-helper-retry": "3.0.0-beta.247",
40
- "@webex/test-helper-test-users": "3.0.0-beta.247",
35
+ "@webex/plugin-meetings": "3.0.0-beta.249",
36
+ "@webex/test-helper-chai": "3.0.0-beta.249",
37
+ "@webex/test-helper-mocha": "3.0.0-beta.249",
38
+ "@webex/test-helper-mock-webex": "3.0.0-beta.249",
39
+ "@webex/test-helper-retry": "3.0.0-beta.249",
40
+ "@webex/test-helper-test-users": "3.0.0-beta.249",
41
41
  "chai": "^4.3.4",
42
42
  "chai-as-promised": "^7.1.1",
43
43
  "jsdom-global": "3.0.2",
@@ -46,19 +46,19 @@
46
46
  "typescript": "^4.7.4"
47
47
  },
48
48
  "dependencies": {
49
- "@webex/common": "3.0.0-beta.247",
49
+ "@webex/common": "3.0.0-beta.249",
50
50
  "@webex/internal-media-core": "1.39.3",
51
- "@webex/internal-plugin-conversation": "3.0.0-beta.247",
52
- "@webex/internal-plugin-device": "3.0.0-beta.247",
53
- "@webex/internal-plugin-llm": "3.0.0-beta.247",
54
- "@webex/internal-plugin-mercury": "3.0.0-beta.247",
55
- "@webex/internal-plugin-metrics": "3.0.0-beta.247",
56
- "@webex/internal-plugin-support": "3.0.0-beta.247",
57
- "@webex/internal-plugin-user": "3.0.0-beta.247",
58
- "@webex/media-helpers": "3.0.0-beta.247",
59
- "@webex/plugin-people": "3.0.0-beta.247",
60
- "@webex/plugin-rooms": "3.0.0-beta.247",
61
- "@webex/webex-core": "3.0.0-beta.247",
51
+ "@webex/internal-plugin-conversation": "3.0.0-beta.249",
52
+ "@webex/internal-plugin-device": "3.0.0-beta.249",
53
+ "@webex/internal-plugin-llm": "3.0.0-beta.249",
54
+ "@webex/internal-plugin-mercury": "3.0.0-beta.249",
55
+ "@webex/internal-plugin-metrics": "3.0.0-beta.249",
56
+ "@webex/internal-plugin-support": "3.0.0-beta.249",
57
+ "@webex/internal-plugin-user": "3.0.0-beta.249",
58
+ "@webex/media-helpers": "3.0.0-beta.249",
59
+ "@webex/plugin-people": "3.0.0-beta.249",
60
+ "@webex/plugin-rooms": "3.0.0-beta.249",
61
+ "@webex/webex-core": "3.0.0-beta.249",
62
62
  "ampersand-collection": "^2.0.2",
63
63
  "bowser": "^2.11.0",
64
64
  "btoa": "^1.2.1",
@@ -542,7 +542,8 @@ export default class Meeting extends StatelessWebexPlugin {
542
542
  meetingJoinUrl: any;
543
543
  meetingNumber: any;
544
544
  meetingState: any;
545
- permissionToken: any;
545
+ permissionToken: string;
546
+ permissionTokenPayload: any;
546
547
  resourceId: any;
547
548
  resourceUrl: string;
548
549
  selfId: string;
@@ -3021,7 +3022,8 @@ export default class Meeting extends StatelessWebexPlugin {
3021
3022
  webexMeetingInfo?.hostId ||
3022
3023
  this.owner;
3023
3024
  this.permissionToken = webexMeetingInfo?.permissionToken;
3024
- this.setSelfUserPolicies(this.permissionToken);
3025
+ this.setPermissionTokenPayload(webexMeetingInfo?.permissionToken);
3026
+ this.setSelfUserPolicies();
3025
3027
  // Need to populate environment when sending CA event
3026
3028
  this.environment = locusMeetingObject?.info.channel || webexMeetingInfo?.channel;
3027
3029
  }
@@ -3285,11 +3287,20 @@ export default class Meeting extends StatelessWebexPlugin {
3285
3287
 
3286
3288
  /**
3287
3289
  * Sets the self user policies based on the contents of the permission token
3290
+ * @returns {void}
3291
+ */
3292
+ setSelfUserPolicies() {
3293
+ this.selfUserPolicies = this.permissionTokenPayload?.permission?.userPolicies;
3294
+ }
3295
+
3296
+ /**
3297
+ * Sets the permission token payload on the class instance
3298
+ *
3288
3299
  * @param {String} permissionToken
3289
3300
  * @returns {void}
3290
3301
  */
3291
- setSelfUserPolicies(permissionToken: string) {
3292
- this.selfUserPolicies = jwt.decode(permissionToken)?.permission?.userPolicies;
3302
+ public setPermissionTokenPayload(permissionToken: string) {
3303
+ this.permissionTokenPayload = jwt.decode(permissionToken);
3293
3304
  }
3294
3305
 
3295
3306
  /**
@@ -7179,4 +7190,26 @@ export default class Meeting extends StatelessWebexPlugin {
7179
7190
  }
7180
7191
  }
7181
7192
  }
7193
+
7194
+ /**
7195
+ * Gets the time left in seconds till the permission token expires
7196
+ * (from the time the function has been fired)
7197
+ *
7198
+ * @returns {number} time left in seconds
7199
+ */
7200
+ public getPermissionTokenTimeLeftInSec(): number | undefined {
7201
+ if (!this.permissionTokenPayload) {
7202
+ return undefined;
7203
+ }
7204
+
7205
+ const permissionTokenExpValue = Number(this.permissionTokenPayload.exp);
7206
+
7207
+ // using new Date instead of Date.now() to allow for accurate unit testing
7208
+ // https://github.com/sinonjs/fake-timers/issues/321
7209
+ const now = new Date().getTime();
7210
+
7211
+ // substract current time from the permissionTokenExp
7212
+ // (permissionTokenExp is a epoch timestamp, not a time to live duration)
7213
+ return (permissionTokenExpValue - now) / 1000;
7214
+ }
7182
7215
  }
@@ -5563,29 +5563,40 @@ describe('plugin-meetings', () => {
5563
5563
  });
5564
5564
  });
5565
5565
 
5566
+ describe('#setPermissionTokenPayload', () => {
5567
+ it('sets correctly', () => {
5568
+ assert.notOk(meeting.permissionTokenPayload);
5569
+
5570
+ const permissionTokenPayloadData = {permission: {userPolicies: {a: true}}, exp: '1234'};
5571
+
5572
+ const jwtDecodeStub = sinon.stub(jwt, 'decode').returns(permissionTokenPayloadData);
5573
+
5574
+ meeting.setPermissionTokenPayload();
5575
+
5576
+ assert.calledOnce(jwtDecodeStub);
5577
+ assert.deepEqual(meeting.permissionTokenPayload, permissionTokenPayloadData);
5578
+ });
5579
+ });
5580
+
5566
5581
  describe('#setSelfUserPolicies', () => {
5567
5582
  it('sets correctly when policy data is present in token', () => {
5568
5583
  assert.notOk(meeting.selfUserPolicies);
5569
5584
 
5570
- const dummyToken = 'some data';
5571
5585
  const policyData = {permission: {userPolicies: {a: true}}};
5586
+ meeting.permissionTokenPayload = policyData;
5572
5587
 
5573
- sinon.stub(jwt, 'decode').returns(policyData);
5574
-
5575
- meeting.setSelfUserPolicies(dummyToken);
5588
+ meeting.setSelfUserPolicies();
5576
5589
 
5577
- assert.deepEqual(meeting.selfUserPolicies, {a: true});
5590
+ assert.deepEqual(meeting.selfUserPolicies, policyData.permission.userPolicies);
5578
5591
  });
5579
5592
 
5580
5593
  it('handles missing permission data', () => {
5581
5594
  assert.notOk(meeting.selfUserPolicies);
5582
5595
 
5583
- const dummyToken = 'some data';
5584
5596
  const policyData = {};
5597
+ meeting.permissionTokenPayload = policyData;
5585
5598
 
5586
- sinon.stub(jwt, 'decode').returns(policyData);
5587
-
5588
- meeting.setSelfUserPolicies(dummyToken);
5599
+ meeting.setSelfUserPolicies();
5589
5600
 
5590
5601
  assert.deepEqual(meeting.selfUserPolicies, undefined);
5591
5602
  });
@@ -5593,12 +5604,10 @@ describe('plugin-meetings', () => {
5593
5604
  it('handles missing policy data', () => {
5594
5605
  assert.notOk(meeting.selfUserPolicies);
5595
5606
 
5596
- const dummyToken = 'some data';
5597
5607
  const policyData = {permission: {}};
5608
+ meeting.permissionTokenPayload = policyData;
5598
5609
 
5599
- sinon.stub(jwt, 'decode').returns(policyData);
5600
-
5601
- meeting.setSelfUserPolicies(dummyToken);
5610
+ meeting.setSelfUserPolicies();
5602
5611
 
5603
5612
  assert.deepEqual(meeting.selfUserPolicies, undefined);
5604
5613
  });
@@ -5658,19 +5667,37 @@ describe('plugin-meetings', () => {
5658
5667
  assert.equal(meeting.owner, expectedInfoToParse.owner);
5659
5668
  assert.equal(meeting.permissionToken, expectedInfoToParse.permissionToken);
5660
5669
  assert.deepEqual(meeting.selfUserPolicies, expectedInfoToParse.selfUserPolicies);
5670
+
5671
+ if(expectedInfoToParse.permissionTokenPayload) {
5672
+ assert.deepEqual(meeting.permissionTokenPayload, expectedInfoToParse.permissionTokenPayload);
5673
+ }
5661
5674
  };
5662
5675
 
5663
5676
  it('should parse meeting info from api return when locus meeting object is not available, set values, and return null', () => {
5664
5677
  meeting.config.experimental = {enableMediaNegotiatedEvent: true};
5665
5678
  meeting.config.experimental.enableUnifiedMeetings = true;
5679
+
5680
+ const expectedPermissionTokenPayload = {
5681
+ exp: "123456",
5682
+ permission: {
5683
+ userPolicies: {
5684
+ a: true
5685
+ }
5686
+ }
5687
+ };
5688
+
5689
+ // generated permissionToken with secret `secret` and
5690
+ // value `JSON.stringify(expectedPermissionTokenPayload)`
5691
+ const permissionToken =
5692
+ 'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxMjM0NTYiLCJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX19.wkTk0Hp8sUlq2wi2nP4-Ym4Xb7aEUHzyXA1kzk6f0V0';
5693
+
5666
5694
  const FAKE_MEETING_INFO = {
5667
5695
  body: {
5668
5696
  conversationUrl: uuid1,
5669
5697
  locusUrl: url1,
5670
5698
  meetingJoinUrl: url2,
5671
5699
  meetingNumber: '12345',
5672
- permissionToken:
5673
- 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX0sImlhdCI6MTY4OTE2NDEwMn0.9uL_U7QUdYyMerrgHC_gCKOax2j_bz04u8Ikbv9KiXU',
5700
+ permissionToken,
5674
5701
  sipMeetingUri: test1,
5675
5702
  sipUrl: test1,
5676
5703
  owner: test2,
@@ -5678,6 +5705,7 @@ describe('plugin-meetings', () => {
5678
5705
  };
5679
5706
 
5680
5707
  meeting.parseMeetingInfo(FAKE_MEETING_INFO);
5708
+
5681
5709
  const expectedInfoToParse = {
5682
5710
  conversationUrl: uuid1,
5683
5711
  locusUrl: url1,
@@ -5686,8 +5714,8 @@ describe('plugin-meetings', () => {
5686
5714
  meetingJoinUrl: url2,
5687
5715
  owner: test2,
5688
5716
  selfUserPolicies: {a: true},
5689
- permissionToken:
5690
- 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwZXJtaXNzaW9uIjp7InVzZXJQb2xpY2llcyI6eyJhIjp0cnVlfX0sImlhdCI6MTY4OTE2NDEwMn0.9uL_U7QUdYyMerrgHC_gCKOax2j_bz04u8Ikbv9KiXU',
5717
+ permissionToken,
5718
+ permissionTokenPayload: expectedPermissionTokenPayload
5691
5719
  };
5692
5720
 
5693
5721
  checkParseMeetingInfo(expectedInfoToParse);
@@ -7997,4 +8025,36 @@ describe('plugin-meetings', () => {
7997
8025
  });
7998
8026
  });
7999
8027
  });
8028
+
8029
+ describe('#getPermissionTokenTimeLeftInSec', () => {
8030
+ let now;
8031
+ let clock;
8032
+
8033
+ beforeEach(() => {
8034
+ now = Date.now();
8035
+
8036
+ // mock `new Date()` with constant `now`
8037
+ clock = sinon.useFakeTimers(now);
8038
+ });
8039
+
8040
+ afterEach(() => {
8041
+ clock.restore();
8042
+ })
8043
+
8044
+ it('should return undefined if exp is undefined', () => {
8045
+ assert.equal(meeting.getPermissionTokenTimeLeftInSec(), undefined)
8046
+ });
8047
+
8048
+ it('should return the expected positive exp', () => {
8049
+ // set permission token as now + 1 sec
8050
+ meeting.permissionTokenPayload = {exp: (now + 1000).toString()};
8051
+ assert.equal(meeting.getPermissionTokenTimeLeftInSec(), 1);
8052
+ });
8053
+
8054
+ it('should return the expected negative exp', () => {
8055
+ // set permission token as now - 1 sec
8056
+ meeting.permissionTokenPayload = {exp: (now - 1000).toString()};
8057
+ assert.equal(meeting.getPermissionTokenTimeLeftInSec(), -1);
8058
+ });
8059
+ });
8000
8060
  });