@furystack/security 3.0.0 → 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.
Files changed (43) hide show
  1. package/esm/crypto-password-hasher.js +41 -0
  2. package/esm/crypto-password-hasher.js.map +1 -0
  3. package/esm/errors/index.js +4 -0
  4. package/esm/errors/index.js.map +1 -0
  5. package/esm/errors/password-complexity-error.js +11 -0
  6. package/esm/errors/password-complexity-error.js.map +1 -0
  7. package/esm/errors/unauthenticated-error.js +6 -0
  8. package/esm/errors/unauthenticated-error.js.map +1 -0
  9. package/esm/helpers.js +12 -0
  10. package/esm/helpers.js.map +1 -0
  11. package/esm/index.js +9 -0
  12. package/esm/index.js.map +1 -0
  13. package/esm/models/index.js +6 -0
  14. package/esm/models/index.js.map +1 -0
  15. package/esm/models/password-check-result.js +2 -0
  16. package/esm/models/password-check-result.js.map +1 -0
  17. package/esm/models/password-complexity-result.js +2 -0
  18. package/esm/models/password-complexity-result.js.map +1 -0
  19. package/esm/models/password-complexity-rule.js +2 -0
  20. package/esm/models/password-complexity-rule.js.map +1 -0
  21. package/esm/models/password-credential.js +6 -0
  22. package/esm/models/password-credential.js.map +1 -0
  23. package/esm/models/password-reset-token.js +3 -0
  24. package/esm/models/password-reset-token.js.map +1 -0
  25. package/esm/password-authenticator.js +103 -0
  26. package/esm/password-authenticator.js.map +1 -0
  27. package/esm/password-complexity-rules/contains-lowercase.js +25 -0
  28. package/esm/password-complexity-rules/contains-lowercase.js.map +1 -0
  29. package/esm/password-complexity-rules/contains-uppercase.js +23 -0
  30. package/esm/password-complexity-rules/contains-uppercase.js.map +1 -0
  31. package/esm/password-complexity-rules/index.js +5 -0
  32. package/esm/password-complexity-rules/index.js.map +1 -0
  33. package/esm/password-complexity-rules/max-length.js +15 -0
  34. package/esm/password-complexity-rules/max-length.js.map +1 -0
  35. package/esm/password-complexity-rules/min-length.js +15 -0
  36. package/esm/password-complexity-rules/min-length.js.map +1 -0
  37. package/esm/password-hasher.js +20 -0
  38. package/esm/password-hasher.js.map +1 -0
  39. package/esm/security-policy-manager.js +57 -0
  40. package/esm/security-policy-manager.js.map +1 -0
  41. package/esm/security-policy.js +37 -0
  42. package/esm/security-policy.js.map +1 -0
  43. package/package.json +5 -5
