@zarex/next 0.1.0 → 0.1.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 (2) hide show
  1. package/README.md +117 -0
  2. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,117 @@
1
+ # @zarex/next
2
+
3
+ Garde Zarex pour Next.js — fonctionne dans le middleware (runtime edge) **et** dans les route handlers. Aucune dépendance à `next` à l'exécution : utilise la `Request`/`Response` standard, sans risque d'incompatibilité de version.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @zarex/next
9
+ ```
10
+
11
+ ## Démarrage rapide — middleware
12
+
13
+ ```ts
14
+ // middleware.ts
15
+ import { NextResponse } from "next/server";
16
+ import { zarexNext, shield, rateLimit } from "@zarex/next";
17
+
18
+ const guard = zarexNext({
19
+ key: process.env.ZAREX_KEY!,
20
+ ipSource: "vercel", // voir "L'adresse IP du visiteur" ci-dessous
21
+ rules: [shield(), rateLimit({ max: 100, window: "1m" })],
22
+ });
23
+
24
+ export async function middleware(request: Request) {
25
+ // `guard.finalize(...)` sur la réponse AUTORISÉE aussi, pas seulement sur un refus —
26
+ // sans cet appel, secureHeaders/responseGuard ne s'appliqueraient JAMAIS au trafic autorisé.
27
+ return (await guard(request)) ?? guard.finalize(NextResponse.next(), request);
28
+ }
29
+ ```
30
+
31
+ **Fail-open** : si Zarex est injoignable, lent ou répond de façon inattendue, la requête passe toujours.
32
+
33
+ ## Démarrage rapide — route handler
34
+
35
+ ```ts
36
+ // app/api/produits/route.ts
37
+ import { withZarex, shield } from "@zarex/next";
38
+
39
+ export const GET = withZarex(
40
+ { key: process.env.ZAREX_KEY!, ipSource: "vercel", rules: [shield()] },
41
+ async (request) => Response.json({ produits: [] })
42
+ );
43
+ ```
44
+
45
+ Avec `withZarex`, `secureHeaders`/`responseGuard` s'appliquent automatiquement à la réponse — pas d'appel à `finalize` à faire soi-même.
46
+
47
+ ## L'adresse IP du visiteur — point important
48
+
49
+ Le **middleware** Next.js ne voit jamais l'adresse de la connexion TCP (limite de la plateforme, pas du SDK). Seules les sources qui lisent un en-tête posé par la plateforme fonctionnent donc en middleware :
50
+
51
+ | `ipSource` | Quand l'utiliser |
52
+ |---|---|
53
+ | `"vercel"` | Hébergé sur Vercel. |
54
+ | `"fly"` | Hébergé sur Fly.io. |
55
+ | `"auto"` | Détecte Vercel/Fly via les variables d'environnement du serveur. |
56
+ | `"cloudflare"` | Derrière Cloudflare : lit `CF-Connecting-IP`, seulement si la connexion vient réellement de Cloudflare. |
57
+ | `{ proxies: n }` / `{ trustedProxies: [...] }` | Un nombre connu de proxys de confiance, ou leurs plages CIDR exactes. |
58
+
59
+ Hébergé ailleurs (nginx, Docker, un VPS...) sans que la plateforme ne pose un en-tête fiable : utiliser un route handler avec `withZarex` ne change rien à cette limite non plus, puisque la limite vient de Next.js lui-même, pas de l'adaptateur.
60
+
61
+ ## Options
62
+
63
+ ```ts
64
+ zarexNext({
65
+ key: string, // obligatoire : clé API du projet
66
+ rules: Rule[], // obligatoire : 1 à 10 règles, voir ci-dessous
67
+ ipSource: IpSource, // obligatoire — voir ci-dessus
68
+ inspectBody?: boolean,
69
+ secureHeaders?: boolean | SecureHeadersOptions,
70
+ responseGuard?: boolean | ResponseGuardOptions,
71
+ onDeny?: (request, decision) => Response | undefined,
72
+ onDegraded?: (request, decision) => void,
73
+ call?: (request: Request) => ProtectCall | undefined,
74
+ timeoutMs?: number, // défaut 500 ms
75
+ breaker?: BreakerOptions | false,
76
+ })
77
+ ```
78
+
79
+ ### En-têtes de sécurité et surveillance des réponses
80
+
81
+ ```ts
82
+ const guard = zarexNext({ ..., secureHeaders: true, responseGuard: true });
83
+ ```
84
+
85
+ En **middleware**, appelez bien `guard.finalize(response, request)` sur la réponse autorisée (voir l'exemple de démarrage rapide) — un avertissement s'affiche au démarrage (`console.warn`) si `secureHeaders`/`responseGuard` est configuré sans jamais appeler `finalize` sur le chemin autorisé, pour éviter que cette protection reste silencieusement inactive. En **route handler** (`withZarex`), c'est automatique.
86
+
87
+ ### Identifiants personnalisés (`call`)
88
+
89
+ ```ts
90
+ zarexNext({
91
+ key, ipSource: "vercel",
92
+ rules: [rateLimit({ max: 100, window: "1m", characteristics: ["userId"] })],
93
+ call: (request) => ({ characteristics: { userId: request.headers.get("x-user-id") ?? undefined } }),
94
+ });
95
+ ```
96
+
97
+ Les valeurs sont hachées en SHA-256 avant l'envoi à Zarex. Une erreur dans cette fonction est silencieusement ignorée. `call` peut aussi fournir `tokensRequested`, `email`/`phone` ou `text` (voir [`@zarex/core`](https://www.npmjs.com/package/@zarex/core)).
98
+
99
+ ## Règles disponibles
100
+
101
+ | Fonction | Résumé |
102
+ |---|---|
103
+ | `shield(opts?)` | Pare-feu applicatif : injection SQL, XSS, traversée de répertoires, SSRF, SSTI... |
104
+ | `rateLimit({ max, window, ... })` | Limite de requêtes par visiteur sur une fenêtre de temps. |
105
+ | `tokenBucket({ capacity, refillRate, interval })` | Budget de jetons avec pics autorisés. |
106
+ | `detectBot(opts?)` | Détecte les robots connus, avec vérification DNS inversée. |
107
+ | `requestFilter({ expressions, logic })` | Règles personnalisées sur IP, chemin, en-têtes, cookies, pays... |
108
+ | `sensitiveInfo(opts?)` | Refuse une requête contenant une donnée sensible (nécessite `inspectBody`). |
109
+ | `emailValidation(opts?)` | Valide un email donné via `call: () => ({ email })`. |
110
+ | `phoneValidation(opts?)` | Valide un numéro donné, orienté opérateurs africains (MTN, Moov, Orange, Wave...). |
111
+ | `promptInjection(opts?)` | Détecte les tentatives de manipulation d'un assistant IA, via `call: () => ({ text })`. |
112
+
113
+ Chaque règle accepte `mode: "LIVE" | "DRY_RUN" | "OFF"`. Détails complets des options : voir [`@zarex/core`](https://www.npmjs.com/package/@zarex/core).
114
+
115
+ ## Licence
116
+
117
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zarex/next",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Zarex — Next.js (middleware edge et route handlers)",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -27,7 +27,7 @@
27
27
  ],
28
28
  "sideEffects": false,
29
29
  "dependencies": {
30
- "@zarex/core": "^0.1.0"
30
+ "@zarex/core": "^0.1.1"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "next": ">=13"