@furystack/security 2.1.16 → 3.0.1
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 → esm}/crypto-password-hasher.js +7 -10
- package/esm/crypto-password-hasher.js.map +1 -0
- package/esm/errors/index.js +4 -0
- package/esm/errors/index.js.map +1 -0
- package/esm/errors/password-complexity-error.js +11 -0
- package/esm/errors/password-complexity-error.js.map +1 -0
- package/esm/errors/unauthenticated-error.js +6 -0
- package/{dist → esm}/errors/unauthenticated-error.js.map +1 -1
- package/esm/helpers.js +12 -0
- package/esm/helpers.js.map +1 -0
- package/esm/index.js +9 -0
- package/esm/index.js.map +1 -0
- package/esm/models/index.js +6 -0
- package/esm/models/index.js.map +1 -0
- package/esm/models/password-check-result.js +2 -0
- package/esm/models/password-complexity-result.js +2 -0
- package/esm/models/password-complexity-rule.js +2 -0
- package/esm/models/password-credential.js +6 -0
- package/{dist → esm}/models/password-credential.js.map +1 -1
- package/esm/models/password-reset-token.js +3 -0
- package/{dist → esm}/models/password-reset-token.js.map +1 -1
- package/{dist → esm}/password-authenticator.js +20 -25
- package/esm/password-authenticator.js.map +1 -0
- package/{dist → esm}/password-complexity-rules/contains-lowercase.js +1 -5
- package/esm/password-complexity-rules/contains-lowercase.js.map +1 -0
- package/{dist → esm}/password-complexity-rules/contains-uppercase.js +1 -5
- package/esm/password-complexity-rules/contains-uppercase.js.map +1 -0
- package/esm/password-complexity-rules/index.js +5 -0
- package/{dist → esm}/password-complexity-rules/index.js.map +1 -1
- package/{dist → esm}/password-complexity-rules/max-length.js +1 -5
- package/esm/password-complexity-rules/max-length.js.map +1 -0
- package/{dist → esm}/password-complexity-rules/min-length.js +1 -5
- package/esm/password-complexity-rules/min-length.js.map +1 -0
- package/{dist → esm}/password-hasher.js +3 -6
- package/esm/password-hasher.js.map +1 -0
- package/{dist → esm}/security-policy-manager.js +6 -9
- package/esm/security-policy-manager.js.map +1 -0
- package/{dist → esm}/security-policy.js +5 -8
- package/esm/security-policy.js.map +1 -0
- package/package.json +28 -13
- package/src/helpers.ts +0 -1
- package/src/password-authenticator.spec.ts +4 -3
- package/src/password-authenticator.ts +1 -3
- package/src/password-complexity-rules/contains-lowercase.spec.ts +1 -0
- package/src/password-complexity-rules/contains-uppercase.spec.ts +1 -0
- package/src/password-complexity-rules/max-length.spec.ts +1 -0
- package/src/password-complexity-rules/min-length.spec.ts +1 -0
- package/src/security-policy-manager.spec.ts +1 -0
- package/types/helpers.d.ts +0 -1
- package/types/helpers.d.ts.map +1 -1
- package/types/password-authenticator.d.ts +1 -3
- package/types/password-authenticator.d.ts.map +1 -1
- package/dist/crypto-password-hasher.js.map +0 -1
- package/dist/errors/index.js +0 -20
- package/dist/errors/index.js.map +0 -1
- package/dist/errors/password-complexity-error.js +0 -15
- package/dist/errors/password-complexity-error.js.map +0 -1
- package/dist/errors/unauthenticated-error.js +0 -10
- package/dist/helpers.js +0 -17
- package/dist/helpers.js.map +0 -1
- package/dist/index.js +0 -25
- package/dist/index.js.map +0 -1
- package/dist/models/index.js +0 -22
- package/dist/models/index.js.map +0 -1
- package/dist/models/password-check-result.js +0 -3
- package/dist/models/password-complexity-result.js +0 -3
- package/dist/models/password-complexity-rule.js +0 -3
- package/dist/models/password-credential.js +0 -10
- package/dist/models/password-reset-token.js +0 -7
- package/dist/password-authenticator.js.map +0 -1
- package/dist/password-authenticator.spec.js +0 -292
- package/dist/password-authenticator.spec.js.map +0 -1
- package/dist/password-complexity-rules/contains-lowercase.js.map +0 -1
- package/dist/password-complexity-rules/contains-lowercase.spec.js +0 -28
- package/dist/password-complexity-rules/contains-lowercase.spec.js.map +0 -1
- package/dist/password-complexity-rules/contains-uppercase.js.map +0 -1
- package/dist/password-complexity-rules/contains-uppercase.spec.js +0 -28
- package/dist/password-complexity-rules/contains-uppercase.spec.js.map +0 -1
- package/dist/password-complexity-rules/index.js +0 -21
- package/dist/password-complexity-rules/max-length.js.map +0 -1
- package/dist/password-complexity-rules/max-length.spec.js +0 -17
- package/dist/password-complexity-rules/max-length.spec.js.map +0 -1
- package/dist/password-complexity-rules/min-length.js.map +0 -1
- package/dist/password-complexity-rules/min-length.spec.js +0 -17
- package/dist/password-complexity-rules/min-length.spec.js.map +0 -1
- package/dist/password-hasher.js.map +0 -1
- package/dist/security-policy-manager.js.map +0 -1
- package/dist/security-policy-manager.spec.js +0 -18
- package/dist/security-policy-manager.spec.js.map +0 -1
- package/dist/security-policy.js.map +0 -1
- package/types/password-authenticator.spec.d.ts +0 -2
- package/types/password-authenticator.spec.d.ts.map +0 -1
- package/types/password-complexity-rules/contains-lowercase.spec.d.ts +0 -2
- package/types/password-complexity-rules/contains-lowercase.spec.d.ts.map +0 -1
- package/types/password-complexity-rules/contains-uppercase.spec.d.ts +0 -2
- package/types/password-complexity-rules/contains-uppercase.spec.d.ts.map +0 -1
- package/types/password-complexity-rules/max-length.spec.d.ts +0 -2
- package/types/password-complexity-rules/max-length.spec.d.ts.map +0 -1
- package/types/password-complexity-rules/min-length.spec.d.ts +0 -2
- package/types/password-complexity-rules/min-length.spec.d.ts.map +0 -1
- package/types/security-policy-manager.spec.d.ts +0 -2
- package/types/security-policy-manager.spec.d.ts.map +0 -1
- /package/{dist → esm}/models/password-check-result.js.map +0 -0
- /package/{dist → esm}/models/password-complexity-result.js.map +0 -0
- /package/{dist → esm}/models/password-complexity-rule.js.map +0 -0
|
@@ -41,8 +41,7 @@ export class PasswordAuthenticator {
|
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
44
|
+
*Sets the password for the specific user
|
|
46
45
|
* @param userName The user to set the password for
|
|
47
46
|
* @param lastPassword The last user password
|
|
48
47
|
* @param plainPassword The password as a plain string
|
|
@@ -66,7 +65,6 @@ export class PasswordAuthenticator {
|
|
|
66
65
|
|
|
67
66
|
/**
|
|
68
67
|
* Resets the password with a Password Reset token entry
|
|
69
|
-
*
|
|
70
68
|
* @param resetToken The Reset Token value
|
|
71
69
|
* @param plainPassword The new password in plain string
|
|
72
70
|
*/
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PasswordComplexityFailedResult } from '../models'
|
|
2
2
|
import { createContainsLowercasePolicy } from './contains-lowercase'
|
|
3
|
+
import { describe, it, expect } from 'vitest'
|
|
3
4
|
|
|
4
5
|
describe('Contains-lowercase', () => {
|
|
5
6
|
it('Should fail if the password is shorter than expected', async () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PasswordComplexityFailedResult } from '../models'
|
|
2
2
|
import { createContainsUppercasePolicy } from './contains-uppercase'
|
|
3
|
+
import { describe, it, expect } from 'vitest'
|
|
3
4
|
|
|
4
5
|
describe('Contains-uppercase', () => {
|
|
5
6
|
it('Should fail if the password is shorter than expected', async () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PasswordComplexityFailedResult } from '../models'
|
|
2
2
|
import { createMaxLengthComplexityRule } from './max-length'
|
|
3
|
+
import { describe, it, expect } from 'vitest'
|
|
3
4
|
|
|
4
5
|
describe('max-length', () => {
|
|
5
6
|
it('Should fail if the password is longer than expected', async () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PasswordComplexityFailedResult } from '../models'
|
|
2
2
|
import { createMinLengthComplexityRule } from './min-length'
|
|
3
|
+
import { describe, it, expect } from 'vitest'
|
|
3
4
|
|
|
4
5
|
describe('min-length', () => {
|
|
5
6
|
it('Should fail if the password is shorter than expected', async () => {
|
|
@@ -2,6 +2,7 @@ import { Injector } from '@furystack/inject'
|
|
|
2
2
|
import { using } from '@furystack/utils'
|
|
3
3
|
import { usePasswordPolicy } from './helpers'
|
|
4
4
|
import { SecurityPolicyManager } from './security-policy-manager'
|
|
5
|
+
import { describe, it, expect } from 'vitest'
|
|
5
6
|
|
|
6
7
|
describe('SecurityPolicyManager', () => {
|
|
7
8
|
it('Should return false when no token expiration has been set', () => {
|
package/types/helpers.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import type { Injector } from '@furystack/inject';
|
|
|
2
2
|
import { SecurityPolicy } from './security-policy';
|
|
3
3
|
/**
|
|
4
4
|
* Sets up the @furystack/security with the provided settings
|
|
5
|
-
*
|
|
6
5
|
* @param injector The Injector instance
|
|
7
6
|
* @param {Partial<SecurityPolicy>} policy The security policy to use
|
|
8
7
|
*/
|
package/types/helpers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAElD
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAElD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,aAAc,QAAQ,WAAW,QAAQ,cAAc,CAAC,SAIrF,CAAA"}
|
|
@@ -12,8 +12,7 @@ export declare class PasswordAuthenticator {
|
|
|
12
12
|
checkPasswordForUser(userName: string, plainPassword: string): Promise<PasswordCheckResult>;
|
|
13
13
|
/**
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
*Sets the password for the specific user
|
|
17
16
|
* @param userName The user to set the password for
|
|
18
17
|
* @param lastPassword The last user password
|
|
19
18
|
* @param plainPassword The password as a plain string
|
|
@@ -21,7 +20,6 @@ export declare class PasswordAuthenticator {
|
|
|
21
20
|
setPasswordForUser(userName: string, lastPassword: string, plainPassword: string): Promise<void>;
|
|
22
21
|
/**
|
|
23
22
|
* Resets the password with a Password Reset token entry
|
|
24
|
-
*
|
|
25
23
|
* @param resetToken The Reset Token value
|
|
26
24
|
* @param plainPassword The new password in plain string
|
|
27
25
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password-authenticator.d.ts","sourceRoot":"","sources":["../src/password-authenticator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AAEjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAInD,qBACa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CACoD;IAErF,OAAO,CAAC,QAAQ,CAAC,aAAa,CACoD;IAElF,SAAgB,SAAS,mDAAoE;IAE7F;;;;OAIG;IACU,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAkBxG
|
|
1
|
+
{"version":3,"file":"password-authenticator.d.ts","sourceRoot":"","sources":["../src/password-authenticator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AAEjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAInD,qBACa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CACoD;IAErF,OAAO,CAAC,QAAQ,CAAC,aAAa,CACoD;IAElF,SAAgB,SAAS,mDAAoE;IAE7F;;;;OAIG;IACU,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAkBxG;;;;;;OAMG;IACU,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB7G;;;;OAIG;IACU,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB3F,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IAG7B,aAAa,EAAG,qBAAqB,CAAA;CAC7C"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-password-hasher.js","sourceRoot":"","sources":["../src/crypto-password-hasher.ts"],"names":[],"mappings":";;;;;;;;;AAAA,8CAA8C;AAE9C,mCAA4C;AAI5C,IAAa,oBAAoB,GAAjC,MAAa,oBAAoB;IAAjC;QACmB,eAAU,GAAG,IAAI,CAAA;QACjB,WAAM,GAAG,EAAE,CAAA;IAmC9B,CAAC;IAjCQ,KAAK,CAAC,gBAAgB,CAC3B,QAAgB,EAChB,EAAE,YAAY,EAAE,IAAI,EAAsB;QAE1C,MAAM,OAAO,GAAG,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CACpD,IAAA,eAAM,EAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAC1E,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CACjD,CACF,CAAA;QACD,IAAI,OAAO,KAAK,YAAY,EAAE;YAC5B,OAAO;gBACL,OAAO,EAAE,IAAI;aACd,CAAA;SACF;QACD,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,uBAAuB;SAChC,CAAA;IACH,CAAC;IACM,KAAK,CAAC,gBAAgB,CAAC,QAAgB,EAAE,QAAgB;QAC9D,MAAM,IAAI,GAAG,IAAA,oBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QAC5C,MAAM,YAAY,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CACjE,IAAA,eAAM,EAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAC1E,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CACjD,CACF,CAAA;QACD,OAAO;YACL,QAAQ;YACR,IAAI;YACJ,YAAY;YACZ,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACvC,CAAA;IACH,CAAC;CACF,CAAA;AArCY,oBAAoB;IADhC,IAAA,mBAAU,EAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;GACzB,oBAAoB,CAqChC;AArCY,oDAAoB"}
|
package/dist/errors/index.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./password-complexity-error"), exports);
|
|
18
|
-
__exportStar(require("./unauthenticated-error"), exports);
|
|
19
|
-
__exportStar(require("./password-complexity-error"), exports);
|
|
20
|
-
//# sourceMappingURL=index.js.map
|
package/dist/errors/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8DAA2C;AAC3C,0DAAuC;AACvC,8DAA2C"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PasswordComplexityError = void 0;
|
|
4
|
-
class PasswordComplexityError extends Error {
|
|
5
|
-
/**
|
|
6
|
-
* @param result A detailed error result array
|
|
7
|
-
* @param message The Error message
|
|
8
|
-
*/
|
|
9
|
-
constructor(result, message) {
|
|
10
|
-
super(message);
|
|
11
|
-
this.result = result;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
exports.PasswordComplexityError = PasswordComplexityError;
|
|
15
|
-
//# sourceMappingURL=password-complexity-error.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"password-complexity-error.js","sourceRoot":"","sources":["../../src/errors/password-complexity-error.ts"],"names":[],"mappings":";;;AAAA,MAAa,uBAAwB,SAAQ,KAAK;IAChD;;;OAGG;IACH,YAA4B,MAAgD,EAAE,OAAgB;QAC5F,KAAK,CAAC,OAAO,CAAC,CAAA;QADY,WAAM,GAAN,MAAM,CAA0C;IAE5E,CAAC;CACF;AARD,0DAQC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.UnauthenticatedError = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Error that can be thrown if an authentication is required but not provided
|
|
6
|
-
*/
|
|
7
|
-
class UnauthenticatedError extends Error {
|
|
8
|
-
}
|
|
9
|
-
exports.UnauthenticatedError = UnauthenticatedError;
|
|
10
|
-
//# sourceMappingURL=unauthenticated-error.js.map
|
package/dist/helpers.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.usePasswordPolicy = void 0;
|
|
4
|
-
const security_policy_1 = require("./security-policy");
|
|
5
|
-
/**
|
|
6
|
-
* Sets up the @furystack/security with the provided settings
|
|
7
|
-
*
|
|
8
|
-
* @param injector The Injector instance
|
|
9
|
-
* @param {Partial<SecurityPolicy>} policy The security policy to use
|
|
10
|
-
*/
|
|
11
|
-
const usePasswordPolicy = (injector, policy) => {
|
|
12
|
-
const plainPolicy = new security_policy_1.SecurityPolicy();
|
|
13
|
-
policy && Object.assign(plainPolicy, policy);
|
|
14
|
-
injector.setExplicitInstance(plainPolicy, security_policy_1.SecurityPolicy);
|
|
15
|
-
};
|
|
16
|
-
exports.usePasswordPolicy = usePasswordPolicy;
|
|
17
|
-
//# sourceMappingURL=helpers.js.map
|
package/dist/helpers.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":";;;AACA,uDAAkD;AAElD;;;;;GAKG;AACI,MAAM,iBAAiB,GAAG,CAAC,QAAkB,EAAE,MAAgC,EAAE,EAAE;IACxF,MAAM,WAAW,GAAG,IAAI,gCAAc,EAAE,CAAA;IACxC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IAC5C,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,gCAAc,CAAC,CAAA;AAC3D,CAAC,CAAA;AAJY,QAAA,iBAAiB,qBAI7B"}
|
package/dist/index.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./crypto-password-hasher"), exports);
|
|
18
|
-
__exportStar(require("./errors"), exports);
|
|
19
|
-
__exportStar(require("./models"), exports);
|
|
20
|
-
__exportStar(require("./password-authenticator"), exports);
|
|
21
|
-
__exportStar(require("./password-complexity-rules"), exports);
|
|
22
|
-
__exportStar(require("./password-hasher"), exports);
|
|
23
|
-
__exportStar(require("./security-policy-manager"), exports);
|
|
24
|
-
__exportStar(require("./helpers"), exports);
|
|
25
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2DAAwC;AACxC,2CAAwB;AACxB,2CAAwB;AACxB,2DAAwC;AACxC,8DAA2C;AAC3C,oDAAiC;AACjC,4DAAyC;AAEzC,4CAAyB"}
|
package/dist/models/index.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./password-check-result"), exports);
|
|
18
|
-
__exportStar(require("./password-complexity-result"), exports);
|
|
19
|
-
__exportStar(require("./password-complexity-rule"), exports);
|
|
20
|
-
__exportStar(require("./password-credential"), exports);
|
|
21
|
-
__exportStar(require("./password-reset-token"), exports);
|
|
22
|
-
//# sourceMappingURL=index.js.map
|
package/dist/models/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0DAAuC;AACvC,+DAA4C;AAC5C,6DAA0C;AAC1C,wDAAqC;AACrC,yDAAsC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PasswordCredential = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Entry that stores credential info for password login
|
|
6
|
-
*/
|
|
7
|
-
class PasswordCredential {
|
|
8
|
-
}
|
|
9
|
-
exports.PasswordCredential = PasswordCredential;
|
|
10
|
-
//# sourceMappingURL=password-credential.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"password-authenticator.js","sourceRoot":"","sources":["../src/password-authenticator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const core_1 = require("@furystack/core");
|
|
4
|
-
const inject_1 = require("@furystack/inject");
|
|
5
|
-
const utils_1 = require("@furystack/utils");
|
|
6
|
-
const helpers_1 = require("./helpers");
|
|
7
|
-
const models_1 = require("./models");
|
|
8
|
-
const password_authenticator_1 = require("./password-authenticator");
|
|
9
|
-
const password_complexity_rules_1 = require("./password-complexity-rules");
|
|
10
|
-
const security_policy_manager_1 = require("./security-policy-manager");
|
|
11
|
-
const errors_1 = require("./errors");
|
|
12
|
-
const crypto_1 = require("crypto");
|
|
13
|
-
const randomString = () => (0, crypto_1.randomBytes)(32).toString('hex');
|
|
14
|
-
describe('PasswordAuthenticator', () => {
|
|
15
|
-
it('Should be instantiated', () => {
|
|
16
|
-
(0, utils_1.using)(new inject_1.Injector(), (i) => {
|
|
17
|
-
const auth = i.getInstance(password_authenticator_1.PasswordAuthenticator);
|
|
18
|
-
expect(auth).toBeInstanceOf(password_authenticator_1.PasswordAuthenticator);
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
it('Should inherit policy from the extension method', () => {
|
|
22
|
-
(0, utils_1.using)(new inject_1.Injector(), (i) => {
|
|
23
|
-
(0, helpers_1.usePasswordPolicy)(i, {
|
|
24
|
-
passwordComplexityRules: [(0, password_complexity_rules_1.createMinLengthComplexityRule)(3)],
|
|
25
|
-
});
|
|
26
|
-
const auth = i.getInstance(password_authenticator_1.PasswordAuthenticator);
|
|
27
|
-
expect(auth).toBeInstanceOf(password_authenticator_1.PasswordAuthenticator);
|
|
28
|
-
expect(auth.policyManager.policy.passwordComplexityRules[0].name).toBe('minLength');
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
describe('checkPasswordForUser', () => {
|
|
32
|
-
it('Should return a truthy value for valid username and password', async () => {
|
|
33
|
-
await (0, utils_1.usingAsync)(new inject_1.Injector(), async (i) => {
|
|
34
|
-
const userName = randomString();
|
|
35
|
-
const password = randomString();
|
|
36
|
-
(0, core_1.addStore)(i, new core_1.InMemoryStore({ model: models_1.PasswordCredential, primaryKey: 'userName' })).addStore(new core_1.InMemoryStore({ model: core_1.User, primaryKey: 'username' }));
|
|
37
|
-
(0, helpers_1.usePasswordPolicy)(i, {});
|
|
38
|
-
const authenticator = i.getInstance(password_authenticator_1.PasswordAuthenticator);
|
|
39
|
-
const hasher = authenticator.getHasher();
|
|
40
|
-
const passwordStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordCredential, 'userName');
|
|
41
|
-
const entry = await hasher.createCredential(userName, password);
|
|
42
|
-
await passwordStore.add(entry);
|
|
43
|
-
const successResult = await authenticator.checkPasswordForUser(userName, password);
|
|
44
|
-
expect(successResult.isValid).toBeTruthy();
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
it('Should return a falsy value for invalid username', async () => {
|
|
48
|
-
await (0, utils_1.usingAsync)(new inject_1.Injector(), async (i) => {
|
|
49
|
-
const userName = randomString();
|
|
50
|
-
const password = randomString();
|
|
51
|
-
(0, core_1.addStore)(i, new core_1.InMemoryStore({ model: models_1.PasswordCredential, primaryKey: 'userName' })).addStore(new core_1.InMemoryStore({ model: core_1.User, primaryKey: 'username' }));
|
|
52
|
-
(0, helpers_1.usePasswordPolicy)(i);
|
|
53
|
-
const authenticator = i.getInstance(password_authenticator_1.PasswordAuthenticator);
|
|
54
|
-
const hasher = authenticator.getHasher();
|
|
55
|
-
const passwordStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordCredential, 'userName');
|
|
56
|
-
const entry = await hasher.createCredential(userName, password);
|
|
57
|
-
await passwordStore.add(entry);
|
|
58
|
-
const failResult = await authenticator.checkPasswordForUser('invalidUsername', password);
|
|
59
|
-
expect(failResult.isValid).toBeFalsy();
|
|
60
|
-
expect(failResult.reason).toBe('badUsernameOrPassword');
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
it('Should return a falsy value for invalid password', async () => {
|
|
64
|
-
await (0, utils_1.usingAsync)(new inject_1.Injector(), async (i) => {
|
|
65
|
-
const userName = randomString();
|
|
66
|
-
const password = randomString();
|
|
67
|
-
(0, core_1.addStore)(i, new core_1.InMemoryStore({ model: models_1.PasswordCredential, primaryKey: 'userName' })).addStore(new core_1.InMemoryStore({ model: core_1.User, primaryKey: 'username' }));
|
|
68
|
-
(0, helpers_1.usePasswordPolicy)(i);
|
|
69
|
-
const authenticator = i.getInstance(password_authenticator_1.PasswordAuthenticator);
|
|
70
|
-
const hasher = authenticator.getHasher();
|
|
71
|
-
const passwordStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordCredential, 'userName');
|
|
72
|
-
const entry = await hasher.createCredential(userName, password);
|
|
73
|
-
await passwordStore.add(entry);
|
|
74
|
-
const failResult = await authenticator.checkPasswordForUser(userName, 'someInvalidPassword');
|
|
75
|
-
expect(failResult.isValid).toBeFalsy();
|
|
76
|
-
expect(failResult.reason).toBe('badUsernameOrPassword');
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
it('Should return a falsy value for an expired password', async () => {
|
|
80
|
-
await (0, utils_1.usingAsync)(new inject_1.Injector(), async (i) => {
|
|
81
|
-
const userName = randomString();
|
|
82
|
-
const password = randomString();
|
|
83
|
-
(0, core_1.addStore)(i, new core_1.InMemoryStore({ model: models_1.PasswordCredential, primaryKey: 'userName' })).addStore(new core_1.InMemoryStore({ model: core_1.User, primaryKey: 'username' }));
|
|
84
|
-
(0, helpers_1.usePasswordPolicy)(i, { passwordExpirationDays: 1 });
|
|
85
|
-
const authenticator = i.getInstance(password_authenticator_1.PasswordAuthenticator);
|
|
86
|
-
const hasher = authenticator.getHasher();
|
|
87
|
-
const passwordStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordCredential, 'userName');
|
|
88
|
-
const entry = await hasher.createCredential(userName, password);
|
|
89
|
-
const creationDate = new Date();
|
|
90
|
-
creationDate.setDate(creationDate.getDate() - 2);
|
|
91
|
-
entry.creationDate = creationDate.toISOString();
|
|
92
|
-
await passwordStore.add(entry);
|
|
93
|
-
const failResult = await authenticator.checkPasswordForUser(userName, password);
|
|
94
|
-
expect(failResult.isValid).toBeFalsy();
|
|
95
|
-
expect(failResult.reason).toBe('passwordExpired');
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
describe('setPasswordForUser', () => {
|
|
100
|
-
it('Should be able to set the password for the user using the last password', async () => {
|
|
101
|
-
await (0, utils_1.usingAsync)(new inject_1.Injector(), async (i) => {
|
|
102
|
-
const userName = randomString();
|
|
103
|
-
const lastPassword = randomString();
|
|
104
|
-
const password = randomString();
|
|
105
|
-
(0, core_1.addStore)(i, new core_1.InMemoryStore({ model: models_1.PasswordCredential, primaryKey: 'userName' })).addStore(new core_1.InMemoryStore({ model: core_1.User, primaryKey: 'username' }));
|
|
106
|
-
(0, helpers_1.usePasswordPolicy)(i);
|
|
107
|
-
const authenticator = i.getInstance(password_authenticator_1.PasswordAuthenticator);
|
|
108
|
-
const hasher = authenticator.getHasher();
|
|
109
|
-
const passwordStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordCredential, 'userName');
|
|
110
|
-
const policyManager = i.getInstance(security_policy_manager_1.SecurityPolicyManager);
|
|
111
|
-
const pmSpy = jest.spyOn(policyManager, 'matchPasswordComplexityRules');
|
|
112
|
-
const entry = await hasher.createCredential(userName, lastPassword);
|
|
113
|
-
await passwordStore.add(entry);
|
|
114
|
-
await authenticator.setPasswordForUser(userName, lastPassword, password);
|
|
115
|
-
expect(pmSpy).toBeCalled();
|
|
116
|
-
const entryCount = await passwordStore.count({ userName: { $eq: userName } });
|
|
117
|
-
expect(entryCount).toBe(1); // old entry should be removed
|
|
118
|
-
const successResult = await authenticator.checkPasswordForUser(userName, password);
|
|
119
|
-
expect(successResult.isValid).toBeTruthy();
|
|
120
|
-
// Password updated, cannot use the last password
|
|
121
|
-
const failResult = await authenticator.checkPasswordForUser(userName, lastPassword);
|
|
122
|
-
expect(failResult.isValid).toBeFalsy();
|
|
123
|
-
expect(failResult.reason).toBe('badUsernameOrPassword');
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
it('Should throw PasswordComplexityError if the complexity rules are not respected', async () => {
|
|
127
|
-
await (0, utils_1.usingAsync)(new inject_1.Injector(), async (i) => {
|
|
128
|
-
const userName = randomString();
|
|
129
|
-
const lastPassword = randomString();
|
|
130
|
-
const password = '';
|
|
131
|
-
(0, core_1.addStore)(i, new core_1.InMemoryStore({ model: models_1.PasswordCredential, primaryKey: 'userName' })).addStore(new core_1.InMemoryStore({ model: core_1.User, primaryKey: 'username' }));
|
|
132
|
-
(0, helpers_1.usePasswordPolicy)(i, { passwordComplexityRules: [(0, password_complexity_rules_1.createMinLengthComplexityRule)(3)] });
|
|
133
|
-
const authenticator = i.getInstance(password_authenticator_1.PasswordAuthenticator);
|
|
134
|
-
const hasher = authenticator.getHasher();
|
|
135
|
-
const passwordStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordCredential, 'userName');
|
|
136
|
-
const policyManager = i.getInstance(security_policy_manager_1.SecurityPolicyManager);
|
|
137
|
-
const pmSpy = jest.spyOn(policyManager, 'matchPasswordComplexityRules');
|
|
138
|
-
const entry = await hasher.createCredential(userName, lastPassword);
|
|
139
|
-
await passwordStore.add(entry);
|
|
140
|
-
await expect(authenticator.setPasswordForUser(userName, lastPassword, password)).rejects.toThrowError(errors_1.PasswordComplexityError);
|
|
141
|
-
expect(pmSpy).toBeCalled();
|
|
142
|
-
const entryCount = await passwordStore.count({ userName: { $eq: userName } });
|
|
143
|
-
expect(entryCount).toBe(1); // old entry should be removed
|
|
144
|
-
const failResult = await authenticator.checkPasswordForUser(userName, password);
|
|
145
|
-
// Password NOT updated, can use the last password
|
|
146
|
-
expect(failResult.isValid).toBeFalsy();
|
|
147
|
-
expect(failResult.reason).toBe('badUsernameOrPassword');
|
|
148
|
-
// Password NOT updated, cannot use the new password
|
|
149
|
-
const successResult = await authenticator.checkPasswordForUser(userName, lastPassword);
|
|
150
|
-
expect(successResult.isValid).toBeTruthy();
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
it('Should throw UnauthenticatedError if the last password is not valid', async () => {
|
|
154
|
-
await (0, utils_1.usingAsync)(new inject_1.Injector(), async (i) => {
|
|
155
|
-
const userName = randomString();
|
|
156
|
-
const lastPassword = randomString();
|
|
157
|
-
const password = randomString();
|
|
158
|
-
(0, core_1.addStore)(i, new core_1.InMemoryStore({ model: models_1.PasswordCredential, primaryKey: 'userName' })).addStore(new core_1.InMemoryStore({ model: core_1.User, primaryKey: 'username' }));
|
|
159
|
-
(0, helpers_1.usePasswordPolicy)(i);
|
|
160
|
-
const authenticator = i.getInstance(password_authenticator_1.PasswordAuthenticator);
|
|
161
|
-
const hasher = authenticator.getHasher();
|
|
162
|
-
const passwordStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordCredential, 'userName');
|
|
163
|
-
const policyManager = i.getInstance(security_policy_manager_1.SecurityPolicyManager);
|
|
164
|
-
const pmSpy = jest.spyOn(policyManager, 'matchPasswordComplexityRules');
|
|
165
|
-
const entry = await hasher.createCredential(userName, lastPassword);
|
|
166
|
-
await passwordStore.add(entry);
|
|
167
|
-
await expect(authenticator.setPasswordForUser(userName, 'someBadLastPassword', password)).rejects.toThrowError(errors_1.UnauthenticatedError);
|
|
168
|
-
expect(pmSpy).toBeCalled();
|
|
169
|
-
const entryCount = await passwordStore.count({ userName: { $eq: userName } });
|
|
170
|
-
expect(entryCount).toBe(1); // old entry should be removed
|
|
171
|
-
const failResult = await authenticator.checkPasswordForUser(userName, password);
|
|
172
|
-
// Password NOT updated, can use the last password
|
|
173
|
-
expect(failResult.isValid).toBeFalsy();
|
|
174
|
-
expect(failResult.reason).toBe('badUsernameOrPassword');
|
|
175
|
-
// Password NOT updated, cannot use the new password
|
|
176
|
-
const successResult = await authenticator.checkPasswordForUser(userName, lastPassword);
|
|
177
|
-
expect(successResult.isValid).toBeTruthy();
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
describe('resetPasswordForUser', () => {
|
|
182
|
-
it('Should reset the password with the valid token', async () => {
|
|
183
|
-
await (0, utils_1.usingAsync)(new inject_1.Injector(), async (i) => {
|
|
184
|
-
const userName = randomString();
|
|
185
|
-
const lastPassword = randomString();
|
|
186
|
-
const password = randomString();
|
|
187
|
-
const token = randomString();
|
|
188
|
-
(0, core_1.addStore)(i, new core_1.InMemoryStore({ model: models_1.PasswordCredential, primaryKey: 'userName' }))
|
|
189
|
-
.addStore(new core_1.InMemoryStore({ model: core_1.User, primaryKey: 'username' }))
|
|
190
|
-
.addStore(new core_1.InMemoryStore({ model: models_1.PasswordResetToken, primaryKey: 'token' }));
|
|
191
|
-
(0, helpers_1.usePasswordPolicy)(i);
|
|
192
|
-
const authenticator = i.getInstance(password_authenticator_1.PasswordAuthenticator);
|
|
193
|
-
const hasher = authenticator.getHasher();
|
|
194
|
-
const passwordStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordCredential, 'userName');
|
|
195
|
-
const resetTokenStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordResetToken, 'token');
|
|
196
|
-
const entry = await hasher.createCredential(userName, lastPassword);
|
|
197
|
-
await passwordStore.add(entry);
|
|
198
|
-
await resetTokenStore.add({ userName, createdAt: new Date().toISOString(), token });
|
|
199
|
-
await authenticator.resetPasswordForUser(token, password);
|
|
200
|
-
const successResult = await authenticator.checkPasswordForUser(userName, password);
|
|
201
|
-
expect(successResult.isValid).toBeTruthy();
|
|
202
|
-
// Password updated, cannot use the last password
|
|
203
|
-
const failResult = await authenticator.checkPasswordForUser(userName, lastPassword);
|
|
204
|
-
expect(failResult.isValid).toBeFalsy();
|
|
205
|
-
expect(failResult.reason).toBe('badUsernameOrPassword');
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
it('Should throw PasswordComplexityError if the complexity rules are not respected', async () => {
|
|
209
|
-
await (0, utils_1.usingAsync)(new inject_1.Injector(), async (i) => {
|
|
210
|
-
const userName = randomString();
|
|
211
|
-
const lastPassword = randomString();
|
|
212
|
-
const password = '';
|
|
213
|
-
const token = randomString();
|
|
214
|
-
(0, core_1.addStore)(i, new core_1.InMemoryStore({ model: models_1.PasswordCredential, primaryKey: 'userName' }))
|
|
215
|
-
.addStore(new core_1.InMemoryStore({ model: core_1.User, primaryKey: 'username' }))
|
|
216
|
-
.addStore(new core_1.InMemoryStore({ model: models_1.PasswordResetToken, primaryKey: 'token' }));
|
|
217
|
-
(0, helpers_1.usePasswordPolicy)(i, { passwordComplexityRules: [(0, password_complexity_rules_1.createMinLengthComplexityRule)(3)] });
|
|
218
|
-
const authenticator = i.getInstance(password_authenticator_1.PasswordAuthenticator);
|
|
219
|
-
const hasher = authenticator.getHasher();
|
|
220
|
-
const passwordStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordCredential, 'userName');
|
|
221
|
-
const resetTokenStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordResetToken, 'token');
|
|
222
|
-
const entry = await hasher.createCredential(userName, lastPassword);
|
|
223
|
-
await passwordStore.add(entry);
|
|
224
|
-
await resetTokenStore.add({ userName, createdAt: new Date().toISOString(), token });
|
|
225
|
-
await expect(authenticator.resetPasswordForUser(token, password)).rejects.toThrowError(errors_1.PasswordComplexityError);
|
|
226
|
-
const successResult = await authenticator.checkPasswordForUser(userName, lastPassword);
|
|
227
|
-
expect(successResult.isValid).toBeTruthy();
|
|
228
|
-
// Password updated, cannot use the last password
|
|
229
|
-
const failResult = await authenticator.checkPasswordForUser(userName, password);
|
|
230
|
-
expect(failResult.isValid).toBeFalsy();
|
|
231
|
-
expect(failResult.reason).toBe('badUsernameOrPassword');
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
it('Should throw UnauthenticatedError if the token is not valid', async () => {
|
|
235
|
-
await (0, utils_1.usingAsync)(new inject_1.Injector(), async (i) => {
|
|
236
|
-
const userName = randomString();
|
|
237
|
-
const lastPassword = randomString();
|
|
238
|
-
const password = '';
|
|
239
|
-
const token = randomString();
|
|
240
|
-
(0, core_1.addStore)(i, new core_1.InMemoryStore({ model: models_1.PasswordCredential, primaryKey: 'userName' }))
|
|
241
|
-
.addStore(new core_1.InMemoryStore({ model: core_1.User, primaryKey: 'username' }))
|
|
242
|
-
.addStore(new core_1.InMemoryStore({ model: models_1.PasswordResetToken, primaryKey: 'token' }));
|
|
243
|
-
(0, helpers_1.usePasswordPolicy)(i);
|
|
244
|
-
const authenticator = i.getInstance(password_authenticator_1.PasswordAuthenticator);
|
|
245
|
-
const hasher = authenticator.getHasher();
|
|
246
|
-
const passwordStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordCredential, 'userName');
|
|
247
|
-
const resetTokenStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordResetToken, 'token');
|
|
248
|
-
const entry = await hasher.createCredential(userName, lastPassword);
|
|
249
|
-
await passwordStore.add(entry);
|
|
250
|
-
await resetTokenStore.add({ userName, createdAt: new Date().toISOString(), token });
|
|
251
|
-
await expect(authenticator.resetPasswordForUser('someBadToken', password)).rejects.toThrowError(errors_1.UnauthenticatedError);
|
|
252
|
-
const successResult = await authenticator.checkPasswordForUser(userName, lastPassword);
|
|
253
|
-
expect(successResult.isValid).toBeTruthy();
|
|
254
|
-
// Password updated, cannot use the last password
|
|
255
|
-
const failResult = await authenticator.checkPasswordForUser(userName, password);
|
|
256
|
-
expect(failResult.isValid).toBeFalsy();
|
|
257
|
-
expect(failResult.reason).toBe('badUsernameOrPassword');
|
|
258
|
-
});
|
|
259
|
-
});
|
|
260
|
-
it('Should throw UnauthenticatedError and clean up token if the token has been expired', async () => {
|
|
261
|
-
await (0, utils_1.usingAsync)(new inject_1.Injector(), async (i) => {
|
|
262
|
-
const userName = randomString();
|
|
263
|
-
const lastPassword = randomString();
|
|
264
|
-
const password = '';
|
|
265
|
-
const token = randomString();
|
|
266
|
-
(0, core_1.addStore)(i, new core_1.InMemoryStore({ model: models_1.PasswordCredential, primaryKey: 'userName' }))
|
|
267
|
-
.addStore(new core_1.InMemoryStore({ model: core_1.User, primaryKey: 'username' }))
|
|
268
|
-
.addStore(new core_1.InMemoryStore({ model: models_1.PasswordResetToken, primaryKey: 'token' }));
|
|
269
|
-
(0, helpers_1.usePasswordPolicy)(i, { resetTokenExpirationSeconds: 1 });
|
|
270
|
-
const authenticator = i.getInstance(password_authenticator_1.PasswordAuthenticator);
|
|
271
|
-
const hasher = authenticator.getHasher();
|
|
272
|
-
const passwordStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordCredential, 'userName');
|
|
273
|
-
const resetTokenStore = i.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordResetToken, 'token');
|
|
274
|
-
const entry = await hasher.createCredential(userName, lastPassword);
|
|
275
|
-
await passwordStore.add(entry);
|
|
276
|
-
const creationDate = new Date();
|
|
277
|
-
creationDate.setDate(creationDate.getDate() - 2);
|
|
278
|
-
await resetTokenStore.add({ userName, createdAt: creationDate.toISOString(), token });
|
|
279
|
-
await expect(authenticator.resetPasswordForUser(token, password)).rejects.toThrowError(errors_1.UnauthenticatedError);
|
|
280
|
-
const successResult = await authenticator.checkPasswordForUser(userName, lastPassword);
|
|
281
|
-
expect(successResult.isValid).toBeTruthy();
|
|
282
|
-
// Password updated, cannot use the last password
|
|
283
|
-
const failResult = await authenticator.checkPasswordForUser(userName, password);
|
|
284
|
-
expect(failResult.isValid).toBeFalsy();
|
|
285
|
-
expect(failResult.reason).toBe('badUsernameOrPassword');
|
|
286
|
-
const tokenCount = await resetTokenStore.count();
|
|
287
|
-
expect(tokenCount).toBe(0);
|
|
288
|
-
});
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
});
|
|
292
|
-
//# sourceMappingURL=password-authenticator.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"password-authenticator.spec.js","sourceRoot":"","sources":["../src/password-authenticator.spec.ts"],"names":[],"mappings":"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"}
|