@webex/webex-core 3.12.0-next.41 → 3.12.0-next.43
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/dist/config.js +9 -0
- package/dist/config.js.map +1 -1
- package/dist/lib/batcher.js +1 -1
- package/dist/lib/credentials/credentials.js +1 -1
- package/dist/lib/credentials/token.js +1 -1
- package/dist/lib/services/services.js +70 -42
- package/dist/lib/services/services.js.map +1 -1
- package/dist/lib/services-v2/services-v2.js +70 -42
- package/dist/lib/services-v2/services-v2.js.map +1 -1
- package/dist/plugins/logger.js +1 -1
- package/dist/webex-core.js +2 -2
- package/package.json +13 -13
- package/src/config.js +10 -0
- package/src/lib/services/services.js +55 -27
- package/src/lib/services-v2/services-v2.ts +55 -26
- package/test/integration/spec/services/services.js +148 -113
- package/test/integration/spec/services-v2/services-v2.js +134 -99
- package/test/unit/spec/services/services.js +135 -2
- package/test/unit/spec/services-v2/services-v2.ts +138 -2
|
@@ -1418,6 +1418,28 @@ const Services = WebexPlugin.extend({
|
|
|
1418
1418
|
this.ready = true;
|
|
1419
1419
|
},
|
|
1420
1420
|
|
|
1421
|
+
/**
|
|
1422
|
+
* Build a promise that rejects once the catalog init timeout elapses. Race
|
|
1423
|
+
* this against catalog collection so a hung request never leaves
|
|
1424
|
+
* `services.ready` false forever - that would stall `webex.ready` and leave
|
|
1425
|
+
* consumers waiting on it indefinitely. Timeout is configurable via
|
|
1426
|
+
* `config.services.catalogInitTimeout` (defaults to 15s in config). Created
|
|
1427
|
+
* lazily so paths that skip catalog collection never schedule a stray timer.
|
|
1428
|
+
*
|
|
1429
|
+
* @private
|
|
1430
|
+
* @returns {Promise<never>}
|
|
1431
|
+
*/
|
|
1432
|
+
_makeInitTimeout() {
|
|
1433
|
+
const initTimeoutMs = this.webex.config?.services?.catalogInitTimeout;
|
|
1434
|
+
|
|
1435
|
+
return new Promise((_, reject) => {
|
|
1436
|
+
setTimeout(
|
|
1437
|
+
() => reject(new Error(`services: init timed out after ${initTimeoutMs}ms`)),
|
|
1438
|
+
initTimeoutMs
|
|
1439
|
+
);
|
|
1440
|
+
});
|
|
1441
|
+
},
|
|
1442
|
+
|
|
1421
1443
|
/**
|
|
1422
1444
|
* Initializer
|
|
1423
1445
|
*
|
|
@@ -1492,6 +1514,14 @@ const Services = WebexPlugin.extend({
|
|
|
1492
1514
|
} else {
|
|
1493
1515
|
const {email} = this.webex.config;
|
|
1494
1516
|
|
|
1517
|
+
if (this.webex.config?.services?.skipPreauthCatalogOnUnauthenticated === true) {
|
|
1518
|
+
this.logger.info(
|
|
1519
|
+
'services: skipping preauth catalog collection while unauthenticated as per the config'
|
|
1520
|
+
);
|
|
1521
|
+
|
|
1522
|
+
return;
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1495
1525
|
this.collectPreauthCatalog(email ? {email} : undefined).catch((error) => {
|
|
1496
1526
|
this.initFailed = true;
|
|
1497
1527
|
this.logger.error(
|
|
@@ -1526,25 +1556,12 @@ const Services = WebexPlugin.extend({
|
|
|
1526
1556
|
}
|
|
1527
1557
|
const {supertoken} = this.webex.credentials;
|
|
1528
1558
|
|
|
1529
|
-
// Race init against a hard timeout so a hung request never leaves
|
|
1530
|
-
// `services.ready` false forever - that would stall `webex.ready` and
|
|
1531
|
-
// leave consumers waiting on it indefinitely. Timeout is configurable via
|
|
1532
|
-
// `config.services.catalogInitTimeout` (defaults to 15s in config).
|
|
1533
|
-
const initTimeoutMs = this.webex.config?.services?.catalogInitTimeout;
|
|
1534
|
-
|
|
1535
|
-
const initServiceCatalogsTimeout = new Promise((_, reject) => {
|
|
1536
|
-
setTimeout(
|
|
1537
|
-
() => reject(new Error(`services: init timed out after ${initTimeoutMs}ms`)),
|
|
1538
|
-
initTimeoutMs
|
|
1539
|
-
);
|
|
1540
|
-
});
|
|
1541
|
-
|
|
1542
1559
|
// Validate if the supertoken exists.
|
|
1543
1560
|
if (supertoken && supertoken.access_token) {
|
|
1544
1561
|
// `initServiceCatalogs` marks the catalog ready internally once the
|
|
1545
1562
|
// postauth catalog is collected - even if it loses the timeout race
|
|
1546
|
-
//
|
|
1547
|
-
Promise.race([this.initServiceCatalogs(),
|
|
1563
|
+
// below, so a slow fetch still eventually flips `catalog.isReady`.
|
|
1564
|
+
Promise.race([this.initServiceCatalogs(), this._makeInitTimeout()])
|
|
1548
1565
|
.catch((error) => {
|
|
1549
1566
|
this.initFailed = true;
|
|
1550
1567
|
this.logger.error(
|
|
@@ -1555,18 +1572,6 @@ const Services = WebexPlugin.extend({
|
|
|
1555
1572
|
} else {
|
|
1556
1573
|
const {email} = this.webex.config;
|
|
1557
1574
|
|
|
1558
|
-
Promise.race([
|
|
1559
|
-
this.collectPreauthCatalog(email ? {email} : undefined),
|
|
1560
|
-
initServiceCatalogsTimeout,
|
|
1561
|
-
])
|
|
1562
|
-
.catch((error) => {
|
|
1563
|
-
this.initFailed = true;
|
|
1564
|
-
this.logger.error(
|
|
1565
|
-
`services: failed to init initial services when no credentials available, ${error?.message}`
|
|
1566
|
-
);
|
|
1567
|
-
})
|
|
1568
|
-
.finally(() => this._finalizeReady());
|
|
1569
|
-
|
|
1570
1575
|
// Handle fresh login: 'loaded' fires before OAuth completes, so listen
|
|
1571
1576
|
// for `canAuthorize` flipping true and then collect the postauth catalog.
|
|
1572
1577
|
this.listenToOnce(this.webex, 'change:canAuthorize', () => {
|
|
@@ -1579,6 +1584,29 @@ const Services = WebexPlugin.extend({
|
|
|
1579
1584
|
});
|
|
1580
1585
|
}
|
|
1581
1586
|
});
|
|
1587
|
+
|
|
1588
|
+
if (this.webex.config?.services?.skipPreauthCatalogOnUnauthenticated === true) {
|
|
1589
|
+
// Skip the preauth catalog fetch (it will be collected manually
|
|
1590
|
+
// later), but still finalize `services.ready` so `webex.ready` is not
|
|
1591
|
+
// stalled while unauthenticated. No timeout is created here so there
|
|
1592
|
+
// is no stray timer or unhandled rejection.
|
|
1593
|
+
this.logger.info(
|
|
1594
|
+
'services: skipping preauth catalog collection while unauthenticated as per the config'
|
|
1595
|
+
);
|
|
1596
|
+
this._finalizeReady();
|
|
1597
|
+
} else {
|
|
1598
|
+
Promise.race([
|
|
1599
|
+
this.collectPreauthCatalog(email ? {email} : undefined),
|
|
1600
|
+
this._makeInitTimeout(),
|
|
1601
|
+
])
|
|
1602
|
+
.catch((error) => {
|
|
1603
|
+
this.initFailed = true;
|
|
1604
|
+
this.logger.error(
|
|
1605
|
+
`services: failed to init initial services when no credentials available, ${error?.message}`
|
|
1606
|
+
);
|
|
1607
|
+
})
|
|
1608
|
+
.finally(() => this._finalizeReady());
|
|
1609
|
+
}
|
|
1582
1610
|
}
|
|
1583
1611
|
});
|
|
1584
1612
|
},
|
|
@@ -1388,6 +1388,28 @@ const Services = WebexPlugin.extend({
|
|
|
1388
1388
|
this.ready = true;
|
|
1389
1389
|
},
|
|
1390
1390
|
|
|
1391
|
+
/**
|
|
1392
|
+
* Build a promise that rejects once the catalog init timeout elapses. Race
|
|
1393
|
+
* this against catalog collection so a hung request never leaves
|
|
1394
|
+
* `services.ready` false forever - that would stall `webex.ready` and leave
|
|
1395
|
+
* consumers waiting on it indefinitely. Timeout is configurable via
|
|
1396
|
+
* `config.services.catalogInitTimeout` (defaults to 15s in config). Created
|
|
1397
|
+
* lazily so paths that skip catalog collection never schedule a stray timer.
|
|
1398
|
+
*
|
|
1399
|
+
* @private
|
|
1400
|
+
* @returns {Promise<never>}
|
|
1401
|
+
*/
|
|
1402
|
+
_makeInitTimeout(): Promise<never> {
|
|
1403
|
+
const initTimeoutMs = this.webex.config?.services?.catalogInitTimeout;
|
|
1404
|
+
|
|
1405
|
+
return new Promise<never>((_, reject) => {
|
|
1406
|
+
setTimeout(
|
|
1407
|
+
() => reject(new Error(`services: init timed out after ${initTimeoutMs}ms`)),
|
|
1408
|
+
initTimeoutMs
|
|
1409
|
+
);
|
|
1410
|
+
});
|
|
1411
|
+
},
|
|
1412
|
+
|
|
1391
1413
|
/**
|
|
1392
1414
|
* Initializer
|
|
1393
1415
|
*
|
|
@@ -1455,6 +1477,14 @@ const Services = WebexPlugin.extend({
|
|
|
1455
1477
|
} else {
|
|
1456
1478
|
const {email} = this.webex.config;
|
|
1457
1479
|
|
|
1480
|
+
if (this.webex.config?.services?.skipPreauthCatalogOnUnauthenticated === true) {
|
|
1481
|
+
this.logger.info(
|
|
1482
|
+
'services: skipping preauth catalog collection while unauthenticated as per the config'
|
|
1483
|
+
);
|
|
1484
|
+
|
|
1485
|
+
return;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1458
1488
|
this.collectPreauthCatalog(email ? {email} : undefined).catch((error) => {
|
|
1459
1489
|
this.initFailed = true;
|
|
1460
1490
|
this.logger.error(
|
|
@@ -1489,24 +1519,12 @@ const Services = WebexPlugin.extend({
|
|
|
1489
1519
|
}
|
|
1490
1520
|
const {supertoken} = this.webex.credentials;
|
|
1491
1521
|
|
|
1492
|
-
// Race init against a hard timeout so a hung request never leaves
|
|
1493
|
-
// `services.ready` false forever - that would stall `webex.ready` and
|
|
1494
|
-
// leave consumers waiting on it indefinitely. Timeout is configurable via
|
|
1495
|
-
// `config.services.catalogInitTimeout` (defaults to 15s in config).
|
|
1496
|
-
const initTimeoutMs = this.webex.config?.services?.catalogInitTimeout;
|
|
1497
|
-
const initServiceCatalogsTimeout = new Promise<never>((_, reject) => {
|
|
1498
|
-
setTimeout(
|
|
1499
|
-
() => reject(new Error(`services: init timed out after ${initTimeoutMs}ms`)),
|
|
1500
|
-
initTimeoutMs
|
|
1501
|
-
);
|
|
1502
|
-
});
|
|
1503
|
-
|
|
1504
1522
|
// Validate if the supertoken exists.
|
|
1505
1523
|
if (supertoken && supertoken.access_token) {
|
|
1506
1524
|
// `initServiceCatalogs` marks the catalog ready internally once the
|
|
1507
1525
|
// postauth catalog is collected - even if it loses the timeout race
|
|
1508
|
-
//
|
|
1509
|
-
Promise.race([this.initServiceCatalogs(),
|
|
1526
|
+
// below, so a slow fetch still eventually flips `catalog.isReady`.
|
|
1527
|
+
Promise.race([this.initServiceCatalogs(), this._makeInitTimeout()])
|
|
1510
1528
|
.catch((error) => {
|
|
1511
1529
|
this.initFailed = true;
|
|
1512
1530
|
this.logger.error(
|
|
@@ -1517,18 +1535,6 @@ const Services = WebexPlugin.extend({
|
|
|
1517
1535
|
} else {
|
|
1518
1536
|
const {email} = this.webex.config;
|
|
1519
1537
|
|
|
1520
|
-
Promise.race([
|
|
1521
|
-
this.collectPreauthCatalog(email ? {email} : undefined),
|
|
1522
|
-
initServiceCatalogsTimeout,
|
|
1523
|
-
])
|
|
1524
|
-
.catch((error) => {
|
|
1525
|
-
this.initFailed = true;
|
|
1526
|
-
this.logger.error(
|
|
1527
|
-
`services: failed to init initial services when no credentials available, ${error?.message}`
|
|
1528
|
-
);
|
|
1529
|
-
})
|
|
1530
|
-
.finally(() => this._finalizeReady());
|
|
1531
|
-
|
|
1532
1538
|
// Handle fresh login: 'loaded' fires before OAuth completes, so listen
|
|
1533
1539
|
// for `canAuthorize` flipping true and then collect the postauth catalog.
|
|
1534
1540
|
this.listenToOnce(this.webex, 'change:canAuthorize', () => {
|
|
@@ -1541,6 +1547,29 @@ const Services = WebexPlugin.extend({
|
|
|
1541
1547
|
});
|
|
1542
1548
|
}
|
|
1543
1549
|
});
|
|
1550
|
+
|
|
1551
|
+
if (this.webex.config?.services?.skipPreauthCatalogOnUnauthenticated === true) {
|
|
1552
|
+
// Skip the preauth catalog fetch (it will be collected manually
|
|
1553
|
+
// later), but still finalize `services.ready` so `webex.ready` is not
|
|
1554
|
+
// stalled while unauthenticated. No timeout is created here so there
|
|
1555
|
+
// is no stray timer or unhandled rejection.
|
|
1556
|
+
this.logger.info(
|
|
1557
|
+
'services: skipping preauth catalog collection while unauthenticated as per the config'
|
|
1558
|
+
);
|
|
1559
|
+
this._finalizeReady();
|
|
1560
|
+
} else {
|
|
1561
|
+
Promise.race([
|
|
1562
|
+
this.collectPreauthCatalog(email ? {email} : undefined),
|
|
1563
|
+
this._makeInitTimeout(),
|
|
1564
|
+
])
|
|
1565
|
+
.catch((error) => {
|
|
1566
|
+
this.initFailed = true;
|
|
1567
|
+
this.logger.error(
|
|
1568
|
+
`services: failed to init initial services when no credentials available, ${error?.message}`
|
|
1569
|
+
);
|
|
1570
|
+
})
|
|
1571
|
+
.finally(() => this._finalizeReady());
|
|
1572
|
+
}
|
|
1544
1573
|
}
|
|
1545
1574
|
});
|
|
1546
1575
|
},
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import '@webex/internal-plugin-device';
|
|
6
6
|
|
|
7
7
|
import {assert} from '@webex/test-helper-chai';
|
|
8
|
-
import {flaky} from '@webex/test-helper-mocha';
|
|
8
|
+
import {flaky, retryOn429} from '@webex/test-helper-mocha';
|
|
9
9
|
import WebexCore, {
|
|
10
10
|
ServiceCatalog,
|
|
11
11
|
ServiceRegistry,
|
|
@@ -443,7 +443,10 @@ describe('webex-core', () => {
|
|
|
443
443
|
// Before init settles, webex.ready must be false because services.ready
|
|
444
444
|
// is a dependency and starts false in the gated path.
|
|
445
445
|
assert.isFalse(gatedWebex.internal.services.ready, 'services.ready should start false');
|
|
446
|
-
assert.isFalse(
|
|
446
|
+
assert.isFalse(
|
|
447
|
+
gatedWebex.ready,
|
|
448
|
+
'webex.ready should not fire while services.ready is false'
|
|
449
|
+
);
|
|
447
450
|
|
|
448
451
|
// Wait up to 30s for services init to complete and flip ready.
|
|
449
452
|
await new Promise((resolve, reject) => {
|
|
@@ -463,7 +466,10 @@ describe('webex-core', () => {
|
|
|
463
466
|
});
|
|
464
467
|
});
|
|
465
468
|
|
|
466
|
-
assert.isTrue(
|
|
469
|
+
assert.isTrue(
|
|
470
|
+
gatedWebex.internal.services.ready,
|
|
471
|
+
'services.ready should flip true after init settles'
|
|
472
|
+
);
|
|
467
473
|
assert.isTrue(gatedWebex.ready, 'webex.ready should fire once services.ready flips');
|
|
468
474
|
});
|
|
469
475
|
});
|
|
@@ -903,18 +909,22 @@ describe('webex-core', () => {
|
|
|
903
909
|
}));
|
|
904
910
|
|
|
905
911
|
it('validates an authorized user and webex instance', () =>
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
912
|
+
retryOn429(() =>
|
|
913
|
+
services.validateUser({email: webexUser.email}).then((r) => {
|
|
914
|
+
assert.hasAllKeys(r, ['activated', 'exists', 'user', 'details']);
|
|
915
|
+
assert.equal(r.activated, true);
|
|
916
|
+
assert.equal(r.exists, true);
|
|
917
|
+
})
|
|
918
|
+
));
|
|
911
919
|
|
|
912
920
|
it('validates an authorized EU user and webex instance', () =>
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
921
|
+
retryOn429(() =>
|
|
922
|
+
servicesEU.validateUser({email: webexUserEU.email}).then((r) => {
|
|
923
|
+
assert.hasAllKeys(r, ['activated', 'exists', 'user', 'details']);
|
|
924
|
+
assert.equal(r.activated, true);
|
|
925
|
+
assert.equal(r.exists, true);
|
|
926
|
+
})
|
|
927
|
+
));
|
|
918
928
|
|
|
919
929
|
it("returns a rejected promise if the provided email isn't valid", () =>
|
|
920
930
|
unauthServices
|
|
@@ -927,131 +937,152 @@ describe('webex-core', () => {
|
|
|
927
937
|
}));
|
|
928
938
|
|
|
929
939
|
it('validates a non-existing user', () =>
|
|
930
|
-
|
|
931
|
-
.validateUser({email: createActivationEmail()})
|
|
932
|
-
.then((r) => {
|
|
940
|
+
retryOn429(() =>
|
|
941
|
+
unauthServices.validateUser({email: createActivationEmail()}).then((r) => {
|
|
933
942
|
assert.hasAllKeys(r, ['activated', 'exists', 'user', 'details']);
|
|
934
943
|
assert.equal(r.activated, false);
|
|
935
944
|
assert.equal(r.exists, false);
|
|
936
945
|
assert.isAbove(Object.keys(unauthServices.list(false, 'preauth')).length, 0);
|
|
937
946
|
assert.equal(Object.keys(unauthServices.list(false, 'signin')).length, 0);
|
|
938
947
|
assert.equal(Object.keys(unauthServices.list(false, 'postauth')).length, 0);
|
|
939
|
-
})
|
|
948
|
+
})
|
|
949
|
+
));
|
|
940
950
|
|
|
941
951
|
it('validates new user with activationOptions suppressEmail false', () =>
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
952
|
+
retryOn429(() =>
|
|
953
|
+
unauthServices
|
|
954
|
+
.validateUser({
|
|
955
|
+
email: createActivationEmail(),
|
|
956
|
+
activationOptions: {suppressEmail: false},
|
|
957
|
+
})
|
|
958
|
+
.then((r) => {
|
|
959
|
+
assert.hasAllKeys(r, ['activated', 'exists', 'user', 'details']);
|
|
960
|
+
assert.equal(r.activated, false);
|
|
961
|
+
assert.equal(r.exists, false);
|
|
962
|
+
assert.equal(r.user.verificationEmailTriggered, true);
|
|
963
|
+
assert.isAbove(Object.keys(unauthServices.list(false, 'preauth')).length, 0);
|
|
964
|
+
assert.equal(Object.keys(unauthServices.list(false, 'signin')).length, 0);
|
|
965
|
+
assert.equal(Object.keys(unauthServices.list(false, 'postauth')).length, 0);
|
|
966
|
+
})
|
|
967
|
+
));
|
|
956
968
|
|
|
957
969
|
it('validates new user with activationOptions suppressEmail true', () =>
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
970
|
+
retryOn429(() =>
|
|
971
|
+
unauthServices
|
|
972
|
+
.validateUser({
|
|
973
|
+
email: createActivationEmail(),
|
|
974
|
+
activationOptions: {suppressEmail: true},
|
|
975
|
+
})
|
|
976
|
+
.then((r) => {
|
|
977
|
+
assert.hasAllKeys(r, ['activated', 'exists', 'user', 'details']);
|
|
978
|
+
assert.equal(r.activated, false);
|
|
979
|
+
assert.equal(r.exists, false);
|
|
980
|
+
assert.equal(r.user.verificationEmailTriggered, false);
|
|
981
|
+
assert.isAbove(Object.keys(unauthServices.list(false, 'preauth')).length, 0);
|
|
982
|
+
assert.equal(Object.keys(unauthServices.list(false, 'signin')).length, 0);
|
|
983
|
+
assert.equal(Object.keys(unauthServices.list(false, 'postauth')).length, 0);
|
|
984
|
+
})
|
|
985
|
+
));
|
|
972
986
|
|
|
973
987
|
it('validates an inactive user', () => {
|
|
974
988
|
const inactive = 'webex.web.client+nonactivated@gmail.com';
|
|
975
989
|
|
|
976
|
-
return
|
|
977
|
-
|
|
978
|
-
|
|
990
|
+
return retryOn429(() =>
|
|
991
|
+
unauthServices
|
|
992
|
+
.validateUser({email: inactive, activationOptions: {suppressEmail: true}})
|
|
993
|
+
.then((r) => {
|
|
994
|
+
assert.hasAllKeys(r, ['activated', 'exists', 'user', 'details']);
|
|
995
|
+
assert.equal(r.activated, false, 'activated');
|
|
996
|
+
assert.equal(r.exists, true, 'exists');
|
|
997
|
+
assert.isAbove(Object.keys(unauthServices.list(false, 'preauth')).length, 0);
|
|
998
|
+
assert.equal(Object.keys(unauthServices.list(false, 'signin')).length, 0);
|
|
999
|
+
assert.equal(Object.keys(unauthServices.list(false, 'postauth')).length, 0);
|
|
1000
|
+
})
|
|
1001
|
+
).catch(() => {
|
|
1002
|
+
assert(true);
|
|
1003
|
+
});
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
it('validates an existing user', () =>
|
|
1007
|
+
retryOn429(() =>
|
|
1008
|
+
unauthServices.validateUser({email: webexUser.email}).then((r) => {
|
|
979
1009
|
assert.hasAllKeys(r, ['activated', 'exists', 'user', 'details']);
|
|
980
|
-
assert.equal(r.activated,
|
|
981
|
-
assert.equal(r.exists, true
|
|
1010
|
+
assert.equal(r.activated, true);
|
|
1011
|
+
assert.equal(r.exists, true);
|
|
982
1012
|
assert.isAbove(Object.keys(unauthServices.list(false, 'preauth')).length, 0);
|
|
983
|
-
assert.
|
|
1013
|
+
assert.isAbove(Object.keys(unauthServices.list(false, 'signin')).length, 0);
|
|
984
1014
|
assert.equal(Object.keys(unauthServices.list(false, 'postauth')).length, 0);
|
|
985
1015
|
})
|
|
986
|
-
|
|
987
|
-
assert(true);
|
|
988
|
-
});
|
|
989
|
-
});
|
|
990
|
-
|
|
991
|
-
it('validates an existing user', () =>
|
|
992
|
-
unauthServices.validateUser({email: webexUser.email}).then((r) => {
|
|
993
|
-
assert.hasAllKeys(r, ['activated', 'exists', 'user', 'details']);
|
|
994
|
-
assert.equal(r.activated, true);
|
|
995
|
-
assert.equal(r.exists, true);
|
|
996
|
-
assert.isAbove(Object.keys(unauthServices.list(false, 'preauth')).length, 0);
|
|
997
|
-
assert.isAbove(Object.keys(unauthServices.list(false, 'signin')).length, 0);
|
|
998
|
-
assert.equal(Object.keys(unauthServices.list(false, 'postauth')).length, 0);
|
|
999
|
-
}));
|
|
1016
|
+
));
|
|
1000
1017
|
|
|
1001
1018
|
it('validates an existing EU user', () =>
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1019
|
+
retryOn429(() =>
|
|
1020
|
+
unauthServices.validateUser({email: webexUserEU.email}).then((r) => {
|
|
1021
|
+
assert.hasAllKeys(r, ['activated', 'exists', 'user', 'details']);
|
|
1022
|
+
assert.equal(r.activated, true);
|
|
1023
|
+
assert.equal(r.exists, true);
|
|
1024
|
+
assert.isAbove(Object.keys(unauthServices.list(false, 'preauth')).length, 0);
|
|
1025
|
+
assert.isAbove(Object.keys(unauthServices.list(false, 'signin')).length, 0);
|
|
1026
|
+
assert.equal(Object.keys(unauthServices.list(false, 'postauth')).length, 0);
|
|
1027
|
+
})
|
|
1028
|
+
));
|
|
1010
1029
|
|
|
1011
1030
|
it('sends the prelogin user id as undefined when not specified', () => {
|
|
1012
1031
|
const requestStub = sandbox.spy(unauthServices, 'request');
|
|
1013
1032
|
|
|
1014
|
-
return
|
|
1015
|
-
.
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1033
|
+
return retryOn429(() => {
|
|
1034
|
+
requestStub.resetHistory();
|
|
1035
|
+
|
|
1036
|
+
return unauthServices
|
|
1037
|
+
.validateUser({
|
|
1038
|
+
email: createActivationEmail(),
|
|
1039
|
+
activationOptions: {suppressEmail: true},
|
|
1040
|
+
})
|
|
1041
|
+
.then(() => {
|
|
1042
|
+
assert.isUndefined(getActivationRequest(requestStub).headers['x-prelogin-userid']);
|
|
1043
|
+
});
|
|
1044
|
+
});
|
|
1022
1045
|
});
|
|
1023
1046
|
|
|
1024
1047
|
it('sends the prelogin user id as provided when specified', () => {
|
|
1025
1048
|
const requestStub = sandbox.spy(unauthServices, 'request');
|
|
1026
1049
|
const preloginUserId = uuid.v4();
|
|
1027
1050
|
|
|
1028
|
-
return
|
|
1029
|
-
.
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1051
|
+
return retryOn429(() => {
|
|
1052
|
+
requestStub.resetHistory();
|
|
1053
|
+
|
|
1054
|
+
return unauthServices
|
|
1055
|
+
.validateUser({
|
|
1056
|
+
email: createActivationEmail(),
|
|
1057
|
+
activationOptions: {suppressEmail: true},
|
|
1058
|
+
preloginUserId,
|
|
1059
|
+
})
|
|
1060
|
+
.then(() => {
|
|
1061
|
+
assert.strictEqual(
|
|
1062
|
+
getActivationRequest(requestStub).headers['x-prelogin-userid'],
|
|
1063
|
+
preloginUserId
|
|
1064
|
+
);
|
|
1065
|
+
});
|
|
1066
|
+
});
|
|
1040
1067
|
});
|
|
1041
1068
|
|
|
1042
1069
|
it('uses the license service by default', () => {
|
|
1043
1070
|
const requestStub = sandbox.spy(unauthServices, 'request');
|
|
1044
1071
|
|
|
1045
|
-
return
|
|
1046
|
-
.
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1072
|
+
return retryOn429(() => {
|
|
1073
|
+
requestStub.resetHistory();
|
|
1074
|
+
|
|
1075
|
+
return unauthServices
|
|
1076
|
+
.validateUser({
|
|
1077
|
+
email: createActivationEmail(),
|
|
1078
|
+
activationOptions: {suppressEmail: true},
|
|
1079
|
+
})
|
|
1080
|
+
.then(() => {
|
|
1081
|
+
const request = getActivationRequest(requestStub, false);
|
|
1082
|
+
assert.strictEqual(request.service, 'license');
|
|
1083
|
+
assert.strictEqual(request.resource, 'users/activations');
|
|
1084
|
+
});
|
|
1085
|
+
});
|
|
1055
1086
|
});
|
|
1056
1087
|
|
|
1057
1088
|
it('uses the user-onboarding service when useUserOnboardingServiceForActivations config is true', () => {
|
|
@@ -1065,16 +1096,20 @@ describe('webex-core', () => {
|
|
|
1065
1096
|
const userOnboardingServices = userOnboardingWebex.internal.services;
|
|
1066
1097
|
const requestStub = sandbox.spy(userOnboardingServices, 'request');
|
|
1067
1098
|
|
|
1068
|
-
return
|
|
1069
|
-
.
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1099
|
+
return retryOn429(() => {
|
|
1100
|
+
requestStub.resetHistory();
|
|
1101
|
+
|
|
1102
|
+
return userOnboardingServices
|
|
1103
|
+
.validateUser({
|
|
1104
|
+
email: createActivationEmail(),
|
|
1105
|
+
activationOptions: {suppressEmail: true},
|
|
1106
|
+
})
|
|
1107
|
+
.then(() => {
|
|
1108
|
+
const request = getActivationRequest(requestStub, true);
|
|
1109
|
+
assert.strictEqual(request.service, 'user-onboarding');
|
|
1110
|
+
assert.strictEqual(request.resource, 'api/v1/users/activations');
|
|
1111
|
+
});
|
|
1112
|
+
});
|
|
1078
1113
|
});
|
|
1079
1114
|
});
|
|
1080
1115
|
|