wiki-formant 0.9.4 → 0.10.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.
package/dist/rola.d.ts ADDED
@@ -0,0 +1,128 @@
1
+ export interface AuthSession {
2
+ userId: string;
3
+ radixAddress: string;
4
+ personaAddress?: string;
5
+ displayName?: string;
6
+ expiresAt: Date;
7
+ }
8
+ export interface SignedChallenge {
9
+ challenge: string;
10
+ address: string;
11
+ proof: {
12
+ publicKey: string;
13
+ signature: string;
14
+ curve: 'curve25519' | 'secp256k1';
15
+ };
16
+ }
17
+ /**
18
+ * The two Prisma delegates this needs, structurally. Both wikis' `Session` and
19
+ * `Challenge` models already satisfy it, so the binding is
20
+ * `{ session: prisma.session, challenge: prisma.challenge }`.
21
+ */
22
+ export interface RolaStore {
23
+ session: {
24
+ create(args: {
25
+ data: {
26
+ userId: string;
27
+ token: string;
28
+ expiresAt: Date;
29
+ };
30
+ }): Promise<unknown>;
31
+ findUnique(args: {
32
+ where: {
33
+ token: string;
34
+ };
35
+ }): Promise<{
36
+ id: string;
37
+ expiresAt: Date;
38
+ } | null>;
39
+ delete(args: {
40
+ where: {
41
+ id: string;
42
+ };
43
+ }): Promise<unknown>;
44
+ deleteMany(args: {
45
+ where: {
46
+ token: string;
47
+ };
48
+ }): Promise<unknown>;
49
+ };
50
+ challenge: {
51
+ create(args: {
52
+ data: {
53
+ challenge: string;
54
+ expiresAt: Date;
55
+ };
56
+ }): Promise<unknown>;
57
+ findUnique(args: {
58
+ where: {
59
+ challenge: string;
60
+ };
61
+ }): Promise<{
62
+ id: string;
63
+ expiresAt: Date;
64
+ } | null>;
65
+ delete(args: {
66
+ where: {
67
+ id: string;
68
+ };
69
+ }): Promise<unknown>;
70
+ };
71
+ }
72
+ /** What `await cookies()` already gives you, narrowed to what this uses. */
73
+ export interface CookieJar {
74
+ get(name: string): {
75
+ value: string;
76
+ } | undefined;
77
+ set(name: string, value: string, options: {
78
+ httpOnly: boolean;
79
+ secure: boolean;
80
+ sameSite: 'lax';
81
+ expires: Date;
82
+ path: string;
83
+ }): void;
84
+ delete(name: string): void;
85
+ }
86
+ export interface RolaAuthConfig {
87
+ /** This wiki's session cookie. The one thing the two copies actually differed in. */
88
+ cookieName: string;
89
+ jwtSecret: Uint8Array;
90
+ store: RolaStore;
91
+ cookies: () => Promise<CookieJar>;
92
+ rola: {
93
+ expectedOrigin: string;
94
+ dAppDefinitionAddress: string;
95
+ networkId: number;
96
+ applicationName: string;
97
+ };
98
+ sessionDurationMs?: number;
99
+ challengeTtlSec?: number;
100
+ /** Defaults to `process.env.NODE_ENV === 'production'`. */
101
+ secureCookies?: boolean;
102
+ }
103
+ /**
104
+ * A wallet address tells you which proof type it is, and getting it wrong is a
105
+ * silent rejection: the ROLA library verifies an `identity_*` proof only under
106
+ * `type: 'persona'`. One of the two copies this replaces hardcoded `'account'`
107
+ * and so could never accept a persona login at all.
108
+ */
109
+ export declare function proofType(address: string): 'account' | 'persona' | null;
110
+ export interface RolaAuth {
111
+ createSession(userId: string, radixAddress: string, personaAddress?: string, displayName?: string): Promise<string>;
112
+ getSession(request?: {
113
+ headers: {
114
+ get(name: string): string | null;
115
+ };
116
+ }): Promise<AuthSession | null>;
117
+ destroySession(): Promise<void>;
118
+ generateChallenge(): Promise<{
119
+ challenge: string;
120
+ expiresAt: Date;
121
+ }>;
122
+ verifySignedChallenge(signed: SignedChallenge): Promise<{
123
+ isValid: boolean;
124
+ error?: string;
125
+ }>;
126
+ }
127
+ export declare function createRolaAuth(config: RolaAuthConfig): RolaAuth;
128
+ //# sourceMappingURL=rola.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rola.d.ts","sourceRoot":"","sources":["../src/rola.ts"],"names":[],"mappings":"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"}
package/dist/rola.js ADDED
@@ -0,0 +1,150 @@
1
+ // rola.ts — Radix On-Ledger Authentication: challenge, proof, session.
2
+ //
3
+ // Both Radix wikis had written this file, and the two copies were 94% identical
4
+ // — the whole difference was a cookie name, plus the half radix-wiki had learned
5
+ // since and miow had not: persona (identity_*) proofs, which miow rejected
6
+ // because it passed `type: 'account'` unconditionally, and the error logging
7
+ // that makes a failed verification diagnosable at all.
8
+ //
9
+ // This is radix-wiki's version, parameterised on the two things a second wiki
10
+ // actually differs in: the cookie name and its dApp identity.
11
+ //
12
+ // Storage and cookies are ports rather than imports. A Prisma client is
13
+ // generated per repo and cannot be shared, and taking `next/headers` here would
14
+ // bind the package to a framework it otherwise knows nothing about. Both ports
15
+ // are shaped so the caller passes what it already has — the delegate and the
16
+ // cookie jar — with no adapter to write.
17
+ //
18
+ // `jose` and `@radixdlt/rola` are optional peers: only a repo importing this
19
+ // subpath needs them installed.
20
+ import { SignJWT, jwtVerify } from 'jose';
21
+ import { Rola } from '@radixdlt/rola';
22
+ const DEFAULT_SESSION_MS = 7 * 24 * 60 * 60 * 1000;
23
+ const DEFAULT_CHALLENGE_TTL_SEC = 300;
24
+ const bytesToHex = (bytes) => Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
25
+ /**
26
+ * A wallet address tells you which proof type it is, and getting it wrong is a
27
+ * silent rejection: the ROLA library verifies an `identity_*` proof only under
28
+ * `type: 'persona'`. One of the two copies this replaces hardcoded `'account'`
29
+ * and so could never accept a persona login at all.
30
+ */
31
+ export function proofType(address) {
32
+ if (address.startsWith('account_'))
33
+ return 'account';
34
+ if (address.startsWith('identity_'))
35
+ return 'persona';
36
+ return null;
37
+ }
38
+ export function createRolaAuth(config) {
39
+ const { cookieName, jwtSecret, store, cookies, sessionDurationMs = DEFAULT_SESSION_MS, challengeTtlSec = DEFAULT_CHALLENGE_TTL_SEC, secureCookies = process.env.NODE_ENV === 'production', } = config;
40
+ const rola = Rola(config.rola);
41
+ async function verifyToken(token) {
42
+ try {
43
+ const { payload } = await jwtVerify(token, jwtSecret);
44
+ const session = await store.session.findUnique({ where: { token } });
45
+ if (!session || session.expiresAt < new Date()) {
46
+ if (session)
47
+ await store.session.delete({ where: { id: session.id } }).catch(() => { });
48
+ return null;
49
+ }
50
+ return {
51
+ userId: payload.userId,
52
+ radixAddress: payload.radixAddress,
53
+ personaAddress: payload.personaAddress,
54
+ displayName: payload.displayName,
55
+ expiresAt: new Date(payload.exp * 1000),
56
+ };
57
+ }
58
+ catch {
59
+ return null;
60
+ }
61
+ }
62
+ /** Consumes the challenge: a replayed one must not verify twice. */
63
+ async function validateChallenge(challenge) {
64
+ const stored = await store.challenge.findUnique({ where: { challenge } });
65
+ if (!stored || stored.expiresAt < new Date()) {
66
+ if (stored)
67
+ await store.challenge.delete({ where: { id: stored.id } });
68
+ return false;
69
+ }
70
+ await store.challenge.delete({ where: { id: stored.id } });
71
+ return true;
72
+ }
73
+ return {
74
+ async createSession(userId, radixAddress, personaAddress, displayName) {
75
+ const expiresAt = new Date(Date.now() + sessionDurationMs);
76
+ const token = await new SignJWT({ userId, radixAddress, personaAddress, displayName })
77
+ .setProtectedHeader({ alg: 'HS256' })
78
+ .setIssuedAt()
79
+ .setExpirationTime(expiresAt)
80
+ .setJti(crypto.randomUUID())
81
+ .sign(jwtSecret);
82
+ await store.session.create({ data: { userId, token, expiresAt } });
83
+ const jar = await cookies();
84
+ jar.set(cookieName, token, {
85
+ httpOnly: true,
86
+ secure: secureCookies,
87
+ sameSite: 'lax',
88
+ expires: expiresAt,
89
+ path: '/',
90
+ });
91
+ return token;
92
+ },
93
+ async getSession(request) {
94
+ const jar = await cookies();
95
+ const cookieToken = jar.get(cookieName)?.value;
96
+ if (cookieToken) {
97
+ const session = await verifyToken(cookieToken);
98
+ if (session)
99
+ return session;
100
+ }
101
+ // Agents authenticate per-request with a Bearer token rather than a
102
+ // cookie, so the header is a second, equal route in — not a fallback.
103
+ if (request) {
104
+ const authHeader = request.headers.get('Authorization');
105
+ const bearerToken = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null;
106
+ if (bearerToken)
107
+ return verifyToken(bearerToken);
108
+ }
109
+ return null;
110
+ },
111
+ async destroySession() {
112
+ const jar = await cookies();
113
+ const token = jar.get(cookieName)?.value;
114
+ if (token)
115
+ await store.session.deleteMany({ where: { token } });
116
+ jar.delete(cookieName);
117
+ },
118
+ async generateChallenge() {
119
+ const array = new Uint8Array(32);
120
+ crypto.getRandomValues(array);
121
+ const challenge = bytesToHex(array);
122
+ const expiresAt = new Date(Date.now() + challengeTtlSec * 1000);
123
+ await store.challenge.create({ data: { challenge, expiresAt } });
124
+ return { challenge, expiresAt };
125
+ },
126
+ async verifySignedChallenge(signedChallenge) {
127
+ try {
128
+ if (!(await validateChallenge(signedChallenge.challenge))) {
129
+ console.error('ROLA: challenge validation failed', signedChallenge.challenge.slice(0, 16) + '...');
130
+ return { isValid: false, error: 'Invalid or expired challenge' };
131
+ }
132
+ const type = proofType(signedChallenge.address);
133
+ if (!type) {
134
+ throw new Error(`ROLA: unrecognized address prefix (expected account_* or identity_*): ${signedChallenge.address}`);
135
+ }
136
+ const result = await rola.verifySignedChallenge({ ...signedChallenge, type });
137
+ if (result.isErr()) {
138
+ console.error('ROLA: verification failed', result.error.reason, result.error);
139
+ return { isValid: false, error: result.error.reason };
140
+ }
141
+ return { isValid: true };
142
+ }
143
+ catch (error) {
144
+ console.error('ROLA verification error:', error);
145
+ return { isValid: false, error: 'Verification failed' };
146
+ }
147
+ },
148
+ };
149
+ }
150
+ //# sourceMappingURL=rola.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rola.js","sourceRoot":"","sources":["../src/rola.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wiki-formant",
3
- "version": "0.9.4",
3
+ "version": "0.10.0",
4
4
  "description": "The portable half of a wiki: derived taxonomy with pressable facet controls, a spec-correct MCP transport, markdown twins, block rendering, link normalisation, freshness, rate limiting, a collapsible sidebar, typeahead and hover-preview hooks, editor nodes, server-side analytics for both the agent and human lanes, and the conditional-GET plumbing agent surfaces need.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -135,6 +135,10 @@
