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 +21 -36
- package/dist/index.js +27 -81
- package/package.json +6 -6
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
|
-
* //
|
|
16
|
-
* app.use(soulprint({ minScore:
|
|
14
|
+
* // Basic — require verified bots
|
|
15
|
+
* app.use(soulprint({ minScore: 40 }));
|
|
17
16
|
*
|
|
18
|
-
* //
|
|
19
|
-
*
|
|
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
|
-
* //
|
|
22
|
-
*
|
|
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
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
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
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
|
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.
|
|
3
|
+
exports.verifySPT = void 0;
|
|
4
4
|
exports.soulprint = soulprint;
|
|
5
|
-
|
|
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
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
+
"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": "
|
|
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
|
+
}
|