@lifeready/core 1.1.14 → 1.1.16
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/bundles/lifeready-core.umd.js +99 -103
- package/bundles/lifeready-core.umd.js.map +1 -1
- package/bundles/lifeready-core.umd.min.js +1 -1
- package/bundles/lifeready-core.umd.min.js.map +1 -1
- package/esm2015/lib/auth/life-ready-auth.service.js +4 -1
- package/esm2015/lib/key/key-factory.service.js +21 -32
- package/esm2015/lib/key/key.types.js +1 -1
- package/esm2015/lib/lbop/lbop.service.js +3 -3
- package/esm2015/lib/password/password.service.js +7 -7
- package/esm2015/lib/register/register.service.js +1 -1
- package/esm2015/lib/time/time.service.js +2 -2
- package/esm2015/lib/tp-password-reset/tp-password-reset-user.service.js +1 -1
- package/esm2015/lib/web-crypto/web-crypto.service.js +3 -3
- package/fesm2015/lifeready-core.js +34 -42
- package/fesm2015/lifeready-core.js.map +1 -1
- package/lib/auth/life-ready-auth.service.d.ts +6 -5
- package/lib/key/key-factory.service.d.ts +3 -3
- package/lib/key/key.types.d.ts +3 -3
- package/lib/lbop/lbop.service.d.ts +11 -3
- package/lib/password/password.service.d.ts +4 -4
- package/lib/register/register.service.d.ts +1 -1
- package/lib/tp-password-reset/tp-password-reset-user.service.d.ts +1 -1
- package/lib/web-crypto/web-crypto.service.d.ts +1 -1
- package/lifeready-core.metadata.json +1 -1
- package/package.json +1 -1
|
@@ -276,7 +276,7 @@ class TimeService {
|
|
|
276
276
|
handleApolloError(res.errors);
|
|
277
277
|
const serverTime = parseInt(res.data.serverTime.timestamp, 10);
|
|
278
278
|
const roundtrip = end - start;
|
|
279
|
-
this.offsetMs = serverTime - (start + roundtrip / 2);
|
|
279
|
+
this.offsetMs = Math.round(serverTime - (start + roundtrip / 2));
|
|
280
280
|
if (this.VERIFY_ENABLED) {
|
|
281
281
|
yield this.verifyCognito();
|
|
282
282
|
}
|
|
@@ -518,7 +518,7 @@ EncryptionService.ctorParameters = () => [
|
|
|
518
518
|
|
|
519
519
|
class WebCryptoService {
|
|
520
520
|
constructor() {
|
|
521
|
-
this.
|
|
521
|
+
this.kcCrypto = window.crypto;
|
|
522
522
|
}
|
|
523
523
|
toHex(buffer) {
|
|
524
524
|
// Ref: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
|
|
@@ -530,7 +530,7 @@ class WebCryptoService {
|
|
|
530
530
|
return __awaiter(this, void 0, void 0, function* () {
|
|
531
531
|
const encoder = new TextEncoder();
|
|
532
532
|
const data = encoder.encode(message);
|
|
533
|
-
const hash = yield this.
|
|
533
|
+
const hash = yield this.kcCrypto.subtle.digest(algorithm, data);
|
|
534
534
|
return this.toHex(hash);
|
|
535
535
|
});
|
|
536
536
|
}
|
|
@@ -542,21 +542,6 @@ WebCryptoService.decorators = [
|
|
|
542
542
|
},] }
|
|
543
543
|
];
|
|
544
544
|
|
|
545
|
-
function sha256(message) {
|
|
546
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
547
|
-
// encode as UTF-8
|
|
548
|
-
const msgBuffer = new TextEncoder().encode(message);
|
|
549
|
-
// hash the message
|
|
550
|
-
const hashBuffer = yield crypto.subtle.digest('SHA-256', msgBuffer);
|
|
551
|
-
// convert ArrayBuffer to Array
|
|
552
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
553
|
-
// convert bytes to hex string
|
|
554
|
-
const hashHex = hashArray
|
|
555
|
-
.map((b) => ('00' + b.toString(16)).slice(-2))
|
|
556
|
-
.join('');
|
|
557
|
-
return hashHex;
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
545
|
class KeyFactoryService {
|
|
561
546
|
constructor(webCryptoService) {
|
|
562
547
|
this.webCryptoService = webCryptoService;
|
|
@@ -575,7 +560,7 @@ class KeyFactoryService {
|
|
|
575
560
|
this.DEFAULT_PASS_IDP_PBKDF_ITER = this.MIN_PASS_IDP_PBKDF_ITER;
|
|
576
561
|
this.DEFAULT_PASS_KEY_PBKDF_ITER = this.MIN_PASS_KEY_PBKDF_ITER;
|
|
577
562
|
this.DEFAULT_LBOP_KEY_PBKDF_ITER = this.MIN_LBOP_KEY_PBKDF_ITER;
|
|
578
|
-
this.
|
|
563
|
+
this.kcCrypto = this.webCryptoService.kcCrypto;
|
|
579
564
|
}
|
|
580
565
|
static asKey(key, form, extras) {
|
|
581
566
|
// <AZ> Using a single global key store did not seem to improve speed.
|
|
@@ -588,7 +573,7 @@ class KeyFactoryService {
|
|
|
588
573
|
}
|
|
589
574
|
const validChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
590
575
|
let array = new Uint32Array(digits);
|
|
591
|
-
this.
|
|
576
|
+
this.kcCrypto.getRandomValues(array);
|
|
592
577
|
array = array.map((x) => validChars.charCodeAt(x % validChars.length));
|
|
593
578
|
return String.fromCharCode.apply(null, array);
|
|
594
579
|
}
|
|
@@ -603,7 +588,7 @@ class KeyFactoryService {
|
|
|
603
588
|
throw new LrBadArgumentException('chooseN <= 0');
|
|
604
589
|
}
|
|
605
590
|
const values = new Uint32Array(chooseN);
|
|
606
|
-
this.
|
|
591
|
+
this.kcCrypto.getRandomValues(values);
|
|
607
592
|
const ret = [];
|
|
608
593
|
values.forEach((v) => ret.push(array[v % array.length]));
|
|
609
594
|
return ret;
|
|
@@ -613,13 +598,13 @@ class KeyFactoryService {
|
|
|
613
598
|
}
|
|
614
599
|
createKey() {
|
|
615
600
|
return __awaiter(this, void 0, void 0, function* () {
|
|
616
|
-
const key = yield this.
|
|
601
|
+
const key = yield this.kcCrypto.subtle.generateKey({
|
|
617
602
|
name: 'AES-GCM',
|
|
618
603
|
length: 256,
|
|
619
604
|
}, true, // whether the key is extractable (i.e. can be used in exportKey)
|
|
620
605
|
['encrypt', 'decrypt'] // must be ["encrypt", "decrypt"] or ["wrapKey", "unwrapKey"]
|
|
621
606
|
);
|
|
622
|
-
const jwk = yield this.
|
|
607
|
+
const jwk = yield this.kcCrypto.subtle.exportKey('jwk', key);
|
|
623
608
|
// Removing the fields not needed by node-jose
|
|
624
609
|
delete jwk.ext;
|
|
625
610
|
delete jwk.key_ops;
|
|
@@ -628,11 +613,11 @@ class KeyFactoryService {
|
|
|
628
613
|
}
|
|
629
614
|
createSignKey() {
|
|
630
615
|
return __awaiter(this, void 0, void 0, function* () {
|
|
631
|
-
const key = yield this.
|
|
616
|
+
const key = yield this.kcCrypto.subtle.generateKey({
|
|
632
617
|
name: 'HMAC',
|
|
633
618
|
hash: { name: 'SHA-512' },
|
|
634
619
|
}, true, ['sign', 'verify']);
|
|
635
|
-
const jwk = yield this.
|
|
620
|
+
const jwk = yield this.kcCrypto.subtle.exportKey('jwk', key);
|
|
636
621
|
// Removing the fields not needed by node-jose
|
|
637
622
|
delete jwk.key_ops;
|
|
638
623
|
delete jwk.ext;
|
|
@@ -646,7 +631,7 @@ class KeyFactoryService {
|
|
|
646
631
|
// does not support sync version, so it uses the javascript implementation, which is way too slow.
|
|
647
632
|
// So we generate using webcrypto and import the key.
|
|
648
633
|
// Unfortunately Elliptical Curve is not supported by Webcrypto. So we have to settle for RSA.
|
|
649
|
-
const key = yield this.
|
|
634
|
+
const key = yield this.kcCrypto.subtle.generateKey({
|
|
650
635
|
name: 'RSA-OAEP',
|
|
651
636
|
modulusLength: 2048,
|
|
652
637
|
// As per suggestion: https://developer.mozilla.org/en-US/docs/Web/API/RsaHashedKeyGenParams
|
|
@@ -655,7 +640,7 @@ class KeyFactoryService {
|
|
|
655
640
|
}, true, // whether the key is extractable (i.e. can be used in exportKey)
|
|
656
641
|
['encrypt', 'decrypt'] // must be ["encrypt", "decrypt"] or ["wrapKey", "unwrapKey"]
|
|
657
642
|
);
|
|
658
|
-
const jwk = yield this.
|
|
643
|
+
const jwk = yield this.kcCrypto.subtle.exportKey('jwk', key.privateKey);
|
|
659
644
|
// Removing the fields not needed by node-jose
|
|
660
645
|
delete jwk.key_ops;
|
|
661
646
|
delete jwk.ext;
|
|
@@ -664,7 +649,7 @@ class KeyFactoryService {
|
|
|
664
649
|
}
|
|
665
650
|
createPkcSignKey() {
|
|
666
651
|
return __awaiter(this, void 0, void 0, function* () {
|
|
667
|
-
const key = yield this.
|
|
652
|
+
const key = yield this.kcCrypto.subtle.generateKey({
|
|
668
653
|
name: 'RSASSA-PKCS1-v1_5',
|
|
669
654
|
modulusLength: 2048,
|
|
670
655
|
// As per suggestion: https://developer.mozilla.org/en-US/docs/Web/API/RsaHashedKeyGenParams
|
|
@@ -673,24 +658,28 @@ class KeyFactoryService {
|
|
|
673
658
|
}, true, // whether the key is extractable (i.e. can be used in exportKey)
|
|
674
659
|
['sign', 'verify'] // can be any combination of "sign" and "verify"
|
|
675
660
|
);
|
|
676
|
-
const jwk = yield this.
|
|
661
|
+
const jwk = yield this.kcCrypto.subtle.exportKey('jwk', key.privateKey);
|
|
677
662
|
// Removing the fields not needed by node-jose
|
|
678
663
|
delete jwk.key_ops;
|
|
679
664
|
delete jwk.ext;
|
|
680
665
|
return KeyFactoryService.asKey(jwk);
|
|
681
666
|
});
|
|
682
667
|
}
|
|
683
|
-
|
|
668
|
+
importPassword(plainPassword) {
|
|
684
669
|
return __awaiter(this, void 0, void 0, function* () {
|
|
685
670
|
const enc = new TextEncoder();
|
|
686
|
-
|
|
687
|
-
|
|
671
|
+
return this.kcCrypto.subtle.importKey('raw', enc.encode(plainPassword), 'PBKDF2', false, ['deriveKey']);
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
deriveKey({ password, salt, iterations, kid, }) {
|
|
675
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
676
|
+
const passKey = yield this.kcCrypto.subtle.deriveKey({
|
|
688
677
|
name: 'PBKDF2',
|
|
689
678
|
salt: new TextEncoder().encode(salt),
|
|
690
679
|
iterations,
|
|
691
680
|
hash: 'SHA-256',
|
|
692
|
-
},
|
|
693
|
-
const passKeyJson = yield
|
|
681
|
+
}, password, { name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']);
|
|
682
|
+
const passKeyJson = yield this.kcCrypto.subtle.exportKey('jwk', passKey);
|
|
694
683
|
if (kid) {
|
|
695
684
|
passKeyJson.kid = kid;
|
|
696
685
|
}
|
|
@@ -4396,19 +4385,19 @@ class PasswordService {
|
|
|
4396
4385
|
this.idleService = idleService;
|
|
4397
4386
|
this.CLIENT_NONCE_LENGTH = 32;
|
|
4398
4387
|
}
|
|
4399
|
-
checkPassword(
|
|
4388
|
+
checkPassword(plainPassword) {
|
|
4400
4389
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4401
|
-
const { years } = this.passwordStrength(
|
|
4390
|
+
const { years } = this.passwordStrength(plainPassword);
|
|
4402
4391
|
return {
|
|
4403
|
-
length:
|
|
4392
|
+
length: plainPassword.length,
|
|
4404
4393
|
timeToCrack: moment$1.duration({ years }),
|
|
4405
|
-
passwordExposed: yield this.getExposureCount(
|
|
4394
|
+
passwordExposed: yield this.getExposureCount(plainPassword),
|
|
4406
4395
|
};
|
|
4407
4396
|
});
|
|
4408
4397
|
}
|
|
4409
|
-
getExposureCount(
|
|
4398
|
+
getExposureCount(plainPassword) {
|
|
4410
4399
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4411
|
-
const sha1Password = yield this.webCryptoService.stringDigest('SHA-1',
|
|
4400
|
+
const sha1Password = yield this.webCryptoService.stringDigest('SHA-1', plainPassword);
|
|
4412
4401
|
const first5sha1 = sha1Password.substring(0, 5);
|
|
4413
4402
|
const response = yield this.http
|
|
4414
4403
|
.get(`https://api.pwnedpasswords.com/range/${first5sha1}`, {
|
|
@@ -5519,6 +5508,9 @@ class LifeReadyAuthService {
|
|
|
5519
5508
|
Hub.listen('auth', (data) => this.hubSubject.next(data.payload));
|
|
5520
5509
|
});
|
|
5521
5510
|
}
|
|
5511
|
+
importPassword(plainPassword) {
|
|
5512
|
+
return this.keyFactory.importPassword(plainPassword);
|
|
5513
|
+
}
|
|
5522
5514
|
addLogoutListener(callback) {
|
|
5523
5515
|
this.logoutListeners.add(callback);
|
|
5524
5516
|
}
|
|
@@ -9142,7 +9134,7 @@ class LbopService {
|
|
|
9142
9134
|
}
|
|
9143
9135
|
}
|
|
9144
9136
|
const lbopKeyParams = yield this.keyFactory.createLbopKeyParams();
|
|
9145
|
-
const lbopKey = (yield this.keyFactory.deriveLbopKey(Object.assign({ password: lbopString }, lbopKeyParams))).jwk;
|
|
9137
|
+
const lbopKey = (yield this.keyFactory.deriveLbopKey(Object.assign({ password: yield this.keyFactory.importPassword(lbopString) }, lbopKeyParams))).jwk;
|
|
9146
9138
|
const lbopKeyVerifier = yield this.keyFactory.createSignKey();
|
|
9147
9139
|
const wrappedLbopKeyVerifier = yield this.encryptionService.encrypt(lbopKey, lbopKeyVerifier.toJSON(true));
|
|
9148
9140
|
// Re-encrypt master key with new key
|
|
@@ -9186,7 +9178,7 @@ class LbopService {
|
|
|
9186
9178
|
return __awaiter(this, void 0, void 0, function* () {
|
|
9187
9179
|
const clientNonce = this.keyFactory.randomString(this.CLIENT_NONCE_LENGTH);
|
|
9188
9180
|
for (const lbop of challengeResult.lbops) {
|
|
9189
|
-
const lbopKey = (yield this.keyFactory.deriveLbopKey(Object.assign({ password: lbopString }, lbop.lbopKeyParams))).jwk;
|
|
9181
|
+
const lbopKey = (yield this.keyFactory.deriveLbopKey(Object.assign({ password: yield this.keyFactory.importPassword(lbopString) }, lbop.lbopKeyParams))).jwk;
|
|
9190
9182
|
// If decoding successful then it's the correct lbop
|
|
9191
9183
|
try {
|
|
9192
9184
|
const lbopKeyVerifier = (yield this.encryptionService.decrypt(lbopKey, lbop.wrappedLbopKeyVerifier));
|