soulprint-express 0.1.3 → 0.1.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/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { SoulprintToken } from "soulprint-core";
2
1
  import { verifySPT, SoulprintOptions } from "./verify.js";
3
2
  export { verifySPT, SoulprintOptions };
4
3
  /**
@@ -12,49 +11,35 @@ export { verifySPT, SoulprintOptions };
12
11
  *
13
12
  * const app = express();
14
13
  *
15
- * // Protect entire API — require KYC verified humans
16
- * app.use(soulprint({ minScore: 60 }));
14
+ * // Basic — require verified bots
15
+ * app.use(soulprint({ minScore: 40 }));
17
16
  *
18
- * // Protect specific route require full biometric KYC
19
- * app.post("/sensitive", soulprint({ require: ["DocumentVerified", "FaceMatch"] }), handler);
17
+ * // Con auto-renew: el middleware renueva el SPT automáticamente
18
+ * // cuando queda < 1h o expiró hace < 7 días.
19
+ * // El nuevo token llega en el header X-Soulprint-Token-Renewed.
20
+ * app.use(soulprint({ minScore: 40, nodeUrl: "https://my-validator.example.com" }));
20
21
  *
21
- * // Inside a handler get the verified identity
22
- * app.get("/me", soulprint({ minScore: 20 }), (req, res) => {
23
- * const identity = req.soulprint; // SoulprintToken
24
- * res.json({ nullifier: identity.nullifier, score: identity.score });
25
- * });
22
+ * // El cliente debe leer el header y guardar el nuevo token:
23
+ * // X-Soulprint-Token-Renewed: <nuevo_spt>
26
24
  * ```
27
25
  *
28
26
  * Token is read from:
29
27
  * - HTTP header: X-Soulprint: <SPT>
30
28
  * - Query param: ?spt=<SPT>
31
29
  * - Bearer token: Authorization: Bearer <SPT>
32
- */
33
- export declare function soulprint(opts?: SoulprintOptions): (req: any, res: any, next: Function) => void;
34
- /**
35
- * soulprintFastify() — Fastify plugin for Soulprint verification.
36
- *
37
- * USAGE:
38
30
  *
39
- * ```typescript
40
- * import Fastify from "fastify";
41
- * import { soulprintFastify } from "soulprint-express";
42
- *
43
- * const fastify = Fastify();
44
- * await fastify.register(soulprintFastify, { minScore: 60 });
45
- *
46
- * fastify.get("/me", async (request) => {
47
- * const identity = request.soulprint;
48
- * return { nullifier: identity?.nullifier };
49
- * });
50
- * ```
31
+ * Auto-renew header response:
32
+ * - X-Soulprint-Token-Renewed: <nuevo_spt> (solo cuando se renovó)
33
+ * - X-Soulprint-Expires-In: <segundos> (tiempo restante del nuevo token)
51
34
  */
