@namzu/cli 30.0.0 → 33.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.
- package/CHANGELOG.md +261 -1
- package/dist/browser/commands.js +11 -7
- package/dist/browser/commands.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +26 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/acp.d.ts +20 -2
- package/dist/commands/acp.d.ts.map +1 -1
- package/dist/commands/acp.js +42 -5
- package/dist/commands/acp.js.map +1 -1
- package/dist/commands/archive.d.ts +4 -0
- package/dist/commands/archive.d.ts.map +1 -0
- package/dist/commands/archive.js +62 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/drain.d.ts.map +1 -1
- package/dist/commands/drain.js +2 -1
- package/dist/commands/drain.js.map +1 -1
- package/dist/commands/exec-json.d.ts.map +1 -1
- package/dist/commands/exec-json.js +24 -1
- package/dist/commands/exec-json.js.map +1 -1
- package/dist/commands/exec.d.ts.map +1 -1
- package/dist/commands/exec.js +2 -1
- package/dist/commands/exec.js.map +1 -1
- package/dist/commands/login.d.ts +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +33 -11
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/mcp-oauth-login.d.ts +19 -0
- package/dist/commands/mcp-oauth-login.d.ts.map +1 -0
- package/dist/commands/mcp-oauth-login.js +213 -0
- package/dist/commands/mcp-oauth-login.js.map +1 -0
- package/dist/commands/mcp.d.ts +3 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +288 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/prior-messages.d.ts.map +1 -1
- package/dist/commands/prior-messages.js +42 -2
- package/dist/commands/prior-messages.js.map +1 -1
- package/dist/commands/schedule.d.ts.map +1 -1
- package/dist/commands/schedule.js +7 -5
- package/dist/commands/schedule.js.map +1 -1
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +60 -5
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/types.d.ts +2 -0
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/worktree.d.ts +6 -0
- package/dist/commands/worktree.d.ts.map +1 -0
- package/dist/commands/worktree.js +85 -0
- package/dist/commands/worktree.js.map +1 -0
- package/dist/config/composer-triggers.d.ts +41 -0
- package/dist/config/composer-triggers.d.ts.map +1 -0
- package/dist/config/composer-triggers.js +80 -0
- package/dist/config/composer-triggers.js.map +1 -0
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +58 -0
- package/dist/config/load.js.map +1 -1
- package/dist/config/schema.d.ts +34 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/config/user-config.d.ts +2 -0
- package/dist/config/user-config.d.ts.map +1 -1
- package/dist/config/user-config.js +76 -6
- package/dist/config/user-config.js.map +1 -1
- package/dist/context/doctrine.d.ts +3 -3
- package/dist/context/doctrine.d.ts.map +1 -1
- package/dist/context/doctrine.js +3 -3
- package/dist/context/doctrine.js.map +1 -1
- package/dist/context/runtime-message.d.ts.map +1 -1
- package/dist/context/runtime-message.js +4 -0
- package/dist/context/runtime-message.js.map +1 -1
- package/dist/doctor/checks/credentials.d.ts.map +1 -1
- package/dist/doctor/checks/credentials.js +2 -0
- package/dist/doctor/checks/credentials.js.map +1 -1
- package/dist/integrations/mcp/oauth-store.d.ts +40 -0
- package/dist/integrations/mcp/oauth-store.d.ts.map +1 -0
- package/dist/integrations/mcp/oauth-store.js +549 -0
- package/dist/integrations/mcp/oauth-store.js.map +1 -0
- package/dist/integrations/mcp/servers.d.ts +72 -5
- package/dist/integrations/mcp/servers.d.ts.map +1 -1
- package/dist/integrations/mcp/servers.js +298 -24
- package/dist/integrations/mcp/servers.js.map +1 -1
- package/dist/integrations/mcp/user-config.d.ts +25 -0
- package/dist/integrations/mcp/user-config.d.ts.map +1 -0
- package/dist/integrations/mcp/user-config.js +92 -0
- package/dist/integrations/mcp/user-config.js.map +1 -0
- package/dist/integrations/plugins/runtime.d.ts +11 -9
- package/dist/integrations/plugins/runtime.d.ts.map +1 -1
- package/dist/integrations/plugins/runtime.js +17 -36
- package/dist/integrations/plugins/runtime.js.map +1 -1
- package/dist/integrations/providers/credential-store.d.ts +8 -0
- package/dist/integrations/providers/credential-store.d.ts.map +1 -1
- package/dist/integrations/providers/credential-store.js +111 -22
- package/dist/integrations/providers/credential-store.js.map +1 -1
- package/dist/integrations/providers/discover.d.ts +11 -5
- package/dist/integrations/providers/discover.d.ts.map +1 -1
- package/dist/integrations/providers/discover.js +26 -12
- package/dist/integrations/providers/discover.js.map +1 -1
- package/dist/integrations/providers/index.d.ts +1 -1
- package/dist/integrations/providers/index.d.ts.map +1 -1
- package/dist/integrations/providers/index.js +1 -1
- package/dist/integrations/providers/index.js.map +1 -1
- package/dist/integrations/resident/session-step.d.ts.map +1 -1
- package/dist/integrations/resident/session-step.js +2 -1
- package/dist/integrations/resident/session-step.js.map +1 -1
- package/dist/integrations/sessions/store.d.ts +23 -5
- package/dist/integrations/sessions/store.d.ts.map +1 -1
- package/dist/integrations/sessions/store.js +184 -26
- package/dist/integrations/sessions/store.js.map +1 -1
- package/dist/integrations/subagents/NamzuCliAgent.d.ts +8 -0
- package/dist/integrations/subagents/NamzuCliAgent.d.ts.map +1 -0
- package/dist/integrations/subagents/NamzuCliAgent.js +9 -0
- package/dist/integrations/subagents/NamzuCliAgent.js.map +1 -0
- package/dist/integrations/subagents/runtime.d.ts +9 -6
- package/dist/integrations/subagents/runtime.d.ts.map +1 -1
- package/dist/integrations/subagents/runtime.js +108 -19
- package/dist/integrations/subagents/runtime.js.map +1 -1
- package/dist/integrations/subagents/worktree-driver.d.ts +17 -0
- package/dist/integrations/subagents/worktree-driver.d.ts.map +1 -0
- package/dist/integrations/subagents/worktree-driver.js +72 -0
- package/dist/integrations/subagents/worktree-driver.js.map +1 -0
- package/dist/integrations/web/search.d.ts.map +1 -1
- package/dist/integrations/web/search.js +8 -6
- package/dist/integrations/web/search.js.map +1 -1
- package/dist/integrations/worktrees/managed.d.ts +49 -0
- package/dist/integrations/worktrees/managed.d.ts.map +1 -0
- package/dist/integrations/worktrees/managed.js +231 -0
- package/dist/integrations/worktrees/managed.js.map +1 -0
- package/dist/permissions/rules.d.ts +5 -1
- package/dist/permissions/rules.d.ts.map +1 -1
- package/dist/permissions/rules.js +85 -3
- package/dist/permissions/rules.js.map +1 -1
- package/dist/schedule/build.d.ts +19 -2
- package/dist/schedule/build.d.ts.map +1 -1
- package/dist/schedule/build.js +119 -21
- package/dist/schedule/build.js.map +1 -1
- package/dist/schedule/changes.d.ts.map +1 -1
- package/dist/schedule/changes.js +13 -0
- package/dist/schedule/changes.js.map +1 -1
- package/dist/schedule/commands/add.d.ts +1 -1
- package/dist/schedule/commands/add.d.ts.map +1 -1
- package/dist/schedule/commands/add.js +186 -40
- package/dist/schedule/commands/add.js.map +1 -1
- package/dist/schedule/commands/list.d.ts +2 -0
- package/dist/schedule/commands/list.d.ts.map +1 -1
- package/dist/schedule/commands/list.js +64 -19
- package/dist/schedule/commands/list.js.map +1 -1
- package/dist/schedule/daemon/daemon.d.ts +1 -1
- package/dist/schedule/daemon/daemon.d.ts.map +1 -1
- package/dist/schedule/daemon/daemon.js +17 -5
- package/dist/schedule/daemon/daemon.js.map +1 -1
- package/dist/schedule/daemon/notify.d.ts +21 -1
- package/dist/schedule/daemon/notify.d.ts.map +1 -1
- package/dist/schedule/daemon/notify.js +43 -0
- package/dist/schedule/daemon/notify.js.map +1 -1
- package/dist/schedule/fire/fire.d.ts +1 -1
- package/dist/schedule/fire/fire.d.ts.map +1 -1
- package/dist/schedule/fire/fire.js +205 -14
- package/dist/schedule/fire/fire.js.map +1 -1
- package/dist/schedule/fire/result.d.ts +1 -1
- package/dist/schedule/fire/result.d.ts.map +1 -1
- package/dist/schedule/fire/result.js +2 -1
- package/dist/schedule/fire/result.js.map +1 -1
- package/dist/schedule/fire/run-script.d.ts +46 -0
- package/dist/schedule/fire/run-script.d.ts.map +1 -0
- package/dist/schedule/fire/run-script.js +81 -0
- package/dist/schedule/fire/run-script.js.map +1 -0
- package/dist/schedule/fire/unattended-note.d.ts +8 -0
- package/dist/schedule/fire/unattended-note.d.ts.map +1 -1
- package/dist/schedule/fire/unattended-note.js +5 -0
- package/dist/schedule/fire/unattended-note.js.map +1 -1
- package/dist/schedule/fire/wake-gate.d.ts +39 -0
- package/dist/schedule/fire/wake-gate.d.ts.map +1 -0
- package/dist/schedule/fire/wake-gate.js +90 -0
- package/dist/schedule/fire/wake-gate.js.map +1 -0
- package/dist/schedule/floor.d.ts +1 -1
- package/dist/schedule/floor.d.ts.map +1 -1
- package/dist/schedule/floor.js +288 -16
- package/dist/schedule/floor.js.map +1 -1
- package/dist/schedule/policy.d.ts +40 -0
- package/dist/schedule/policy.d.ts.map +1 -1
- package/dist/schedule/policy.js +36 -0
- package/dist/schedule/policy.js.map +1 -1
- package/dist/schedule/script-check.d.ts +53 -0
- package/dist/schedule/script-check.d.ts.map +1 -0
- package/dist/schedule/script-check.js +145 -0
- package/dist/schedule/script-check.js.map +1 -0
- package/dist/schedule/script-shell.d.ts +3 -0
- package/dist/schedule/script-shell.d.ts.map +1 -0
- package/dist/schedule/script-shell.js +5 -0
- package/dist/schedule/script-shell.js.map +1 -0
- package/dist/schedule/service/manifest.js +1 -1
- package/dist/schedule/service/manifest.js.map +1 -1
- package/dist/schedule/store/atomic.d.ts +5 -2
- package/dist/schedule/store/atomic.d.ts.map +1 -1
- package/dist/schedule/store/atomic.js +7 -4
- package/dist/schedule/store/atomic.js.map +1 -1
- package/dist/schedule/store/claims.js +1 -1
- package/dist/schedule/store/claims.js.map +1 -1
- package/dist/schedule/store/history.d.ts +1 -1
- package/dist/schedule/store/history.d.ts.map +1 -1
- package/dist/schedule/store/history.js +4 -1
- package/dist/schedule/store/history.js.map +1 -1
- package/dist/schedule/store/jobs.d.ts +19 -3
- package/dist/schedule/store/jobs.d.ts.map +1 -1
- package/dist/schedule/store/jobs.js +83 -16
- package/dist/schedule/store/jobs.js.map +1 -1
- package/dist/schedule/store/state.js +1 -1
- package/dist/schedule/store/state.js.map +1 -1
- package/dist/schedule/types.d.ts +71 -6
- package/dist/schedule/types.d.ts.map +1 -1
- package/dist/schedule/types.js +25 -1
- package/dist/schedule/types.js.map +1 -1
- package/dist/schedule/visible-source.d.ts +18 -0
- package/dist/schedule/visible-source.d.ts.map +1 -0
- package/dist/schedule/visible-source.js +59 -0
- package/dist/schedule/visible-source.js.map +1 -0
- package/dist/skills/audit.d.ts +31 -0
- package/dist/skills/audit.d.ts.map +1 -0
- package/dist/skills/audit.js +75 -0
- package/dist/skills/audit.js.map +1 -0
- package/dist/test-support/toolset.d.ts +23 -0
- package/dist/test-support/toolset.d.ts.map +1 -0
- package/dist/test-support/toolset.js +27 -0
- package/dist/test-support/toolset.js.map +1 -0
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +568 -106
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/ChoicePicker.d.ts +2 -0
- package/dist/tui/ChoicePicker.d.ts.map +1 -1
- package/dist/tui/ChoicePicker.js +10 -2
- package/dist/tui/ChoicePicker.js.map +1 -1
- package/dist/tui/Composer.d.ts +62 -3
- package/dist/tui/Composer.d.ts.map +1 -1
- package/dist/tui/Composer.js +162 -25
- package/dist/tui/Composer.js.map +1 -1
- package/dist/tui/ComposerFrame.d.ts +1 -1
- package/dist/tui/ComposerFrame.js +3 -3
- package/dist/tui/ComposerFrame.js.map +1 -1
- package/dist/tui/EffortSlider.d.ts +8 -9
- package/dist/tui/EffortSlider.d.ts.map +1 -1
- package/dist/tui/EffortSlider.js +15 -12
- package/dist/tui/EffortSlider.js.map +1 -1
- package/dist/tui/Picker.d.ts.map +1 -1
- package/dist/tui/Picker.js +18 -3
- package/dist/tui/Picker.js.map +1 -1
- package/dist/tui/ResumePicker.d.ts +2 -1
- package/dist/tui/ResumePicker.d.ts.map +1 -1
- package/dist/tui/ResumePicker.js +3 -3
- package/dist/tui/ResumePicker.js.map +1 -1
- package/dist/tui/StatusBar.d.ts +12 -12
- package/dist/tui/StatusBar.d.ts.map +1 -1
- package/dist/tui/StatusBar.js +15 -15
- package/dist/tui/StatusBar.js.map +1 -1
- package/dist/tui/agent.d.ts +46 -7
- package/dist/tui/agent.d.ts.map +1 -1
- package/dist/tui/agent.js +399 -182
- package/dist/tui/agent.js.map +1 -1
- package/dist/tui/browser-notices.d.ts.map +1 -1
- package/dist/tui/browser-notices.js +6 -1
- package/dist/tui/browser-notices.js.map +1 -1
- package/dist/tui/credential-entry.d.ts +4 -29
- package/dist/tui/credential-entry.d.ts.map +1 -1
- package/dist/tui/credential-entry.js +7 -29
- package/dist/tui/credential-entry.js.map +1 -1
- package/dist/tui/hypermode.d.ts +37 -0
- package/dist/tui/hypermode.d.ts.map +1 -0
- package/dist/tui/hypermode.js +58 -0
- package/dist/tui/hypermode.js.map +1 -0
- package/dist/tui/login-prompt.d.ts +3 -1
- package/dist/tui/login-prompt.d.ts.map +1 -1
- package/dist/tui/login-prompt.js +11 -0
- package/dist/tui/login-prompt.js.map +1 -1
- package/dist/tui/permission-review.d.ts +1 -1
- package/dist/tui/permission-review.js +1 -1
- package/dist/tui/provider-list.d.ts.map +1 -1
- package/dist/tui/provider-list.js +3 -1
- package/dist/tui/provider-list.js.map +1 -1
- package/dist/tui/schedule/host-commands.d.ts.map +1 -1
- package/dist/tui/schedule/host-commands.js +94 -33
- package/dist/tui/schedule/host-commands.js.map +1 -1
- package/dist/tui/schedule/integration.d.ts +6 -2
- package/dist/tui/schedule/integration.d.ts.map +1 -1
- package/dist/tui/schedule/integration.js +3 -1
- package/dist/tui/schedule/integration.js.map +1 -1
- package/dist/tui/schedule/resume.d.ts.map +1 -1
- package/dist/tui/schedule/resume.js +10 -1
- package/dist/tui/schedule/resume.js.map +1 -1
- package/dist/tui/schedule/tool-host.d.ts +4 -1
- package/dist/tui/schedule/tool-host.d.ts.map +1 -1
- package/dist/tui/schedule/tool-host.js +155 -40
- package/dist/tui/schedule/tool-host.js.map +1 -1
- package/dist/tui/slashCommands.d.ts +33 -6
- package/dist/tui/slashCommands.d.ts.map +1 -1
- package/dist/tui/slashCommands.js +96 -34
- package/dist/tui/slashCommands.js.map +1 -1
- package/dist/tui/theme.d.ts +10 -4
- package/dist/tui/theme.d.ts.map +1 -1
- package/dist/tui/theme.js +4 -3
- package/dist/tui/theme.js.map +1 -1
- package/dist/tui/triggers/analyze.d.ts +57 -0
- package/dist/tui/triggers/analyze.d.ts.map +1 -0
- package/dist/tui/triggers/analyze.js +221 -0
- package/dist/tui/triggers/analyze.js.map +1 -0
- package/dist/tui/triggers/context-text.d.ts +21 -0
- package/dist/tui/triggers/context-text.d.ts.map +1 -0
- package/dist/tui/triggers/context-text.js +44 -0
- package/dist/tui/triggers/context-text.js.map +1 -0
- package/dist/tui/triggers/copy.d.ts +38 -0
- package/dist/tui/triggers/copy.d.ts.map +1 -0
- package/dist/tui/triggers/copy.js +163 -0
- package/dist/tui/triggers/copy.js.map +1 -0
- package/dist/tui/triggers/detect.d.ts +83 -0
- package/dist/tui/triggers/detect.d.ts.map +1 -0
- package/dist/tui/triggers/detect.js +295 -0
- package/dist/tui/triggers/detect.js.map +1 -0
- package/dist/tui/triggers/fold.d.ts +34 -0
- package/dist/tui/triggers/fold.d.ts.map +1 -0
- package/dist/tui/triggers/fold.js +44 -0
- package/dist/tui/triggers/fold.js.map +1 -0
- package/dist/tui/triggers/pattern.d.ts +66 -0
- package/dist/tui/triggers/pattern.d.ts.map +1 -0
- package/dist/tui/triggers/pattern.js +243 -0
- package/dist/tui/triggers/pattern.js.map +1 -0
- package/dist/tui/triggers/provenance.d.ts +58 -0
- package/dist/tui/triggers/provenance.d.ts.map +1 -0
- package/dist/tui/triggers/provenance.js +98 -0
- package/dist/tui/triggers/provenance.js.map +1 -0
- package/dist/tui/triggers/registry.d.ts +113 -0
- package/dist/tui/triggers/registry.d.ts.map +1 -0
- package/dist/tui/triggers/registry.js +164 -0
- package/dist/tui/triggers/registry.js.map +1 -0
- package/dist/tui/triggers/setting.d.ts +18 -0
- package/dist/tui/triggers/setting.d.ts.map +1 -0
- package/dist/tui/triggers/setting.js +61 -0
- package/dist/tui/triggers/setting.js.map +1 -0
- package/dist/tui/triggers/verbs.d.ts +29 -0
- package/dist/tui/triggers/verbs.d.ts.map +1 -0
- package/dist/tui/triggers/verbs.js +140 -0
- package/dist/tui/triggers/verbs.js.map +1 -0
- package/dist/tui/turn-interruption.d.ts.map +1 -1
- package/dist/tui/turn-interruption.js +4 -0
- package/dist/tui/turn-interruption.js.map +1 -1
- package/dist/tui/types.d.ts +3 -1
- package/dist/tui/types.d.ts.map +1 -1
- package/package.json +13 -12
- package/skills/schedule-task/SKILL.md +115 -3
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Namzu-owned MCP OAuth state. Each complete resource endpoint has its own
|
|
3
|
+
* private file: a token for one path or query must never be sent to another.
|
|
4
|
+
* Discovery and PKCE state share that file so a browser round trip cannot
|
|
5
|
+
* accidentally resume against a different authorization server.
|
|
6
|
+
*/
|
|
7
|
+
import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
8
|
+
import { closeSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, renameSync, rmSync, writeSync, } from 'node:fs';
|
|
9
|
+
import { platform } from 'node:os';
|
|
10
|
+
import { basename, dirname, join } from 'node:path';
|
|
11
|
+
import { restrictToOwner } from '../providers/credential-store.js';
|
|
12
|
+
import { namzuHomePath } from '../state/home.js';
|
|
13
|
+
const FILE_MODE = 0o600;
|
|
14
|
+
const DIR_MODE = 0o700;
|
|
15
|
+
const PENDING_LIFETIME_MS = 10 * 60 * 1000;
|
|
16
|
+
export class McpOAuthStoreError extends Error {
|
|
17
|
+
name = 'McpOAuthStoreError';
|
|
18
|
+
}
|
|
19
|
+
export class McpOAuthLoginRequiredError extends Error {
|
|
20
|
+
name = 'McpOAuthLoginRequiredError';
|
|
21
|
+
constructor() {
|
|
22
|
+
super('MCP authorization requires `namzu mcp login <name>`.');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function normalizedEndpoint(value) {
|
|
26
|
+
if (value !== value.trim())
|
|
27
|
+
throw new McpOAuthStoreError('Invalid MCP OAuth endpoint.');
|
|
28
|
+
let url;
|
|
29
|
+
try {
|
|
30
|
+
url = new URL(value);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new McpOAuthStoreError('Invalid MCP OAuth endpoint.');
|
|
34
|
+
}
|
|
35
|
+
if (!isSecureMcpOAuthUrl(url)) {
|
|
36
|
+
throw new McpOAuthStoreError('MCP OAuth requires HTTPS or a loopback HTTP endpoint without embedded credentials or a fragment.');
|
|
37
|
+
}
|
|
38
|
+
return url.href;
|
|
39
|
+
}
|
|
40
|
+
/** Shared network policy for interactive sign-in and background token refresh. */
|
|
41
|
+
export function isSecureMcpOAuthUrl(url) {
|
|
42
|
+
return ((url.protocol === 'https:' ||
|
|
43
|
+
(url.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname))) &&
|
|
44
|
+
!url.username &&
|
|
45
|
+
!url.password &&
|
|
46
|
+
!url.hash);
|
|
47
|
+
}
|
|
48
|
+
function normalizedRedirect(value) {
|
|
49
|
+
let url;
|
|
50
|
+
try {
|
|
51
|
+
url = new URL(value);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
throw new McpOAuthStoreError('Invalid MCP OAuth callback URL.');
|
|
55
|
+
}
|
|
56
|
+
if (!isSecureMcpOAuthUrl(url)) {
|
|
57
|
+
throw new McpOAuthStoreError('MCP OAuth callback must use HTTPS or loopback HTTP.');
|
|
58
|
+
}
|
|
59
|
+
return url.href;
|
|
60
|
+
}
|
|
61
|
+
/** A hash keeps possibly secret URL path and query values out of file names. */
|
|
62
|
+
export function mcpOAuthPath(endpoint, home) {
|
|
63
|
+
const exact = normalizedEndpoint(endpoint);
|
|
64
|
+
const key = createHash('sha256').update(exact).digest('hex');
|
|
65
|
+
return join(namzuHomePath(home), 'mcp-oauth', `${key}.json`);
|
|
66
|
+
}
|
|
67
|
+
function ensurePrivateDirectory(file, home) {
|
|
68
|
+
const appHome = namzuHomePath(home);
|
|
69
|
+
const storeDir = dirname(file);
|
|
70
|
+
mkdirSync(appHome, { recursive: true, mode: DIR_MODE });
|
|
71
|
+
assertRealDirectory(appHome);
|
|
72
|
+
if (platform() === 'win32')
|
|
73
|
+
restrictToOwner(appHome);
|
|
74
|
+
mkdirSync(storeDir, { recursive: true, mode: DIR_MODE });
|
|
75
|
+
assertRealDirectory(storeDir);
|
|
76
|
+
restrictToOwner(storeDir);
|
|
77
|
+
}
|
|
78
|
+
function assertRealDirectory(path) {
|
|
79
|
+
const entry = lstatSync(path);
|
|
80
|
+
if (!entry.isDirectory() || entry.isSymbolicLink()) {
|
|
81
|
+
throw new McpOAuthStoreError('MCP OAuth credentials require a real private directory.');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function existingEntry(path) {
|
|
85
|
+
try {
|
|
86
|
+
return lstatSync(path);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
if (error.code === 'ENOENT')
|
|
90
|
+
return null;
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function checkPrivateDirectoryForRead(file, home) {
|
|
95
|
+
const appHome = namzuHomePath(home);
|
|
96
|
+
const storeDir = dirname(file);
|
|
97
|
+
if (!existingEntry(appHome))
|
|
98
|
+
return false;
|
|
99
|
+
assertRealDirectory(appHome);
|
|
100
|
+
if (platform() === 'win32')
|
|
101
|
+
restrictToOwner(appHome);
|
|
102
|
+
if (!existingEntry(storeDir))
|
|
103
|
+
return false;
|
|
104
|
+
assertRealDirectory(storeDir);
|
|
105
|
+
restrictToOwner(storeDir);
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
function readRecord(endpoint, home) {
|
|
109
|
+
const exact = normalizedEndpoint(endpoint);
|
|
110
|
+
const file = mcpOAuthPath(exact, home);
|
|
111
|
+
if (!checkPrivateDirectoryForRead(file, home))
|
|
112
|
+
return null;
|
|
113
|
+
const entry = existingEntry(file);
|
|
114
|
+
if (!entry)
|
|
115
|
+
return null;
|
|
116
|
+
if (!entry.isFile() || entry.isSymbolicLink()) {
|
|
117
|
+
throw new McpOAuthStoreError('MCP OAuth credential file must be a regular file.');
|
|
118
|
+
}
|
|
119
|
+
restrictToOwner(file);
|
|
120
|
+
let parsed;
|
|
121
|
+
try {
|
|
122
|
+
parsed = JSON.parse(readFileSync(file, 'utf8'));
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
throw new McpOAuthStoreError('MCP OAuth credential file is invalid.');
|
|
126
|
+
}
|
|
127
|
+
if (!isRecord(parsed) || parsed.version !== 1 || parsed.endpoint !== exact) {
|
|
128
|
+
throw new McpOAuthStoreError('MCP OAuth credential file does not match its endpoint.');
|
|
129
|
+
}
|
|
130
|
+
const issuer = parsed.issuer;
|
|
131
|
+
if (issuer !== undefined && !nonempty(issuer)) {
|
|
132
|
+
throw new McpOAuthStoreError('MCP OAuth credential issuer is invalid.');
|
|
133
|
+
}
|
|
134
|
+
const client = parsed.clientInformation;
|
|
135
|
+
if (client !== undefined &&
|
|
136
|
+
(!isRecord(client) ||
|
|
137
|
+
!nonempty(client.client_id) ||
|
|
138
|
+
!nonempty(client.issuer) ||
|
|
139
|
+
client.issuer !== issuer)) {
|
|
140
|
+
throw new McpOAuthStoreError('MCP OAuth client information has no matching issuer stamp.');
|
|
141
|
+
}
|
|
142
|
+
const tokens = parsed.tokens;
|
|
143
|
+
if (tokens !== undefined &&
|
|
144
|
+
(!isRecord(tokens) ||
|
|
145
|
+
!nonempty(tokens.access_token) ||
|
|
146
|
+
!nonempty(tokens.token_type) ||
|
|
147
|
+
tokens.token_type.toLowerCase() !== 'bearer' ||
|
|
148
|
+
!nonempty(tokens.issuer) ||
|
|
149
|
+
tokens.issuer !== issuer)) {
|
|
150
|
+
throw new McpOAuthStoreError('MCP OAuth tokens have no matching issuer stamp.');
|
|
151
|
+
}
|
|
152
|
+
if (parsed.redirectUrl !== undefined && !nonempty(parsed.redirectUrl)) {
|
|
153
|
+
throw new McpOAuthStoreError('MCP OAuth callback URL is invalid.');
|
|
154
|
+
}
|
|
155
|
+
if (typeof parsed.redirectUrl === 'string')
|
|
156
|
+
normalizedRedirect(parsed.redirectUrl);
|
|
157
|
+
if (tokens !== undefined && client === undefined) {
|
|
158
|
+
throw new McpOAuthStoreError('MCP OAuth tokens have no client registration.');
|
|
159
|
+
}
|
|
160
|
+
if (parsed.discovery !== undefined)
|
|
161
|
+
checkedDiscovery(parsed.discovery);
|
|
162
|
+
if (parsed.pending !== undefined)
|
|
163
|
+
checkedPending(parsed.pending);
|
|
164
|
+
return parsed;
|
|
165
|
+
}
|
|
166
|
+
function isRecord(value) {
|
|
167
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
168
|
+
}
|
|
169
|
+
function nonempty(value) {
|
|
170
|
+
return typeof value === 'string' && value.length > 0;
|
|
171
|
+
}
|
|
172
|
+
function checkedDiscovery(value) {
|
|
173
|
+
if (!isRecord(value) || !nonempty(value.authorizationServerUrl)) {
|
|
174
|
+
throw new McpOAuthStoreError('MCP OAuth discovery state is invalid.');
|
|
175
|
+
}
|
|
176
|
+
const metadata = value.authorizationServerMetadata;
|
|
177
|
+
if (metadata !== undefined && (!isRecord(metadata) || !nonempty(metadata.issuer))) {
|
|
178
|
+
throw new McpOAuthStoreError('MCP OAuth authorization server issuer is invalid.');
|
|
179
|
+
}
|
|
180
|
+
normalizedEndpoint(value.authorizationServerUrl);
|
|
181
|
+
return value;
|
|
182
|
+
}
|
|
183
|
+
function checkedPending(value) {
|
|
184
|
+
if (!isRecord(value) ||
|
|
185
|
+
!nonempty(value.state) ||
|
|
186
|
+
(typeof value.codeVerifier !== 'undefined' && !nonempty(value.codeVerifier)) ||
|
|
187
|
+
typeof value.createdAt !== 'number' ||
|
|
188
|
+
!Number.isFinite(value.createdAt) ||
|
|
189
|
+
typeof value.consumed !== 'boolean' ||
|
|
190
|
+
(value.baseTokens !== null && !nonempty(value.baseTokens)) ||
|
|
191
|
+
(value.baseClient !== null && !nonempty(value.baseClient))) {
|
|
192
|
+
throw new McpOAuthStoreError('MCP OAuth login state is invalid.');
|
|
193
|
+
}
|
|
194
|
+
checkedDiscovery(value.discovery);
|
|
195
|
+
return value;
|
|
196
|
+
}
|
|
197
|
+
function writeRecord(file, record) {
|
|
198
|
+
const temp = `${file}.tmp.${process.pid}.${randomBytes(12).toString('hex')}`;
|
|
199
|
+
let descriptor;
|
|
200
|
+
try {
|
|
201
|
+
const previous = existingEntry(file);
|
|
202
|
+
if (previous) {
|
|
203
|
+
if (!previous.isFile() || previous.isSymbolicLink()) {
|
|
204
|
+
throw new McpOAuthStoreError('MCP OAuth credential file must be a regular file.');
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
descriptor = openSync(temp, 'wx', FILE_MODE);
|
|
208
|
+
// Windows file modes do not prove ACL privacy. Secure the empty file first.
|
|
209
|
+
restrictToOwner(temp);
|
|
210
|
+
const body = Buffer.from(`${JSON.stringify(record)}\n`, 'utf8');
|
|
211
|
+
for (let offset = 0; offset < body.length;) {
|
|
212
|
+
const written = writeSync(descriptor, body, offset, body.length - offset);
|
|
213
|
+
if (written <= 0)
|
|
214
|
+
throw new McpOAuthStoreError('Could not write MCP OAuth credentials.');
|
|
215
|
+
offset += written;
|
|
216
|
+
}
|
|
217
|
+
fsyncSync(descriptor);
|
|
218
|
+
closeSync(descriptor);
|
|
219
|
+
descriptor = undefined;
|
|
220
|
+
restrictToOwner(temp);
|
|
221
|
+
renameSync(temp, file);
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
if (descriptor !== undefined)
|
|
225
|
+
closeSync(descriptor);
|
|
226
|
+
rmSync(temp, { force: true });
|
|
227
|
+
if (error instanceof McpOAuthStoreError)
|
|
228
|
+
throw error;
|
|
229
|
+
throw new McpOAuthStoreError('Could not store MCP OAuth credentials privately.');
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function withRecordLock(endpoint, home, work, options = {}) {
|
|
233
|
+
const exact = normalizedEndpoint(endpoint);
|
|
234
|
+
const file = mcpOAuthPath(exact, home);
|
|
235
|
+
ensurePrivateDirectory(file, home);
|
|
236
|
+
const lock = `${file}.lock`;
|
|
237
|
+
const token = randomBytes(32).toString('hex');
|
|
238
|
+
let descriptor;
|
|
239
|
+
try {
|
|
240
|
+
descriptor = openSync(lock, 'wx', FILE_MODE);
|
|
241
|
+
restrictToOwner(lock);
|
|
242
|
+
const bytes = Buffer.from(token, 'utf8');
|
|
243
|
+
for (let offset = 0; offset < bytes.length;) {
|
|
244
|
+
const written = writeSync(descriptor, bytes, offset, bytes.length - offset);
|
|
245
|
+
if (written <= 0)
|
|
246
|
+
throw new McpOAuthStoreError('Could not write MCP OAuth store lock.');
|
|
247
|
+
offset += written;
|
|
248
|
+
}
|
|
249
|
+
fsyncSync(descriptor);
|
|
250
|
+
closeSync(descriptor);
|
|
251
|
+
descriptor = undefined;
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
if (descriptor !== undefined) {
|
|
255
|
+
closeSync(descriptor);
|
|
256
|
+
try {
|
|
257
|
+
rmSync(lock, { force: true });
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
// The next writer will refuse the unproven lock.
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
throw new McpOAuthStoreError('MCP OAuth credential store is locked or cannot be made private.');
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
removeOwnTemporaryFiles(file);
|
|
267
|
+
return work(options.skipRead
|
|
268
|
+
? { version: 1, endpoint: exact }
|
|
269
|
+
: (readRecord(exact, home) ?? { version: 1, endpoint: exact }));
|
|
270
|
+
}
|
|
271
|
+
finally {
|
|
272
|
+
// Never remove a lock replaced by another owner.
|
|
273
|
+
try {
|
|
274
|
+
if (readFileSync(lock, 'utf8') === token)
|
|
275
|
+
rmSync(lock, { force: true });
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
// A missing or replaced lock does not undo the credential write.
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/** Only the endpoint lock owner may remove its private crash leftovers. */
|
|
283
|
+
function removeOwnTemporaryFiles(file) {
|
|
284
|
+
const prefix = `${basename(file)}.tmp.`;
|
|
285
|
+
for (const entry of readdirSync(dirname(file))) {
|
|
286
|
+
if (!entry.startsWith(prefix) || !/^\d+\.[0-9a-f]{24}$/u.test(entry.slice(prefix.length))) {
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
rmSync(join(dirname(file), entry), { force: true });
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function updateRecord(endpoint, home, transform) {
|
|
293
|
+
withRecordLock(endpoint, home, (record) => {
|
|
294
|
+
writeRecord(mcpOAuthPath(endpoint, home), transform(record));
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
function discoveryIssuer(state) {
|
|
298
|
+
return state.authorizationServerMetadata?.issuer ?? state.authorizationServerUrl;
|
|
299
|
+
}
|
|
300
|
+
function fingerprint(value) {
|
|
301
|
+
return value === undefined
|
|
302
|
+
? null
|
|
303
|
+
: createHash('sha256').update(JSON.stringify(value)).digest('hex');
|
|
304
|
+
}
|
|
305
|
+
/** True only for a private, issuer-stamped token belonging to this exact URL. */
|
|
306
|
+
export function hasMcpOAuthTokens(endpoint, home) {
|
|
307
|
+
const record = readRecord(endpoint, home);
|
|
308
|
+
return !!(record?.issuer && record.tokens?.issuer === record.issuer);
|
|
309
|
+
}
|
|
310
|
+
/** Validate and consume state before passing callback parameters to `finishAuth`. */
|
|
311
|
+
export function consumeMcpOAuthCallbackState(endpoint, state, home) {
|
|
312
|
+
withRecordLock(endpoint, home, (record) => {
|
|
313
|
+
const pending = record.pending;
|
|
314
|
+
if (!pending ||
|
|
315
|
+
pending.consumed ||
|
|
316
|
+
!pending.codeVerifier ||
|
|
317
|
+
Date.now() - pending.createdAt > PENDING_LIFETIME_MS ||
|
|
318
|
+
pending.createdAt > Date.now() ||
|
|
319
|
+
fingerprint(record.clientInformation) !== pending.baseClient ||
|
|
320
|
+
!state ||
|
|
321
|
+
!sameSecret(state, pending.state)) {
|
|
322
|
+
throw new McpOAuthStoreError('MCP OAuth callback state is invalid or expired.');
|
|
323
|
+
}
|
|
324
|
+
writeRecord(mcpOAuthPath(endpoint, home), {
|
|
325
|
+
...record,
|
|
326
|
+
pending: { ...pending, consumed: true },
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
function sameSecret(left, right) {
|
|
331
|
+
const a = Buffer.from(left);
|
|
332
|
+
const b = Buffer.from(right);
|
|
333
|
+
return a.length === b.length && timingSafeEqual(a, b);
|
|
334
|
+
}
|
|
335
|
+
export function clearMcpOAuthPending(endpoint, home) {
|
|
336
|
+
withRecordLock(endpoint, home, (record) => {
|
|
337
|
+
if (!record.pending)
|
|
338
|
+
return;
|
|
339
|
+
const { pending: _pending, ...rest } = record;
|
|
340
|
+
writeRecord(mcpOAuthPath(endpoint, home), rest);
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
/** Remove only this URL's credentials; another server on the same host survives. */
|
|
344
|
+
export function clearMcpOAuthCredentials(endpoint, home) {
|
|
345
|
+
return withRecordLock(endpoint, home, (record) => {
|
|
346
|
+
const file = mcpOAuthPath(endpoint, home);
|
|
347
|
+
const entry = existingEntry(file);
|
|
348
|
+
if (!entry)
|
|
349
|
+
return false;
|
|
350
|
+
if (!entry.isFile() || entry.isSymbolicLink()) {
|
|
351
|
+
throw new McpOAuthStoreError('MCP OAuth credential file must be a regular file.');
|
|
352
|
+
}
|
|
353
|
+
if (record.endpoint !== normalizedEndpoint(endpoint)) {
|
|
354
|
+
throw new McpOAuthStoreError('MCP OAuth credential endpoint mismatch.');
|
|
355
|
+
}
|
|
356
|
+
rmSync(file);
|
|
357
|
+
return true;
|
|
358
|
+
}, { skipRead: true });
|
|
359
|
+
}
|
|
360
|
+
/** The official MCP client consumes this provider for login and token refresh. */
|
|
361
|
+
export function createMcpOAuthProvider(options) {
|
|
362
|
+
const endpoint = normalizedEndpoint(options.endpoint);
|
|
363
|
+
const interactive = options.onRedirect !== undefined;
|
|
364
|
+
if (interactive !== (options.redirectUrl !== undefined)) {
|
|
365
|
+
throw new McpOAuthStoreError('Interactive MCP OAuth requires a callback and browser opener together.');
|
|
366
|
+
}
|
|
367
|
+
const requestedRedirect = options.redirectUrl
|
|
368
|
+
? normalizedRedirect(options.redirectUrl)
|
|
369
|
+
: undefined;
|
|
370
|
+
const initial = readRecord(endpoint, options.home);
|
|
371
|
+
const redirect = requestedRedirect ?? initial?.redirectUrl;
|
|
372
|
+
if (!redirect)
|
|
373
|
+
throw new McpOAuthLoginRequiredError();
|
|
374
|
+
const home = options.home;
|
|
375
|
+
let observedTokens;
|
|
376
|
+
let observedClient;
|
|
377
|
+
return {
|
|
378
|
+
get redirectUrl() {
|
|
379
|
+
return redirect;
|
|
380
|
+
},
|
|
381
|
+
get clientMetadata() {
|
|
382
|
+
return { redirect_uris: [redirect], client_name: 'Namzu', application_type: 'native' };
|
|
383
|
+
},
|
|
384
|
+
state() {
|
|
385
|
+
if (!interactive)
|
|
386
|
+
throw new McpOAuthLoginRequiredError();
|
|
387
|
+
const state = randomBytes(32).toString('base64url');
|
|
388
|
+
updateRecord(endpoint, home, (record) => {
|
|
389
|
+
if (!record.discovery) {
|
|
390
|
+
throw new McpOAuthStoreError('MCP OAuth discovery is missing before redirect.');
|
|
391
|
+
}
|
|
392
|
+
return {
|
|
393
|
+
...record,
|
|
394
|
+
pending: {
|
|
395
|
+
state,
|
|
396
|
+
createdAt: Date.now(),
|
|
397
|
+
consumed: false,
|
|
398
|
+
discovery: record.discovery,
|
|
399
|
+
baseTokens: fingerprint(record.tokens),
|
|
400
|
+
baseClient: fingerprint(record.clientInformation),
|
|
401
|
+
},
|
|
402
|
+
};
|
|
403
|
+
});
|
|
404
|
+
return state;
|
|
405
|
+
},
|
|
406
|
+
clientInformation(ctx) {
|
|
407
|
+
const record = readRecord(endpoint, home);
|
|
408
|
+
if (ctx)
|
|
409
|
+
observedClient = fingerprint(record?.clientInformation);
|
|
410
|
+
if (!ctx?.issuer || !record?.issuer || record.issuer !== ctx.issuer)
|
|
411
|
+
return undefined;
|
|
412
|
+
if (requestedRedirect && record.redirectUrl !== requestedRedirect)
|
|
413
|
+
return undefined;
|
|
414
|
+
return record.clientInformation?.issuer === ctx.issuer ? record.clientInformation : undefined;
|
|
415
|
+
},
|
|
416
|
+
saveClientInformation(info, ctx) {
|
|
417
|
+
if (!interactive)
|
|
418
|
+
throw new McpOAuthLoginRequiredError();
|
|
419
|
+
if (!ctx?.issuer || info.issuer !== ctx.issuer || !nonempty(info.client_id)) {
|
|
420
|
+
throw new McpOAuthStoreError('MCP OAuth client information is missing its issuer stamp.');
|
|
421
|
+
}
|
|
422
|
+
updateRecord(endpoint, home, (record) => {
|
|
423
|
+
if (observedClient === undefined ||
|
|
424
|
+
fingerprint(record.clientInformation) !== observedClient) {
|
|
425
|
+
throw new McpOAuthStoreError('MCP OAuth client registration changed during authorization.');
|
|
426
|
+
}
|
|
427
|
+
const priorClient = record.clientInformation;
|
|
428
|
+
const replacing = record.issuer !== ctx.issuer ||
|
|
429
|
+
record.redirectUrl !== redirect ||
|
|
430
|
+
priorClient?.client_id !== info.client_id;
|
|
431
|
+
return {
|
|
432
|
+
...record,
|
|
433
|
+
issuer: ctx.issuer,
|
|
434
|
+
redirectUrl: redirect,
|
|
435
|
+
clientInformation: info,
|
|
436
|
+
...(replacing ? { tokens: undefined } : {}),
|
|
437
|
+
};
|
|
438
|
+
});
|
|
439
|
+
observedClient = fingerprint(info);
|
|
440
|
+
observedTokens = null;
|
|
441
|
+
},
|
|
442
|
+
tokens(ctx) {
|
|
443
|
+
const record = readRecord(endpoint, home);
|
|
444
|
+
const tokens = record?.issuer &&
|
|
445
|
+
(!ctx || ctx.issuer === record.issuer) &&
|
|
446
|
+
record.tokens?.issuer === record.issuer
|
|
447
|
+
? record.tokens
|
|
448
|
+
: undefined;
|
|
449
|
+
if (ctx)
|
|
450
|
+
observedTokens = fingerprint(record?.tokens);
|
|
451
|
+
return tokens;
|
|
452
|
+
},
|
|
453
|
+
saveTokens(tokens, ctx) {
|
|
454
|
+
if (!ctx?.issuer ||
|
|
455
|
+
tokens.issuer !== ctx.issuer ||
|
|
456
|
+
!nonempty(tokens.access_token) ||
|
|
457
|
+
!nonempty(tokens.token_type) ||
|
|
458
|
+
tokens.token_type.toLowerCase() !== 'bearer') {
|
|
459
|
+
throw new McpOAuthStoreError('MCP OAuth requires issuer-stamped Bearer tokens.');
|
|
460
|
+
}
|
|
461
|
+
updateRecord(endpoint, home, (record) => {
|
|
462
|
+
if (record.issuer !== ctx.issuer || record.clientInformation?.issuer !== ctx.issuer) {
|
|
463
|
+
throw new McpOAuthStoreError('MCP OAuth token issuer does not match its client registration.');
|
|
464
|
+
}
|
|
465
|
+
const expected = record.pending?.consumed ? record.pending.baseTokens : observedTokens;
|
|
466
|
+
if (expected === undefined || fingerprint(record.tokens) !== expected) {
|
|
467
|
+
throw new McpOAuthStoreError('MCP OAuth credential changed during token refresh.');
|
|
468
|
+
}
|
|
469
|
+
if (record.pending?.consumed &&
|
|
470
|
+
fingerprint(record.clientInformation) !== record.pending.baseClient) {
|
|
471
|
+
throw new McpOAuthStoreError('MCP OAuth client registration changed during authorization.');
|
|
472
|
+
}
|
|
473
|
+
return { ...record, tokens };
|
|
474
|
+
});
|
|
475
|
+
observedTokens = fingerprint(tokens);
|
|
476
|
+
},
|
|
477
|
+
redirectToAuthorization(url) {
|
|
478
|
+
if (!options.onRedirect)
|
|
479
|
+
throw new McpOAuthLoginRequiredError();
|
|
480
|
+
return options.onRedirect(url);
|
|
481
|
+
},
|
|
482
|
+
saveCodeVerifier(codeVerifier) {
|
|
483
|
+
if (!interactive || !nonempty(codeVerifier))
|
|
484
|
+
throw new McpOAuthLoginRequiredError();
|
|
485
|
+
updateRecord(endpoint, home, (record) => {
|
|
486
|
+
if (!record.pending || record.pending.consumed) {
|
|
487
|
+
throw new McpOAuthStoreError('MCP OAuth login state is missing.');
|
|
488
|
+
}
|
|
489
|
+
return { ...record, pending: { ...record.pending, codeVerifier } };
|
|
490
|
+
});
|
|
491
|
+
},
|
|
492
|
+
codeVerifier() {
|
|
493
|
+
const pending = readRecord(endpoint, home)?.pending;
|
|
494
|
+
if (!pending?.consumed || !pending.codeVerifier) {
|
|
495
|
+
throw new McpOAuthStoreError('MCP OAuth callback state has not been verified.');
|
|
496
|
+
}
|
|
497
|
+
return pending.codeVerifier;
|
|
498
|
+
},
|
|
499
|
+
saveDiscoveryState(state) {
|
|
500
|
+
checkedDiscovery(state);
|
|
501
|
+
updateRecord(endpoint, home, (record) => ({ ...record, discovery: state }));
|
|
502
|
+
},
|
|
503
|
+
discoveryState() {
|
|
504
|
+
const record = readRecord(endpoint, home);
|
|
505
|
+
// The callback must reuse the exact discovery snapshot that generated
|
|
506
|
+
// its authorization URL, even if another process refreshed the cache.
|
|
507
|
+
return record?.pending?.consumed ? record.pending.discovery : record?.discovery;
|
|
508
|
+
},
|
|
509
|
+
invalidateCredentials(scope) {
|
|
510
|
+
if (scope === 'all') {
|
|
511
|
+
clearMcpOAuthCredentials(endpoint, home);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
updateRecord(endpoint, home, (record) => {
|
|
515
|
+
if (scope === 'tokens') {
|
|
516
|
+
if (observedTokens === undefined || fingerprint(record.tokens) !== observedTokens) {
|
|
517
|
+
throw new McpOAuthStoreError('MCP OAuth credential changed during token refresh.');
|
|
518
|
+
}
|
|
519
|
+
return { ...record, tokens: undefined };
|
|
520
|
+
}
|
|
521
|
+
if (scope === 'client') {
|
|
522
|
+
if (observedClient === undefined ||
|
|
523
|
+
fingerprint(record.clientInformation) !== observedClient) {
|
|
524
|
+
throw new McpOAuthStoreError('MCP OAuth client registration changed during authorization.');
|
|
525
|
+
}
|
|
526
|
+
return { ...record, clientInformation: undefined, tokens: undefined, issuer: undefined };
|
|
527
|
+
}
|
|
528
|
+
if (scope === 'verifier')
|
|
529
|
+
return { ...record, pending: undefined };
|
|
530
|
+
return { ...record, discovery: undefined, pending: undefined };
|
|
531
|
+
});
|
|
532
|
+
if (scope === 'client') {
|
|
533
|
+
observedClient = null;
|
|
534
|
+
observedTokens = null;
|
|
535
|
+
}
|
|
536
|
+
else if (scope === 'tokens') {
|
|
537
|
+
observedTokens = null;
|
|
538
|
+
}
|
|
539
|
+
},
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
/** The authorization-server identity captured before the browser opened. */
|
|
543
|
+
export function pendingMcpOAuthIssuer(endpoint, home) {
|
|
544
|
+
const pending = readRecord(endpoint, home)?.pending;
|
|
545
|
+
return pending && Date.now() - pending.createdAt <= PENDING_LIFETIME_MS
|
|
546
|
+
? discoveryIssuer(pending.discovery)
|
|
547
|
+
: null;
|
|
548
|
+
}
|
|
549
|
+
//# sourceMappingURL=oauth-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-store.js","sourceRoot":"","sources":["../../../src/integrations/mcp/oauth-store.ts"],"names":[],"mappings":"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"}
|