@chrischall/mcp-utils 2.10.0 → 2.12.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/README.md +448 -15
- package/dist/concurrency/index.d.ts +3 -1
- package/dist/concurrency/index.d.ts.map +1 -1
- package/dist/concurrency/index.js +3 -1
- package/dist/concurrency/index.js.map +1 -1
- package/dist/concurrency/verify-after-write.d.ts +84 -0
- package/dist/concurrency/verify-after-write.d.ts.map +1 -0
- package/dist/concurrency/verify-after-write.js +108 -0
- package/dist/concurrency/verify-after-write.js.map +1 -0
- package/dist/errors/index.d.ts +35 -1
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +79 -1
- package/dist/errors/index.js.map +1 -1
- package/dist/fetchproxy/fallback.d.ts +130 -0
- package/dist/fetchproxy/fallback.d.ts.map +1 -0
- package/dist/fetchproxy/fallback.js +199 -0
- package/dist/fetchproxy/fallback.js.map +1 -0
- package/dist/fetchproxy/index.d.ts +31 -1
- package/dist/fetchproxy/index.d.ts.map +1 -1
- package/dist/fetchproxy/index.js +120 -13
- package/dist/fetchproxy/index.js.map +1 -1
- package/dist/fs/confine.d.ts +9 -0
- package/dist/fs/confine.d.ts.map +1 -1
- package/dist/fs/confine.js +11 -2
- package/dist/fs/confine.js.map +1 -1
- package/dist/fs/index.d.ts +9 -2
- package/dist/fs/index.d.ts.map +1 -1
- package/dist/fs/index.js +13 -4
- package/dist/fs/index.js.map +1 -1
- package/dist/fs/magic.d.ts +35 -0
- package/dist/fs/magic.d.ts.map +1 -0
- package/dist/fs/magic.js +110 -0
- package/dist/fs/magic.js.map +1 -0
- package/dist/fs/output.d.ts +14 -10
- package/dist/fs/output.d.ts.map +1 -1
- package/dist/fs/output.js +21 -45
- package/dist/fs/output.js.map +1 -1
- package/dist/fs/upload-guard.d.ts +97 -0
- package/dist/fs/upload-guard.d.ts.map +1 -0
- package/dist/fs/upload-guard.js +185 -0
- package/dist/fs/upload-guard.js.map +1 -0
- package/dist/fs/write.d.ts +100 -0
- package/dist/fs/write.d.ts.map +1 -0
- package/dist/fs/write.js +207 -0
- package/dist/fs/write.js.map +1 -0
- package/dist/graphql/client.d.ts +223 -0
- package/dist/graphql/client.d.ts.map +1 -0
- package/dist/graphql/client.js +335 -0
- package/dist/graphql/client.js.map +1 -0
- package/dist/graphql/index.d.ts +20 -0
- package/dist/graphql/index.d.ts.map +1 -0
- package/dist/graphql/index.js +20 -0
- package/dist/graphql/index.js.map +1 -0
- package/dist/graphql/operation-kind.d.ts +58 -0
- package/dist/graphql/operation-kind.d.ts.map +1 -0
- package/dist/graphql/operation-kind.js +237 -0
- package/dist/graphql/operation-kind.js.map +1 -0
- package/dist/html/index.d.ts +33 -0
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +81 -1
- package/dist/html/index.js.map +1 -1
- package/dist/http/index.d.ts +11 -1
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +35 -7
- package/dist/http/index.js.map +1 -1
- package/dist/response/index.d.ts +1 -0
- package/dist/response/index.d.ts.map +1 -1
- package/dist/response/index.js +1 -0
- package/dist/response/index.js.map +1 -1
- package/dist/response/untrusted.d.ts +72 -0
- package/dist/response/untrusted.d.ts.map +1 -0
- package/dist/response/untrusted.js +55 -0
- package/dist/response/untrusted.js.map +1 -0
- package/dist/scrape/index.d.ts +75 -0
- package/dist/scrape/index.d.ts.map +1 -1
- package/dist/scrape/index.js +272 -0
- package/dist/scrape/index.js.map +1 -1
- package/dist/server/confirm-env.d.ts +12 -2
- package/dist/server/confirm-env.d.ts.map +1 -1
- package/dist/server/confirm-env.js +49 -3
- package/dist/server/confirm-env.js.map +1 -1
- package/dist/server/confirm-spent-file.d.ts +7 -0
- package/dist/server/confirm-spent-file.d.ts.map +1 -0
- package/dist/server/confirm-spent-file.js +118 -0
- package/dist/server/confirm-spent-file.js.map +1 -0
- package/dist/server/confirm-token.d.ts +12 -2
- package/dist/server/confirm-token.d.ts.map +1 -1
- package/dist/server/confirm-token.js +8 -1
- package/dist/server/confirm-token.js.map +1 -1
- package/dist/server/confirm-write.d.ts +152 -0
- package/dist/server/confirm-write.d.ts.map +1 -0
- package/dist/server/confirm-write.js +107 -0
- package/dist/server/confirm-write.js.map +1 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -1
- package/dist/session/atomic-write.d.ts +15 -0
- package/dist/session/atomic-write.d.ts.map +1 -0
- package/dist/session/atomic-write.js +42 -0
- package/dist/session/atomic-write.js.map +1 -0
- package/dist/session/file-lock.d.ts +57 -0
- package/dist/session/file-lock.d.ts.map +1 -0
- package/dist/session/file-lock.js +215 -0
- package/dist/session/file-lock.js.map +1 -0
- package/dist/session/index.d.ts +118 -2
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/index.js +200 -82
- package/dist/session/index.js.map +1 -1
- package/dist/session/login-page.d.ts +73 -0
- package/dist/session/login-page.d.ts.map +1 -0
- package/dist/session/login-page.js +143 -0
- package/dist/session/login-page.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An advisory, cross-process lock file — the read-modify-write guard that
|
|
3
|
+
* several fleet servers hand-rolled around a shared state file.
|
|
4
|
+
*
|
|
5
|
+
* Why it exists: more than one process routinely shares a server's state file
|
|
6
|
+
* (Claude Desktop beside a Claude Code session; two children of one `mcp-host`
|
|
7
|
+
* registration on the same data dir). An atomic rename keeps the file from
|
|
8
|
+
* tearing, but it does nothing for a read-modify-write: two writers each read
|
|
9
|
+
* the old content and the second rename silently drops the first one's change.
|
|
10
|
+
* For a credential that rotates on use, "dropped" means an account lockout.
|
|
11
|
+
*
|
|
12
|
+
* The reference implementation is freshbooks-mcp's `withRefreshLock`
|
|
13
|
+
* (`src/auth.ts`, fleet-audit#1008): an exclusively-created lock file next to
|
|
14
|
+
* the state file holding `<pid>:<uuid>` (staged and hard-linked into place, so
|
|
15
|
+
* it never exists ownerless — mcp-utils#330); a lock whose holder is dead, or that has been
|
|
16
|
+
* held past `staleMs`, is broken rather than waited on forever; release is
|
|
17
|
+
* owner-checked so a lock broken as stale and re-taken by someone else is not
|
|
18
|
+
* removed out from under them. If the lock file cannot be created at all (an
|
|
19
|
+
* unwritable directory) the critical section runs UNLOCKED — the state write
|
|
20
|
+
* inside it fails the same way, and that failure is the one worth reporting.
|
|
21
|
+
*
|
|
22
|
+
* Advisory only: it coordinates processes that use it, nothing else.
|
|
23
|
+
*/
|
|
24
|
+
import { randomUUID } from 'node:crypto';
|
|
25
|
+
import { closeSync, existsSync, linkSync, mkdirSync, openSync, readFileSync, statSync, unlinkSync, writeFileSync, writeSync, } from 'node:fs';
|
|
26
|
+
import { dirname } from 'node:path';
|
|
27
|
+
const DEFAULT_POLL_MS = 25;
|
|
28
|
+
/**
|
|
29
|
+
* Whether the process named in a lock file is still running.
|
|
30
|
+
*
|
|
31
|
+
* Content that names no pid — empty, or not yet written by a holder that
|
|
32
|
+
* created the file a moment ago — counts as ALIVE: it proves nothing about the
|
|
33
|
+
* holder, and reading it as dead let a second process break a held lock
|
|
34
|
+
* (mcp-utils#330). The `staleMs` age check still breaks it if it lingers.
|
|
35
|
+
*/
|
|
36
|
+
function holderAlive(lockPath) {
|
|
37
|
+
let pid;
|
|
38
|
+
try {
|
|
39
|
+
pid = Number.parseInt(readFileSync(lockPath, 'utf8'), 10);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return true; // unreadable now (released, or racing) — let the caller retry
|
|
43
|
+
}
|
|
44
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
45
|
+
return true;
|
|
46
|
+
try {
|
|
47
|
+
process.kill(pid, 0);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
// EPERM: the process exists but belongs to another user — still alive.
|
|
52
|
+
return err.code === 'EPERM';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create the lock file with its owner ALREADY in it: write a private staging
|
|
57
|
+
* file, then hard-link it to `lockPath`. `link` fails with EEXIST exactly like
|
|
58
|
+
* an `O_EXCL` create, but the file appears complete, so no reader ever sees an
|
|
59
|
+
* ownerless lock. On a filesystem without hard links, fall back to `O_EXCL`
|
|
60
|
+
* create + write (where the ownerless window is covered by `holderAlive`).
|
|
61
|
+
*/
|
|
62
|
+
function createLockFile(lockPath, owner) {
|
|
63
|
+
const staging = `${lockPath}.${randomUUID()}.tmp`;
|
|
64
|
+
let linked = false;
|
|
65
|
+
try {
|
|
66
|
+
writeFileSync(staging, owner, { mode: 0o600, flag: 'wx' });
|
|
67
|
+
linkSync(staging, lockPath);
|
|
68
|
+
linked = true;
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
const code = err.code;
|
|
72
|
+
if (code === 'EEXIST' && existsSync(staging))
|
|
73
|
+
throw err; // the lock is held
|
|
74
|
+
if (code !== 'EPERM' && code !== 'ENOTSUP' && code !== 'EOPNOTSUPP' && code !== 'ENOSYS' && code !== 'EXDEV') {
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
try {
|
|
80
|
+
unlinkSync(staging);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
/* never created */
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (linked)
|
|
87
|
+
return;
|
|
88
|
+
const fd = openSync(lockPath, 'wx', 0o600);
|
|
89
|
+
try {
|
|
90
|
+
writeSync(fd, owner);
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
closeSync(fd);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/** One acquisition attempt; breaks a dead or stale lock so the next attempt can win. */
|
|
97
|
+
function tryAcquire(lockPath, owner, staleMs) {
|
|
98
|
+
try {
|
|
99
|
+
createLockFile(lockPath, owner);
|
|
100
|
+
return 'acquired';
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
if (err.code !== 'EEXIST')
|
|
104
|
+
return 'unlockable';
|
|
105
|
+
}
|
|
106
|
+
let stale;
|
|
107
|
+
try {
|
|
108
|
+
stale = !holderAlive(lockPath) || Date.now() - statSync(lockPath).mtimeMs > staleMs;
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return 'busy'; // released between our open and stat — retry
|
|
112
|
+
}
|
|
113
|
+
if (stale) {
|
|
114
|
+
try {
|
|
115
|
+
unlinkSync(lockPath);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
/* someone else broke it first */
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return 'busy';
|
|
122
|
+
}
|
|
123
|
+
/** Remove the lock only if it is still ours — it may have been broken and re-taken. */
|
|
124
|
+
function release(lockPath, owner) {
|
|
125
|
+
try {
|
|
126
|
+
if (readFileSync(lockPath, 'utf8') === owner)
|
|
127
|
+
unlinkSync(lockPath);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
/* already gone */
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function prepare(lockPath) {
|
|
134
|
+
try {
|
|
135
|
+
mkdirSync(dirname(lockPath), { recursive: true, mode: 0o700 });
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
/* fall through: openSync reports the real problem */
|
|
139
|
+
}
|
|
140
|
+
return `${process.pid}:${randomUUID()}`;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Run `fn` holding the advisory lock at `lockPath` (conventionally
|
|
144
|
+
* `<stateFile>.lock`), waiting for any other holder first.
|
|
145
|
+
*
|
|
146
|
+
* Waits are polled (`pollMs`) and bounded: a dead holder is broken at once, a
|
|
147
|
+
* live one after `staleMs`. Pass `signal` to give up waiting early.
|
|
148
|
+
*/
|
|
149
|
+
export async function withFileLock(lockPath, fn, opts = {}) {
|
|
150
|
+
const staleMs = opts.staleMs ?? 60_000;
|
|
151
|
+
const pollMs = opts.pollMs ?? DEFAULT_POLL_MS;
|
|
152
|
+
const { signal } = opts;
|
|
153
|
+
const owner = prepare(lockPath);
|
|
154
|
+
let held = false;
|
|
155
|
+
for (;;) {
|
|
156
|
+
signal?.throwIfAborted();
|
|
157
|
+
const r = tryAcquire(lockPath, owner, staleMs);
|
|
158
|
+
if (r === 'acquired') {
|
|
159
|
+
held = true;
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
if (r === 'unlockable')
|
|
163
|
+
break; // run unlocked: the write will report the real failure
|
|
164
|
+
await new Promise((resolve) => {
|
|
165
|
+
const done = () => {
|
|
166
|
+
clearTimeout(timer);
|
|
167
|
+
signal?.removeEventListener('abort', done);
|
|
168
|
+
resolve();
|
|
169
|
+
};
|
|
170
|
+
const timer = setTimeout(done, pollMs);
|
|
171
|
+
signal?.addEventListener('abort', done, { once: true });
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
try {
|
|
175
|
+
return await fn();
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
if (held)
|
|
179
|
+
release(lockPath, owner);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/** Block the thread for `ms` without spinning the CPU. */
|
|
183
|
+
function sleepSync(ms) {
|
|
184
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Synchronous form of {@link withFileLock}, for stores whose API is synchronous
|
|
188
|
+
* ({@link SessionStore}). A waiter BLOCKS the thread between polls, so keep the
|
|
189
|
+
* critical section to a file read and write — which is all it is meant for —
|
|
190
|
+
* and note the shorter default `staleMs` (5 s).
|
|
191
|
+
*/
|
|
192
|
+
export function withFileLockSync(lockPath, fn, opts = {}) {
|
|
193
|
+
const staleMs = opts.staleMs ?? 5_000;
|
|
194
|
+
const pollMs = opts.pollMs ?? DEFAULT_POLL_MS;
|
|
195
|
+
const owner = prepare(lockPath);
|
|
196
|
+
let held = false;
|
|
197
|
+
for (;;) {
|
|
198
|
+
const r = tryAcquire(lockPath, owner, staleMs);
|
|
199
|
+
if (r === 'acquired') {
|
|
200
|
+
held = true;
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
if (r === 'unlockable')
|
|
204
|
+
break;
|
|
205
|
+
sleepSync(pollMs);
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
return fn();
|
|
209
|
+
}
|
|
210
|
+
finally {
|
|
211
|
+
if (held)
|
|
212
|
+
release(lockPath, owner);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=file-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-lock.js","sourceRoot":"","sources":["../../src/session/file-lock.ts"],"names":[],"mappings":"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"}
|
package/dist/session/index.d.ts
CHANGED
|
@@ -32,6 +32,8 @@
|
|
|
32
32
|
* the one audited implementation the fleet shares.
|
|
33
33
|
*/
|
|
34
34
|
import type { McpServer } from '@modelcontextprotocol/server';
|
|
35
|
+
export { looksLikeLoginPage, expiredByLoginPage, LOGIN_PAGE_SCAN_MAX, type LoginPageView, type LoginPageSignals, } from './login-page.js';
|
|
36
|
+
export { withFileLock, withFileLockSync, type FileLockOptions } from './file-lock.js';
|
|
35
37
|
/** How a session was authenticated. Open-ended so per-MCP modes slot in. */
|
|
36
38
|
export type AuthMode = 'browser_session' | 'unknown' | (string & {});
|
|
37
39
|
/** A registered, signed-in session as surfaced to tools and clients. */
|
|
@@ -113,6 +115,32 @@ export interface RegisterSessionToolsOptions {
|
|
|
113
115
|
prefix: string;
|
|
114
116
|
/** Human label for the service (defaults to the prefix). */
|
|
115
117
|
serviceLabel?: string;
|
|
118
|
+
/**
|
|
119
|
+
* What the registry is FOR in this server, which decides what the tool
|
|
120
|
+
* descriptions may promise.
|
|
121
|
+
*
|
|
122
|
+
* - `'routed'` (default, the previous wording) — tools read the registry to
|
|
123
|
+
* pick a session, and accept a per-call `session_id`. onehome-mcp.
|
|
124
|
+
* - `'label-only'` — the registry is bookkeeping for the conversation: nothing
|
|
125
|
+
* reads it to route a request (a fetchproxy bridge always uses the bound
|
|
126
|
+
* tab). The descriptions say so and make no routing claim. zillow, redfin,
|
|
127
|
+
* homes and compass; homes-mcp used to Proxy-patch the server to get this
|
|
128
|
+
* (fleet-audit#1092).
|
|
129
|
+
*/
|
|
130
|
+
routing?: 'routed' | 'label-only';
|
|
131
|
+
/**
|
|
132
|
+
* `'label-only'` only: a sentence appended to each description saying what
|
|
133
|
+
* DOES pick the account — e.g. "Every homes tool call goes through whichever
|
|
134
|
+
* browser tab the extension is signed into; to read a different account, sign
|
|
135
|
+
* that tab into it."
|
|
136
|
+
*/
|
|
137
|
+
labelOnlyNote?: string;
|
|
138
|
+
/** Replace a tool's generated description outright (wins over `routing`). */
|
|
139
|
+
descriptions?: {
|
|
140
|
+
register?: string;
|
|
141
|
+
setActive?: string;
|
|
142
|
+
context?: string;
|
|
143
|
+
};
|
|
116
144
|
}
|
|
117
145
|
/**
|
|
118
146
|
* Register the structurally-identical session tool trio against `server`,
|
|
@@ -123,6 +151,10 @@ export interface RegisterSessionToolsOptions {
|
|
|
123
151
|
* made active in the same call (equivalent to a follow-up
|
|
124
152
|
* `${prefix}_set_active_session`). Omitting it preserves the
|
|
125
153
|
* first-registered-wins active-session behaviour.
|
|
154
|
+
*
|
|
155
|
+
* Pass `routing: 'label-only'` when nothing in the server reads the registry to
|
|
156
|
+
* pick a session — the default wording promises routing that such a server does
|
|
157
|
+
* not do (see {@link RegisterSessionToolsOptions.routing}).
|
|
126
158
|
*/
|
|
127
159
|
export declare function registerSessionTools(server: McpServer, registry: SessionRegistry, opts: RegisterSessionToolsOptions): void;
|
|
128
160
|
/**
|
|
@@ -141,6 +173,24 @@ export interface SessionStoreOptions<T> {
|
|
|
141
173
|
* {@link normalizeOrigin}. The stored record's key field is also normalized.
|
|
142
174
|
*/
|
|
143
175
|
normalizeKey?: (key: string) => string;
|
|
176
|
+
/**
|
|
177
|
+
* Treat the FILE, not this instance, as the source of truth: re-read it before
|
|
178
|
+
* every `get`/`list`/`getActiveSession`, and do every `add`/`remove` as a
|
|
179
|
+
* read-modify-write under a cross-process lock file (`<filePath>.lock`, see
|
|
180
|
+
* {@link withFileLockSync}).
|
|
181
|
+
*
|
|
182
|
+
* Turn this on whenever more than one process can share the file — Claude
|
|
183
|
+
* Desktop beside a Claude Code session is the everyday case. Without it each
|
|
184
|
+
* instance works from the snapshot its constructor read and rewrites the whole
|
|
185
|
+
* file from that snapshot on every write, so a sibling's sign-in is dropped and
|
|
186
|
+
* its sign-out is undone (fleet-audit#1116). simplepractice-mcp, kiaaccess-mcp
|
|
187
|
+
* and freshbooks-mcp each worked around that by re-constructing the store per
|
|
188
|
+
* access; this is that workaround, done once, plus the lock none of them had.
|
|
189
|
+
*
|
|
190
|
+
* Default `false` (the previous snapshot behaviour) — the cost is one small
|
|
191
|
+
* file read per access, and a lock file beside the store during writes.
|
|
192
|
+
*/
|
|
193
|
+
fresh?: boolean;
|
|
144
194
|
}
|
|
145
195
|
/**
|
|
146
196
|
* Disk-persisted session store with hardened file permissions. Records are kept
|
|
@@ -150,7 +200,13 @@ export interface SessionStoreOptions<T> {
|
|
|
150
200
|
*
|
|
151
201
|
* `add` marks the record most-recently-used; {@link SessionStore.getActiveSession}
|
|
152
202
|
* (and `get()` with no argument) returns it, so a tool call that omits an explicit
|
|
153
|
-
* key picks up the latest session automatically.
|
|
203
|
+
* key picks up the latest session automatically. Re-adding an existing key moves
|
|
204
|
+
* it to the end, so the active pointer a later process restores (the last record
|
|
205
|
+
* on disk) is the one this process last added.
|
|
206
|
+
*
|
|
207
|
+
* By default the file is read once, at construction. Pass
|
|
208
|
+
* {@link SessionStoreOptions.fresh} when other processes share the file, or call
|
|
209
|
+
* {@link SessionStore.reload} to pick up their changes on demand.
|
|
154
210
|
*/
|
|
155
211
|
export declare class SessionStore<T extends Record<string, unknown>> {
|
|
156
212
|
private sessions;
|
|
@@ -158,7 +214,28 @@ export declare class SessionStore<T extends Record<string, unknown>> {
|
|
|
158
214
|
private readonly filePath;
|
|
159
215
|
private readonly keyOf;
|
|
160
216
|
private readonly normalizeKey;
|
|
217
|
+
private readonly fresh;
|
|
161
218
|
constructor(opts: SessionStoreOptions<T>);
|
|
219
|
+
/**
|
|
220
|
+
* Replace the in-memory state with what is on disk now — picking up records
|
|
221
|
+
* another process added or removed. A {@link SessionStoreOptions.fresh} store
|
|
222
|
+
* does this before every access; a default store only when asked.
|
|
223
|
+
*/
|
|
224
|
+
reload(): void;
|
|
225
|
+
/** Read-modify-write under the cross-process lock (fresh mode), else in place. */
|
|
226
|
+
private mutate;
|
|
227
|
+
private lockPath;
|
|
228
|
+
/**
|
|
229
|
+
* Load the file into memory. `underLock` says the caller already holds the
|
|
230
|
+
* store's lock, so no writer can be mid-write.
|
|
231
|
+
*
|
|
232
|
+
* A fresh-mode store reads WITHOUT the lock on every get/list, so a parse
|
|
233
|
+
* failure there may be a torn read rather than a corrupt file. Before
|
|
234
|
+
* anything is quarantined it is re-read under the lock; only a file that is
|
|
235
|
+
* still unparseable then is treated as corrupt (mcp-utils#330 — writes are
|
|
236
|
+
* atomic now, so this is defence in depth, e.g. against a writer on an older
|
|
237
|
+
* mcp-utils that still rewrites in place).
|
|
238
|
+
*/
|
|
162
239
|
private loadFromDisk;
|
|
163
240
|
/**
|
|
164
241
|
* Move a corrupt store file to `<filePath>.corrupt` (or `.corrupt-<n>` if a
|
|
@@ -178,7 +255,7 @@ export declare class SessionStore<T extends Record<string, unknown>> {
|
|
|
178
255
|
get(key?: string): T | null;
|
|
179
256
|
/** The most-recently-added session, or `null`. */
|
|
180
257
|
getActiveSession(): T | null;
|
|
181
|
-
/** All sessions
|
|
258
|
+
/** All sessions, least- to most-recently added. */
|
|
182
259
|
list(): T[];
|
|
183
260
|
/** Remove a session; fixes up the active pointer. Returns whether it existed. */
|
|
184
261
|
remove(key: string): boolean;
|
|
@@ -223,6 +300,15 @@ export interface StatePersistence<T> {
|
|
|
223
300
|
* straight back off disk and the expiry loops.
|
|
224
301
|
*/
|
|
225
302
|
clear?(): void | Promise<void>;
|
|
303
|
+
/**
|
|
304
|
+
* Run `fn` holding a lock that every other user of the SAME stored state
|
|
305
|
+
* respects — across processes, not just within one. Optional; a manager that
|
|
306
|
+
* needs a read-modify-write to be atomic (see
|
|
307
|
+
* {@link TokenManagerOptions.reloadBeforeRefresh}) uses it when present.
|
|
308
|
+
* {@link createFileStatePersistence} implements it with a lock file beside
|
|
309
|
+
* the state file ({@link withFileLock}).
|
|
310
|
+
*/
|
|
311
|
+
withLock?<R>(fn: () => Promise<R>): Promise<R>;
|
|
226
312
|
}
|
|
227
313
|
/**
|
|
228
314
|
* A {@link StatePersistence} that is synchronous by construction — what the
|
|
@@ -246,6 +332,8 @@ export interface SyncStatePersistence<T> {
|
|
|
246
332
|
save(state: T): void;
|
|
247
333
|
/** Discard the stored state. */
|
|
248
334
|
clear(): void;
|
|
335
|
+
/** See {@link StatePersistence.withLock}. The file-backed single-record store provides it. */
|
|
336
|
+
withLock?<R>(fn: () => Promise<R>): Promise<R>;
|
|
249
337
|
}
|
|
250
338
|
/**
|
|
251
339
|
* Wraps a failure that came from WRITING state, so the managers can tell it
|
|
@@ -500,6 +588,29 @@ export interface TokenManagerOptions {
|
|
|
500
588
|
* fatal**, with a message naming the recovery (freshbooks-mcp's case).
|
|
501
589
|
*/
|
|
502
590
|
onPersistError?: (err: unknown) => void;
|
|
591
|
+
/**
|
|
592
|
+
* Re-read {@link TokenManagerOptions.persistence} before every refresh, under
|
|
593
|
+
* its cross-process lock ({@link StatePersistence.withLock}), and write the
|
|
594
|
+
* result before releasing it. Requires `persistence`.
|
|
595
|
+
*
|
|
596
|
+
* Turn this on when more than one process shares the token store AND the
|
|
597
|
+
* service rotates single-use refresh tokens (FreshBooks; any OAuth server with
|
|
598
|
+
* refresh-token rotation). Otherwise the manager, which reads the store once
|
|
599
|
+
* per process, spends the refresh token it loaded at start-up — which a
|
|
600
|
+
* sibling process may have spent already — and the account is locked out
|
|
601
|
+
* behind an `invalid_grant` while a valid successor sits on disk
|
|
602
|
+
* (fleet-audit#1008). Under the lock, a record newer than the one in memory
|
|
603
|
+
* wins: its access token is adopted outright if still outside the skew
|
|
604
|
+
* window, otherwise its refresh token is the one spent. A record OLDER than
|
|
605
|
+
* the one in memory (lower `expiresAt`) is ignored.
|
|
606
|
+
*
|
|
607
|
+
* Off by default: it costs a file read and a lock file per refresh, and for a
|
|
608
|
+
* service that does not rotate (or a store only one process ever opens) the
|
|
609
|
+
* snapshot is already correct. A persistence with no `withLock` is still
|
|
610
|
+
* re-read, but two processes can then interleave — use
|
|
611
|
+
* {@link createFileStatePersistence}, which has one.
|
|
612
|
+
*/
|
|
613
|
+
reloadBeforeRefresh?: boolean;
|
|
503
614
|
/** Injectable clock (defaults to `Date.now`) — for tests. */
|
|
504
615
|
now?: () => number;
|
|
505
616
|
}
|
|
@@ -534,6 +645,7 @@ export declare class TokenManager {
|
|
|
534
645
|
private readonly now;
|
|
535
646
|
private readonly isRefreshRevokedFn;
|
|
536
647
|
private readonly onPersistErrorFn;
|
|
648
|
+
private readonly reloadBeforeRefresh;
|
|
537
649
|
private inFlight;
|
|
538
650
|
private bootstrapInFlight;
|
|
539
651
|
/**
|
|
@@ -573,6 +685,10 @@ export declare class TokenManager {
|
|
|
573
685
|
refreshNow(): Promise<void>;
|
|
574
686
|
/** One refresh attempt against the current refresh token. */
|
|
575
687
|
private runRefresh;
|
|
688
|
+
/** The stored tokens as they are on disk now, bypassing the once-per-process read. Never throws. */
|
|
689
|
+
private readStoredNow;
|
|
690
|
+
/** Spend `rt`, then install and persist what comes back. */
|
|
691
|
+
private exchange;
|
|
576
692
|
/**
|
|
577
693
|
* Recover from a refresh the current credential could not satisfy — commonly
|
|
578
694
|
* a refresh token restored from a previous process and revoked since. Without
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"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"}
|