52
- export declare function soulprintFastify(fastify: any, opts?: SoulprintOptions): Promise<void>;
53
- declare global {
54
- namespace Express {
55
- interface Request {
56
- soulprint?: SoulprintToken;
57
- }
58
- }
35
+ export interface SoulprintMiddlewareOptions extends SoulprintOptions {
36
+ /**
37
+ * URL del nodo validador para auto-renew.
38
+ * Si no se provee, el auto-renew está desactivado.
39
+ * Ejemplo: "https://validator.soulprint.digital"
40
+ */
41
+ nodeUrl?: string;
42
+ /** Timeout para la petición de renew. Default: 5000ms */
43
+ renewTimeoutMs?: number;
59
44
  }
60
- export { decodeToken, SoulprintToken, TrustLevel, CredentialType } from "soulprint-core";
45
+ export declare function soulprint(opts?: SoulprintMiddlewareOptions): (req: any, res: any, next: Function) => Promise<void>;
package/dist/index.js CHANGED
@@ -1,116 +1,62 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.decodeToken = exports.verifySPT = void 0;
3
+ exports.verifySPT = void 0;
4
4
  exports.soulprint = soulprint;
5
- exports.soulprintFastify = soulprintFastify;
5
+ const soulprint_core_1 = require("soulprint-core");
6
6
  const verify_js_1 = require("./verify.js");
7
7
  Object.defineProperty(exports, "verifySPT", { enumerable: true, get: function () { return verify_js_1.verifySPT; } });
8
- // ── Express Middleware ────────────────────────────────────────────────────────
9
- /**
10
- * soulprint() — Express/Connect middleware for Soulprint identity verification.
11
- *
12
- * USAGE:
13
- *
14
- * ```typescript
15
- * import express from "express";
16
- * import { soulprint } from "soulprint-express";
17
- *
18
- * const app = express();
19
- *
20
- * // Protect entire API — require KYC verified humans
21
- * app.use(soulprint({ minScore: 60 }));
22
- *
23
- * // Protect specific route — require full biometric KYC
24
- * app.post("/sensitive", soulprint({ require: ["DocumentVerified", "FaceMatch"] }), handler);
25
- *
26
- * // Inside a handler — get the verified identity
27
- * app.get("/me", soulprint({ minScore: 20 }), (req, res) => {
28
- * const identity = req.soulprint; // SoulprintToken
29
- * res.json({ nullifier: identity.nullifier, score: identity.score });
30
- * });
31
- * ```
32
- *
33
- * Token is read from:
34
- * - HTTP header: X-Soulprint: <SPT>
35
- * - Query param: ?spt=<SPT>
36
- * - Bearer token: Authorization: Bearer <SPT>
37
- */
38
8
  function soulprint(opts = {}) {
39
- return function soulprintMiddleware(req, res, next) {
9
+ return async function soulprintMiddleware(req, res, next) {
40
10
  const spt = extractSPT(req);
41
- const result = (0, verify_js_1.verifySPT)(spt, opts);
11
+ // ── Auto-renew preemptivo ────────────────────────────────────────────
12
+ // Si el token está próximo a expirar y hay nodeUrl → intentar renovar
13
+ let activeSpt = spt;
14
+ if (spt && opts.nodeUrl) {
15
+ const check = (0, soulprint_core_1.needsRenewal)(spt);
16
+ if (check.needsRenew) {
17
+ const renewal = await (0, soulprint_core_1.autoRenew)(spt, {
18
+ nodeUrl: opts.nodeUrl,
19
+ timeoutMs: opts.renewTimeoutMs ?? 5_000,
20
+ });
21
+ if (renewal.renewed && renewal.spt !== activeSpt) {
22
+ activeSpt = renewal.spt;
23
+ // Entregar nuevo token al cliente via header
24
+ res.setHeader("X-Soulprint-Token-Renewed", renewal.spt);
25
+ res.setHeader("X-Soulprint-Expires-In", String(renewal.expiresIn ?? 86400));
26
+ res.setHeader("X-Soulprint-Renew-Method", "auto");
27
+ }
28
+ }
29
+ }
30
+ const result = (0, verify_js_1.verifySPT)(activeSpt, opts);
42
31
  if (!result.allowed) {
43
32
  opts.onRejected?.(result.reason);
44
33
  res.status(403).json({
45
34
  error: "soulprint_required",
46
35
  message: opts.rejectMessage ?? result.reason,
47
36
  docs: "https://github.com/manuelariasfz/soulprint",
48
- required: {
49
- minScore: opts.minScore ?? 40,
50
- require: opts.require,
51
- },
37
+ hint: opts.nodeUrl
38
+ ? "Auto-renew activado — verifica que el token no tenga más de 7 días de expirado"
39
+ : "Configura nodeUrl en el middleware para habilitar auto-renew",
40
+ required: { minScore: opts.minScore ?? 40, require: opts.require },
52
41
  });
53
42
  return;
54
43
  }
55
44
  opts.onVerified?.(result.token);
56
- // Attach to req for downstream handlers
57
45
  req.soulprint = result.token;
58
46
  next();
59
47
  };
60
48
  }
61
49
  function extractSPT(req) {
62
- // 1. Header dedicado
63
50
  const header = req.headers?.["x-soulprint"] ?? req.headers?.["X-Soulprint"];
64
51
  if (header)
65
52
  return header;
66
- // 2. Authorization: Bearer <SPT>
67
53
  const auth = req.headers?.authorization ?? "";
68
54
  if (auth.startsWith("Bearer ")) {
69
55
  const token = auth.slice(7);
70
- // Solo si parece un SPT (base64url largo) — no interferir con JWTs normales
71
56
  if (token.length > 200)
72
57
  return token;
73
58
  }
74
- // 3. Query param: ?spt=...
75
59
  if (req.query?.spt)
76
60
  return req.query.spt;
77
61
  return undefined;
78
62
  }
79
- // ── Fastify Plugin ────────────────────────────────────────────────────────────
80
- /**
81
- * soulprintFastify() — Fastify plugin for Soulprint verification.
82
- *
83
- * USAGE:
84
- *
85
- * ```typescript
86
- * import Fastify from "fastify";
87
- * import { soulprintFastify } from "soulprint-express";
88
- *
89
- * const fastify = Fastify();
90
- * await fastify.register(soulprintFastify, { minScore: 60 });
91
- *
92
- * fastify.get("/me", async (request) => {
93
- * const identity = request.soulprint;
94
- * return { nullifier: identity?.nullifier };
95
- * });
96
- * ```
97
- */
98
- async function soulprintFastify(fastify, opts = {}) {
99
- fastify.addHook("preHandler", async (request, reply) => {
100
- const spt = extractSPT(request);
101
- const result = (0, verify_js_1.verifySPT)(spt, opts);
102
- if (!result.allowed) {
103
- opts.onRejected?.(result.reason);
104
- reply.status(403).send({
105
- error: "soulprint_required",
106
- message: opts.rejectMessage ?? result.reason,
107
- docs: "https://github.com/manuelariasfz/soulprint",
108
- });
109
- return;
110
- }
111
- opts.onVerified?.(result.token);
112
- request.soulprint = result.token;
113
- });
114
- }
115
- var soulprint_core_1 = require("soulprint-core");
116
- Object.defineProperty(exports, "decodeToken", { enumerable: true, get: function () { return soulprint_core_1.decodeToken; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "soulprint-express",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Soulprint Express/Fastify middleware — app.use(soulprint({ minScore: 40 }))",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -8,6 +8,9 @@
8
8
  "dist",
9
9
  "README.md"
10
10
  ],
11
+ "scripts": {
12
+ "build": "tsc"
13
+ },
11
14
  "publishConfig": {
12
15
  "access": "public"
13
16
  },
@@ -28,7 +31,7 @@
28
31
  ],
29
32
  "license": "MIT",
30
33
  "dependencies": {
31
- "soulprint-core": "0.1.3"
34
+ "soulprint-core": "workspace:*"
32
35
  },
33
36
  "peerDependencies": {
34
37
  "express": ">=4.0.0"
@@ -45,8 +48,5 @@
45
48
  },
46
49
  "engines": {
47
50
  "node": ">=18.0.0"
48
- },
49
- "scripts": {
50
- "build": "tsc"
51
51
  }
52
- }
52
+ }