@nodefony/security 10.0.0-alpha.5 → 10.0.0-alpha.7
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/_virtual/{_@oxc-project_runtime@0.149.0 → _@oxc-project_runtime@0.150.0}/helpers/esm/decorate.js +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.149.0 → _@oxc-project_runtime@0.150.0}/helpers/esm/decorateMetadata.js +1 -1
- package/dist/index.js +2 -2
- package/dist/nodefony/command/security-user-add.js +23 -5
- package/dist/nodefony/command/security-user-password.js +5 -2
- package/dist/types/nodefony/command/security-user-add.d.ts +7 -0
- package/dist/types/nodefony/command/security-user-password.d.ts +5 -2
- package/docs/authenticators.md +1 -1
- package/docs/firewall.md +1 -1
- package/package.json +14 -14
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region \0@oxc-project+runtime@0.
|
|
1
|
+
//#region \0@oxc-project+runtime@0.150.0/helpers/esm/decorate.js
|
|
2
2
|
function __decorate(decorators, target, key, desc) {
|
|
3
3
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
4
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region \0@oxc-project+runtime@0.
|
|
1
|
+
//#region \0@oxc-project+runtime@0.150.0/helpers/esm/decorateMetadata.js
|
|
2
2
|
function __decorateMetadata(k, v) {
|
|
3
3
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4
4
|
}
|
package/dist/index.js
CHANGED
|
@@ -77,8 +77,8 @@ import SecurityUserPassword from "./nodefony/command/security-user-password.js";
|
|
|
77
77
|
import SecurityToken from "./nodefony/command/security-token.js";
|
|
78
78
|
import { createSecurityAdminApi, parseAuditQuery, registerSecurityAdminApi } from "./nodefony/src/admin/SecurityAdminApi.js";
|
|
79
79
|
import { registerUserRevocationCascade } from "./nodefony/src/admin/userRevocationCascade.js";
|
|
80
|
-
import __decorateMetadata from "./_virtual/_@oxc-project_runtime@0.
|
|
81
|
-
import __decorate from "./_virtual/_@oxc-project_runtime@0.
|
|
80
|
+
import __decorateMetadata from "./_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
|
|
81
|
+
import __decorate from "./_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
|
|
82
82
|
import { tokenStatusCriteria } from "./nodefony/src/token/tokenCriteria.js";
|
|
83
83
|
import { AccessDeniedError } from "./nodefony/errors/AccessDeniedError.js";
|
|
84
84
|
import "./nodefony/errors/index.js";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CONSOLE_DATA_RUN_PROFILE, Command, askPasswordMasked } from "nodefony";
|
|
2
|
+
import { WeakPasswordError } from "@nodefony/user";
|
|
2
3
|
//#region nodefony/command/security-user-add.ts
|
|
3
4
|
const options = {
|
|
4
5
|
runProfile: CONSOLE_DATA_RUN_PROFILE,
|
|
@@ -47,6 +48,13 @@ const AUTH_LOGIN_PATH = "/nodefony/security/api/auth/login";
|
|
|
47
48
|
*
|
|
48
49
|
* Le service `users` est posé par l'APPLICATION (cf `provisionUsers` du
|
|
49
50
|
* template d'app) — absent = message actionnable, pas de stack.
|
|
51
|
+
*
|
|
52
|
+
* **Le mot de passe est soumis à la politique** (`PasswordPolicy`, posée d'office
|
|
53
|
+
* sur `UserService`) : longueur minimale (10 par défaut), mot de passe qui
|
|
54
|
+
* reprend l'identifiant du compte, motif répété de bout en bout, suite de
|
|
55
|
+
* touches, liste de l'application, et les ~10 000 mots de passe les plus
|
|
56
|
+
* courants. Un refus sort en **code non nul**, NOMME la règle enfreinte, et ne
|
|
57
|
+
* crée aucun compte — `--password abc` échoue, là où il réussissait.
|
|
50
58
|
*/
|
|
51
59
|
var SecurityUserAdd = class extends Command {
|
|
52
60
|
constructor(cli) {
|
|
@@ -135,11 +143,21 @@ var SecurityUserAdd = class extends Command {
|
|
|
135
143
|
});
|
|
136
144
|
roles = chosen.length > 0 ? chosen : [ROLE_BASE];
|
|
137
145
|
} else roles = [ROLE_BASE];
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
146
|
+
let user;
|
|
147
|
+
try {
|
|
148
|
+
user = await users.createUser({
|
|
149
|
+
identifier,
|
|
150
|
+
plainPassword: password,
|
|
151
|
+
roles
|
|
152
|
+
});
|
|
153
|
+
} catch (e) {
|
|
154
|
+
if (e instanceof WeakPasswordError) {
|
|
155
|
+
this.log(`${e.message}\n la politique se règle à l'application : \`new PasswordPolicy({ minLength, blocklist })\` posée sur \`users.passwordBlocklist\`.`, "ERROR");
|
|
156
|
+
process.exitCode = 1;
|
|
157
|
+
return this;
|
|
158
|
+
}
|
|
159
|
+
throw e;
|
|
160
|
+
}
|
|
143
161
|
process.stdout.write(`\n${GREEN}✓ compte créé${RESET} — ${BOLD}${user.identifier}${RESET} ${DIM}(id ${user.id})${RESET}\n rôles : ${roles.join(" · ")}\n` + (opts.admin ? ` ${DIM}accès console Studio : /nodefony${RESET}\n` : "") + ` ${DIM}pour t'authentifier : POST ${AUTH_LOGIN_PATH}${RESET}\n ${DIM} body JSON {"username","password"} → cookie de session ; l'identité courante se relit sur GET /nodefony/security/api/auth/me${RESET}\n` + (opts.password ? ` ${YELLOW}⚠ mot de passe passé en argument — pense à purger l'historique shell${RESET}\n` : ""));
|
|
144
162
|
return this;
|
|
145
163
|
}
|
|
@@ -26,8 +26,11 @@ const RESET = "\x1B[0m";
|
|
|
26
26
|
* Mot de passe : `--password` (visible dans l'historique shell — accepté pour
|
|
27
27
|
* les scripts) ou PROMPT MASQUÉ en TTY, demandé deux fois. Le hachage est celui
|
|
28
28
|
* du service (`UserService.changePassword` → Argon2id) : jamais de clair
|
|
29
|
-
* persisté, et la
|
|
30
|
-
*
|
|
29
|
+
* persisté, et la POLITIQUE de mot de passe s'applique comme à la création —
|
|
30
|
+
* longueur minimale (10 par défaut), mot de passe qui reprend l'identifiant du
|
|
31
|
+
* compte, motif répété, suite de touches, liste de l'application, et les ~10 000
|
|
32
|
+
* mots de passe les plus courants. Un refus sort en code non nul et NOMME la
|
|
33
|
+
* règle enfreinte ; il ne crée ni ne modifie rien.
|
|
31
34
|
*
|
|
32
35
|
* 🔒 **Les sessions et les jetons du compte sont RÉVOQUÉS**, et ce n'est pas une
|
|
33
36
|
* option : on change un mot de passe parce qu'il est compromis ou perdu, et
|
|
@@ -31,6 +31,13 @@ export declare const AUTH_LOGIN_PATH = "/nodefony/security/api/auth/login";
|
|
|
31
31
|
*
|
|
32
32
|
* Le service `users` est posé par l'APPLICATION (cf `provisionUsers` du
|
|
33
33
|
* template d'app) — absent = message actionnable, pas de stack.
|
|
34
|
+
*
|
|
35
|
+
* **Le mot de passe est soumis à la politique** (`PasswordPolicy`, posée d'office
|
|
36
|
+
* sur `UserService`) : longueur minimale (10 par défaut), mot de passe qui
|
|
37
|
+
* reprend l'identifiant du compte, motif répété de bout en bout, suite de
|
|
38
|
+
* touches, liste de l'application, et les ~10 000 mots de passe les plus
|
|
39
|
+
* courants. Un refus sort en **code non nul**, NOMME la règle enfreinte, et ne
|
|
40
|
+
* crée aucun compte — `--password abc` échoue, là où il réussissait.
|
|
34
41
|
*/
|
|
35
42
|
declare class SecurityUserAdd extends Command {
|
|
36
43
|
#private;
|
|
@@ -12,8 +12,11 @@ import { CliKernel, Command } from "nodefony";
|
|
|
12
12
|
* Mot de passe : `--password` (visible dans l'historique shell — accepté pour
|
|
13
13
|
* les scripts) ou PROMPT MASQUÉ en TTY, demandé deux fois. Le hachage est celui
|
|
14
14
|
* du service (`UserService.changePassword` → Argon2id) : jamais de clair
|
|
15
|
-
* persisté, et la
|
|
16
|
-
*
|
|
15
|
+
* persisté, et la POLITIQUE de mot de passe s'applique comme à la création —
|
|
16
|
+
* longueur minimale (10 par défaut), mot de passe qui reprend l'identifiant du
|
|
17
|
+
* compte, motif répété, suite de touches, liste de l'application, et les ~10 000
|
|
18
|
+
* mots de passe les plus courants. Un refus sort en code non nul et NOMME la
|
|
19
|
+
* règle enfreinte ; il ne crée ni ne modifie rien.
|
|
17
20
|
*
|
|
18
21
|
* 🔒 **Les sessions et les jetons du compte sont RÉVOQUÉS**, et ce n'est pas une
|
|
19
22
|
* option : on change un mot de passe parce qu'il est compromis ou perdu, et
|
package/docs/authenticators.md
CHANGED
|
@@ -183,7 +183,7 @@ curl -si http://localhost:5151/api/v1/whoami | grep -E "^(HTTP|WWW)"
|
|
|
183
183
|
# HTTP/1.1 401 Unauthorized
|
|
184
184
|
# WWW-Authenticate: Bearer
|
|
185
185
|
|
|
186
|
-
# 2) Web — login BFF (compte dev seedé admin/
|
|
186
|
+
# 2) Web — login BFF (compte dev seedé admin/nodefony-dev-42) → cookie de session
|
|
187
187
|
curl -si -c /tmp/jar -H 'Content-Type: application/json' \
|
|
188
188
|
-d '{"username":"admin","password":"admin"}' \
|
|
189
189
|
http://localhost:5151/nodefony/security/api/auth/login | head -1
|
package/docs/firewall.md
CHANGED
|
@@ -149,7 +149,7 @@ le fait pour toi.)
|
|
|
149
149
|
curl -si http://localhost:5151/api/secure/account/me | head -1
|
|
150
150
|
# HTTP/1.1 401 Unauthorized
|
|
151
151
|
|
|
152
|
-
# 2) Login BFF (compte dev seedé admin/
|
|
152
|
+
# 2) Login BFF (compte dev seedé admin/nodefony-dev-42) → cookie de session
|
|
153
153
|
curl -si -c /tmp/jar -H 'Content-Type: application/json' \
|
|
154
154
|
-d '{"username":"admin","password":"admin"}' \
|
|
155
155
|
http://localhost:5151/nodefony/security/api/auth/login | head -1
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodefony/security",
|
|
3
|
-
"version": "10.0.0-alpha.
|
|
3
|
+
"version": "10.0.0-alpha.7",
|
|
4
4
|
"description": "Pare-feu applicatif par zones pour Nodefony : authentification, autorisation par rôles, protection CSRF, journal d'audit",
|
|
5
5
|
"author": "Christophe CAMENSULI <ccamensuli@gmail.com>",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -44,29 +44,29 @@
|
|
|
44
44
|
"directory": "src/packages/@nodefony/security"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@simplewebauthn/server": "14.0.
|
|
47
|
+
"@simplewebauthn/server": "14.0.2",
|
|
48
48
|
"jose": "6.2.12",
|
|
49
49
|
"tslib": "2.8.1",
|
|
50
|
-
"zod": "^4.6.
|
|
50
|
+
"zod": "^4.6.5"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@nodefony/framework": "^10.0.0-alpha.
|
|
54
|
-
"@nodefony/http": "^10.0.0-alpha.
|
|
55
|
-
"@nodefony/user": "^10.0.0-alpha.
|
|
56
|
-
"@types/node": "26.
|
|
57
|
-
"@vitest/coverage-v8": "5.0.
|
|
58
|
-
"nodefony": "^10.0.0-alpha.
|
|
53
|
+
"@nodefony/framework": "^10.0.0-alpha.7",
|
|
54
|
+
"@nodefony/http": "^10.0.0-alpha.7",
|
|
55
|
+
"@nodefony/user": "^10.0.0-alpha.7",
|
|
56
|
+
"@types/node": "26.6.1",
|
|
57
|
+
"@vitest/coverage-v8": "5.0.1",
|
|
58
|
+
"nodefony": "^10.0.0-alpha.7",
|
|
59
59
|
"rimraf": "6.1.3",
|
|
60
|
-
"vitest": "5.0.
|
|
60
|
+
"vitest": "5.0.1"
|
|
61
61
|
},
|
|
62
62
|
"license": "Apache-2.0",
|
|
63
63
|
"readmeFilename": "README.md",
|
|
64
64
|
"contributors": [],
|
|
65
65
|
"peerDependencies": {
|
|
66
|
-
"@nodefony/framework": "^10.0.0-alpha.
|
|
67
|
-
"@nodefony/http": "^10.0.0-alpha.
|
|
68
|
-
"@nodefony/user": "^10.0.0-alpha.
|
|
69
|
-
"nodefony": "^10.0.0-alpha.
|
|
66
|
+
"@nodefony/framework": "^10.0.0-alpha.7",
|
|
67
|
+
"@nodefony/http": "^10.0.0-alpha.7",
|
|
68
|
+
"@nodefony/user": "^10.0.0-alpha.7",
|
|
69
|
+
"nodefony": "^10.0.0-alpha.7"
|
|
70
70
|
},
|
|
71
71
|
"files": [
|
|
72
72
|
"dist",
|