@webex/webex-core 3.12.0-next.5 → 3.12.0-next.50
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/README.md +5 -2
- package/dist/config.js +38 -0
- package/dist/config.js.map +1 -1
- package/dist/credentials-config.js +12 -0
- package/dist/credentials-config.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/interceptors/catalog-url.js +87 -0
- package/dist/interceptors/catalog-url.js.map +1 -0
- package/dist/interceptors/payload-transformer.js +25 -4
- package/dist/interceptors/payload-transformer.js.map +1 -1
- package/dist/lib/batcher.js +23 -7
- package/dist/lib/batcher.js.map +1 -1
- package/dist/lib/credentials/credentials.js +103 -4
- package/dist/lib/credentials/credentials.js.map +1 -1
- package/dist/lib/credentials/token.js +1 -1
- package/dist/lib/domains.js +90 -0
- package/dist/lib/domains.js.map +1 -0
- package/dist/lib/services/service-catalog.js +108 -18
- package/dist/lib/services/service-catalog.js.map +1 -1
- package/dist/lib/services/services.js +232 -34
- package/dist/lib/services/services.js.map +1 -1
- package/dist/lib/services-v2/service-catalog.js +14 -13
- package/dist/lib/services-v2/service-catalog.js.map +1 -1
- package/dist/lib/services-v2/services-v2.js +241 -37
- package/dist/lib/services-v2/services-v2.js.map +1 -1
- package/dist/plugins/logger.js +1 -1
- package/dist/webex-core.js +11 -3
- package/dist/webex-core.js.map +1 -1
- package/package.json +13 -13
- package/src/config.js +42 -0
- package/src/credentials-config.js +13 -0
- package/src/index.js +1 -0
- package/src/interceptors/catalog-url.js +66 -0
- package/src/interceptors/payload-transformer.js +23 -1
- package/src/lib/batcher.js +25 -10
- package/src/lib/credentials/credentials.js +93 -3
- package/src/lib/domains.ts +94 -0
- package/src/lib/services/service-catalog.js +112 -16
- package/src/lib/services/services.js +208 -20
- package/src/lib/services-v2/service-catalog.ts +16 -12
- package/src/lib/services-v2/services-v2.ts +218 -21
- package/src/webex-core.js +8 -0
- package/test/fixtures/activation-email.ts +22 -0
- package/test/integration/spec/services/services.js +183 -112
- package/test/integration/spec/services-v2/services-v2.js +169 -98
- package/test/unit/spec/credentials/credentials.js +247 -3
- package/test/unit/spec/interceptors/auth.js +56 -0
- package/test/unit/spec/interceptors/catalog-url.js +224 -0
- package/test/unit/spec/interceptors/payload-transformer.js +119 -1
- package/test/unit/spec/lib/batcher.js +56 -0
- package/test/unit/spec/services/service-catalog.js +368 -11
- package/test/unit/spec/services/services.js +440 -2
- package/test/unit/spec/services-v2/service-catalog.ts +134 -11
- package/test/unit/spec/services-v2/services-v2.ts +467 -0
- package/test/unit/spec/webex-core.js +77 -1
|
@@ -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,
|
|
@@ -20,6 +20,7 @@ import WebexCore, {
|
|
|
20
20
|
import testUsers from '@webex/test-helper-test-users';
|
|
21
21
|
import uuid from 'uuid';
|
|
22
22
|
import sinon from 'sinon';
|
|
23
|
+
import {createActivationEmail} from '../../../fixtures/activation-email';
|
|
23
24
|
|
|
24
25
|
/* eslint-disable no-underscore-dangle */
|
|
25
26
|
describe('webex-core', () => {
|
|
@@ -408,11 +409,13 @@ describe('webex-core', () => {
|
|
|
408
409
|
services._loadCatalogFromCache = sinon.stub().resolves(false);
|
|
409
410
|
services.initServiceCatalogs = sinon.stub().resolves();
|
|
410
411
|
services.initialize();
|
|
412
|
+
// The mode-specific ('ready'/'loaded') listener is registered inside the
|
|
413
|
+
// change:config handler, so fire change:config first, then 'ready'.
|
|
414
|
+
webex.trigger('change:config');
|
|
411
415
|
webex.trigger('ready');
|
|
412
416
|
// Wait for the async 'ready' handler to complete
|
|
413
417
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
414
418
|
assert.called(services.initServiceCatalogs);
|
|
415
|
-
assert.isTrue(catalog.isReady);
|
|
416
419
|
});
|
|
417
420
|
|
|
418
421
|
it('should collect different catalogs based on OrgId region', () =>
|
|
@@ -430,6 +433,45 @@ describe('webex-core', () => {
|
|
|
430
433
|
done();
|
|
431
434
|
}, 2000);
|
|
432
435
|
});
|
|
436
|
+
|
|
437
|
+
it('blocks webex.ready until services.ready flips when waitForCatalogInit is enabled', async () => {
|
|
438
|
+
const gatedWebex = new WebexCore({
|
|
439
|
+
credentials: {supertoken: webexUser.token},
|
|
440
|
+
config: {services: {waitForCatalogInit: true}},
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
// Before init settles, webex.ready must be false because services.ready
|
|
444
|
+
// is a dependency and starts false in the gated path.
|
|
445
|
+
assert.isFalse(gatedWebex.internal.services.ready, 'services.ready should start false');
|
|
446
|
+
assert.isFalse(
|
|
447
|
+
gatedWebex.ready,
|
|
448
|
+
'webex.ready should not fire while services.ready is false'
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
// Wait up to 30s for services init to complete and flip ready.
|
|
452
|
+
await new Promise((resolve, reject) => {
|
|
453
|
+
if (gatedWebex.internal.services.ready) {
|
|
454
|
+
resolve();
|
|
455
|
+
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
const timer = setTimeout(
|
|
459
|
+
() => reject(new Error('timed out waiting for services.ready')),
|
|
460
|
+
30_000
|
|
461
|
+
);
|
|
462
|
+
|
|
463
|
+
gatedWebex.internal.services.once('change:ready', () => {
|
|
464
|
+
clearTimeout(timer);
|
|
465
|
+
resolve();
|
|
466
|
+
});
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
assert.isTrue(
|
|
470
|
+
gatedWebex.internal.services.ready,
|
|
471
|
+
'services.ready should flip true after init settles'
|
|
472
|
+
);
|
|
473
|
+
assert.isTrue(gatedWebex.ready, 'webex.ready should fire once services.ready flips');
|
|
474
|
+
});
|
|
433
475
|
});
|
|
434
476
|
|
|
435
477
|
describe('#initServiceCatalogs()', () => {
|
|
@@ -867,18 +909,22 @@ describe('webex-core', () => {
|
|
|
867
909
|
}));
|
|
868
910
|
|
|
869
911
|
it('validates an authorized user and webex instance', () =>
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
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
|
+
));
|
|
875
919
|
|
|
876
920
|
it('validates an authorized EU user and webex instance', () =>
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
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
|
+
));
|
|
882
928
|
|
|
883
929
|
it("returns a rejected promise if the provided email isn't valid", () =>
|
|
884
930
|
unauthServices
|
|
@@ -891,131 +937,152 @@ describe('webex-core', () => {
|
|
|
891
937
|
}));
|
|
892
938
|
|
|
893
939
|
it('validates a non-existing user', () =>
|
|
894
|
-
|
|
895
|
-
.validateUser({email:
|
|
896
|
-
.then((r) => {
|
|
940
|
+
retryOn429(() =>
|
|
941
|
+
unauthServices.validateUser({email: createActivationEmail()}).then((r) => {
|
|
897
942
|
assert.hasAllKeys(r, ['activated', 'exists', 'user', 'details']);
|
|
898
943
|
assert.equal(r.activated, false);
|
|
899
944
|
assert.equal(r.exists, false);
|
|
900
945
|
assert.isAbove(Object.keys(unauthServices.list(false, 'preauth')).length, 0);
|
|
901
946
|
assert.equal(Object.keys(unauthServices.list(false, 'signin')).length, 0);
|
|
902
947
|
assert.equal(Object.keys(unauthServices.list(false, 'postauth')).length, 0);
|
|
903
|
-
})
|
|
948
|
+
})
|
|
949
|
+
));
|
|
904
950
|
|
|
905
951
|
it('validates new user with activationOptions suppressEmail false', () =>
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
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
|
+
));
|
|
920
968
|
|
|
921
969
|
it('validates new user with activationOptions suppressEmail true', () =>
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
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
|
+
));
|
|
936
986
|
|
|
937
987
|
it('validates an inactive user', () => {
|
|
938
988
|
const inactive = 'webex.web.client+nonactivated@gmail.com';
|
|
939
989
|
|
|
940
|
-
return
|
|
941
|
-
|
|
942
|
-
|
|
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) => {
|
|
943
1009
|
assert.hasAllKeys(r, ['activated', 'exists', 'user', 'details']);
|
|
944
|
-
assert.equal(r.activated,
|
|
945
|
-
assert.equal(r.exists, true
|
|
1010
|
+
assert.equal(r.activated, true);
|
|
1011
|
+
assert.equal(r.exists, true);
|
|
946
1012
|
assert.isAbove(Object.keys(unauthServices.list(false, 'preauth')).length, 0);
|
|
947
|
-
assert.
|
|
1013
|
+
assert.isAbove(Object.keys(unauthServices.list(false, 'signin')).length, 0);
|
|
948
1014
|
assert.equal(Object.keys(unauthServices.list(false, 'postauth')).length, 0);
|
|
949
1015
|
})
|
|
950
|
-
|
|
951
|
-
assert(true);
|
|
952
|
-
});
|
|
953
|
-
});
|
|
954
|
-
|
|
955
|
-
it('validates an existing user', () =>
|
|
956
|
-
unauthServices.validateUser({email: webexUser.email}).then((r) => {
|
|
957
|
-
assert.hasAllKeys(r, ['activated', 'exists', 'user', 'details']);
|
|
958
|
-
assert.equal(r.activated, true);
|
|
959
|
-
assert.equal(r.exists, true);
|
|
960
|
-
assert.isAbove(Object.keys(unauthServices.list(false, 'preauth')).length, 0);
|
|
961
|
-
assert.isAbove(Object.keys(unauthServices.list(false, 'signin')).length, 0);
|
|
962
|
-
assert.equal(Object.keys(unauthServices.list(false, 'postauth')).length, 0);
|
|
963
|
-
}));
|
|
1016
|
+
));
|
|
964
1017
|
|
|
965
1018
|
it('validates an existing EU user', () =>
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
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
|
+
));
|
|
974
1029
|
|
|
975
1030
|
it('sends the prelogin user id as undefined when not specified', () => {
|
|
976
1031
|
const requestStub = sandbox.spy(unauthServices, 'request');
|
|
977
1032
|
|
|
978
|
-
return
|
|
979
|
-
.
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
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
|
+
});
|
|
986
1045
|
});
|
|
987
1046
|
|
|
988
1047
|
it('sends the prelogin user id as provided when specified', () => {
|
|
989
1048
|
const requestStub = sandbox.spy(unauthServices, 'request');
|
|
990
1049
|
const preloginUserId = uuid.v4();
|
|
991
1050
|
|
|
992
|
-
return
|
|
993
|
-
.
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
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
|
+
});
|
|
1004
1067
|
});
|
|
1005
1068
|
|
|
1006
1069
|
it('uses the license service by default', () => {
|
|
1007
1070
|
const requestStub = sandbox.spy(unauthServices, 'request');
|
|
1008
1071
|
|
|
1009
|
-
return
|
|
1010
|
-
.
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
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
|
+
});
|
|
1019
1086
|
});
|
|
1020
1087
|
|
|
1021
1088
|
it('uses the user-onboarding service when useUserOnboardingServiceForActivations config is true', () => {
|
|
@@ -1029,16 +1096,20 @@ describe('webex-core', () => {
|
|
|
1029
1096
|
const userOnboardingServices = userOnboardingWebex.internal.services;
|
|
1030
1097
|
const requestStub = sandbox.spy(userOnboardingServices, 'request');
|
|
1031
1098
|
|
|
1032
|
-
return
|
|
1033
|
-
.
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
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
|
+
});
|
|
1042
1113
|
});
|
|
1043
1114
|
});
|
|
1044
1115
|
|