@webex/webex-core 3.12.0-llmrefactor.1 → 3.12.0-llmrefactor.3
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 +74 -44
- package/dist/lib/services/services.js.map +1 -1
- package/dist/lib/services-v2/services-v2.js +74 -44
- 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 +11 -11
- package/src/config.js +10 -0
- package/src/lib/services/services.js +65 -30
- package/src/lib/services-v2/services-v2.ts +65 -29
- 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
|
@@ -1103,9 +1103,16 @@ const Services = WebexPlugin.extend({
|
|
|
1103
1103
|
requestObject.headers = {authorization: token};
|
|
1104
1104
|
}
|
|
1105
1105
|
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1106
|
+
const sendRequest = () => this.request(requestObject);
|
|
1107
|
+
|
|
1108
|
+
const responsePromise = this.webex.internal.newMetrics
|
|
1109
|
+
? this.webex.internal.newMetrics.callDiagnosticLatencies.measureLatency(
|
|
1110
|
+
sendRequest,
|
|
1111
|
+
'internal.get.u2c.time'
|
|
1112
|
+
)
|
|
1113
|
+
: sendRequest();
|
|
1114
|
+
|
|
1115
|
+
return responsePromise.then(({body}) => body);
|
|
1109
1116
|
},
|
|
1110
1117
|
|
|
1111
1118
|
/**
|
|
@@ -1418,6 +1425,28 @@ const Services = WebexPlugin.extend({
|
|
|
1418
1425
|
this.ready = true;
|
|
1419
1426
|
},
|
|
1420
1427
|
|
|
1428
|
+
/**
|
|
1429
|
+
* Build a promise that rejects once the catalog init timeout elapses. Race
|
|
1430
|
+
* this against catalog collection so a hung request never leaves
|
|
1431
|
+
* `services.ready` false forever - that would stall `webex.ready` and leave
|
|
1432
|
+
* consumers waiting on it indefinitely. Timeout is configurable via
|
|
1433
|
+
* `config.services.catalogInitTimeout` (defaults to 15s in config). Created
|
|
1434
|
+
* lazily so paths that skip catalog collection never schedule a stray timer.
|
|
1435
|
+
*
|
|
1436
|
+
* @private
|
|
1437
|
+
* @returns {Promise<never>}
|
|
1438
|
+
*/
|
|
1439
|
+
_makeInitTimeout() {
|
|
1440
|
+
const initTimeoutMs = this.webex.config?.services?.catalogInitTimeout;
|
|
1441
|
+
|
|
1442
|
+
return new Promise((_, reject) => {
|
|
1443
|
+
setTimeout(
|
|
1444
|
+
() => reject(new Error(`services: init timed out after ${initTimeoutMs}ms`)),
|
|
1445
|
+
initTimeoutMs
|
|
1446
|
+
);
|
|
1447
|
+
});
|
|
1448
|
+
},
|
|
1449
|
+
|
|
1421
1450
|
/**
|
|
1422
1451
|
* Initializer
|
|
1423
1452
|
*
|
|
@@ -1492,6 +1521,14 @@ const Services = WebexPlugin.extend({
|
|
|
1492
1521
|
} else {
|
|
1493
1522
|
const {email} = this.webex.config;
|
|
1494
1523
|
|
|
1524
|
+
if (this.webex.config?.services?.skipPreauthCatalogOnUnauthenticated === true) {
|
|
1525
|
+
this.logger.info(
|
|
1526
|
+
'services: skipping preauth catalog collection while unauthenticated as per the config'
|
|
1527
|
+
);
|
|
1528
|
+
|
|
1529
|
+
return;
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1495
1532
|
this.collectPreauthCatalog(email ? {email} : undefined).catch((error) => {
|
|
1496
1533
|
this.initFailed = true;
|
|
1497
1534
|
this.logger.error(
|
|
@@ -1526,25 +1563,12 @@ const Services = WebexPlugin.extend({
|
|
|
1526
1563
|
}
|
|
1527
1564
|
const {supertoken} = this.webex.credentials;
|
|
1528
1565
|
|
|
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
1566
|
// Validate if the supertoken exists.
|
|
1543
1567
|
if (supertoken && supertoken.access_token) {
|
|
1544
1568
|
// `initServiceCatalogs` marks the catalog ready internally once the
|
|
1545
1569
|
// postauth catalog is collected - even if it loses the timeout race
|
|
1546
|
-
//
|
|
1547
|
-
Promise.race([this.initServiceCatalogs(),
|
|
1570
|
+
// below, so a slow fetch still eventually flips `catalog.isReady`.
|
|
1571
|
+
Promise.race([this.initServiceCatalogs(), this._makeInitTimeout()])
|
|
1548
1572
|
.catch((error) => {
|
|
1549
1573
|
this.initFailed = true;
|
|
1550
1574
|
this.logger.error(
|
|
@@ -1555,18 +1579,6 @@ const Services = WebexPlugin.extend({
|
|
|
1555
1579
|
} else {
|
|
1556
1580
|
const {email} = this.webex.config;
|
|
1557
1581
|
|
|
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
1582
|
// Handle fresh login: 'loaded' fires before OAuth completes, so listen
|
|
1571
1583
|
// for `canAuthorize` flipping true and then collect the postauth catalog.
|
|
1572
1584
|
this.listenToOnce(this.webex, 'change:canAuthorize', () => {
|
|
@@ -1579,6 +1591,29 @@ const Services = WebexPlugin.extend({
|
|
|
1579
1591
|
});
|
|
1580
1592
|
}
|
|
1581
1593
|
});
|
|
1594
|
+
|
|
1595
|
+
if (this.webex.config?.services?.skipPreauthCatalogOnUnauthenticated === true) {
|
|
1596
|
+
// Skip the preauth catalog fetch (it will be collected manually
|
|
1597
|
+
// later), but still finalize `services.ready` so `webex.ready` is not
|
|
1598
|
+
// stalled while unauthenticated. No timeout is created here so there
|
|
1599
|
+
// is no stray timer or unhandled rejection.
|
|
1600
|
+
this.logger.info(
|
|
1601
|
+
'services: skipping preauth catalog collection while unauthenticated as per the config'
|
|
1602
|
+
);
|
|
1603
|
+
this._finalizeReady();
|
|
1604
|
+
} else {
|
|
1605
|
+
Promise.race([
|
|
1606
|
+
this.collectPreauthCatalog(email ? {email} : undefined),
|
|
1607
|
+
this._makeInitTimeout(),
|
|
1608
|
+
])
|
|
1609
|
+
.catch((error) => {
|
|
1610
|
+
this.initFailed = true;
|
|
1611
|
+
this.logger.error(
|
|
1612
|
+
`services: failed to init initial services when no credentials available, ${error?.message}`
|
|
1613
|
+
);
|
|
1614
|
+
})
|
|
1615
|
+
.finally(() => this._finalizeReady());
|
|
1616
|
+
}
|
|
1582
1617
|
}
|
|
1583
1618
|
});
|
|
1584
1619
|
},
|
|
@@ -1257,9 +1257,16 @@ const Services = WebexPlugin.extend({
|
|
|
1257
1257
|
requestObject.headers = {authorization: token};
|
|
1258
1258
|
}
|
|
1259
1259
|
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1260
|
+
const sendRequest = () => this.request(requestObject);
|
|
1261
|
+
|
|
1262
|
+
const responsePromise = this.webex.internal.newMetrics
|
|
1263
|
+
? this.webex.internal.newMetrics.callDiagnosticLatencies.measureLatency(
|
|
1264
|
+
sendRequest,
|
|
1265
|
+
'internal.get.u2c.time'
|
|
1266
|
+
)
|
|
1267
|
+
: sendRequest();
|
|
1268
|
+
|
|
1269
|
+
return responsePromise.then(({body}) => this._formatReceivedHostmap(body || {}));
|
|
1263
1270
|
},
|
|
1264
1271
|
|
|
1265
1272
|
/**
|
|
@@ -1388,6 +1395,28 @@ const Services = WebexPlugin.extend({
|
|
|
1388
1395
|
this.ready = true;
|
|
1389
1396
|
},
|
|
1390
1397
|
|
|
1398
|
+
/**
|
|
1399
|
+
* Build a promise that rejects once the catalog init timeout elapses. Race
|
|
1400
|
+
* this against catalog collection so a hung request never leaves
|
|
1401
|
+
* `services.ready` false forever - that would stall `webex.ready` and leave
|
|
1402
|
+
* consumers waiting on it indefinitely. Timeout is configurable via
|
|
1403
|
+
* `config.services.catalogInitTimeout` (defaults to 15s in config). Created
|
|
1404
|
+
* lazily so paths that skip catalog collection never schedule a stray timer.
|
|
1405
|
+
*
|
|
1406
|
+
* @private
|
|
1407
|
+
* @returns {Promise<never>}
|
|
1408
|
+
*/
|
|
1409
|
+
_makeInitTimeout(): Promise<never> {
|
|
1410
|
+
const initTimeoutMs = this.webex.config?.services?.catalogInitTimeout;
|
|
1411
|
+
|
|
1412
|
+
return new Promise<never>((_, reject) => {
|
|
1413
|
+
setTimeout(
|
|
1414
|
+
() => reject(new Error(`services: init timed out after ${initTimeoutMs}ms`)),
|
|
1415
|
+
initTimeoutMs
|
|
1416
|
+
);
|
|
1417
|
+
});
|
|
1418
|
+
},
|
|
1419
|
+
|
|
1391
1420
|
/**
|
|
1392
1421
|
* Initializer
|
|
1393
1422
|
*
|
|
@@ -1455,6 +1484,14 @@ const Services = WebexPlugin.extend({
|
|
|
1455
1484
|
} else {
|
|
1456
1485
|
const {email} = this.webex.config;
|
|
1457
1486
|
|
|
1487
|
+
if (this.webex.config?.services?.skipPreauthCatalogOnUnauthenticated === true) {
|
|
1488
|
+
this.logger.info(
|
|
1489
|
+
'services: skipping preauth catalog collection while unauthenticated as per the config'
|
|
1490
|
+
);
|
|
1491
|
+
|
|
1492
|
+
return;
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1458
1495
|
this.collectPreauthCatalog(email ? {email} : undefined).catch((error) => {
|
|
1459
1496
|
this.initFailed = true;
|
|
1460
1497
|
this.logger.error(
|
|
@@ -1489,24 +1526,12 @@ const Services = WebexPlugin.extend({
|
|
|
1489
1526
|
}
|
|
1490
1527
|
const {supertoken} = this.webex.credentials;
|
|
1491
1528
|
|
|
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
1529
|
// Validate if the supertoken exists.
|
|
1505
1530
|
if (supertoken && supertoken.access_token) {
|
|
1506
1531
|
// `initServiceCatalogs` marks the catalog ready internally once the
|
|
1507
1532
|
// postauth catalog is collected - even if it loses the timeout race
|
|
1508
|
-
//
|
|
1509
|
-
Promise.race([this.initServiceCatalogs(),
|
|
1533
|
+
// below, so a slow fetch still eventually flips `catalog.isReady`.
|
|
1534
|
+
Promise.race([this.initServiceCatalogs(), this._makeInitTimeout()])
|
|
1510
1535
|
.catch((error) => {
|
|
1511
1536
|
this.initFailed = true;
|
|
1512
1537
|
this.logger.error(
|
|
@@ -1517,18 +1542,6 @@ const Services = WebexPlugin.extend({
|
|
|
1517
1542
|
} else {
|
|
1518
1543
|
const {email} = this.webex.config;
|
|
1519
1544
|
|
|
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
1545
|
// Handle fresh login: 'loaded' fires before OAuth completes, so listen
|
|
1533
1546
|
// for `canAuthorize` flipping true and then collect the postauth catalog.
|
|
1534
1547
|
this.listenToOnce(this.webex, 'change:canAuthorize', () => {
|
|
@@ -1541,6 +1554,29 @@ const Services = WebexPlugin.extend({
|
|
|
1541
1554
|
});
|
|
1542
1555
|
}
|
|
1543
1556
|
});
|
|
1557
|
+
|
|
1558
|
+
if (this.webex.config?.services?.skipPreauthCatalogOnUnauthenticated === true) {
|
|
1559
|
+
// Skip the preauth catalog fetch (it will be collected manually
|
|
1560
|
+
// later), but still finalize `services.ready` so `webex.ready` is not
|
|
1561
|
+
// stalled while unauthenticated. No timeout is created here so there
|
|
1562
|
+
// is no stray timer or unhandled rejection.
|
|
1563
|
+
this.logger.info(
|
|
1564
|
+
'services: skipping preauth catalog collection while unauthenticated as per the config'
|
|
1565
|
+
);
|
|
1566
|
+
this._finalizeReady();
|
|
1567
|
+
} else {
|
|
1568
|
+
Promise.race([
|
|
1569
|
+
this.collectPreauthCatalog(email ? {email} : undefined),
|
|
1570
|
+
this._makeInitTimeout(),
|
|
1571
|
+
])
|
|
1572
|
+
.catch((error) => {
|
|
1573
|
+
this.initFailed = true;
|
|
1574
|
+
this.logger.error(
|
|
1575
|
+
`services: failed to init initial services when no credentials available, ${error?.message}`
|
|
1576
|
+
);
|
|
1577
|
+
})
|
|
1578
|
+
.finally(() => this._finalizeReady());
|
|
1579
|
+
}
|
|
1544
1580
|
}
|
|
1545
1581
|
});
|
|
1546
1582
|
},
|
|
@@ -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
|
|