@nawa-captcha/server 0.0.0-stage → 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.
- package/README.md +65 -2
- package/dist/binding.d.ts +22 -0
- package/dist/binding.d.ts.map +1 -0
- package/dist/binding.js +46 -0
- package/dist/binding.js.map +1 -0
- package/dist/catalog.d.ts +12 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +42 -0
- package/dist/catalog.js.map +1 -0
- package/dist/crypto.d.ts +44 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +108 -0
- package/dist/crypto.js.map +1 -0
- package/dist/engine.d.ts +245 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +407 -0
- package/dist/engine.js.map +1 -0
- package/dist/express.d.ts +47 -0
- package/dist/express.d.ts.map +1 -0
- package/dist/express.js +107 -0
- package/dist/express.js.map +1 -0
- package/dist/heuristics.d.ts +33 -0
- package/dist/heuristics.d.ts.map +1 -0
- package/dist/heuristics.js +152 -0
- package/dist/heuristics.js.map +1 -0
- package/dist/http.d.ts +51 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +70 -0
- package/dist/http.js.map +1 -0
- package/dist/i18n.d.ts +237 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +92 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/primitives.browser.d.ts +15 -0
- package/dist/primitives.browser.d.ts.map +1 -0
- package/dist/primitives.browser.js +328 -0
- package/dist/primitives.browser.js.map +1 -0
- package/dist/primitives.d.ts +17 -0
- package/dist/primitives.d.ts.map +1 -0
- package/dist/primitives.js +58 -0
- package/dist/primitives.js.map +1 -0
- package/dist/puzzles/accessible.d.ts +43 -0
- package/dist/puzzles/accessible.d.ts.map +1 -0
- package/dist/puzzles/accessible.js +317 -0
- package/dist/puzzles/accessible.js.map +1 -0
- package/dist/puzzles/audio.d.ts +42 -0
- package/dist/puzzles/audio.d.ts.map +1 -0
- package/dist/puzzles/audio.js +109 -0
- package/dist/puzzles/audio.js.map +1 -0
- package/dist/puzzles/biggest.d.ts +5 -0
- package/dist/puzzles/biggest.d.ts.map +1 -0
- package/dist/puzzles/biggest.js +40 -0
- package/dist/puzzles/biggest.js.map +1 -0
- package/dist/puzzles/clock.d.ts +8 -0
- package/dist/puzzles/clock.d.ts.map +1 -0
- package/dist/puzzles/clock.js +68 -0
- package/dist/puzzles/clock.js.map +1 -0
- package/dist/puzzles/color-name.d.ts +5 -0
- package/dist/puzzles/color-name.d.ts.map +1 -0
- package/dist/puzzles/color-name.js +73 -0
- package/dist/puzzles/color-name.js.map +1 -0
- package/dist/puzzles/common.d.ts +75 -0
- package/dist/puzzles/common.d.ts.map +1 -0
- package/dist/puzzles/common.js +268 -0
- package/dist/puzzles/common.js.map +1 -0
- package/dist/puzzles/count.d.ts +8 -0
- package/dist/puzzles/count.d.ts.map +1 -0
- package/dist/puzzles/count.js +38 -0
- package/dist/puzzles/count.js.map +1 -0
- package/dist/puzzles/dice.d.ts +8 -0
- package/dist/puzzles/dice.d.ts.map +1 -0
- package/dist/puzzles/dice.js +61 -0
- package/dist/puzzles/dice.js.map +1 -0
- package/dist/puzzles/find-shape.d.ts +8 -0
- package/dist/puzzles/find-shape.d.ts.map +1 -0
- package/dist/puzzles/find-shape.js +45 -0
- package/dist/puzzles/find-shape.js.map +1 -0
- package/dist/puzzles/grid.d.ts +44 -0
- package/dist/puzzles/grid.d.ts.map +1 -0
- package/dist/puzzles/grid.js +33 -0
- package/dist/puzzles/grid.js.map +1 -0
- package/dist/puzzles/hold.d.ts +24 -0
- package/dist/puzzles/hold.d.ts.map +1 -0
- package/dist/puzzles/hold.js +68 -0
- package/dist/puzzles/hold.js.map +1 -0
- package/dist/puzzles/icons-objects.d.ts +3 -0
- package/dist/puzzles/icons-objects.d.ts.map +1 -0
- package/dist/puzzles/icons-objects.js +5 -0
- package/dist/puzzles/icons-objects.js.map +1 -0
- package/dist/puzzles/icons-weather.d.ts +3 -0
- package/dist/puzzles/icons-weather.d.ts.map +1 -0
- package/dist/puzzles/icons-weather.js +5 -0
- package/dist/puzzles/icons-weather.js.map +1 -0
- package/dist/puzzles/icons.d.ts +14 -0
- package/dist/puzzles/icons.d.ts.map +1 -0
- package/dist/puzzles/icons.js +49 -0
- package/dist/puzzles/icons.js.map +1 -0
- package/dist/puzzles/index.d.ts +63 -0
- package/dist/puzzles/index.d.ts.map +1 -0
- package/dist/puzzles/index.js +93 -0
- package/dist/puzzles/index.js.map +1 -0
- package/dist/puzzles/jigsaw.d.ts +22 -0
- package/dist/puzzles/jigsaw.d.ts.map +1 -0
- package/dist/puzzles/jigsaw.js +38 -0
- package/dist/puzzles/jigsaw.js.map +1 -0
- package/dist/puzzles/math-compare.d.ts +8 -0
- package/dist/puzzles/math-compare.d.ts.map +1 -0
- package/dist/puzzles/math-compare.js +47 -0
- package/dist/puzzles/math-compare.js.map +1 -0
- package/dist/puzzles/math.d.ts +16 -0
- package/dist/puzzles/math.d.ts.map +1 -0
- package/dist/puzzles/math.js +106 -0
- package/dist/puzzles/math.js.map +1 -0
- package/dist/puzzles/maze.d.ts +18 -0
- package/dist/puzzles/maze.d.ts.map +1 -0
- package/dist/puzzles/maze.js +138 -0
- package/dist/puzzles/maze.js.map +1 -0
- package/dist/puzzles/odd-one-out.d.ts +5 -0
- package/dist/puzzles/odd-one-out.d.ts.map +1 -0
- package/dist/puzzles/odd-one-out.js +36 -0
- package/dist/puzzles/odd-one-out.js.map +1 -0
- package/dist/puzzles/odd-rotation.d.ts +8 -0
- package/dist/puzzles/odd-rotation.d.ts.map +1 -0
- package/dist/puzzles/odd-rotation.js +48 -0
- package/dist/puzzles/odd-rotation.js.map +1 -0
- package/dist/puzzles/order-numbers.d.ts +5 -0
- package/dist/puzzles/order-numbers.d.ts.map +1 -0
- package/dist/puzzles/order-numbers.js +32 -0
- package/dist/puzzles/order-numbers.js.map +1 -0
- package/dist/puzzles/order-size.d.ts +5 -0
- package/dist/puzzles/order-size.d.ts.map +1 -0
- package/dist/puzzles/order-size.js +30 -0
- package/dist/puzzles/order-size.js.map +1 -0
- package/dist/puzzles/order-time.d.ts +5 -0
- package/dist/puzzles/order-time.d.ts.map +1 -0
- package/dist/puzzles/order-time.js +27 -0
- package/dist/puzzles/order-time.js.map +1 -0
- package/dist/puzzles/order.d.ts +30 -0
- package/dist/puzzles/order.d.ts.map +1 -0
- package/dist/puzzles/order.js +61 -0
- package/dist/puzzles/order.js.map +1 -0
- package/dist/puzzles/pairs.d.ts +15 -0
- package/dist/puzzles/pairs.d.ts.map +1 -0
- package/dist/puzzles/pairs.js +63 -0
- package/dist/puzzles/pairs.js.map +1 -0
- package/dist/puzzles/pattern.d.ts +8 -0
- package/dist/puzzles/pattern.d.ts.map +1 -0
- package/dist/puzzles/pattern.js +68 -0
- package/dist/puzzles/pattern.js.map +1 -0
- package/dist/puzzles/pow.d.ts +23 -0
- package/dist/puzzles/pow.d.ts.map +1 -0
- package/dist/puzzles/pow.js +52 -0
- package/dist/puzzles/pow.js.map +1 -0
- package/dist/puzzles/rotate-match.d.ts +8 -0
- package/dist/puzzles/rotate-match.d.ts.map +1 -0
- package/dist/puzzles/rotate-match.js +34 -0
- package/dist/puzzles/rotate-match.js.map +1 -0
- package/dist/puzzles/rotate-object.d.ts +5 -0
- package/dist/puzzles/rotate-object.d.ts.map +1 -0
- package/dist/puzzles/rotate-object.js +33 -0
- package/dist/puzzles/rotate-object.js.map +1 -0
- package/dist/puzzles/rotate.d.ts +24 -0
- package/dist/puzzles/rotate.d.ts.map +1 -0
- package/dist/puzzles/rotate.js +40 -0
- package/dist/puzzles/rotate.js.map +1 -0
- package/dist/puzzles/shadow-drag.d.ts +20 -0
- package/dist/puzzles/shadow-drag.d.ts.map +1 -0
- package/dist/puzzles/shadow-drag.js +64 -0
- package/dist/puzzles/shadow-drag.js.map +1 -0
- package/dist/puzzles/shadow-pick.d.ts +5 -0
- package/dist/puzzles/shadow-pick.d.ts.map +1 -0
- package/dist/puzzles/shadow-pick.js +38 -0
- package/dist/puzzles/shadow-pick.js.map +1 -0
- package/dist/puzzles/slide-unlock.d.ts +11 -0
- package/dist/puzzles/slide-unlock.d.ts.map +1 -0
- package/dist/puzzles/slide-unlock.js +79 -0
- package/dist/puzzles/slide-unlock.js.map +1 -0
- package/dist/puzzles/slider.d.ts +23 -0
- package/dist/puzzles/slider.d.ts.map +1 -0
- package/dist/puzzles/slider.js +74 -0
- package/dist/puzzles/slider.js.map +1 -0
- package/dist/puzzles/spell.d.ts +8 -0
- package/dist/puzzles/spell.d.ts.map +1 -0
- package/dist/puzzles/spell.js +41 -0
- package/dist/puzzles/spell.js.map +1 -0
- package/dist/puzzles/story.d.ts +5 -0
- package/dist/puzzles/story.d.ts.map +1 -0
- package/dist/puzzles/story.js +101 -0
- package/dist/puzzles/story.js.map +1 -0
- package/dist/puzzles/symmetry.d.ts +8 -0
- package/dist/puzzles/symmetry.d.ts.map +1 -0
- package/dist/puzzles/symmetry.js +49 -0
- package/dist/puzzles/symmetry.js.map +1 -0
- package/dist/puzzles/tap-order.d.ts +20 -0
- package/dist/puzzles/tap-order.d.ts.map +1 -0
- package/dist/puzzles/tap-order.js +37 -0
- package/dist/puzzles/tap-order.js.map +1 -0
- package/dist/puzzles/trace-letters.d.ts +5 -0
- package/dist/puzzles/trace-letters.d.ts.map +1 -0
- package/dist/puzzles/trace-letters.js +19 -0
- package/dist/puzzles/trace-letters.js.map +1 -0
- package/dist/puzzles/trace.d.ts +32 -0
- package/dist/puzzles/trace.d.ts.map +1 -0
- package/dist/puzzles/trace.js +81 -0
- package/dist/puzzles/trace.js.map +1 -0
- package/dist/render/audio.d.ts +53 -0
- package/dist/render/audio.d.ts.map +1 -0
- package/dist/render/audio.js +236 -0
- package/dist/render/audio.js.map +1 -0
- package/dist/render/clock.d.ts +6 -0
- package/dist/render/clock.d.ts.map +1 -0
- package/dist/render/clock.js +23 -0
- package/dist/render/clock.js.map +1 -0
- package/dist/render/glyphs.d.ts +18 -0
- package/dist/render/glyphs.d.ts.map +1 -0
- package/dist/render/glyphs.js +70 -0
- package/dist/render/glyphs.js.map +1 -0
- package/dist/render/pictograms.d.ts +60 -0
- package/dist/render/pictograms.d.ts.map +1 -0
- package/dist/render/pictograms.js +167 -0
- package/dist/render/pictograms.js.map +1 -0
- package/dist/render/png.d.ts +11 -0
- package/dist/render/png.d.ts.map +1 -0
- package/dist/render/png.js +107 -0
- package/dist/render/png.js.map +1 -0
- package/dist/render/raster.d.ts +61 -0
- package/dist/render/raster.d.ts.map +1 -0
- package/dist/render/raster.js +389 -0
- package/dist/render/raster.js.map +1 -0
- package/dist/render/shapes.d.ts +25 -0
- package/dist/render/shapes.d.ts.map +1 -0
- package/dist/render/shapes.js +157 -0
- package/dist/render/shapes.js.map +1 -0
- package/dist/rng.d.ts +25 -0
- package/dist/rng.d.ts.map +1 -0
- package/dist/rng.js +93 -0
- package/dist/rng.js.map +1 -0
- package/dist/selection.d.ts +54 -0
- package/dist/selection.d.ts.map +1 -0
- package/dist/selection.js +85 -0
- package/dist/selection.js.map +1 -0
- package/dist/store.d.ts +66 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +100 -0
- package/dist/store.js.map +1 -0
- package/dist/tokens.d.ts +70 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +103 -0
- package/dist/tokens.js.map +1 -0
- package/dist/types.d.ts +62 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +61 -0
- package/dist/types.js.map +1 -0
- package/package.json +68 -4
package/dist/tokens.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { BIND_MODES } from './binding.js';
|
|
2
|
+
import { b64url, fromB64url, fromUtf8, hmac, isValidKid, open, safeEqual, seal, utf8 } from './crypto.js';
|
|
3
|
+
export const CHALLENGE_PREFIX = 'ngc1';
|
|
4
|
+
export const PASS_PREFIX = 'ngp1';
|
|
5
|
+
/** Upper bound for anything that claims to be a token; checked before any parsing. */
|
|
6
|
+
export const MAX_TOKEN_LENGTH = 8192;
|
|
7
|
+
// ------------------------------------------------------------------ challenge tokens
|
|
8
|
+
export function sealChallenge(keys, claims) {
|
|
9
|
+
const kid = keys.activeKid;
|
|
10
|
+
const key = keys.key(kid, 'challenge-token');
|
|
11
|
+
if (!key)
|
|
12
|
+
throw new Error('nawa-captcha: active key missing');
|
|
13
|
+
const aad = `${CHALLENGE_PREFIX}.${kid}`;
|
|
14
|
+
const { iv, data } = seal(key, JSON.stringify(claims), aad);
|
|
15
|
+
return `${aad}.${b64url(iv)}.${b64url(data)}`;
|
|
16
|
+
}
|
|
17
|
+
export function openChallenge(keys, token) {
|
|
18
|
+
if (typeof token !== 'string' || token.length > MAX_TOKEN_LENGTH)
|
|
19
|
+
return undefined;
|
|
20
|
+
const parts = token.split('.');
|
|
21
|
+
if (parts.length !== 4)
|
|
22
|
+
return undefined;
|
|
23
|
+
const [prefix, kid, ivText, dataText] = parts;
|
|
24
|
+
if (prefix !== CHALLENGE_PREFIX || !isValidKid(kid))
|
|
25
|
+
return undefined;
|
|
26
|
+
const key = keys.key(kid, 'challenge-token');
|
|
27
|
+
const iv = fromB64url(ivText);
|
|
28
|
+
const data = fromB64url(dataText);
|
|
29
|
+
if (!key || !iv || !data)
|
|
30
|
+
return undefined;
|
|
31
|
+
const json = open(key, iv, data, `${prefix}.${kid}`);
|
|
32
|
+
if (json === undefined)
|
|
33
|
+
return undefined;
|
|
34
|
+
try {
|
|
35
|
+
const claims = JSON.parse(json);
|
|
36
|
+
return claims && claims.v === 1 && typeof claims.id === 'string' ? { claims, kid } : undefined;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// ------------------------------------------------------------------ pass tokens
|
|
43
|
+
/**
|
|
44
|
+
* Format (documented in README and mirrored by the .NET verifier):
|
|
45
|
+
* ngp1.<kid>.<base64url(JSON claims)>.<base64url(HMAC-SHA256(K_pass, "ngp1.<kid>.<payload>"))>
|
|
46
|
+
*/
|
|
47
|
+
export function signPassToken(keys, claims) {
|
|
48
|
+
const kid = keys.activeKid;
|
|
49
|
+
const key = keys.key(kid, 'pass-token');
|
|
50
|
+
if (!key)
|
|
51
|
+
throw new Error('nawa-captcha: active key missing');
|
|
52
|
+
const head = `${PASS_PREFIX}.${kid}.${b64url(utf8(JSON.stringify(claims)))}`;
|
|
53
|
+
return `${head}.${b64url(hmac(key, head))}`;
|
|
54
|
+
}
|
|
55
|
+
export function parsePassToken(keys, token) {
|
|
56
|
+
if (typeof token !== 'string' || token.length === 0 || token.length > MAX_TOKEN_LENGTH)
|
|
57
|
+
return { ok: false, error: 'malformed' };
|
|
58
|
+
const parts = token.split('.');
|
|
59
|
+
if (parts.length !== 4)
|
|
60
|
+
return { ok: false, error: 'malformed' };
|
|
61
|
+
const [prefix, kid, payload, sig] = parts;
|
|
62
|
+
if (prefix !== PASS_PREFIX || !isValidKid(kid))
|
|
63
|
+
return { ok: false, error: 'malformed' };
|
|
64
|
+
const key = keys.key(kid, 'pass-token');
|
|
65
|
+
if (!key)
|
|
66
|
+
return { ok: false, error: 'unknown-key' };
|
|
67
|
+
const sigBytes = fromB64url(sig);
|
|
68
|
+
if (!sigBytes || !fromB64url(payload))
|
|
69
|
+
return { ok: false, error: 'malformed' };
|
|
70
|
+
// Signature first: nothing inside the payload is trusted (or even parsed) before it verifies.
|
|
71
|
+
if (!safeEqual(sigBytes, hmac(key, `${prefix}.${kid}.${payload}`)))
|
|
72
|
+
return { ok: false, error: 'bad-signature' };
|
|
73
|
+
try {
|
|
74
|
+
const text = fromUtf8(fromB64url(payload));
|
|
75
|
+
if (text === undefined)
|
|
76
|
+
return { ok: false, error: 'malformed' };
|
|
77
|
+
const claims = JSON.parse(text);
|
|
78
|
+
if (!isPassClaims(claims))
|
|
79
|
+
return { ok: false, error: 'malformed' };
|
|
80
|
+
return { ok: true, claims, kid };
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return { ok: false, error: 'malformed' };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function isPassClaims(c) {
|
|
87
|
+
if (!c || typeof c !== 'object')
|
|
88
|
+
return false;
|
|
89
|
+
const o = c;
|
|
90
|
+
return (o['v'] === 1 &&
|
|
91
|
+
typeof o['jti'] === 'string' &&
|
|
92
|
+
typeof o['sk'] === 'string' &&
|
|
93
|
+
typeof o['act'] === 'string' &&
|
|
94
|
+
typeof o['typ'] === 'string' &&
|
|
95
|
+
Number.isInteger(o['iat']) &&
|
|
96
|
+
Number.isInteger(o['exp']) &&
|
|
97
|
+
Number.isInteger(o['lvl']) &&
|
|
98
|
+
typeof o['cbm'] === 'string' &&
|
|
99
|
+
BIND_MODES.includes(o['cbm']) &&
|
|
100
|
+
(o['cb'] === undefined || typeof o['cb'] === 'string') &&
|
|
101
|
+
(o['stp'] === undefined || (Array.isArray(o['stp']) && o['stp'].length >= 1 && o['stp'].length <= 5 && o['stp'].every((t) => typeof t === 'string'))));
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { Rng } from './rng.js';
|
|
2
|
+
/**
|
|
3
|
+
* Every challenge type, grouped by what the person does. Each type lives in its own module under
|
|
4
|
+
* `src/puzzles/` and is rendered by one of the widget's generic views (see {@link ViewKind}).
|
|
5
|
+
*/
|
|
6
|
+
export declare const CHALLENGE_TYPES: readonly ["slider", "slide-unlock", "shadow-drag", "jigsaw", "rotate", "rotate-object", "rotate-match", "hold", "icons", "icons-weather", "icons-objects", "odd-one-out", "odd-rotation", "color-name", "biggest", "find-shape", "shadow-pick", "pattern", "clock", "math-compare", "symmetry", "pairs", "tap-order", "spell", "order", "order-size", "order-numbers", "order-time", "story", "trace", "trace-letters", "maze", "math", "count", "dice", "pow", "accessible", "audio"];
|
|
7
|
+
export type ChallengeType = (typeof CHALLENGE_TYPES)[number];
|
|
8
|
+
/**
|
|
9
|
+
* The widget view that renders a type. Views are generic interaction patterns; the public data
|
|
10
|
+
* of each view is documented next to the puzzles that use it.
|
|
11
|
+
*/
|
|
12
|
+
export declare const VIEW_KINDS: readonly ["slide", "drag", "rotate", "swap", "hold", "grid", "pairs", "taps", "order", "path", "text", "pow", "accessible", "audio"];
|
|
13
|
+
export type ViewKind = (typeof VIEW_KINDS)[number];
|
|
14
|
+
export declare const LANGS: readonly ["ar", "en"];
|
|
15
|
+
export type Lang = (typeof LANGS)[number];
|
|
16
|
+
/** A pointer/keyboard sample in image coordinates: [x, y, msSinceStart]. */
|
|
17
|
+
export type TracePoint = readonly [x: number, y: number, t: number];
|
|
18
|
+
export type InputMode = 'mouse' | 'touch' | 'pen' | 'keyboard';
|
|
19
|
+
export interface Interaction {
|
|
20
|
+
readonly mode: InputMode;
|
|
21
|
+
readonly trail: readonly TracePoint[];
|
|
22
|
+
}
|
|
23
|
+
export interface GenerateContext {
|
|
24
|
+
readonly level: number;
|
|
25
|
+
readonly lang: Lang;
|
|
26
|
+
/** Randomness source. The engine always passes a CSPRNG; tests may pass a seeded one. */
|
|
27
|
+
readonly rng: Rng;
|
|
28
|
+
}
|
|
29
|
+
export interface Generated<Sol, Pub> {
|
|
30
|
+
readonly solution: Sol;
|
|
31
|
+
readonly publicData: Pub;
|
|
32
|
+
readonly prompt: string;
|
|
33
|
+
}
|
|
34
|
+
export interface CheckContext {
|
|
35
|
+
readonly level: number;
|
|
36
|
+
/** Server-measured ms between issue and verification (from the sealed `iat`). */
|
|
37
|
+
readonly elapsedMs: number;
|
|
38
|
+
}
|
|
39
|
+
export type CheckFailure = 'invalid-answer' | 'wrong-answer' | 'bot-suspected';
|
|
40
|
+
export type CheckResult = {
|
|
41
|
+
readonly ok: true;
|
|
42
|
+
} | {
|
|
43
|
+
readonly ok: false;
|
|
44
|
+
readonly reason: CheckFailure;
|
|
45
|
+
readonly detail?: string;
|
|
46
|
+
};
|
|
47
|
+
export interface PuzzleDefinition<Sol = unknown, Pub = unknown> {
|
|
48
|
+
readonly type: ChallengeType;
|
|
49
|
+
/** Which widget view renders it. */
|
|
50
|
+
readonly view: ViewKind;
|
|
51
|
+
/** Verification is refused if answered sooner than this after issue. */
|
|
52
|
+
readonly minSolveMs: number;
|
|
53
|
+
/** Wrong answers allowed on one challenge before it is burned. */
|
|
54
|
+
readonly maxAttempts: number;
|
|
55
|
+
generate(ctx: GenerateContext): Generated<Sol, Pub>;
|
|
56
|
+
/** Validates the untrusted answer shape AND checks it against the sealed solution. */
|
|
57
|
+
check(solution: Sol, answer: unknown, ctx: CheckContext): CheckResult;
|
|
58
|
+
}
|
|
59
|
+
export declare const ok: CheckResult;
|
|
60
|
+
export declare const invalid: (detail?: string) => CheckResult;
|
|
61
|
+
export declare const wrong: (detail?: string) => CheckResult;
|
|
62
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC;;;GAGG;AACH,eAAO,MAAM,eAAe,wdA8ClB,CAAC;AACX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D;;;GAGG;AACH,eAAO,MAAM,UAAU,sIAAuI,CAAC;AAC/J,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD,eAAO,MAAM,KAAK,uBAAwB,CAAC;AAC3C,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1C,4EAA4E;AAC5E,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;AAEpE,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,UAAU,CAAC;AAE/D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,yFAAyF;IACzF,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;CACnB;AAED,MAAM,WAAW,SAAS,CAAC,GAAG,EAAE,GAAG;IACjC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,cAAc,GAAG,eAAe,CAAC;AAE/E,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAElI,MAAM,WAAW,gBAAgB,CAAC,GAAG,GAAG,OAAO,EAAE,GAAG,GAAG,OAAO;IAC5D,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,wEAAwE;IACxE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACpD,sFAAsF;IACtF,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,GAAG,WAAW,CAAC;CACvE;AAED,eAAO,MAAM,EAAE,EAAE,WAA0B,CAAC;AAC5C,eAAO,MAAM,OAAO,GAAI,SAAS,MAAM,KAAG,WAAuF,CAAC;AAClI,eAAO,MAAM,KAAK,GAAI,SAAS,MAAM,KAAG,WAAqF,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every challenge type, grouped by what the person does. Each type lives in its own module under
|
|
3
|
+
* `src/puzzles/` and is rendered by one of the widget's generic views (see {@link ViewKind}).
|
|
4
|
+
*/
|
|
5
|
+
export const CHALLENGE_TYPES = [
|
|
6
|
+
// drag, slide, rotate, hold
|
|
7
|
+
'slider',
|
|
8
|
+
'slide-unlock',
|
|
9
|
+
'shadow-drag',
|
|
10
|
+
'jigsaw',
|
|
11
|
+
'rotate',
|
|
12
|
+
'rotate-object',
|
|
13
|
+
'rotate-match',
|
|
14
|
+
'hold',
|
|
15
|
+
// select in a picture grid
|
|
16
|
+
'icons',
|
|
17
|
+
'icons-weather',
|
|
18
|
+
'icons-objects',
|
|
19
|
+
'odd-one-out',
|
|
20
|
+
'odd-rotation',
|
|
21
|
+
'color-name',
|
|
22
|
+
'biggest',
|
|
23
|
+
'find-shape',
|
|
24
|
+
'shadow-pick',
|
|
25
|
+
'pattern',
|
|
26
|
+
'clock',
|
|
27
|
+
'math-compare',
|
|
28
|
+
'symmetry',
|
|
29
|
+
'pairs',
|
|
30
|
+
// tap in order
|
|
31
|
+
'tap-order',
|
|
32
|
+
'spell',
|
|
33
|
+
// put in order
|
|
34
|
+
'order',
|
|
35
|
+
'order-size',
|
|
36
|
+
'order-numbers',
|
|
37
|
+
'order-time',
|
|
38
|
+
'story',
|
|
39
|
+
// draw a path
|
|
40
|
+
'trace',
|
|
41
|
+
'trace-letters',
|
|
42
|
+
'maze',
|
|
43
|
+
// type the answer
|
|
44
|
+
'math',
|
|
45
|
+
'count',
|
|
46
|
+
'dice',
|
|
47
|
+
// invisible / text alternative
|
|
48
|
+
'pow',
|
|
49
|
+
'accessible',
|
|
50
|
+
'audio',
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* The widget view that renders a type. Views are generic interaction patterns; the public data
|
|
54
|
+
* of each view is documented next to the puzzles that use it.
|
|
55
|
+
*/
|
|
56
|
+
export const VIEW_KINDS = ['slide', 'drag', 'rotate', 'swap', 'hold', 'grid', 'pairs', 'taps', 'order', 'path', 'text', 'pow', 'accessible', 'audio'];
|
|
57
|
+
export const LANGS = ['ar', 'en'];
|
|
58
|
+
export const ok = { ok: true };
|
|
59
|
+
export const invalid = (detail) => ({ ok: false, reason: 'invalid-answer', ...(detail ? { detail } : {}) });
|
|
60
|
+
export const wrong = (detail) => ({ ok: false, reason: 'wrong-answer', ...(detail ? { detail } : {}) });
|
|
61
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,4BAA4B;IAC5B,QAAQ;IACR,cAAc;IACd,aAAa;IACb,QAAQ;IACR,QAAQ;IACR,eAAe;IACf,cAAc;IACd,MAAM;IACN,2BAA2B;IAC3B,OAAO;IACP,eAAe;IACf,eAAe;IACf,aAAa;IACb,cAAc;IACd,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,aAAa;IACb,SAAS;IACT,OAAO;IACP,cAAc;IACd,UAAU;IACV,OAAO;IACP,eAAe;IACf,WAAW;IACX,OAAO;IACP,eAAe;IACf,OAAO;IACP,YAAY;IACZ,eAAe;IACf,YAAY;IACZ,OAAO;IACP,cAAc;IACd,OAAO;IACP,eAAe;IACf,MAAM;IACN,kBAAkB;IAClB,MAAM;IACN,OAAO;IACP,MAAM;IACN,+BAA+B;IAC/B,KAAK;IACL,YAAY;IACZ,OAAO;CACC,CAAC;AAGX;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,CAAU,CAAC;AAG/J,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE,IAAI,CAAU,CAAC;AAiD3C,MAAM,CAAC,MAAM,EAAE,GAAgB,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AAC5C,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAe,EAAe,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAClI,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,MAAe,EAAe,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,70 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nawa-captcha/server",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Nawa Captcha server: self-hosted, privacy-friendly puzzle CAPTCHA for Node.js. 37 challenge types you choose from, sealed answers, single-use pass tokens, multi-step chains, Express middleware. A reCAPTCHA / hCaptcha alternative with no third-party tracking.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./express": {
|
|
15
|
+
"types": "./dist/express.d.ts",
|
|
16
|
+
"import": "./dist/express.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc -p tsconfig.json",
|
|
29
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"nodejs",
|
|
33
|
+
"express",
|
|
34
|
+
"middleware",
|
|
35
|
+
"server",
|
|
36
|
+
"verification",
|
|
37
|
+
"captcha",
|
|
38
|
+
"recaptcha-alternative",
|
|
39
|
+
"hcaptcha-alternative",
|
|
40
|
+
"turnstile-alternative",
|
|
41
|
+
"self-hosted-captcha",
|
|
42
|
+
"accessible-captcha",
|
|
43
|
+
"puzzle-captcha",
|
|
44
|
+
"slider-captcha",
|
|
45
|
+
"privacy",
|
|
46
|
+
"gdpr",
|
|
47
|
+
"bot-protection",
|
|
48
|
+
"anti-spam",
|
|
49
|
+
"proof-of-work",
|
|
50
|
+
"nawa-captcha",
|
|
51
|
+
"pelagic-ui",
|
|
52
|
+
"arabic",
|
|
53
|
+
"rtl",
|
|
54
|
+
"accessibility"
|
|
55
|
+
],
|
|
56
|
+
"homepage": "https://oriebalzyuot96.github.io/nawa-captcha/",
|
|
57
|
+
"repository": {
|
|
58
|
+
"type": "git",
|
|
59
|
+
"url": "git+https://github.com/oriebalzyuot96/nawa-captcha.git",
|
|
60
|
+
"directory": "packages/server"
|
|
61
|
+
},
|
|
62
|
+
"bugs": "https://github.com/oriebalzyuot96/nawa-captcha/issues",
|
|
63
|
+
"author": "oriebalzyuot96",
|
|
64
|
+
"publishConfig": {
|
|
65
|
+
"access": "public"
|
|
66
|
+
},
|
|
67
|
+
"browser": {
|
|
68
|
+
"./dist/primitives.js": "./dist/primitives.browser.js"
|
|
69
|
+
}
|
|
70
|
+
}
|