@@ -0,0 +1,41 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Injectable } from '@furystack/inject';
8
+ import { randomBytes, pbkdf2 } from 'crypto';
9
+ let CryptoPasswordHasher = class CryptoPasswordHasher {
10
+ constructor() {
11
+ this.iterations = 1000;
12
+ this.keylen = 64;
13
+ }
14
+ async verifyCredential(password, { passwordHash, salt }) {
15
+ const newHash = await new Promise((resolve, reject) => pbkdf2(password, salt, this.iterations, this.keylen, 'sha512', (err, key) => err ? reject(err) : resolve(key.toString('hex'))));
16
+ if (newHash === passwordHash) {
17
+ return {
18
+ isValid: true,
19
+ };
20
+ }
21
+ return {
22
+ isValid: false,
23
+ reason: 'badUsernameOrPassword',
24
+ };
25
+ }
26
+ async createCredential(userName, password) {
27
+ const salt = randomBytes(16).toString('hex');
28
+ const passwordHash = await new Promise((resolve, reject) => pbkdf2(password, salt, this.iterations, this.keylen, 'sha512', (err, key) => err ? reject(err) : resolve(key.toString('hex'))));
29
+ return {
30
+ userName,
31
+ salt,
32
+ passwordHash,
33
+ creationDate: new Date().toISOString(),
34
+ };
35
+ }
36
+ };
37
+ CryptoPasswordHasher = __decorate([
38
+ Injectable({ lifetime: 'singleton' })
39
+ ], CryptoPasswordHasher);
40
+ export { CryptoPasswordHasher };
41
+ //# sourceMappingURL=crypto-password-hasher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto-password-hasher.js","sourceRoot":"","sources":["../src/crypto-password-hasher.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;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,MAAM,CAAC,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,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QAC5C,MAAM,YAAY,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CACjE,MAAM,CAAC,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,UAAU,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;GACzB,oBAAoB,CAqChC;SArCY,oBAAoB"}
@@ -0,0 +1,4 @@
1
+ export * from './password-complexity-error';
2
+ export * from './unauthenticated-error';
3
+ export * from './password-complexity-error';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA"}
@@ -0,0 +1,11 @@
1
+ export class PasswordComplexityError extends Error {
2
+ /**
3
+ * @param result A detailed error result array
4
+ * @param message The Error message
5
+ */
6
+ constructor(result, message) {
7
+ super(message);
8
+ this.result = result;
9
+ }
10
+ }
11
+ //# sourceMappingURL=password-complexity-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-complexity-error.js","sourceRoot":"","sources":["../../src/errors/password-complexity-error.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAChD;;;OAGG;IACH,YAA4B,MAAgD,EAAE,OAAgB;QAC5F,KAAK,CAAC,OAAO,CAAC,CAAA;QADY,WAAM,GAAN,MAAM,CAA0C;IAE5E,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Error that can be thrown if an authentication is required but not provided
3
+ */
4
+ export class UnauthenticatedError extends Error {
5
+ }
6
+ //# sourceMappingURL=unauthenticated-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unauthenticated-error.js","sourceRoot":"","sources":["../../src/errors/unauthenticated-error.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;CAAG"}
package/esm/helpers.js ADDED
@@ -0,0 +1,12 @@
1
+ import { SecurityPolicy } from './security-policy';
2
+ /**
3
+ * Sets up the @furystack/security with the provided settings
4
+ * @param injector The Injector instance
5
+ * @param {Partial<SecurityPolicy>} policy The security policy to use
6
+ */
7
+ export const usePasswordPolicy = (injector, policy) => {
8
+ const plainPolicy = new SecurityPolicy();
9
+ policy && Object.assign(plainPolicy, policy);
10
+ injector.setExplicitInstance(plainPolicy, SecurityPolicy);
11
+ };
12
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAElD;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,QAAkB,EAAE,MAAgC,EAAE,EAAE;IACxF,MAAM,WAAW,GAAG,IAAI,cAAc,EAAE,CAAA;IACxC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IAC5C,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,cAAc,CAAC,CAAA;AAC3D,CAAC,CAAA"}
package/esm/index.js ADDED
@@ -0,0 +1,9 @@
1
+ export * from './crypto-password-hasher';
2
+ export * from './errors';
3
+ export * from './models';
4
+ export * from './password-authenticator';
5
+ export * from './password-complexity-rules';
6
+ export * from './password-hasher';
7
+ export * from './security-policy-manager';
8
+ export * from './helpers';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAA;AACxC,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,0BAA0B,CAAA;AACxC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,mBAAmB,CAAA;AACjC,cAAc,2BAA2B,CAAA;AAEzC,cAAc,WAAW,CAAA"}
@@ -0,0 +1,6 @@
1
+ export * from './password-check-result';
2
+ export * from './password-complexity-result';
3
+ export * from './password-complexity-rule';
4
+ export * from './password-credential';
5
+ export * from './password-reset-token';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAA;AACvC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=password-check-result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-check-result.js","sourceRoot":"","sources":["../../src/models/password-check-result.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=password-complexity-result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-complexity-result.js","sourceRoot":"","sources":["../../src/models/password-complexity-result.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=password-complexity-rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-complexity-rule.js","sourceRoot":"","sources":["../../src/models/password-complexity-rule.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Entry that stores credential info for password login
3
+ */
4
+ export class PasswordCredential {
5
+ }
6
+ //# sourceMappingURL=password-credential.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-credential.js","sourceRoot":"","sources":["../../src/models/password-credential.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,kBAAkB;CAmB9B"}
@@ -0,0 +1,3 @@
1
+ export class PasswordResetToken {
2
+ }
3
+ //# sourceMappingURL=password-reset-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-reset-token.js","sourceRoot":"","sources":["../../src/models/password-reset-token.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,kBAAkB;CAa9B"}
@@ -0,0 +1,103 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { StoreManager } from '@furystack/core';
11
+ import { Injectable, Injected, Injector } from '@furystack/inject';
12
+ import { SecurityPolicyManager } from './security-policy-manager';
13
+ import { UnauthenticatedError } from './errors';
14
+ import { PasswordCredential, PasswordResetToken } from './models';
15
+ import { PasswordComplexityError } from './errors/password-complexity-error';
16
+ let PasswordAuthenticator = class PasswordAuthenticator {
17
+ constructor() {
18
+ this.getPasswordStore = () => this.injector.getInstance(StoreManager).getStoreFor(PasswordCredential, 'userName');
19
+ this.getTokenStore = () => this.injector.getInstance(StoreManager).getStoreFor(PasswordResetToken, 'token');
20
+ this.getHasher = () => this.injector.getInstance(this.policyManager.policy.hasher);
21
+ }
22
+ /**
23
+ * @param userName The User's unique name
24
+ * @param plainPassword The plain password to check
25
+ * @returns An object that contains an { isValid } value that indicates if the password is valid
26
+ */
27
+ async checkPasswordForUser(userName, plainPassword) {
28
+ const entry = await this.getPasswordStore().get(userName);
29
+ if (!entry) {
30
+ return {
31
+ isValid: false,
32
+ reason: 'badUsernameOrPassword',
33
+ };
34
+ }
35
+ const result = await this.getHasher().verifyCredential(plainPassword, entry);
36
+ if (result.isValid && this.policyManager.hasPasswordExpired(entry)) {
37
+ return {
38
+ isValid: false,
39
+ reason: 'passwordExpired',
40
+ };
41
+ }
42
+ return result;
43
+ }
44
+ /**
45
+ *
46
+ *Sets the password for the specific user
47
+ * @param userName The user to set the password for
48
+ * @param lastPassword The last user password
49
+ * @param plainPassword The password as a plain string
50
+ */
51
+ async setPasswordForUser(userName, lastPassword, plainPassword) {
52
+ const complexityResult = await this.policyManager.matchPasswordComplexityRules(plainPassword);
53
+ if (!complexityResult.match) {
54
+ throw new PasswordComplexityError(complexityResult.errors);
55
+ }
56
+ const lastResult = await this.checkPasswordForUser(userName, lastPassword);
57
+ if (!lastResult.isValid) {
58
+ throw new UnauthenticatedError();
59
+ }
60
+ const store = this.getPasswordStore();
61
+ const newCredential = await this.getHasher().createCredential(userName, plainPassword);
62
+ const existing = await store.get(userName);
63
+ existing && (await store.remove(existing.userName));
64
+ await store.add(newCredential);
65
+ }
66
+ /**
67
+ * Resets the password with a Password Reset token entry
68
+ * @param resetToken The Reset Token value
69
+ * @param plainPassword The new password in plain string
70
+ */
71
+ async resetPasswordForUser(resetToken, plainPassword) {
72
+ const token = await this.getTokenStore().get(resetToken);
73
+ if (!token) {
74
+ throw new UnauthenticatedError();
75
+ }
76
+ if (this.policyManager.hasTokenExpired(token)) {
77
+ await this.getTokenStore().remove(resetToken); // clean up token
78
+ throw new UnauthenticatedError();
79
+ }
80
+ const complexityResult = await this.policyManager.matchPasswordComplexityRules(plainPassword);
81
+ if (!complexityResult.match) {
82
+ throw new PasswordComplexityError(complexityResult.errors);
83
+ }
84
+ const newCredential = await this.getHasher().createCredential(token.userName, plainPassword);
85
+ const store = this.getPasswordStore();
86
+ const existing = await store.get(token.userName);
87
+ existing && (await store.remove(existing.userName));
88
+ await store.add(newCredential);
89
+ }
90
+ };
91
+ __decorate([
92
+ Injected(Injector),
93
+ __metadata("design:type", Injector)
94
+ ], PasswordAuthenticator.prototype, "injector", void 0);
95
+ __decorate([
96
+ Injected(SecurityPolicyManager),
97
+ __metadata("design:type", SecurityPolicyManager)
98
+ ], PasswordAuthenticator.prototype, "policyManager", void 0);
99
+ PasswordAuthenticator = __decorate([
100
+ Injectable({ lifetime: 'singleton' })
101
+ ], PasswordAuthenticator);
102
+ export { PasswordAuthenticator };
103
+ //# sourceMappingURL=password-authenticator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-authenticator.js","sourceRoot":"","sources":["../src/password-authenticator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @param lowerCaseCount The minimum lower case characters length
3
+ * @returns The created Password Policy object
4
+ */
5
+ export const createContainsLowercasePolicy = (lowerCaseCount) => ({
6
+ name: 'containsLowercase',
7
+ check: async (passwordString) => {
8
+ const actualLowerCaseCount = passwordString.length >= lowerCaseCount
9
+ ? passwordString
10
+ .normalize('NFD')
11
+ .replace(/\p{Diacritic}/gu, '')
12
+ .replace(/[^a-z]/g, '').length
13
+ : 0;
14
+ const success = actualLowerCaseCount >= lowerCaseCount;
15
+ if (success) {
16
+ return { success };
17
+ }
18
+ return {
19
+ success,
20
+ message: `The password should contain at least ${lowerCaseCount} lower case characters`,
21
+ rule: 'containsLowercase',
22
+ };
23
+ },
24
+ });
25
+ //# sourceMappingURL=contains-lowercase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contains-lowercase.js","sourceRoot":"","sources":["../../src/password-complexity-rules/contains-lowercase.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,cAAsB,EAA0B,EAAE,CAAC,CAAC;IAChG,IAAI,EAAE,mBAA4B;IAClC,KAAK,EAAE,KAAK,EAAE,cAAsB,EAAE,EAAE;QACtC,MAAM,oBAAoB,GACxB,cAAc,CAAC,MAAM,IAAI,cAAc;YACrC,CAAC,CAAC,cAAc;iBACX,SAAS,CAAC,KAAK,CAAC;iBAChB,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;iBAC9B,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,MAAM;YAClC,CAAC,CAAC,CAAC,CAAA;QACP,MAAM,OAAO,GAAG,oBAAoB,IAAI,cAAc,CAAA;QACtD,IAAI,OAAO,EAAE;YACX,OAAO,EAAE,OAAO,EAAE,CAAA;SACnB;QACD,OAAO;YACL,OAAO;YACP,OAAO,EAAE,wCAAwC,cAAc,wBAAwB;YACvF,IAAI,EAAE,mBAAmB;SAC1B,CAAA;IACH,CAAC;CACF,CAAC,CAAA"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @param upperCaseCount The minimum upper case characters length
3
+ * @returns The created Password Policy object
4
+ */
5
+ export const createContainsUppercasePolicy = (upperCaseCount) => ({
6
+ name: 'containsUppercase',
7
+ check: async (passwordString) => {
8
+ const actualUpperCaseCount = passwordString
9
+ .normalize('NFD')
10
+ .replace(/\p{Diacritic}/gu, '')
11
+ .replace(/[^A-Z]/g, '').length;
12
+ const success = actualUpperCaseCount >= upperCaseCount;
13
+ if (success) {
14
+ return { success };
15
+ }
16
+ return {
17
+ success,
18
+ message: `The password should contain at least ${upperCaseCount} upper case characters`,
19
+ rule: 'containsUppercase',
20
+ };
21
+ },
22
+ });
23
+ //# sourceMappingURL=contains-uppercase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contains-uppercase.js","sourceRoot":"","sources":["../../src/password-complexity-rules/contains-uppercase.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,cAAsB,EAA0B,EAAE,CAAC,CAAC;IAChG,IAAI,EAAE,mBAA4B;IAClC,KAAK,EAAE,KAAK,EAAE,cAAsB,EAAE,EAAE;QACtC,MAAM,oBAAoB,GAAG,cAAc;aACxC,SAAS,CAAC,KAAK,CAAC;aAChB,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;aAC9B,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,MAAM,CAAA;QAChC,MAAM,OAAO,GAAG,oBAAoB,IAAI,cAAc,CAAA;QACtD,IAAI,OAAO,EAAE;YACX,OAAO,EAAE,OAAO,EAAE,CAAA;SACnB;QACD,OAAO;YACL,OAAO;YACP,OAAO,EAAE,wCAAwC,cAAc,wBAAwB;YACvF,IAAI,EAAE,mBAAmB;SAC1B,CAAA;IACH,CAAC;CACF,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ export * from './contains-lowercase';
2
+ export * from './contains-uppercase';
3
+ export * from './max-length';
4
+ export * from './min-length';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/password-complexity-rules/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @param maxLength The maximum password length
3
+ * @returns The created Password Policy object
4
+ */
5
+ export const createMaxLengthComplexityRule = (maxLength) => ({
6
+ name: 'maxLength',
7
+ check: async (passwordString) => {
8
+ const success = passwordString.length <= maxLength;
9
+ if (success) {
10
+ return { success };
11
+ }
12
+ return { success, message: `The password has to be maximum ${maxLength} character length`, rule: 'maxLength' };
13
+ },
14
+ });
15
+ //# sourceMappingURL=max-length.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"max-length.js","sourceRoot":"","sources":["../../src/password-complexity-rules/max-length.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,SAAiB,EAA0B,EAAE,CAAC,CAAC;IAC3F,IAAI,EAAE,WAAoB;IAC1B,KAAK,EAAE,KAAK,EAAE,cAAsB,EAAE,EAAE;QACtC,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,IAAI,SAAS,CAAA;QAClD,IAAI,OAAO,EAAE;YACX,OAAO,EAAE,OAAO,EAAE,CAAA;SACnB;QACD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,kCAAkC,SAAS,mBAAmB,EAAE,IAAI,EAAE,WAAW,EAAE,CAAA;IAChH,CAAC;CACF,CAAC,CAAA"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @param minLength The minimum password length
3
+ * @returns The created Password Policy object
4
+ */
5
+ export const createMinLengthComplexityRule = (minLength) => ({
6
+ name: 'minLength',
7
+ check: async (passwordString) => {
8
+ const success = passwordString.length >= minLength;
9
+ if (success) {
10
+ return { success };
11
+ }
12
+ return { success, message: `The password has to be at least ${minLength} character length`, rule: 'minLength' };
13
+ },
14
+ });
15
+ //# sourceMappingURL=min-length.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"min-length.js","sourceRoot":"","sources":["../../src/password-complexity-rules/min-length.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,SAAiB,EAA0B,EAAE,CAAC,CAAC;IAC3F,IAAI,EAAE,WAAoB;IAC1B,KAAK,EAAE,KAAK,EAAE,cAAsB,EAAE,EAAE;QACtC,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,IAAI,SAAS,CAAA;QAClD,IAAI,OAAO,EAAE;YACX,OAAO,EAAE,OAAO,EAAE,CAAA;SACnB;QACD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,mCAAmC,SAAS,mBAAmB,EAAE,IAAI,EAAE,WAAW,EAAE,CAAA;IACjH,CAAC;CACF,CAAC,CAAA"}
@@ -0,0 +1,20 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Injectable } from '@furystack/inject';
8
+ let PasswordHasher = class PasswordHasher {
9
+ createCredential(_userName, _password) {
10
+ throw Error('Set up hasher - TODO');
11
+ }
12
+ verifyCredential(_password, _credential) {
13
+ throw Error('Set up hasher - TODO');
14
+ }
15
+ };
16
+ PasswordHasher = __decorate([
17
+ Injectable({ lifetime: 'singleton' })
18
+ ], PasswordHasher);
19
+ export { PasswordHasher };
20
+ //# sourceMappingURL=password-hasher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-hasher.js","sourceRoot":"","sources":["../src/password-hasher.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAI9C,IAAa,cAAc,GAA3B,MAAa,cAAc;IAClB,gBAAgB,CAAC,SAAiB,EAAE,SAAiB;QAC1D,MAAM,KAAK,CAAC,sBAAsB,CAAC,CAAA;IACrC,CAAC;IAEM,gBAAgB,CAAC,SAAiB,EAAE,WAA+B;QACxE,MAAM,KAAK,CAAC,sBAAsB,CAAC,CAAA;IACrC,CAAC;CACF,CAAA;AARY,cAAc;IAD1B,UAAU,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;GACzB,cAAc,CAQ1B;SARY,cAAc"}
@@ -0,0 +1,57 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Injectable, Injected } from '@furystack/inject';
11
+ import { SecurityPolicy } from './security-policy';
12
+ let SecurityPolicyManager = class SecurityPolicyManager {
13
+ /**
14
+ * @param password The Plain password string
15
+ * @returns if the password matches the complexity rules
16
+ */
17
+ async matchPasswordComplexityRules(password) {
18
+ const result = await Promise.all(this.policy.passwordComplexityRules.map((rule) => rule.check(password)));
19
+ const failed = result.filter((r) => r.success === false);
20
+ if (failed.length) {
21
+ return {
22
+ match: false,
23
+ errors: failed.map((f) => f.success === false && { message: f.message, rule: f.rule }),
24
+ };
25
+ }
26
+ return {
27
+ match: true,
28
+ };
29
+ }
30
+ hasPasswordExpired(credential) {
31
+ if (!this.policy.passwordExpirationDays) {
32
+ return false;
33
+ }
34
+ const credentialExpiration = new Date(credential.creationDate);
35
+ credentialExpiration.setDate(credentialExpiration.getDate() + this.policy.passwordExpirationDays);
36
+ const now = new Date();
37
+ return now > credentialExpiration;
38
+ }
39
+ hasTokenExpired(token) {
40
+ if (!this.policy.resetTokenExpirationSeconds) {
41
+ return false;
42
+ }
43
+ const tokenExpiration = new Date(token.createdAt);
44
+ tokenExpiration.setSeconds(tokenExpiration.getSeconds() + this.policy.resetTokenExpirationSeconds);
45
+ const now = new Date();
46
+ return now > tokenExpiration;
47
+ }
48
+ };
49
+ __decorate([
50
+ Injected(SecurityPolicy),
51
+ __metadata("design:type", SecurityPolicy)
52
+ ], SecurityPolicyManager.prototype, "policy", void 0);
53
+ SecurityPolicyManager = __decorate([
54
+ Injectable({ lifetime: 'singleton' })
55
+ ], SecurityPolicyManager);
56
+ export { SecurityPolicyManager };
57
+ //# sourceMappingURL=security-policy-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-policy-manager.js","sourceRoot":"","sources":["../src/security-policy-manager.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAExD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAGlD,IAAa,qBAAqB,GAAlC,MAAa,qBAAqB;IAChC;;;OAGG;IACI,KAAK,CAAC,4BAA4B,CAAC,QAAgB;QACxD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;QACzG,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,CAAA;QACxD,IAAI,MAAM,CAAC,MAAM,EAAE;YACjB,OAAO;gBACL,KAAK,EAAE,KAAc;gBACrB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAGnF;aACH,CAAA;SACF;QAED,OAAO;YACL,KAAK,EAAE,IAAa;SACrB,CAAA;IACH,CAAC;IAEM,kBAAkB,CAAC,UAA8B;QACtD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,EAAE;YACvC,OAAO,KAAK,CAAA;SACb;QACD,MAAM,oBAAoB,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;QAC9D,oBAAoB,CAAC,OAAO,CAAC,oBAAoB,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAA;QACjG,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;QACtB,OAAO,GAAG,GAAG,oBAAoB,CAAA;IACnC,CAAC;IAEM,eAAe,CAAC,KAAyB;QAC9C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,2BAA2B,EAAE;YAC5C,OAAO,KAAK,CAAA;SACb;QACD,MAAM,eAAe,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QACjD,eAAe,CAAC,UAAU,CAAC,eAAe,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAA;QAClG,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;QACtB,OAAO,GAAG,GAAG,eAAe,CAAA;IAC9B,CAAC;CAIF,CAAA;AADiB;IADf,QAAQ,CAAC,cAAc,CAAC;8BACA,cAAc;qDAAA;AA5C5B,qBAAqB;IADjC,UAAU,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;GACzB,qBAAqB,CA6CjC;SA7CY,qBAAqB"}
@@ -0,0 +1,37 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Injectable } from '@furystack/inject';
8
+ import { CryptoPasswordHasher } from './crypto-password-hasher';
9
+ let SecurityPolicy = class SecurityPolicy {
10
+ constructor() {
11
+ /**
12
+ * A Hasher instance for password hash generation
13
+ */
14
+ this.hasher = CryptoPasswordHasher;
15
+ /**
16
+ * Array of password complexity rules to apply
17
+ */
18
+ this.passwordComplexityRules = [];
19
+ /**
20
+ * The password expiration in days
21
+ */
22
+ this.passwordExpirationDays = 0;
23
+ /**
24
+ * Defines if the login needs a second factor authentication
25
+ */
26
+ this.requireSecondFactor = 'never'; // TODO - Challenge based on trusted devices
27
+ /**
28
+ * The Password Reset Token expiration in seconds
29
+ */
30
+ this.resetTokenExpirationSeconds = 15;
31
+ }
32
+ };
33
+ SecurityPolicy = __decorate([
34
+ Injectable({ lifetime: 'singleton' })
35
+ ], SecurityPolicy);
36
+ export { SecurityPolicy };
37
+ //# sourceMappingURL=security-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-policy.js","sourceRoot":"","sources":["../src/security-policy.ts"],"names":[],"mappings":";;;;;;AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAK/D,IAAa,cAAc,GAA3B,MAAa,cAAc;IAA3B;QACE;;WAEG;QACH,WAAM,GAAkC,oBAAoB,CAAA;QAE5D;;WAEG;QACH,4BAAuB,GAA6B,EAAE,CAAA;QAEtD;;WAEG;QACH,2BAAsB,GAAG,CAAC,CAAA;QAE1B;;WAEG;QACH,wBAAmB,GAAuB,OAAO,CAAA,CAAC,4CAA4C;QAE9F;;WAEG;QACH,gCAA2B,GAAG,EAAE,CAAA;IAClC,CAAC;CAAA,CAAA;AAzBY,cAAc;IAD1B,UAAU,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;GACzB,cAAc,CAyB1B;SAzBY,cAAc"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@furystack/security",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Security, password management and authorization related stuff for FuryStack",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -23,7 +23,7 @@
23
23
  }
24
24
  },
25
25
  "files": [
26
- "dist",
26
+ "esm",
27
27
  "types",
28
28
  "src"
29
29
  ],
@@ -44,9 +44,9 @@
44
44
  "url": "https://github.com/furystack/furystack/issues"
45
45
  },
46
46
  "dependencies": {
47
- "@furystack/core": "^12.0.0",
48
- "@furystack/inject": "^8.0.0",
49
- "@furystack/utils": "^4.0.0"
47
+ "@furystack/core": "^12.0.1",
48
+ "@furystack/inject": "^8.0.1",
49
+ "@furystack/utils": "^4.0.1"
50
50
  },
51
51
  "homepage": "https://github.com/furystack/furystack",
52
52
  "devDependencies": {