@askalf/dario 3.31.2 → 3.31.3
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/cc-oauth-detect.d.ts +17 -0
- package/dist/cc-oauth-detect.js +40 -8
- package/package.json +1 -1
|
@@ -46,6 +46,23 @@ export interface DetectedOAuthConfig {
|
|
|
46
46
|
ccPath?: string;
|
|
47
47
|
ccHash?: string;
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Normalize the authorize URL to match what CC uses at runtime.
|
|
51
|
+
*
|
|
52
|
+
* The CC binary ships `CLAUDE_AI_AUTHORIZE_URL: "https://claude.com/cai/oauth/authorize"`
|
|
53
|
+
* as a literal string, but at runtime CC's `/login` opens
|
|
54
|
+
* `https://claude.ai/oauth/authorize` directly (empirically verified against
|
|
55
|
+
* CC v2.1.116 by tetsuco in dario#71). Historically the claude.com edge
|
|
56
|
+
* 307-redirected to claude.ai and the browser followed; recent Anthropic-side
|
|
57
|
+
* changes made the post-redirect validation start returning "Invalid request
|
|
58
|
+
* format", while direct requests to claude.ai continue to work. This normalizer
|
|
59
|
+
* rewrites the legacy URL wherever it appears (binary extraction, manual
|
|
60
|
+
* override, cached config) so dario matches CC's runtime behaviour.
|
|
61
|
+
*
|
|
62
|
+
* Intentionally narrow: only the exact legacy URL is rewritten. Any other
|
|
63
|
+
* operator-supplied URL (e.g. a staging endpoint via override) passes through.
|
|
64
|
+
*/
|
|
65
|
+
export declare function normalizeAuthorizeUrl(url: string): string;
|
|
49
66
|
export declare const FALLBACK_FOR_DRIFT_CHECK: Readonly<DetectedOAuthConfig>;
|
|
50
67
|
/**
|
|
51
68
|
* Scan binary bytes for the PROD OAuth config block.
|
package/dist/cc-oauth-detect.js
CHANGED
|
@@ -42,12 +42,35 @@ import { existsSync } from 'node:fs';
|
|
|
42
42
|
import { homedir, platform } from 'node:os';
|
|
43
43
|
import { join, dirname } from 'node:path';
|
|
44
44
|
import { createHash } from 'node:crypto';
|
|
45
|
+
/**
|
|
46
|
+
* Normalize the authorize URL to match what CC uses at runtime.
|
|
47
|
+
*
|
|
48
|
+
* The CC binary ships `CLAUDE_AI_AUTHORIZE_URL: "https://claude.com/cai/oauth/authorize"`
|
|
49
|
+
* as a literal string, but at runtime CC's `/login` opens
|
|
50
|
+
* `https://claude.ai/oauth/authorize` directly (empirically verified against
|
|
51
|
+
* CC v2.1.116 by tetsuco in dario#71). Historically the claude.com edge
|
|
52
|
+
* 307-redirected to claude.ai and the browser followed; recent Anthropic-side
|
|
53
|
+
* changes made the post-redirect validation start returning "Invalid request
|
|
54
|
+
* format", while direct requests to claude.ai continue to work. This normalizer
|
|
55
|
+
* rewrites the legacy URL wherever it appears (binary extraction, manual
|
|
56
|
+
* override, cached config) so dario matches CC's runtime behaviour.
|
|
57
|
+
*
|
|
58
|
+
* Intentionally narrow: only the exact legacy URL is rewritten. Any other
|
|
59
|
+
* operator-supplied URL (e.g. a staging endpoint via override) passes through.
|
|
60
|
+
*/
|
|
61
|
+
export function normalizeAuthorizeUrl(url) {
|
|
62
|
+
if (url === 'https://claude.com/cai/oauth/authorize') {
|
|
63
|
+
return 'https://claude.ai/oauth/authorize';
|
|
64
|
+
}
|
|
65
|
+
return url;
|
|
66
|
+
}
|
|
45
67
|
// Last-resort fallback if CC binary can't be found or scanned.
|
|
46
68
|
// These values are the CC v2.1.104 PROD OAuth config, extracted from
|
|
47
|
-
// the `nh$` object in the shipped binary.
|
|
69
|
+
// the `nh$` object in the shipped binary. authorizeUrl is normalized —
|
|
70
|
+
// see normalizeAuthorizeUrl() above for why this matters (dario#71).
|
|
48
71
|
const FALLBACK = {
|
|
49
72
|
clientId: '9d1c250a-e61b-44d9-88ed-5944d1962f5e',
|
|
50
|
-
authorizeUrl: 'https://claude.
|
|
73
|
+
authorizeUrl: 'https://claude.ai/oauth/authorize',
|
|
51
74
|
tokenUrl: 'https://platform.claude.com/v1/oauth/token',
|
|
52
75
|
// Scopes match CC v2.1.107+ interactive login: the 5-scope user-only set.
|
|
53
76
|
// Between CC v2.1.104 and v2.1.107, Anthropic's authorize endpoint flipped
|
|
@@ -68,10 +91,12 @@ const FALLBACK = {
|
|
|
68
91
|
// needs the exact values the runtime uses — hardcoding them in the script
|
|
69
92
|
// would drift out of sync silently.
|
|
70
93
|
export const FALLBACK_FOR_DRIFT_CHECK = FALLBACK;
|
|
71
|
-
// -
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
|
|
94
|
+
// -v5 suffix invalidates v3.x caches populated with the pre-normalized
|
|
95
|
+
// authorize URL that now fails "Invalid request format" via the 307-redirect
|
|
96
|
+
// hop (dario#71). On upgrade, users regenerate the cache with the normalized
|
|
97
|
+
// FALLBACK.authorizeUrl automatically — no manual clear required. Previous
|
|
98
|
+
// bump was -v3 → -v4 in v3.19.4 for the 6-scope → 5-scope rotation (dario#42).
|
|
99
|
+
const CACHE_PATH = join(homedir(), '.dario', 'cc-oauth-cache-v5.json');
|
|
75
100
|
const DEFAULT_OVERRIDE_PATH = join(homedir(), '.dario', 'oauth-config.override.json');
|
|
76
101
|
function candidatePaths() {
|
|
77
102
|
const home = homedir();
|
|
@@ -162,9 +187,16 @@ function applyManualOverride(config, override) {
|
|
|
162
187
|
return config;
|
|
163
188
|
warnOnNonHttpsOverride('authorizeUrl', override.authorizeUrl);
|
|
164
189
|
warnOnNonHttpsOverride('tokenUrl', override.tokenUrl);
|
|
190
|
+
// Normalize any override-supplied authorizeUrl too — users who pasted the
|
|
191
|
+
// legacy claude.com URL into ~/.dario/oauth-config.override.json pre-#71
|
|
192
|
+
// shouldn't be silently broken after upgrade.
|
|
193
|
+
const normalizedOverride = { ...override };
|
|
194
|
+
if (normalizedOverride.authorizeUrl) {
|
|
195
|
+
normalizedOverride.authorizeUrl = normalizeAuthorizeUrl(normalizedOverride.authorizeUrl);
|
|
196
|
+
}
|
|
165
197
|
return {
|
|
166
198
|
...config,
|
|
167
|
-
...
|
|
199
|
+
...normalizedOverride,
|
|
168
200
|
source: 'override',
|
|
169
201
|
};
|
|
170
202
|
}
|
|
@@ -222,7 +254,7 @@ export function scanBinaryForOAuthConfig(buf) {
|
|
|
222
254
|
let authorizeUrl = FALLBACK.authorizeUrl;
|
|
223
255
|
const authMatch = /CLAUDE_AI_AUTHORIZE_URL\s*:\s*"([^"]+)"/.exec(prodBlock);
|
|
224
256
|
if (authMatch && authMatch[1])
|
|
225
|
-
authorizeUrl = authMatch[1];
|
|
257
|
+
authorizeUrl = normalizeAuthorizeUrl(authMatch[1]);
|
|
226
258
|
let tokenUrl = FALLBACK.tokenUrl;
|
|
227
259
|
const tokenMatch = /TOKEN_URL\s*:\s*"(https:\/\/[^"]*\/oauth\/token[^"]*)"/.exec(prodBlock);
|
|
228
260
|
if (tokenMatch && tokenMatch[1])
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askalf/dario",
|
|
3
|
-
"version": "3.31.
|
|
3
|
+
"version": "3.31.3",
|
|
4
4
|
"description": "A local LLM router. One endpoint, every provider — Claude subscriptions, OpenAI, OpenRouter, Groq, local LiteLLM, any OpenAI-compat endpoint — your tools don't need to change.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|