@dollhousemcp/mcp-server 2.0.10 → 2.0.11

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 (36) hide show
  1. package/dist/auto-dollhouse/portDiscovery.d.ts +23 -0
  2. package/dist/auto-dollhouse/portDiscovery.d.ts.map +1 -0
  3. package/dist/auto-dollhouse/portDiscovery.js +77 -0
  4. package/dist/cli/console-token.d.ts +18 -0
  5. package/dist/cli/console-token.d.ts.map +1 -0
  6. package/dist/cli/console-token.js +187 -0
  7. package/dist/generated/version.d.ts +2 -2
  8. package/dist/generated/version.js +3 -3
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +24 -5
  11. package/dist/web/console/consoleToken.d.ts +403 -0
  12. package/dist/web/console/consoleToken.d.ts.map +1 -0
  13. package/dist/web/console/consoleToken.js +930 -0
  14. package/dist/web/middleware/authMiddleware.d.ts +64 -0
  15. package/dist/web/middleware/authMiddleware.d.ts.map +1 -0
  16. package/dist/web/middleware/authMiddleware.js +174 -0
  17. package/dist/web/routes/consoleRouteHelpers.d.ts +33 -0
  18. package/dist/web/routes/consoleRouteHelpers.d.ts.map +1 -0
  19. package/dist/web/routes/consoleRouteHelpers.js +60 -0
  20. package/dist/web/routes/tokenRoutes.d.ts +37 -0
  21. package/dist/web/routes/tokenRoutes.d.ts.map +1 -0
  22. package/dist/web/routes/tokenRoutes.js +95 -0
  23. package/dist/web/routes/totpRoutes.d.ts +45 -0
  24. package/dist/web/routes/totpRoutes.d.ts.map +1 -0
  25. package/dist/web/routes/totpRoutes.js +187 -0
  26. package/package.json +1 -1
  27. package/server.json +2 -2
  28. package/dist/constants/version.d.ts +0 -3
  29. package/dist/constants/version.d.ts.map +0 -1
  30. package/dist/constants/version.js +0 -4
  31. package/dist/logging/sinks/SSELogSink.d.ts +0 -35
  32. package/dist/logging/sinks/SSELogSink.d.ts.map +0 -1
  33. package/dist/logging/sinks/SSELogSink.js +0 -181
  34. package/dist/logging/viewer/viewerHtml.d.ts +0 -8
  35. package/dist/logging/viewer/viewerHtml.d.ts.map +0 -1
  36. package/dist/logging/viewer/viewerHtml.js +0 -204
