@nodefony/http 10.0.0-alpha.3 → 10.0.0-alpha.4
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.148.0 → _@oxc-project_runtime@0.149.0}/helpers/esm/decorate.js +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.148.0 → _@oxc-project_runtime@0.149.0}/helpers/esm/decorateMetadata.js +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.148.0 → _@oxc-project_runtime@0.149.0}/helpers/esm/decorateParam.js +1 -1
- package/dist/index.js +2 -2
- package/dist/nodefony/config/config.js +6 -6
- package/dist/nodefony/config/defineModuleConfig.js +2 -2
- package/dist/nodefony/service/certificates.js +4 -4
- package/dist/nodefony/service/http-kernel.js +2 -2
- package/dist/nodefony/service/servers/server-http.js +3 -3
- package/dist/nodefony/service/servers/server-https.js +3 -3
- package/dist/nodefony/service/servers/server-websocket-secure.js +3 -3
- package/dist/nodefony/service/servers/server-websocket.js +3 -3
- package/dist/nodefony/service/sessions/sessions-service.js +5 -5
- package/dist/nodefony/service/upload/upload-service.js +3 -3
- package/dist/types/index.d.ts +2 -2
- package/dist/types/nodefony/config/config.d.ts +4 -4
- package/dist/types/nodefony/interfaces/IHttpConfig.d.ts +14 -10
- package/dist/types/nodefony/service/certificates.d.ts +11 -2
- package/dist/types/nodefony/service/http-kernel.d.ts +2 -2
- package/dist/types/nodefony/src/context/domainMatcher.d.ts +2 -2
- package/docs/servers.md +31 -31
- package/package.json +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region \0@oxc-project+runtime@0.
|
|
1
|
+
//#region \0@oxc-project+runtime@0.149.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.149.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
|
@@ -21,8 +21,8 @@ import DefaultErrorRenderer, { schemaMismatchOf } from "./nodefony/service/error
|
|
|
21
21
|
import DefaultRequestLogger from "./nodefony/service/request-logger.js";
|
|
22
22
|
import JsonAuditLogger from "./nodefony/service/audit-logger.js";
|
|
23
23
|
import PrettyRequestLogger from "./nodefony/service/pretty-request-logger.js";
|
|
24
|
-
import __decorateMetadata from "./_virtual/_@oxc-project_runtime@0.
|
|
25
|
-
import __decorate from "./_virtual/_@oxc-project_runtime@0.
|
|
24
|
+
import __decorateMetadata from "./_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
25
|
+
import __decorate from "./_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
26
26
|
import http_kernel_default from "./nodefony/service/http-kernel.js";
|
|
27
27
|
import server_http_default from "./nodefony/service/servers/server-http.js";
|
|
28
28
|
import server_https_default from "./nodefony/service/servers/server-https.js";
|
|
@@ -58,7 +58,7 @@ import { z } from "zod";
|
|
|
58
58
|
* Ce schéma reste PUR (pas de `Nodefony.getKernel()` ni `process.env`) → sa
|
|
59
59
|
* sortie est déterministe et sérialisable en JSON Schema (`httpConfigJsonSchema`
|
|
60
60
|
* dans `defineModuleConfig.ts`). Les défauts dérivés du kernel
|
|
61
|
-
* (`upload.uploadDir` ← `kernel.tmpDir`, `certificates.
|
|
61
|
+
* (`upload.uploadDir` ← `kernel.tmpDir`, `certificates.selfSigned.attrs` ←
|
|
62
62
|
* `kernel.domain`/`projectName`) sont injectés APRÈS le parse, dans le builder
|
|
63
63
|
* (kernel disponible à `onKernelRegister`).
|
|
64
64
|
*
|
|
@@ -155,12 +155,12 @@ const http2Schema = z.looseObject({
|
|
|
155
155
|
maxSessionMemory: z.number().int().positive().default(10).describe("Mémoire max (Mo) par session HTTP/2 — borne l'amplification mémoire.")
|
|
156
156
|
}).describe("Serveur HTTP/2 (sur le port HTTPS, allowHTTP1). Loose : options `http2.SecureServerOptions` transmises.");
|
|
157
157
|
const http3Schema = z.looseObject({});
|
|
158
|
-
const
|
|
158
|
+
const selfSignedAttrSchema = z.looseObject({
|
|
159
159
|
name: z.string().optional(),
|
|
160
160
|
value: z.string().optional(),
|
|
161
161
|
shortName: z.string().optional()
|
|
162
162
|
}).describe("Champ de sujet/issuer node-forge (CertificateField).");
|
|
163
|
-
const
|
|
163
|
+
const selfSignedSchema = z.strictObject({
|
|
164
164
|
size: z.number().int().positive().default(2048).describe("Taille de la clé RSA (bits). 2048 minimum, 4096 recommandé en prod."),
|
|
165
165
|
hash: z.enum([
|
|
166
166
|
"sha256",
|
|
@@ -169,11 +169,11 @@ const opensslSchema = z.strictObject({
|
|
|
169
169
|
]).default("sha256").describe("Algorithme de hachage de la signature. SHA-1 INTERDIT (collision SHAttered 2017 ; CA/Browser Forum depuis 2016)."),
|
|
170
170
|
validityDays: z.number().int().positive().default(365).describe("Durée de validité du certificat (jours). ≤ 398 recommandé (CA/B Forum)."),
|
|
171
171
|
backdateMinutes: z.number().int().min(0).default(5).describe("Recul de notBefore (minutes) — tolère le décalage d'horloge du client (évite « certificate not yet valid »)."),
|
|
172
|
-
attrs: z.array(
|
|
172
|
+
attrs: z.array(selfSignedAttrSchema).default([]).meta({
|
|
173
173
|
kernelDerived: true,
|
|
174
174
|
description: "Attributs du certificat (commonName, organizationName…). Vide (défaut) = dérivés du kernel par le builder (commonName ← domain)."
|
|
175
175
|
})
|
|
176
|
-
}).describe("
|
|
176
|
+
}).describe("Génération du certificat AUTO-SIGNÉ (node-forge, JavaScript pur — aucun binaire externe n'est invoqué). Ces réglages ne valent QUE pour la stratégie `selfsigned` : sous `mkcert` (défaut en développement) ils sont ignorés — mkcert ne reçoit que les noms d'hôtes — et sous `strategy: \"explicit\"` le certificat est fourni, donc rien n'est généré.");
|
|
177
177
|
const sanSchema = z.strictObject({
|
|
178
178
|
dns: z.array(z.string()).default([]).meta({
|
|
179
179
|
kernelDerived: true,
|
|
@@ -195,7 +195,7 @@ const certificatesSchema = z.strictObject({
|
|
|
195
195
|
privateKeyMode: z.number().int().default(384).meta({ description: "Permissions POSIX de la clé privée écrite sur disque (0600 = lecture/écriture owner uniquement). Une clé TLS ne doit JAMAIS être world-readable." }),
|
|
196
196
|
san: sanSchema.default(() => sanSchema.parse({})),
|
|
197
197
|
dev: certDevSchema.default(() => certDevSchema.parse({})),
|
|
198
|
-
|
|
198
|
+
selfSigned: selfSignedSchema.default(() => selfSignedSchema.parse({}))
|
|
199
199
|
}).describe("Certificats TLS du serveur HTTPS et WSS.");
|
|
200
200
|
const websocketSchema = z.looseObject({
|
|
201
201
|
keepaliveInterval: z.number().int().positive().default(2e4).describe("Intervalle (ms) des pings keep-alive — détecte les connexions zombies."),
|
|
@@ -6,7 +6,7 @@ import { z } from "zod";
|
|
|
6
6
|
* Injecte les défauts dérivés du kernel APRÈS le parse (le schéma reste pur).
|
|
7
7
|
*
|
|
8
8
|
* - `upload.uploadDir` vide → répertoire temporaire du kernel (`kernel.tmpDir`).
|
|
9
|
-
* - `certificates.
|
|
9
|
+
* - `certificates.selfSigned.attrs` vide → sujet du certificat dérivé du kernel
|
|
10
10
|
* (`commonName` ← `kernel.domain`, `organizationName` ← `kernel.projectName`).
|
|
11
11
|
* Sans ce remplissage, le certificat auto-signé n'aurait pas de commonName.
|
|
12
12
|
* - `certificates.san` vide → Subject Alternative Name dérivé du kernel
|
|
@@ -28,7 +28,7 @@ function applyKernelDefaults(config, kernel) {
|
|
|
28
28
|
const p = kernel?.tmpDir?.path;
|
|
29
29
|
config.upload.uploadDir = typeof p === "string" ? p : "/tmp";
|
|
30
30
|
}
|
|
31
|
-
if (config.certificates.
|
|
31
|
+
if (config.certificates.selfSigned.attrs.length === 0) config.certificates.selfSigned.attrs = [
|
|
32
32
|
{
|
|
33
33
|
name: "commonName",
|
|
34
34
|
value: kernel?.domain ?? "nodefony.com"
|
|
@@ -22,7 +22,7 @@ const defaultOptions = {
|
|
|
22
22
|
dns: [],
|
|
23
23
|
ip: []
|
|
24
24
|
},
|
|
25
|
-
|
|
25
|
+
selfSigned: {
|
|
26
26
|
size: 2048,
|
|
27
27
|
hash: "sha256",
|
|
28
28
|
validityDays: 365,
|
|
@@ -418,7 +418,7 @@ var Certificate = class Certificate extends Service {
|
|
|
418
418
|
}
|
|
419
419
|
}
|
|
420
420
|
generateKeys() {
|
|
421
|
-
return this.forgeLib.pki.rsa.generateKeyPair(this.certOptions.
|
|
421
|
+
return this.forgeLib.pki.rsa.generateKeyPair(this.certOptions.selfSigned.size);
|
|
422
422
|
}
|
|
423
423
|
generatePrivateKeyPem() {
|
|
424
424
|
if (this.keysPair) return Buffer.from(this.forgeLib.pki.privateKeyToPem(this.keysPair.privateKey));
|
|
@@ -434,7 +434,7 @@ var Certificate = class Certificate extends Service {
|
|
|
434
434
|
}
|
|
435
435
|
createCertificate() {
|
|
436
436
|
if (!this.keysPair) throw new Error(`KeyPair not found`);
|
|
437
|
-
const o = this.certOptions.
|
|
437
|
+
const o = this.certOptions.selfSigned;
|
|
438
438
|
const cert = this.forgeLib.pki.createCertificate();
|
|
439
439
|
cert.publicKey = this.keysPair.publicKey;
|
|
440
440
|
cert.serialNumber = Certificate.generateSerialHex();
|
|
@@ -491,7 +491,7 @@ var Certificate = class Certificate extends Service {
|
|
|
491
491
|
*/
|
|
492
492
|
sign() {
|
|
493
493
|
if (!this.certForge || !this.keysPair) throw new Error(`pki.rsa.KeyPair or pki.Certificate not found`);
|
|
494
|
-
this.certForge.sign(this.keysPair.privateKey, this.digestFor(this.certOptions.
|
|
494
|
+
this.certForge.sign(this.keysPair.privateKey, this.digestFor(this.certOptions.selfSigned.hash));
|
|
495
495
|
}
|
|
496
496
|
/**
|
|
497
497
|
* Résumé introspectable du certificat serveur courant — réutilisé par la
|
|
@@ -12,8 +12,8 @@ import DefaultRequestLogger from "./request-logger.js";
|
|
|
12
12
|
import JsonAuditLogger from "./audit-logger.js";
|
|
13
13
|
import PrettyRequestLogger from "./pretty-request-logger.js";
|
|
14
14
|
import { resolveTraceparent } from "./trace.js";
|
|
15
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
16
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
15
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
16
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
17
17
|
import { GcScheduler, Module, RequestContext, Service, injectable, logColor, nodefonyError, writeRuntimeState } from "nodefony";
|
|
18
18
|
import cluster from "node:cluster";
|
|
19
19
|
import Ws from "ws";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
3
3
|
import http_kernel_default from "../http-kernel.js";
|
|
4
4
|
import { handleClientError } from "./clientError.js";
|
|
5
5
|
import { createDrainTerminator } from "./serverShutdown.js";
|
|
6
6
|
import { bindWithFallback, buildBindPlan } from "../../src/servers/portBinder.js";
|
|
7
|
-
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.
|
|
7
|
+
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateParam.js";
|
|
8
8
|
import { Module, Service, extend, inject, nodefonyError } from "nodefony";
|
|
9
9
|
import http from "node:http";
|
|
10
10
|
//#region nodefony/service/servers/server-http.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
3
3
|
import http_kernel_default from "../http-kernel.js";
|
|
4
4
|
import { handleClientError } from "./clientError.js";
|
|
5
5
|
import { createDrainTerminator } from "./serverShutdown.js";
|
|
6
6
|
import { bindWithFallback, buildBindPlan } from "../../src/servers/portBinder.js";
|
|
7
|
-
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.
|
|
7
|
+
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateParam.js";
|
|
8
8
|
import { Module, Service, extend, inject, nodefonyError } from "nodefony";
|
|
9
9
|
import http2 from "node:http2";
|
|
10
10
|
import https from "node:https";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
3
3
|
import http_kernel_default from "../http-kernel.js";
|
|
4
|
-
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.
|
|
4
|
+
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateParam.js";
|
|
5
5
|
import { startHeartbeat, trackPong } from "./wsHeartbeat.js";
|
|
6
6
|
import { Module, Service, inject } from "nodefony";
|
|
7
7
|
import Ws, { WebSocketServer } from "ws";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
3
3
|
import http_kernel_default from "../http-kernel.js";
|
|
4
|
-
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.
|
|
4
|
+
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateParam.js";
|
|
5
5
|
import { startHeartbeat, trackPong } from "./wsHeartbeat.js";
|
|
6
6
|
import { Module, Service, inject } from "nodefony";
|
|
7
7
|
import Ws, { WebSocketServer } from "ws";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { SESSION_FACETS } from "../../src/session/storage/sessionFilters.js";
|
|
2
|
-
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.
|
|
3
|
-
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
3
|
+
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
4
4
|
import http_kernel_default from "../http-kernel.js";
|
|
5
|
-
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.
|
|
5
|
+
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateParam.js";
|
|
6
6
|
import Session from "../../src/session/session.js";
|
|
7
7
|
import MemorySessionStorage from "../../src/session/storage/MemorySessionStorage.js";
|
|
8
8
|
import RevocationGuardStorage from "../../src/session/storage/RevocationGuardStorage.js";
|
|
9
|
-
import { AUTO_STORE, EMPTY_INFRA, GcScheduler, Module, Nodefony, RequestContext, Service, countFacets, extend, inject, injectable, readStoreLocation, resolveAutoStore } from "nodefony";
|
|
9
|
+
import { AUTO_STORE, EMPTY_INFRA, GcScheduler, Module, Nodefony, RequestContext, Service, countFacets, extend, inject, injectable, readStoreLocation, resolveAutoStore, runNeedsExternalServices } from "nodefony";
|
|
10
10
|
import { createHash, createHmac } from "node:crypto";
|
|
11
11
|
//#region nodefony/service/sessions/sessions-service.ts
|
|
12
12
|
var _SessionsService;
|
|
@@ -142,7 +142,7 @@ let SessionsService = class SessionsService extends Service {
|
|
|
142
142
|
const configured = storeName;
|
|
143
143
|
let reason = `store explicitement configuré ("${configured}")`;
|
|
144
144
|
if (storeName === AUTO_STORE) {
|
|
145
|
-
const auto = resolveAutoStore("session", this.kernel?.infra ?? EMPTY_INFRA, _SessionsService.storageHandlers(), "memory");
|
|
145
|
+
const auto = resolveAutoStore("session", this.kernel?.infra ?? EMPTY_INFRA, _SessionsService.storageHandlers(), "memory", runNeedsExternalServices(this.kernel));
|
|
146
146
|
storeName = auto.store;
|
|
147
147
|
reason = auto.reason;
|
|
148
148
|
this.log(`session.store "auto" → "${storeName}" (${auto.reason})`, "INFO");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
|
|
3
3
|
import http_kernel_default from "../http-kernel.js";
|
|
4
|
-
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.
|
|
4
|
+
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorateParam.js";
|
|
5
5
|
import { Cli, FileClass, Module, Service, inject } from "nodefony";
|
|
6
6
|
import fs from "node:fs";
|
|
7
7
|
import fsp from "node:fs/promises";
|
package/dist/types/index.d.ts
CHANGED
|
@@ -54,11 +54,11 @@ declare class Http extends Module<IHttpConfig> {
|
|
|
54
54
|
}
|
|
55
55
|
export default Http;
|
|
56
56
|
export { defineHttpConfig, httpConfigJsonSchema, } from "./nodefony/config/defineModuleConfig.js";
|
|
57
|
-
export { httpConfigSchema
|
|
57
|
+
export { httpConfigSchema } from "./nodefony/config/config.js";
|
|
58
58
|
export type { IHttpConfig, IHttpConfigInput, } from "./nodefony/interfaces/IHttpConfig.js";
|
|
59
59
|
export { decideSend, readBackpressureOptions, type WsBackpressurePolicy, type WsSendDecision, type IWsBackpressureOptions, type IBackpressureSocket, type IBackpressureTarget, } from "./nodefony/src/context/websocket/wsBackpressure.js";
|
|
60
60
|
export { compileDomainPattern, compileDomainPatterns, compileTrustedHosts, isDomainAllowed, } from "./nodefony/src/context/domainMatcher.js";
|
|
61
|
-
export type { DomainPattern,
|
|
61
|
+
export type { DomainPattern, ITrustedHostsConfig, } from "./nodefony/src/context/domainMatcher.js";
|
|
62
62
|
export { MemoryRateLimitStore } from "./nodefony/src/rateLimit/MemoryRateLimitStore.js";
|
|
63
63
|
export type { IRateLimitStore, IRateLimitOptions, RateLimitVerdict, } from "./nodefony/src/rateLimit/IRateLimitStore.js";
|
|
64
64
|
export { Context, Session, SessionsService, HttpError, HttpKernel, Response, Http2Response, Response as HttpResponse, wsResponse, wsResponse as WebsocketResponse, Cookie, HttpContext, WebsocketContext, HttpRequest, Http2Request, DefaultErrorRenderer, DefaultRequestLogger, JsonAuditLogger, PrettyRequestLogger, Profiler, };
|
|
@@ -74,7 +74,7 @@ export declare const httpConfigSchema: z.ZodObject<{
|
|
|
74
74
|
dev: z.ZodDefault<z.ZodObject<{
|
|
75
75
|
useMkcert: z.ZodDefault<z.ZodBoolean>;
|
|
76
76
|
}, z.core.$strict>>;
|
|
77
|
-
|
|
77
|
+
selfSigned: z.ZodDefault<z.ZodObject<{
|
|
78
78
|
size: z.ZodDefault<z.ZodNumber>;
|
|
79
79
|
hash: z.ZodDefault<z.ZodEnum<{
|
|
80
80
|
sha256: "sha256";
|
|
@@ -186,12 +186,12 @@ export declare const httpConfigSchema: z.ZodObject<{
|
|
|
186
186
|
wsMaxConnectionsPerIp: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
|
|
187
187
|
}, z.core.$strict>;
|
|
188
188
|
/** Type de sortie (config normalisée + défauts appliqués). */
|
|
189
|
-
export type
|
|
189
|
+
export type IHttpConfig = z.infer<typeof httpConfigSchema>;
|
|
190
190
|
/** Type d'entrée (toutes sections omissibles — défauts du schéma). */
|
|
191
|
-
export type
|
|
191
|
+
export type IHttpConfigInput = z.input<typeof httpConfigSchema>;
|
|
192
192
|
/**
|
|
193
193
|
* Défauts du module, matérialisés depuis le schéma (source unique). Toujours
|
|
194
194
|
* valides par construction ; passés au `super(..., config)` du Module class.
|
|
195
195
|
*/
|
|
196
|
-
declare const config:
|
|
196
|
+
declare const config: IHttpConfig;
|
|
197
197
|
export default config;
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import type { HttpConfig, HttpConfigInput } from "../config/config.js";
|
|
2
1
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Barrel d'interfaces de la configuration de `@nodefony/http`.
|
|
3
|
+
*
|
|
4
|
+
* Ces types sont DÉRIVÉS du schéma Zod — leur source de vérité unique est
|
|
5
|
+
* `../config/config.ts`, et ce fichier ne fait que les republier sous le chemin
|
|
6
|
+
* d'interfaces attendu par la convention du dépôt (`nodefony/interfaces/I*.ts`).
|
|
7
|
+
*
|
|
8
|
+
* ⚠️ Un ré-export, jamais un alias (`export type IHttpConfig = HttpConfig`) :
|
|
9
|
+
* un alias publierait DEUX noms pour le même type, tous deux dans les `.d.ts`
|
|
10
|
+
* et l'autocomplétion du consommateur, sans que rien ne dise lequel est le bon.
|
|
5
11
|
*/
|
|
6
|
-
export type
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
*/
|
|
12
|
-
export type IHttpConfigInput = HttpConfigInput;
|
|
12
|
+
export type {
|
|
13
|
+
/** Type de sortie (config normalisée + défauts appliqués). */
|
|
14
|
+
IHttpConfig,
|
|
15
|
+
/** Type d'entrée (toutes sections omissibles — défauts du schéma). */
|
|
16
|
+
IHttpConfigInput, } from "../config/config.js";
|
|
@@ -10,7 +10,16 @@ type ForgeModule = typeof import("node-forge");
|
|
|
10
10
|
export type CertHash = "sha256" | "sha384" | "sha512";
|
|
11
11
|
/** Stratégie de fourniture du certificat exposée en configuration. */
|
|
12
12
|
export type CertStrategyConfig = "auto" | "mkcert" | "selfsigned" | "explicit";
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Options de génération du certificat AUTO-SIGNÉ (node-forge, JavaScript pur —
|
|
15
|
+
* aucun binaire externe n'est invoqué).
|
|
16
|
+
*
|
|
17
|
+
* ⚠️ Portée : ces réglages ne valent QUE pour la stratégie `selfsigned`. Sous
|
|
18
|
+
* `mkcert` (le défaut en développement) ils sont ignorés — mkcert ne reçoit que
|
|
19
|
+
* les noms d'hôtes — et sous `strategy: "explicit"` le certificat est fourni,
|
|
20
|
+
* donc rien n'est généré.
|
|
21
|
+
*/
|
|
22
|
+
export interface SelfSignedOptions {
|
|
14
23
|
/** Taille de la clé RSA (bits). */
|
|
15
24
|
size: number;
|
|
16
25
|
/** Algorithme de hachage de la signature (jamais SHA-1). */
|
|
@@ -48,7 +57,7 @@ export interface CertificateOptions {
|
|
|
48
57
|
* (Let's Encrypt, ingress, reverse-proxy) : Nodefony n'est pas une CA.
|
|
49
58
|
*/
|
|
50
59
|
strategy?: CertStrategyConfig;
|
|
51
|
-
|
|
60
|
+
selfSigned: SelfSignedOptions;
|
|
52
61
|
dev: CertificateDevOptions;
|
|
53
62
|
san?: CertificateSanOptions;
|
|
54
63
|
/** Permissions POSIX de la clé privée écrite (0600 = owner-only). */
|
|
@@ -4,7 +4,7 @@ import type { Controller } from "@nodefony/framework";
|
|
|
4
4
|
import HttpError from "../src/errors/httpError.js";
|
|
5
5
|
import { type TrustProxyChecker } from "../src/context/trustProxy.js";
|
|
6
6
|
import type { IRateLimitStore } from "../src/rateLimit/IRateLimitStore.js";
|
|
7
|
-
import { type
|
|
7
|
+
import { type ITrustedHostsConfig } from "../src/context/domainMatcher.js";
|
|
8
8
|
import http from "node:http";
|
|
9
9
|
import http2 from "node:http2";
|
|
10
10
|
import type { IncomingMessage } from "node:http";
|
|
@@ -79,7 +79,7 @@ declare class HttpKernel extends Service implements IHttpKernelInterface {
|
|
|
79
79
|
ca: string;
|
|
80
80
|
serverStatic: Statics | null;
|
|
81
81
|
domain: string;
|
|
82
|
-
trustedHosts?:
|
|
82
|
+
trustedHosts?: ITrustedHostsConfig;
|
|
83
83
|
domainCheck: boolean;
|
|
84
84
|
regAlias: RegExp[];
|
|
85
85
|
module: Module;
|
|
@@ -28,7 +28,7 @@ export type DomainPattern = string | RegExp;
|
|
|
28
28
|
* filtre déjà le `Host`, cf doctrine cloud-native).
|
|
29
29
|
* - `string` / `string[]` : patterns additionnels (exact ou `*`-wildcard).
|
|
30
30
|
*/
|
|
31
|
-
export type
|
|
31
|
+
export type ITrustedHostsConfig = boolean | DomainPattern | DomainPattern[];
|
|
32
32
|
/**
|
|
33
33
|
* Compile UN pattern de domaine en `RegExp` selon la politique sûre.
|
|
34
34
|
*
|
|
@@ -56,7 +56,7 @@ export declare function compileDomainPatterns(patterns: DomainPattern | DomainPa
|
|
|
56
56
|
* @param isDev - vrai en environnement `development` (ajoute le loopback).
|
|
57
57
|
* @returns liste de `RegExp` pour {@link isDomainAllowed}.
|
|
58
58
|
*/
|
|
59
|
-
export declare function compileTrustedHosts(domain: string, trusted:
|
|
59
|
+
export declare function compileTrustedHosts(domain: string, trusted: ITrustedHostsConfig | undefined, isDev: boolean): RegExp[];
|
|
60
60
|
/**
|
|
61
61
|
* Teste un `Host` entrant contre une liste de `RegExp` pré-compilée.
|
|
62
62
|
*
|
package/docs/servers.md
CHANGED
|
@@ -133,7 +133,7 @@ session et du même firewall, et se ferme avec le même soin qu'une réponse HTT
|
|
|
133
133
|
|
|
134
134
|
> [!NOTE]
|
|
135
135
|
> Le serveur HTTP/3 (QUIC) est **réservé, pas implémenté** : la clé `http3` existe dans le schéma,
|
|
136
|
-
> marquée `reserved` (`config.ts:
|
|
136
|
+
> marquée `reserved` (`config.ts:1035`). Elle ne fait rien aujourd'hui.
|
|
137
137
|
|
|
138
138
|
## 🚀 Démarrage rapide
|
|
139
139
|
|
|
@@ -400,7 +400,7 @@ C'est la distinction la plus utile de cette page, et celle qu'on rate le plus so
|
|
|
400
400
|
| Question | Où ça se règle | Source |
|
|
401
401
|
| ----------------------------------------- | ------------------------------ | --------------------------------------------------------- |
|
|
402
402
|
| **Quels** serveurs, sur **quels ports** ? | `servers` (config d'app) | `serversSchema` (`src/nodefony/src/config/schema.ts:132`) |
|
|
403
|
-
| **Comment** ces serveurs se comportent ? | `use("@nodefony/http", { … })` | `httpConfigSchema` (`config.ts:
|
|
403
|
+
| **Comment** ces serveurs se comportent ? | `use("@nodefony/http", { … })` | `httpConfigSchema` (`config.ts:953`) |
|
|
404
404
|
|
|
405
405
|
Autrement dit : la **topologie** est une propriété du déploiement (elle change entre le poste du dev,
|
|
406
406
|
la CI et le cluster) ; le **réglage** est une propriété de l'application.
|
|
@@ -451,16 +451,16 @@ Depuis `http2Schema` (`config.ts:332`), appliqué seulement si défini
|
|
|
451
451
|
|
|
452
452
|
### Niveau 2 — WebSocket (`websocket` et `websocketSecure`)
|
|
453
453
|
|
|
454
|
-
Depuis `websocketSchema` (`config.ts:
|
|
455
|
-
lit `websocketSecure` (`config.ts:
|
|
454
|
+
Depuis `websocketSchema` (`config.ts:496`). Les deux sections partagent la forme et les défauts ; le WSS
|
|
455
|
+
lit `websocketSecure` (`config.ts:1043`).
|
|
456
456
|
|
|
457
457
|
| Option | Type | Défaut | Effet |
|
|
458
458
|
| ------------------------ | ------------------- | ------- | ---------------------------------------------------------------------------------- |
|
|
459
459
|
| `keepaliveInterval` | ms | `20000` | Intervalle des pings — détecte les connexions zombies. |
|
|
460
460
|
| `keepaliveGracePeriod` | ms | `10000` | Délai de grâce après un ping sans réponse avant fermeture. |
|
|
461
461
|
| `closeTimeout` | ms | `5000` | Délai de fermeture propre avant destruction de la socket. |
|
|
462
|
-
| `maxPayload` | octets | `1 MiB` | Taille max d'un message entrant → au-delà, **close 1009** (`config.ts:
|
|
463
|
-
| `allowedOrigins` | bool \| str \| list | `false` | Allowlist d'`Origin` au handshake — **anti-CSWSH** (`config.ts:
|
|
462
|
+
| `maxPayload` | octets | `1 MiB` | Taille max d'un message entrant → au-delà, **close 1009** (`config.ts:522`). |
|
|
463
|
+
| `allowedOrigins` | bool \| str \| list | `false` | Allowlist d'`Origin` au handshake — **anti-CSWSH** (`config.ts:531`). |
|
|
464
464
|
| `perMessageDeflate` | bool \| objet | `false` | Compression RFC 7692. Désactivée par défaut : coût CPU/RAM + risque de _zip bomb_. |
|
|
465
465
|
| `skipUTF8Validation` | bool | `false` | Désactive la validation UTF-8 des frames texte (RFC 6455 §8.1). À laisser `false`. |
|
|
466
466
|
| `autoPong` | bool | `true` | Répond automatiquement aux pings entrants (RFC 6455 §5.5.2-3). À laisser `true`. |
|
|
@@ -537,12 +537,12 @@ serveur qui, lui, écoute très bien.
|
|
|
537
537
|
**Générer un certificat est un confort de développement, pas une fonction de production.** Nodefony
|
|
538
538
|
n'est pas une autorité de certification : en production, on fournit un vrai certificat (Let's Encrypt,
|
|
539
539
|
ingress k8s, reverse-proxy). Le service crie un avertissement si ce n'est pas le cas
|
|
540
|
-
(`Certificate.resolveStrategy()`, `certificates.ts:
|
|
540
|
+
(`Certificate.resolveStrategy()`, `certificates.ts:418`).
|
|
541
541
|
|
|
542
542
|
### Les quatre stratégies
|
|
543
543
|
|
|
544
|
-
Réglées par `certificates.strategy` (`certificatesSchema`, `config.ts:
|
|
545
|
-
`Certificate.resolveStrategy()` (`certificates.ts:
|
|
544
|
+
Réglées par `certificates.strategy` (`certificatesSchema`, `config.ts:475`), résolues par
|
|
545
|
+
`Certificate.resolveStrategy()` (`certificates.ts:379`).
|
|
546
546
|
|
|
547
547
|
| Stratégie | Quand l'utiliser | Ce qui se passe |
|
|
548
548
|
| --------------- | ------------------------------------------- | --------------------------------------------------------------------------- |
|
|
@@ -572,13 +572,13 @@ export default defineConfig(() => ({
|
|
|
572
572
|
> [!TIP]
|
|
573
573
|
> Pour un HTTPS de développement **sans avertissement navigateur** (indispensable au HMR cross-origin
|
|
574
574
|
> et au WSS) : `brew install mkcert nss && mkcert -install`. Nodefony le détecte tout seul, sinon il
|
|
575
|
-
> l'annonce et retombe sur l'auto-signé (`certificates.ts:
|
|
575
|
+
> l'annonce et retombe sur l'auto-signé (`certificates.ts:401`).
|
|
576
576
|
|
|
577
577
|
### Ce que le chemin `explicit` évite
|
|
578
578
|
|
|
579
579
|
`node-forge` est une grosse dépendance. Elle est chargée **paresseusement**, uniquement sur le chemin
|
|
580
|
-
de génération (`Certificate.loadForge()`, `certificates.ts:
|
|
581
|
-
fourni, elle n'entre jamais dans le processus (`certificates.ts:
|
|
580
|
+
de génération (`Certificate.loadForge()`, `certificates.ts:227`) : en production avec un certificat
|
|
581
|
+
fourni, elle n'entre jamais dans le processus (`certificates.ts:334`).
|
|
582
582
|
|
|
583
583
|
### Conformité de l'auto-signé
|
|
584
584
|
|
|
@@ -587,16 +587,16 @@ invalid »). Celui de Nodefony respecte les règles qui comptent :
|
|
|
587
587
|
|
|
588
588
|
| Exigence | Norme | Mise en œuvre |
|
|
589
589
|
| --------------------------------------- | -------------------- | --------------------------------------------------------- |
|
|
590
|
-
| Signature SHA-256, **jamais** SHA-1 | RFC 5280, CA/B Forum | `
|
|
591
|
-
| Numéro de série aléatoire 128 bits | RFC 5280 §4.1.2.2 | `Certificate.generateSerialHex()` (`certificates.ts:
|
|
592
|
-
| Le SAN fait foi, pas le CN | RFC 6125 | SAN dérivé du kernel si non fourni (`config.ts:
|
|
593
|
-
| `notBefore` reculé (décalage d'horloge) | pratique | `
|
|
594
|
-
| Clé privée non lisible par tous | hygiène | `privateKeyMode` `0600` (`config.ts:
|
|
590
|
+
| Signature SHA-256, **jamais** SHA-1 | RFC 5280, CA/B Forum | `selfSigned.hash` par défaut `sha256` (`config.ts:400`) |
|
|
591
|
+
| Numéro de série aléatoire 128 bits | RFC 5280 §4.1.2.2 | `Certificate.generateSerialHex()` (`certificates.ts:264`) |
|
|
592
|
+
| Le SAN fait foi, pas le CN | RFC 6125 | SAN dérivé du kernel si non fourni (`config.ts:444`) |
|
|
593
|
+
| `notBefore` reculé (décalage d'horloge) | pratique | `selfSigned.backdateMinutes`, défaut 5 (`config.ts:415`) |
|
|
594
|
+
| Clé privée non lisible par tous | hygiène | `privateKeyMode` `0600` (`config.ts:499`) |
|
|
595
595
|
|
|
596
596
|
### Régénération automatique
|
|
597
597
|
|
|
598
598
|
Un certificat présent sur disque n'est pas forcément **adéquat**. `Certificate.isCertAdequate()`
|
|
599
|
-
(`certificates.ts:
|
|
599
|
+
(`certificates.ts:542`) le régénère s'il est expiré, s'il est signé en SHA-1, ou si son SAN ne couvre
|
|
600
600
|
plus les noms requis — le dernier cas est celui qui sauve : changer le domaine d'écoute sans ce
|
|
601
601
|
contrôle laisserait un certificat obsolète en place indéfiniment.
|
|
602
602
|
|
|
@@ -608,7 +608,7 @@ Dès qu'un proxy est devant l'application, trois questions se posent — et troi
|
|
|
608
608
|
|
|
609
609
|
Sans barrière, n'importe quel client peut envoyer `X-Forwarded-For: 1.2.3.4` et usurper son IP :
|
|
610
610
|
contournement de rate-limit, journaux d'audit falsifiés. Le défaut est donc **`false` — ces en-têtes
|
|
611
|
-
sont ignorés** (`config.ts:
|
|
611
|
+
sont ignorés** (`config.ts:965`), et l'IP retenue est celle de la socket réelle, non falsifiable.
|
|
612
612
|
|
|
613
613
|
| Valeur | Sens |
|
|
614
614
|
| -------------------------------------------- | ------------------------------------------------------------------ |
|
|
@@ -628,7 +628,7 @@ Barrière testée **avant le routage**, contre l'injection d'en-tête `Host`. Le
|
|
|
628
628
|
kernel est toujours accepté, plus le loopback en développement (`HttpKernel.compileAlias()`,
|
|
629
629
|
`http-kernel.ts:936`). `false` (défaut) = ce socle seul ; une liste ajoute des vhosts (exact ou joker
|
|
630
630
|
d'un seul niveau, `*.cdn.example.com`) ; `true` désactive la barrière — à réserver au cas où le proxy
|
|
631
|
-
filtre déjà le `Host` (`config.ts:
|
|
631
|
+
filtre déjà le `Host` (`config.ts:974`).
|
|
632
632
|
|
|
633
633
|
### « Cette page a-t-elle le droit d'ouvrir un WebSocket ? » → `allowedOrigins`
|
|
634
634
|
|
|
@@ -664,7 +664,7 @@ rate-limit**. Un kubelet qui reçoit un `429` croit le pod mort → cascade de r
|
|
|
664
664
|
|
|
665
665
|
| Option | Type | Défaut | Effet |
|
|
666
666
|
| --------------- | ------ | --------- | ---------------------------------------------------------------------- |
|
|
667
|
-
| `enabled` | bool | `true` | Expose les probes (`healthSchema`, `config.ts:
|
|
667
|
+
| `enabled` | bool | `true` | Expose les probes (`healthSchema`, `config.ts:925`). |
|
|
668
668
|
| `livenessPath` | string | `/livez` | Chemin de la sonde de vie (`livenessProbe.httpGet.path` k8s). |
|
|
669
669
|
| `readinessPath` | string | `/readyz` | Chemin de la sonde de disponibilité. |
|
|
670
670
|
| `shutdownDelay` | ms | `0` | Délai entre la bascule `503` et le début du drain (propagation du LB). |
|
|
@@ -790,7 +790,7 @@ est impossible → la connexion est fermée en **1013 « Try Again Later »**
|
|
|
790
790
|
journalisation (un journal par handshake rejeté serait lui-même un amplificateur sous flood).
|
|
791
791
|
|
|
792
792
|
Un second plafond, **désactivé par défaut**, borne le nombre de connexions **simultanées** par IP :
|
|
793
|
-
`wsMaxConnectionsPerIp` (`config.ts:
|
|
793
|
+
`wsMaxConnectionsPerIp` (`config.ts:1052`). En cloud-native, laisser `null` et déléguer à l'edge —
|
|
794
794
|
nginx `limit_conn`, HAProxy `sc_conn_cur` — qui voit tout le trafic, rejette avant le coût du
|
|
795
795
|
descripteur et du TLS, et couvre tous les pods. Ne l'activer que sur une machine sans ingress.
|
|
796
796
|
|
|
@@ -817,7 +817,7 @@ par seconde. Les choix visibles dans le code :
|
|
|
817
817
|
- **Fichiers statiques en repli** — depuis la bascule « router d'abord », une requête qui matche une
|
|
818
818
|
route ne paie plus l'appel disque de `serve-static` (**+28 % de requêtes par seconde** mesurés en
|
|
819
819
|
production mono-processus).
|
|
820
|
-
- **`node-forge` jamais chargé en production** avec un certificat fourni (`certificates.ts:
|
|
820
|
+
- **`node-forge` jamais chargé en production** avec un certificat fourni (`certificates.ts:227`).
|
|
821
821
|
|
|
822
822
|
Ordre de grandeur mesuré : un processus Node saturé sur un cœur tient environ 400 requêtes/s en
|
|
823
823
|
boucle locale avec dégradation gracieuse (1600 connexions concurrentes, aucun crash) ; côté WebSocket,
|
|
@@ -838,15 +838,15 @@ demande le backplane realtime.
|
|
|
838
838
|
| HTTP/2 | RFC 9113 | `ServerHttps.createServerH2()` (`server-https.ts:174`) |
|
|
839
839
|
| HTTP/2 Rapid Reset | CVE-2023-44487 | `maxConcurrentStreams` (`config.ts:334`) |
|
|
840
840
|
| En-têtes trop volumineux → 431 | RFC 6585 §5 | `handleClientError()` (`clientError.ts:25`) |
|
|
841
|
-
| WebSocket — protocole | RFC 6455 | `ws@8` + options (`config.ts:
|
|
841
|
+
| WebSocket — protocole | RFC 6455 | `ws@8` + options (`config.ts:496`) |
|
|
842
842
|
| WebSocket — Close 1001 « Going Away » | RFC 6455 §7.4.1 | `Websocket.terminate()` (`server-websocket.ts:134`) |
|
|
843
|
-
| WebSocket — 1009 « Message Too Big » | RFC 6455 §7.4.1 | `maxPayload` (`config.ts:
|
|
844
|
-
| WebSocket — validation UTF-8 | RFC 6455 §8.1 | `skipUTF8Validation` (`config.ts:
|
|
845
|
-
| WebSocket — compression | RFC 7692 | `perMessageDeflate` (`config.ts:
|
|
843
|
+
| WebSocket — 1009 « Message Too Big » | RFC 6455 §7.4.1 | `maxPayload` (`config.ts:522`) |
|
|
844
|
+
| WebSocket — validation UTF-8 | RFC 6455 §8.1 | `skipUTF8Validation` (`config.ts:602`) |
|
|
845
|
+
| WebSocket — compression | RFC 7692 | `perMessageDeflate` (`config.ts:546`) |
|
|
846
846
|
| CSWSH (Origin au handshake) | OWASP WSTG-CLNT-10 | `HttpKernel.checkWebsocketOrigin()` (`http-kernel.ts:599`) |
|
|
847
847
|
| En-têtes forwarded | RFC 7239 | `resolveForwarded()` (`forwarded.ts:253`) |
|
|
848
|
-
| Certificat — série, SAN, extensions | RFC 5280 | `Certificate.generateSerialHex()` (`certificates.ts:
|
|
849
|
-
| Certificat — identité par le SAN | RFC 6125 | `sanSchema` (`config.ts:
|
|
848
|
+
| Certificat — série, SAN, extensions | RFC 5280 | `Certificate.generateSerialHex()` (`certificates.ts:264`) |
|
|
849
|
+
| Certificat — identité par le SAN | RFC 6125 | `sanSchema` (`config.ts:442`) |
|
|
850
850
|
|
|
851
851
|
## ⚠️ Pièges (symptôme → cause → correction)
|
|
852
852
|
|
|
@@ -863,7 +863,7 @@ demande le backplane realtime.
|
|
|
863
863
|
| Cascade de redémarrages sous charge | Sonde de santé soumise au rate-limit | Déjà géré : les probes court-circuitent avant le rate-limit (`http-kernel.ts:848`) |
|
|
864
864
|
| `curl --http2` renvoie du HTTP/1.1 | `servers.https.protocol: "1.1"`, ou client sans ALPN | Passer `protocol: "2.0"` (défaut) et vérifier le client |
|
|
865
865
|
| Avertissement navigateur en HTTPS de développement | Certificat auto-signé (mkcert absent) | `brew install mkcert nss && mkcert -install`, puis redémarrer |
|
|
866
|
-
| Le certificat n'est pas régénéré après un changement de domaine | On croit qu'un fichier présent suffit | Déjà géré : le SAN est vérifié (`certificates.ts:
|
|
866
|
+
| Le certificat n'est pas régénéré après un changement de domaine | On croit qu'un fichier présent suffit | Déjà géré : le SAN est vérifié (`certificates.ts:555`) |
|
|
867
867
|
| `strategy: "explicit"` fait échouer le boot | `key`/`cert` absents de la configuration | Fournir les deux chemins — l'échec est volontaire, jamais un repli silencieux |
|
|
868
868
|
| Une IP falsifiée passe dans les journaux d'audit | `trustProxy` accordé trop largement | Restreindre à l'IP/CIDR du proxy, ou revenir à `false` |
|
|
869
869
|
| Handshake WebSocket refusé en `1008` | `Origin` non autorisée (anti-CSWSH) | Ajouter l'origine dans `websocket.allowedOrigins` |
|
|
@@ -886,7 +886,7 @@ l'origine du transport.
|
|
|
886
886
|
|
|
887
887
|
`proxy:generate` mérite un mot : la configuration nginx/HAProxy est **dérivée** des domaines de
|
|
888
888
|
confiance, des ports effectifs et des dossiers statiques montés — donc elle ne diverge pas du code. Le
|
|
889
|
-
résumé de certificat vient de `Certificate.describe()` (`certificates.ts:
|
|
889
|
+
résumé de certificat vient de `Certificate.describe()` (`certificates.ts:812`), source unique partagée
|
|
890
890
|
par la commande, le boot et un futur écran d'administration.
|
|
891
891
|
|
|
892
892
|
**Runtime.** `nodefony status` et `nodefony stop` lisent les ports effectifs publiés au boot ; ils
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodefony/http",
|
|
3
|
-
"version": "10.0.0-alpha.
|
|
3
|
+
"version": "10.0.0-alpha.4",
|
|
4
4
|
"description": "Serveurs HTTP, HTTPS, HTTP/2 et WebSocket natifs pour Nodefony : sessions, contextes de requête, certificats TLS",
|
|
5
5
|
"author": "Christophe CAMENSULI <ccamensuli@gmail.com>",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"@types/xml2js": "0.4.14",
|
|
76
76
|
"@vitest/coverage-v8": "5.0.0",
|
|
77
77
|
"chai": "6.2.2",
|
|
78
|
-
"nodefony": "^10.0.0-alpha.
|
|
78
|
+
"nodefony": "^10.0.0-alpha.4",
|
|
79
79
|
"rimraf": "6.1.3",
|
|
80
80
|
"tsx": "4.23.13",
|
|
81
81
|
"vitest": "5.0.0"
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"readmeFilename": "README.md",
|
|
85
85
|
"contributors": [],
|
|
86
86
|
"peerDependencies": {
|
|
87
|
-
"nodefony": "^10.0.0-alpha.
|
|
87
|
+
"nodefony": "^10.0.0-alpha.4",
|
|
88
88
|
"zod": "^4.4.3"
|
|
89
89
|
},
|
|
90
90
|
"files": [
|