@cv-challenge/server 1.0.0

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 +111 -0
  2. package/package.json +43 -0
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # @cv-challenge/server
2
+
3
+ Server-side renderer, token manager, and Express adapter for CV Challenge.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add @cv-challenge/server
9
+ ```
10
+
11
+ ## Requirements
12
+
13
+ - ffmpeg available in PATH
14
+ - OpenCV for opencv4nodejs
15
+
16
+ ## Engine usage
17
+
18
+ ```ts
19
+ import Motion3DChallenge from '@cv-challenge/server';
20
+
21
+ const engine = new Motion3DChallenge(180, 60, 3, 20);
22
+ const { videoBuffer, hitbox, debug } = await engine.generate();
23
+ const ok = engine.validate({ x: 42, y: 12 }, hitbox);
24
+ ```
25
+
26
+ Constructor defaults:
27
+
28
+ - width: 180
29
+ - height: 60
30
+ - durationSec: 3
31
+ - objectCount: 20 (capped at 20)
32
+
33
+ ## Express adapter
34
+
35
+ ```ts
36
+ import express from 'express';
37
+ import Motion3DChallenge, {
38
+ createChallengeExpressRouter,
39
+ createChallengeTokenManager
40
+ } from '@cv-challenge/server';
41
+
42
+ const app = express();
43
+ app.use(express.json({ limit: '1mb' }));
44
+
45
+ const engine = new Motion3DChallenge();
46
+ const tokenManager = createChallengeTokenManager<{ sessionId: string }>({
47
+ secret: process.env.CHALLENGE_JWT_SECRET ?? 'dev-only-change-me',
48
+ tokenTtlSec: 20,
49
+ successTokenTtlSec: 60
50
+ });
51
+
52
+ const router = createChallengeExpressRouter<{ sessionId: string }>({
53
+ challenge: engine,
54
+ tokenManager,
55
+ onVerified: async ({ req }) => {
56
+ const sessionId = String(req.headers['x-session-id'] ?? '');
57
+ if (!sessionId) return null;
58
+ return { expiresInSec: 60, payload: { sessionId } };
59
+ },
60
+ validateSuccessToken: (payload, { req }) => {
61
+ const sessionId = String(req.headers['x-session-id'] ?? '');
62
+ return payload.payload?.sessionId === sessionId;
63
+ },
64
+ debug: 'info'
65
+ });
66
+
67
+ app.use(router);
68
+ ```
69
+
70
+ ## Routes
71
+
72
+ `GET /challenge`
73
+
74
+ - Response: `video/webm`
75
+ - Headers:
76
+ - `X-Challenge-Token`
77
+ - `X-Challenge-Expires-At`
78
+ - `X-Challenge-Expires-In`
79
+ - Optional request header:
80
+ - `X-Challenge-Success-Token`
81
+
82
+ `POST /challenge/verify`
83
+
84
+ - Body: `{ token: string, x: number, y: number }`
85
+ - Response: `{ success, reload, successToken, successTokenExpiresAt, successTokenExpiresIn }`
86
+
87
+ ## Token behavior
88
+
89
+ - Challenge tokens are encrypted with the provided secret.
90
+ - Success tokens are encoded only (alg "none"), intended as a short-lived hint to skip cold start.
91
+ - Use `validateSuccessToken` to bind success tokens to your own session or user data.
92
+ - Success tokens are invalidated after 3 consecutive failed verifications tied to them.
93
+ - Failed verification blacklists the challenge token JTI until expiry.
94
+
95
+ ## API options
96
+
97
+ `createChallengeTokenManager(options)`
98
+
99
+ - `secret` (required): encryption key for challenge tokens.
100
+ - `tokenTtlSec` (default 20): challenge token lifetime.
101
+ - `successTokenTtlSec` (default 60): success token lifetime.
102
+ - Pass a generic type parameter to type the success token payload.
103
+
104
+ `createChallengeExpressRouter(options)`
105
+
106
+ - `challenge` (required): the engine instance.
107
+ - `tokenManager` (required): token manager from `createChallengeTokenManager`.
108
+ - `onVerified`: optional callback; return `undefined` for default success token, object to override TTL/payload, or `null` to skip.
109
+ - `validateSuccessToken`: optional validator for decoded success token payloads.
110
+ - `debug`: `"none"` | `"error"` | `"info"` (default `"none"`).
111
+ - Pass a matching generic type parameter to type `SuccessTokenPayload`.
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@cv-challenge/server",
3
+ "version": "1.0.0",
4
+ "description": "Server-side engine and Express adapter for the CV Challenge interactive verification flow.",
5
+ "keywords": [
6
+ "verification",
7
+ "challenge",
8
+ "express",
9
+ "opencv"
10
+ ],
11
+ "license": "ISC",
12
+ "type": "module",
13
+ "main": "dist/index.js",
14
+ "types": "dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "opencv4nodejs": {
25
+ "disableAutoBuild": 1
26
+ },
27
+ "dependencies": {
28
+ "express": "^5.2.1",
29
+ "fluent-ffmpeg": "^2.1.3",
30
+ "jose": "^5.9.3",
31
+ "opencv4nodejs": "^5.6.0",
32
+ "simplex-noise": "^4.0.3"
33
+ },
34
+ "devDependencies": {
35
+ "@types/express": "^5.0.3",
36
+ "@types/fluent-ffmpeg": "^2.1.25",
37
+ "@types/node": "^22.18.0",
38
+ "typescript": "^5.9.2"
39
+ },
40
+ "scripts": {
41
+ "build": "tsc -p tsconfig.json"
42
+ }
43
+ }