@@ -0,0 +1,403 @@
1
+ /**
2
+ * Console session token storage and verification (#1780).
3
+ *
4
+ * Manages the file at `~/.dollhouse/run/console-token.auth.json` which
5
+ * holds the Bearer tokens that authenticate requests to the web console.
6
+ * The file is created on first leader election and persists across
7
+ * restarts — tokens only rotate when explicitly requested.
8
+ *
9
+ * The `.auth` filename suffix keeps this state isolated from any legacy
10
+ * no-authentication DollhouseMCP installation running on the same
11
+ * machine. The port, lock file, and token file all share the same
12
+ * isolation strategy — see `src/config/env.ts` for the port, and
13
+ * `LeaderElection.ts` for the lock file.
14
+ *
15
+ * Schema is forward-compatible with multi-device, multi-tenant, and
16
+ * scope-restricted tokens for Phase 2+. Phase 1 uses a single "console"
17
+ * kind token and stubs the scope/boundary checks.
18
+ *
19
+ * File format (version 1):
20
+ * ```json
21
+ * {
22
+ * "version": 1,
23
+ * "tokens": [
24
+ * {
25
+ * "id": "018e1a2b-...",
26
+ * "name": "Kermit on mick-MacBook-Pro",
27
+ * "kind": "console",
28
+ * "token": "<64-hex>",
29
+ * "scopes": ["admin"],
30
+ * "elementBoundaries": null,
31
+ * "tenant": null,
32
+ * "platform": "local",
33
+ * "labels": {},
34
+ * "createdAt": "2026-04-04T20:00:00.000Z",
35
+ * "lastUsedAt": null,
36
+ * "createdVia": "initial-setup"
37
+ * }
38
+ * ],
39
+ * "totp": { "enrolled": false, "secret": null, "backupCodes": [] }
40
+ * }
41
+ * ```
42
+ *
43
+ * @since v2.1.0 — Issue #1780
44
+ */
45
+ /**
46
+ * Default path to the authenticated console's token file.
47
+ *
48
+ * The `.auth` suffix isolates this from any legacy no-authentication
49
+ * DollhouseMCP installation that may also be running on the same
50
+ * machine. Legacy installs did not write a token file at all; the
51
+ * authenticated console writes `console-token.auth.json`. Combined with
52
+ * the port and lock-file separation, this gives the two generations of
53
+ * the console fully independent state trees under `~/.dollhouse/run/`.
54
+ *
55
+ * Callers can override via `DOLLHOUSE_CONSOLE_TOKEN_FILE` in the env.
56
+ */
57
+ declare const DEFAULT_TOKEN_FILE: string;
58
+ /** Current token file schema version. */
59
+ declare const TOKEN_FILE_VERSION: 1;
60
+ /**
61
+ * Element visibility boundary — Phase 3 enterprise feature.
62
+ * Phase 1 always stores `null`; the field exists so the schema is stable.
63
+ */
64
+ export interface ElementBoundary {
65
+ allowCategories?: string[];
66
+ denyCategories?: string[];
67
+ allowTypes?: string[];
68
+ denyTypes?: string[];
69
+ }
70
+ /**
71
+ * A single token entry in the console token file.
72
+ *
73
+ * Enterprise-ready fields (`scopes`, `elementBoundaries`, `tenant`, `platform`,
74
+ * `labels`) are present from Phase 1 but not enforced — the middleware treats
75
+ * every valid token as admin-scoped, single-tenant, all-elements for now.
76
+ * Phase 2+ flips enforcement on without requiring a schema migration.
77
+ */
78
+ export interface ConsoleTokenEntry {
79
+ /** Stable unique identifier for this token (UUID v4). */
80
+ id: string;
81
+ /** Human-readable name shown in the Security tab. */
82
+ name: string;
83
+ /** What kind of client this token is for. */
84
+ kind: 'console' | 'device' | 'automation';
85
+ /** The secret Bearer value. 64 hex chars (256 bits of entropy). */
86
+ token: string;
87
+ /** Scopes granted to this token. Phase 1 = always `["admin"]`. */
88
+ scopes: string[];
89
+ /** Element visibility restriction. Phase 1 = always `null`. */
90
+ elementBoundaries: ElementBoundary | null;
91
+ /** Tenant identifier for multi-tenant deployments. Phase 1 = always `null`. */
92
+ tenant: string | null;
93
+ /** Where this token is used. Phase 1 = always `"local"`. */
94
+ platform: string;
95
+ /** Opaque metadata for enterprise tooling. Phase 1 = always `{}`. */
96
+ labels: Record<string, string>;
97
+ /** ISO timestamp of token creation. */
98
+ createdAt: string;
99
+ /** ISO timestamp of most recent use, or null if never used. */
100
+ lastUsedAt: string | null;
101
+ /** How this token was created — "initial-setup", "pairing", "rotation", etc. */
102
+ createdVia: string;
103
+ }
104
+ /**
105
+ * TOTP enrollment state.
106
+ *
107
+ * Populated by Phase 2 (#1794). The `secret` field holds the base32-encoded
108
+ * RFC 6238 secret in plaintext — the surrounding file is 0600, which matches
109
+ * standard file-based TOTP storage practice (SSH keys, age identity files,
110
+ * 1Password vault backups). Encrypting the secret at rest with an OS keychain
111
+ * is a future enhancement.
112
+ *
113
+ * Backup codes are stored as **sha256 hex hashes**, never plaintext. The
114
+ * plaintext codes are shown to the user exactly once at enrollment confirm
115
+ * time. Each backup code is single-use: consuming one removes its hash from
116
+ * this array.
117
+ *
118
+ * `enrolledAt` is optional for backward compatibility with Phase 1 files,
119
+ * which were written with only `{enrolled, secret, backupCodes}`.
120
+ */
121
+ export interface TotpState {
122
+ enrolled: boolean;
123
+ secret: string | null;
124
+ backupCodes: string[];
125
+ enrolledAt?: string | null;
126
+ }
127
+ /**
128
+ * Public-safe view of TOTP state — never leaks secret material.
129
+ * Returned from the status endpoint and from store methods that need to
130
+ * report enrollment state to callers.
131
+ */
132
+ export interface TotpStatus {
133
+ enrolled: boolean;
134
+ enrolledAt: string | null;
135
+ backupCodesRemaining: number;
136
+ }
137
+ /**
138
+ * Result of `beginTotpEnrollment` — the caller needs all of these to show a
139
+ * QR code and manual-entry fallback in the UI. None of this is persisted;
140
+ * the pending state only lives in-memory until confirmed.
141
+ */
142
+ export interface TotpEnrollmentBegin {
143
+ pendingId: string;
144
+ /** Base32-encoded TOTP secret for manual entry (grouped display is caller's job). */
145
+ secret: string;
146
+ /** Full `otpauth://` URI for authenticator apps to import. */
147
+ otpauthUri: string;
148
+ /** Timestamp (ms since epoch) when this pending enrollment expires. */
149
+ expiresAt: number;
150
+ }
151
+ /**
152
+ * Result of `confirmTotpEnrollment` — the plaintext backup codes are
153
+ * returned to the caller exactly once, at this point, and then only their
154
+ * hashes are retained. The caller must display them to the user immediately
155
+ * and never log them.
156
+ */
157
+ export interface TotpEnrollmentConfirm {
158
+ backupCodes: string[];
159
+ enrolledAt: string;
160
+ }
161
+ /**
162
+ * Result of `rotatePrimary` — returned to the caller so they can update
163
+ * the browser token in-place and display the grace-window deadline.
164
+ */
165
+ export interface RotationResult {
166
+ /** The new 64-hex token value. The caller must treat this as a secret. */
167
+ token: string;
168
+ /** ISO timestamp of the rotation. */
169
+ rotatedAt: string;
170
+ /** ms-since-epoch deadline after which the old token stops verifying. */
171
+ graceUntil: number;
172
+ }
173
+ /**
174
+ * Typed error for TOTP store operations. Carries a machine-readable
175
+ * `code` field so the HTTP layer can map failures to consistent response
176
+ * codes without parsing free-form error messages. Callers (CLI, UI) can
177
+ * branch on `code` instead of the human-readable `message`.
178
+ */
179
+ export declare class TotpError extends Error {
180
+ readonly code: TotpErrorCode;
181
+ constructor(message: string, code: TotpErrorCode);
182
+ }
183
+ /** Discriminated set of TOTP failure reasons surfaced by the store. */
184
+ export type TotpErrorCode = 'ALREADY_ENROLLED' | 'NOT_ENROLLED' | 'PENDING_NOT_FOUND' | 'INVALID_TOTP_CODE' | 'STORE_NOT_INITIALIZED' | 'TOO_MANY_PENDING' | 'TOTP_REQUIRED';
185
+ /**
186
+ * The full on-disk token file structure.
187
+ */
188
+ export interface ConsoleTokenFile {
189
+ version: typeof TOKEN_FILE_VERSION;
190
+ tokens: ConsoleTokenEntry[];
191
+ totp: TotpState;
192
+ }
193
+ /**
194
+ * A safe-to-log view of a token entry — the secret `token` field is
195
+ * replaced with a masked preview so it never appears in logs or API responses.
196
+ */
197
+ export interface MaskedTokenEntry extends Omit<ConsoleTokenEntry, 'token'> {
198
+ tokenPreview: string;
199
+ }
200
+ /**
201
+ * Stateful store that owns the console token file and verifies presented tokens.
202
+ *
203
+ * Designed to live on the leader process. Followers should not construct this —
204
+ * they read the file directly via `readTokenFileRaw()` for their own HTTP calls.
205
+ */
206
+ export declare class ConsoleTokenStore {
207
+ private readonly filePath;
208
+ private data;
209
+ /**
210
+ * Pre-converted Buffer cache keyed by entry id. Populated whenever `this.data`
211
+ * is assigned (load, create, future rotation). Verify() reuses the stored
212
+ * buffers so the hot path doesn't re-allocate per-token on every request.
213
+ * Negligible win with 1 token today; meaningful with Phase 2 multi-token
214
+ * lookups. Not serialized — buffers are never written to disk.
215
+ */
216
+ private readonly tokenBuffers;
217
+ /**
218
+ * In-memory pending TOTP enrollments, keyed by opaque pendingId. Nothing
219
+ * lives on disk until confirmTotpEnrollment() succeeds, which limits the
220
+ * window in which a half-completed enrollment leaks a secret via file read.
221
+ * Entries expire after TOTP_PENDING_TTL_MS (#1794).
222
+ */
223
+ private readonly pendingEnrollments;
224
+ /**
225
+ * In-memory grace buffer for recently-rotated tokens (#1795). After a
226
+ * rotation, the old token value is stashed here with a per-rotation expiry
227
+ * so in-flight requests that were sent before the rotation response arrived
228
+ * still authenticate. Entries are per-rotation (concurrent rotations each
229
+ * get their own grace slot) and never persisted to disk.
230
+ */
231
+ private readonly graceEntries;
232
+ constructor(filePath?: string);
233
+ /**
234
+ * Rebuild the token buffer cache after a data load, create, or mutation.
235
+ * Keeps the hot verify() path allocation-free for the stored side.
236
+ */
237
+ private rebuildTokenBuffers;
238
+ /**
239
+ * Read the existing token file, or create a new one with a single initial
240
+ * token if none exists. Idempotent — safe to call on every leader election.
241
+ *
242
+ * @param puppetName - A puppet name picked by the caller (e.g. from SessionNames)
243
+ * used to build the default display name on first run.
244
+ * @returns The primary (first) token entry — convenient for server startup
245
+ * to inject into HTML and stamp on followers.
246
+ */
247
+ ensureInitialized(puppetName: string): Promise<ConsoleTokenEntry>;
248
+ /**
249
+ * Verify a presented Bearer token against the stored entries.
250
+ * Uses timing-safe comparison to prevent side-channel attacks.
251
+ *
252
+ * Updates `lastUsedAt` on the matched entry (in memory only; disk write
253
+ * is debounced to avoid disk thrash on every request — Phase 2 feature).
254
+ *
255
+ * @returns The matching entry, or null if no match.
256
+ */
257
+ verify(presented: string): ConsoleTokenEntry | null;
258
+ /**
259
+ * Get the primary token value for injection into HTML or forwarder config.
260
+ * Returns the first entry's token string, or null if uninitialized.
261
+ */
262
+ getPrimaryTokenValue(): string | null;
263
+ /**
264
+ * Return all tokens with the secret value masked — safe to serialize for
265
+ * the Security tab UI or `GET /api/console/token/info` responses.
266
+ */
267
+ listMasked(): MaskedTokenEntry[];
268
+ /**
269
+ * Get the path to the token file on disk.
270
+ */
271
+ getFilePath(): string;
272
+ /**
273
+ * Returns a safe-to-serialize view of TOTP enrollment state. Never leaks
274
+ * the secret or any backup code material.
275
+ */
276
+ getTotpStatus(): TotpStatus;
277
+ /** Convenience: true if the user has a confirmed TOTP secret. */
278
+ isTotpEnrolled(): boolean;
279
+ /**
280
+ * Begin a TOTP enrollment. Generates a fresh secret, holds it in the
281
+ * in-memory pending map, and returns the data the UI needs to render a
282
+ * QR code and manual-entry fallback. Nothing is persisted until
283
+ * `confirmTotpEnrollment` succeeds.
284
+ *
285
+ * Callers may call this multiple times; each call produces a new pendingId
286
+ * and secret. Old pending entries expire after TOTP_PENDING_TTL_MS.
287
+ *
288
+ * @throws Error if TOTP is already enrolled — callers must disable first.
289
+ */
290
+ beginTotpEnrollment(label?: string): TotpEnrollmentBegin;
291
+ /**
292
+ * Confirm a pending TOTP enrollment. Verifies the code against the pending
293
+ * secret; on success, generates 10 plaintext backup codes, hashes them for
294
+ * storage, and persists the enrollment. Returns the plaintext backup codes
295
+ * exactly once — the caller is responsible for showing them to the user
296
+ * and then discarding them.
297
+ *
298
+ * Wrong codes do NOT consume or invalidate the pending enrollment — the
299
+ * user can retry until it expires. This matches user expectations for
300
+ * "oops, typed the wrong code" and limits the damage from a fat-fingered
301
+ * first attempt.
302
+ *
303
+ * @throws Error if pendingId is unknown, expired, or code invalid.
304
+ */
305
+ confirmTotpEnrollment(pendingId: string, code: string): Promise<TotpEnrollmentConfirm>;
306
+ /**
307
+ * Verify a user-presented code. Accepts either a live TOTP code or a
308
+ * single-use backup code. On successful backup-code match, the consumed
309
+ * code's hash is removed from storage and the file is re-written.
310
+ *
311
+ * Returns a discriminated result so the caller can distinguish "consumed
312
+ * a backup code" (which the UI should surface with a warning about
313
+ * remaining count) from "valid TOTP code" (normal case). Returns
314
+ * `{ ok: false }` on any failure — the caller should not retry within
315
+ * the same request lifecycle.
316
+ */
317
+ verifyTotp(code: string): Promise<{
318
+ ok: true;
319
+ method: 'totp' | 'backup';
320
+ backupCodesRemaining: number;
321
+ } | {
322
+ ok: false;
323
+ }>;
324
+ /**
325
+ * Disable TOTP. Requires a valid code (TOTP or backup) as confirmation so
326
+ * an attacker who momentarily has access to a live session can't silently
327
+ * strip the second factor.
328
+ *
329
+ * @throws Error if not enrolled or code invalid.
330
+ */
331
+ disableTotp(code: string): Promise<void>;
332
+ /** Remove any pending enrollments whose TTL has passed. */
333
+ private sweepExpiredEnrollments;
334
+ /**
335
+ * Rotate the primary console token. Requires TOTP confirmation (Pattern B).
336
+ *
337
+ * Flow:
338
+ * 1. Verify the confirmation code via `verifyTotp()` (live TOTP or backup code).
339
+ * 2. Stash the old token value in the in-memory grace buffer so in-flight
340
+ * requests from the rotating tab (and any other local process that read
341
+ * the file before the rotation) still authenticate for ROTATION_GRACE_MS.
342
+ * 3. Generate a new 32-byte token, mutate the primary entry in place, write
343
+ * the file atomically, and rebuild the buffer cache.
344
+ * 4. Return the new token inline so the caller can update `DollhouseAuth.token`
345
+ * without a page reload.
346
+ *
347
+ * Pattern A (OS dialog fallback for users without TOTP) is deferred — the
348
+ * caller should gate the UI so the rotate action is only available when
349
+ * TOTP is enrolled.
350
+ *
351
+ * @throws TotpError STORE_NOT_INITIALIZED — store never loaded
352
+ * @throws TotpError TOTP_REQUIRED — TOTP not enrolled, rotation requires second-factor confirmation
353
+ * @throws TotpError INVALID_TOTP_CODE — wrong code
354
+ */
355
+ rotatePrimary(confirmationCode: string): Promise<RotationResult>;
356
+ /** Remove expired grace entries so they stop matching in verify(). */
357
+ private sweepExpiredGraceEntries;
358
+ /**
359
+ * Read the token file and distinguish missing from corrupt.
360
+ *
361
+ * Returning a tagged union lets `ensureInitialized()` back up corrupt files
362
+ * before overwriting them — users who hand-edited their tokens with custom
363
+ * names or labels deserve a recovery path instead of a silent destroy.
364
+ */
365
+ private readWithStatus;
366
+ /**
367
+ * Copy the current (presumed corrupt) token file to a timestamped backup
368
+ * alongside it so the user can recover hand-edited data after an accidental
369
+ * syntax error. Best-effort — failure to back up does not block creating
370
+ * a fresh file, since the primary goal is keeping the console usable.
371
+ */
372
+ private backupCorruptFile;
373
+ /**
374
+ * Atomically write the token file with owner-only permissions.
375
+ * Uses temp+rename to avoid partial writes on crash.
376
+ *
377
+ * On Windows, `chmod(0o600)` is effectively a no-op because the file
378
+ * system uses ACLs instead of POSIX modes. We log a one-time warning so
379
+ * users on Windows know the token file does not have OS-enforced access
380
+ * control and can decide whether to use additional tooling (icacls, NTFS
381
+ * permissions, or a different storage location).
382
+ */
383
+ private write;
384
+ /** One-shot flag so the Windows permissions warning is logged at most once. */
385
+ private windowsWarningLogged;
386
+ private warnIfWindowsPermissions;
387
+ }
388
+ /**
389
+ * Read the raw token file from disk without constructing a store.
390
+ * Intended for follower processes that need the primary token to attach
391
+ * to their ingest POSTs. Returns null if the file does not exist or is invalid.
392
+ *
393
+ * @param filePath - Optional override for the token file location
394
+ */
395
+ export declare function readTokenFileRaw(filePath?: string): Promise<ConsoleTokenFile | null>;
396
+ /**
397
+ * Get the primary token value from the token file on disk.
398
+ * Convenience helper for followers and external consumers.
399
+ */
400
+ export declare function getPrimaryTokenFromFile(filePath?: string): Promise<string | null>;
401
+ /** Export the default file path so callers can reference it in logs/docs. */
402
+ export { DEFAULT_TOKEN_FILE };
403
+ //# sourceMappingURL=consoleToken.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consoleToken.d.ts","sourceRoot":"","sources":["../../../src/web/console/consoleToken.ts"],"names":[],"mappings":"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"}