@furystack/security 2.1.16 → 3.0.0
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/package.json +27 -12
- 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 +0 -44
- 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/errors/unauthenticated-error.js.map +0 -1
- 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-check-result.js.map +0 -1
- package/dist/models/password-complexity-result.js +0 -3
- package/dist/models/password-complexity-result.js.map +0 -1
- package/dist/models/password-complexity-rule.js +0 -3
- package/dist/models/password-complexity-rule.js.map +0 -1
- package/dist/models/password-credential.js +0 -10
- package/dist/models/password-credential.js.map +0 -1
- package/dist/models/password-reset-token.js +0 -7
- package/dist/models/password-reset-token.js.map +0 -1
- package/dist/password-authenticator.js +0 -108
- 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 +0 -29
- 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 +0 -27
- 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/index.js.map +0 -1
- package/dist/password-complexity-rules/max-length.js +0 -19
- 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 +0 -19
- 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 +0 -23
- package/dist/password-hasher.js.map +0 -1
- package/dist/security-policy-manager.js +0 -60
- 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 +0 -40
- 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/package.json
CHANGED
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@furystack/security",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Security, password management and authorization related stuff for FuryStack",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"fix:prettier": "prettier \"{,!(dist|temp)/**/}*.{ts,tsx}\" --write",
|
|
8
|
+
"build:es6": "tsc --outDir ./esm",
|
|
9
|
+
"build": "tsc -b"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./esm/index.js",
|
|
14
|
+
"types": "./types/index.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./package.json": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
"typesVersions": {
|
|
19
|
+
"*": {
|
|
20
|
+
"*": [
|
|
21
|
+
"types/*"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
7
25
|
"files": [
|
|
8
26
|
"dist",
|
|
9
27
|
"types",
|
|
10
28
|
"src"
|
|
11
29
|
],
|
|
12
|
-
"scripts": {
|
|
13
|
-
"fix:prettier": "prettier \"{,!(dist|temp)/**/}*.{ts,tsx}\" --write",
|
|
14
|
-
"build": "tsc -b"
|
|
15
|
-
},
|
|
16
30
|
"repository": {
|
|
17
31
|
"type": "git",
|
|
18
32
|
"url": "https://github.com/furystack/furystack.git"
|
|
@@ -30,13 +44,14 @@
|
|
|
30
44
|
"url": "https://github.com/furystack/furystack/issues"
|
|
31
45
|
},
|
|
32
46
|
"dependencies": {
|
|
33
|
-
"@furystack/core": "^
|
|
34
|
-
"@furystack/inject": "^
|
|
35
|
-
"@furystack/utils": "^
|
|
47
|
+
"@furystack/core": "^12.0.0",
|
|
48
|
+
"@furystack/inject": "^8.0.0",
|
|
49
|
+
"@furystack/utils": "^4.0.0"
|
|
36
50
|
},
|
|
37
51
|
"homepage": "https://github.com/furystack/furystack",
|
|
38
52
|
"devDependencies": {
|
|
39
|
-
"@types/
|
|
40
|
-
"
|
|
53
|
+
"@types/node": "^18.15.11",
|
|
54
|
+
"typescript": "^5.0.4",
|
|
55
|
+
"vitest": "^0.30.1"
|
|
41
56
|
}
|
|
42
57
|
}
|
package/src/helpers.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { createMinLengthComplexityRule } from './password-complexity-rules'
|
|
|
9
9
|
import { SecurityPolicyManager } from './security-policy-manager'
|
|
10
10
|
import { PasswordComplexityError, UnauthenticatedError } from './errors'
|
|
11
11
|
import { randomBytes } from 'crypto'
|
|
12
|
+
import { describe, it, expect, vi } from 'vitest'
|
|
12
13
|
|
|
13
14
|
const randomString = () => randomBytes(32).toString('hex')
|
|
14
15
|
|
|
@@ -138,7 +139,7 @@ describe('PasswordAuthenticator', () => {
|
|
|
138
139
|
const hasher = authenticator.getHasher()
|
|
139
140
|
const passwordStore = i.getInstance(StoreManager).getStoreFor(PasswordCredential, 'userName')
|
|
140
141
|
const policyManager = i.getInstance(SecurityPolicyManager)
|
|
141
|
-
const pmSpy =
|
|
142
|
+
const pmSpy = vi.spyOn(policyManager, 'matchPasswordComplexityRules')
|
|
142
143
|
|
|
143
144
|
const entry = await hasher.createCredential(userName, lastPassword)
|
|
144
145
|
|
|
@@ -174,7 +175,7 @@ describe('PasswordAuthenticator', () => {
|
|
|
174
175
|
const hasher = authenticator.getHasher()
|
|
175
176
|
const passwordStore = i.getInstance(StoreManager).getStoreFor(PasswordCredential, 'userName')
|
|
176
177
|
const policyManager = i.getInstance(SecurityPolicyManager)
|
|
177
|
-
const pmSpy =
|
|
178
|
+
const pmSpy = vi.spyOn(policyManager, 'matchPasswordComplexityRules')
|
|
178
179
|
|
|
179
180
|
const entry = await hasher.createCredential(userName, lastPassword)
|
|
180
181
|
|
|
@@ -214,7 +215,7 @@ describe('PasswordAuthenticator', () => {
|
|
|
214
215
|
const hasher = authenticator.getHasher()
|
|
215
216
|
const passwordStore = i.getInstance(StoreManager).getStoreFor(PasswordCredential, 'userName')
|
|
216
217
|
const policyManager = i.getInstance(SecurityPolicyManager)
|
|
217
|
-
const pmSpy =
|
|
218
|
+
const pmSpy = vi.spyOn(policyManager, 'matchPasswordComplexityRules')
|
|
218
219
|
|
|
219
220
|
const entry = await hasher.createCredential(userName, lastPassword)
|
|
220
221
|
|
|
@@ -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,44 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
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;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.CryptoPasswordHasher = void 0;
|
|
10
|
-
const inject_1 = require("@furystack/inject");
|
|
11
|
-
const crypto_1 = require("crypto");
|
|
12
|
-
let CryptoPasswordHasher = class CryptoPasswordHasher {
|
|
13
|
-
constructor() {
|
|
14
|
-
this.iterations = 1000;
|
|
15
|
-
this.keylen = 64;
|
|
16
|
-
}
|
|
17
|
-
async verifyCredential(password, { passwordHash, salt }) {
|
|
18
|
-
const newHash = await new Promise((resolve, reject) => (0, crypto_1.pbkdf2)(password, salt, this.iterations, this.keylen, 'sha512', (err, key) => err ? reject(err) : resolve(key.toString('hex'))));
|
|
19
|
-
if (newHash === passwordHash) {
|
|
20
|
-
return {
|
|
21
|
-
isValid: true,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
return {
|
|
25
|
-
isValid: false,
|
|
26
|
-
reason: 'badUsernameOrPassword',
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
async createCredential(userName, password) {
|
|
30
|
-
const salt = (0, crypto_1.randomBytes)(16).toString('hex');
|
|
31
|
-
const passwordHash = await new Promise((resolve, reject) => (0, crypto_1.pbkdf2)(password, salt, this.iterations, this.keylen, 'sha512', (err, key) => err ? reject(err) : resolve(key.toString('hex'))));
|
|
32
|
-
return {
|
|
33
|
-
userName,
|
|
34
|
-
salt,
|
|
35
|
-
passwordHash,
|
|
36
|
-
creationDate: new Date().toISOString(),
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
CryptoPasswordHasher = __decorate([
|
|
41
|
-
(0, inject_1.Injectable)({ lifetime: 'singleton' })
|
|
42
|
-
], CryptoPasswordHasher);
|
|
43
|
-
exports.CryptoPasswordHasher = CryptoPasswordHasher;
|
|
44
|
-
//# sourceMappingURL=crypto-password-hasher.js.map
|
|
@@ -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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"unauthenticated-error.js","sourceRoot":"","sources":["../../src/errors/unauthenticated-error.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,oBAAqB,SAAQ,KAAK;CAAG;AAAlD,oDAAkD"}
|
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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"password-check-result.js","sourceRoot":"","sources":["../../src/models/password-check-result.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"password-complexity-result.js","sourceRoot":"","sources":["../../src/models/password-complexity-result.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"password-complexity-rule.js","sourceRoot":"","sources":["../../src/models/password-complexity-rule.ts"],"names":[],"mappings":""}
|
|
@@ -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-credential.js","sourceRoot":"","sources":["../../src/models/password-credential.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,kBAAkB;CAmB9B;AAnBD,gDAmBC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"password-reset-token.js","sourceRoot":"","sources":["../../src/models/password-reset-token.ts"],"names":[],"mappings":";;;AAAA,MAAa,kBAAkB;CAa9B;AAbD,gDAaC"}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
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;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.PasswordAuthenticator = void 0;
|
|
13
|
-
const core_1 = require("@furystack/core");
|
|
14
|
-
const inject_1 = require("@furystack/inject");
|
|
15
|
-
const security_policy_manager_1 = require("./security-policy-manager");
|
|
16
|
-
const errors_1 = require("./errors");
|
|
17
|
-
const models_1 = require("./models");
|
|
18
|
-
const password_complexity_error_1 = require("./errors/password-complexity-error");
|
|
19
|
-
let PasswordAuthenticator = class PasswordAuthenticator {
|
|
20
|
-
constructor() {
|
|
21
|
-
this.getPasswordStore = () => this.injector.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordCredential, 'userName');
|
|
22
|
-
this.getTokenStore = () => this.injector.getInstance(core_1.StoreManager).getStoreFor(models_1.PasswordResetToken, 'token');
|
|
23
|
-
this.getHasher = () => this.injector.getInstance(this.policyManager.policy.hasher);
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* @param userName The User's unique name
|
|
27
|
-
* @param plainPassword The plain password to check
|
|
28
|
-
* @returns An object that contains an { isValid } value that indicates if the password is valid
|
|
29
|
-
*/
|
|
30
|
-
async checkPasswordForUser(userName, plainPassword) {
|
|
31
|
-
const entry = await this.getPasswordStore().get(userName);
|
|
32
|
-
if (!entry) {
|
|
33
|
-
return {
|
|
34
|
-
isValid: false,
|
|
35
|
-
reason: 'badUsernameOrPassword',
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
const result = await this.getHasher().verifyCredential(plainPassword, entry);
|
|
39
|
-
if (result.isValid && this.policyManager.hasPasswordExpired(entry)) {
|
|
40
|
-
return {
|
|
41
|
-
isValid: false,
|
|
42
|
-
reason: 'passwordExpired',
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
return result;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
*
|
|
49
|
-
* Sets the password for the specific user
|
|
50
|
-
*
|
|
51
|
-
* @param userName The user to set the password for
|
|
52
|
-
* @param lastPassword The last user password
|
|
53
|
-
* @param plainPassword The password as a plain string
|
|
54
|
-
*/
|
|
55
|
-
async setPasswordForUser(userName, lastPassword, plainPassword) {
|
|
56
|
-
const complexityResult = await this.policyManager.matchPasswordComplexityRules(plainPassword);
|
|
57
|
-
if (!complexityResult.match) {
|
|
58
|
-
throw new password_complexity_error_1.PasswordComplexityError(complexityResult.errors);
|
|
59
|
-
}
|
|
60
|
-
const lastResult = await this.checkPasswordForUser(userName, lastPassword);
|
|
61
|
-
if (!lastResult.isValid) {
|
|
62
|
-
throw new errors_1.UnauthenticatedError();
|
|
63
|
-
}
|
|
64
|
-
const store = this.getPasswordStore();
|
|
65
|
-
const newCredential = await this.getHasher().createCredential(userName, plainPassword);
|
|
66
|
-
const existing = await store.get(userName);
|
|
67
|
-
existing && (await store.remove(existing.userName));
|
|
68
|
-
await store.add(newCredential);
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Resets the password with a Password Reset token entry
|
|
72
|
-
*
|
|
73
|
-
* @param resetToken The Reset Token value
|
|
74
|
-
* @param plainPassword The new password in plain string
|
|
75
|
-
*/
|
|
76
|
-
async resetPasswordForUser(resetToken, plainPassword) {
|
|
77
|
-
const token = await this.getTokenStore().get(resetToken);
|
|
78
|
-
if (!token) {
|
|
79
|
-
throw new errors_1.UnauthenticatedError();
|
|
80
|
-
}
|
|
81
|
-
if (this.policyManager.hasTokenExpired(token)) {
|
|
82
|
-
await this.getTokenStore().remove(resetToken); // clean up token
|
|
83
|
-
throw new errors_1.UnauthenticatedError();
|
|
84
|
-
}
|
|
85
|
-
const complexityResult = await this.policyManager.matchPasswordComplexityRules(plainPassword);
|
|
86
|
-
if (!complexityResult.match) {
|
|
87
|
-
throw new password_complexity_error_1.PasswordComplexityError(complexityResult.errors);
|
|
88
|
-
}
|
|
89
|
-
const newCredential = await this.getHasher().createCredential(token.userName, plainPassword);
|
|
90
|
-
const store = this.getPasswordStore();
|
|
91
|
-
const existing = await store.get(token.userName);
|
|
92
|
-
existing && (await store.remove(existing.userName));
|
|
93
|
-
await store.add(newCredential);
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
__decorate([
|
|
97
|
-
(0, inject_1.Injected)(inject_1.Injector),
|
|
98
|
-
__metadata("design:type", inject_1.Injector)
|
|
99
|
-
], PasswordAuthenticator.prototype, "injector", void 0);
|
|
100
|
-
__decorate([
|
|
101
|
-
(0, inject_1.Injected)(security_policy_manager_1.SecurityPolicyManager),
|
|
102
|
-
__metadata("design:type", security_policy_manager_1.SecurityPolicyManager)
|
|
103
|
-
], PasswordAuthenticator.prototype, "policyManager", void 0);
|
|
104
|
-
PasswordAuthenticator = __decorate([
|
|
105
|
-
(0, inject_1.Injectable)({ lifetime: 'singleton' })
|
|
106
|
-
], PasswordAuthenticator);
|
|
107
|
-
exports.PasswordAuthenticator = PasswordAuthenticator;
|
|
108
|
-
//# sourceMappingURL=password-authenticator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"password-authenticator.js","sourceRoot":"","sources":["../src/password-authenticator.ts"],"names":[],"mappings":"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"}
|