135
135
  "./tiptap": {
136
136
  "types": "./dist/tiptap.d.ts",
137
137
  "import": "./dist/tiptap.js"
138
+ },
139
+ "./rola": {
140
+ "types": "./dist/rola.d.ts",
141
+ "import": "./dist/rola.js"
138
142
  }
139
143
  },
140
144
  "files": [
@@ -149,6 +153,7 @@
149
153
  "prepublishOnly": "npm run build && node --test 'test/*.test.js'"
150
154
  },
151
155
  "devDependencies": {
156
+ "@radixdlt/rola": "^2.1.0",
152
157
  "@tiptap/core": "^2.10.0",
153
158
  "@tiptap/extension-code-block": "^2.10.0",
154
159
  "@tiptap/extension-youtube": "^2.10.0",
@@ -156,15 +161,18 @@
156
161
  "@tiptap/react": "^2.10.0",
157
162
  "@types/node": "^22.0.0",
158
163
  "@types/react": "^19.0.0",
164
+ "jose": "^6.2.10",
159
165
  "react": "^19.2.4",
160
166
  "typescript": "^5.9.0"
161
167
  },
162
168
  "peerDependencies": {
163
- "react": ">=18",
164
169
  "@tiptap/core": ">=2.10",
165
- "@tiptap/react": ">=2.10",
170
+ "@tiptap/extension-code-block": ">=2.10",
166
171
  "@tiptap/extension-youtube": ">=2.10",
167
- "@tiptap/extension-code-block": ">=2.10"
172
+ "@tiptap/react": ">=2.10",
173
+ "react": ">=18",
174
+ "jose": ">=5",
175
+ "@radixdlt/rola": ">=2"
168
176
  },
169
177
  "peerDependenciesMeta": {
170
178
  "react": {
@@ -181,6 +189,12 @@
181
189
  },
182
190
  "@tiptap/extension-code-block": {
183
191
  "optional": true
192
+ },
193
+ "jose": {
194
+ "optional": true
195
+ },
196
+ "@radixdlt/rola": {
197
+ "optional": true
184
198
  }
185
199
  }
186
200
  }