@askalf/dario 1.0.2 → 1.0.4
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 +1 -1
- package/dist/cli.js +1 -1
- package/dist/proxy.js +15 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -146,7 +146,7 @@ curl http://localhost:3456/v1/messages \
|
|
|
146
146
|
-H "Content-Type: application/json" \
|
|
147
147
|
-H "anthropic-version: 2023-06-01" \
|
|
148
148
|
-d '{
|
|
149
|
-
"model": "claude-
|
|
149
|
+
"model": "claude-opus-4-6",
|
|
150
150
|
"max_tokens": 1024,
|
|
151
151
|
"stream": true,
|
|
152
152
|
"messages": [{"role": "user", "content": "Write a haiku about APIs"}]
|
package/dist/cli.js
CHANGED
|
@@ -152,7 +152,7 @@ async function help() {
|
|
|
152
152
|
Example with curl:
|
|
153
153
|
curl http://localhost:3456/v1/messages \\
|
|
154
154
|
-H "Content-Type: application/json" \\
|
|
155
|
-
-d '{"model":"claude-
|
|
155
|
+
-d '{"model":"claude-opus-4-6","max_tokens":1024,"messages":[{"role":"user","content":"Hello"}]}'
|
|
156
156
|
|
|
157
157
|
Your subscription handles the billing. No API key needed.
|
|
158
158
|
Tokens auto-refresh in the background — set it and forget it.
|
package/dist/proxy.js
CHANGED
|
@@ -12,7 +12,6 @@ import { getAccessToken, getStatus } from './oauth.js';
|
|
|
12
12
|
const ANTHROPIC_API = 'https://api.anthropic.com';
|
|
13
13
|
const DEFAULT_PORT = 3456;
|
|
14
14
|
const MAX_BODY_BYTES = 10 * 1024 * 1024; // 10 MB — generous for large prompts, prevents abuse
|
|
15
|
-
const ALLOWED_PATH_PREFIX = '/v1/'; // Only proxy Anthropic API paths
|
|
16
15
|
const LOCALHOST = '127.0.0.1';
|
|
17
16
|
const CORS_ORIGIN = 'http://localhost';
|
|
18
17
|
function sanitizeError(err) {
|
|
@@ -62,14 +61,20 @@ export async function startProxy(opts = {}) {
|
|
|
62
61
|
res.end(JSON.stringify(s));
|
|
63
62
|
return;
|
|
64
63
|
}
|
|
65
|
-
//
|
|
66
|
-
const
|
|
67
|
-
|
|
64
|
+
// Allowlisted API paths — only these are proxied (prevents SSRF)
|
|
65
|
+
const rawPath = req.url?.split('?')[0] ?? '';
|
|
66
|
+
const allowedPaths = {
|
|
67
|
+
'/v1/messages': `${ANTHROPIC_API}/v1/messages`,
|
|
68
|
+
'/v1/models': `${ANTHROPIC_API}/v1/models`,
|
|
69
|
+
'/v1/complete': `${ANTHROPIC_API}/v1/complete`,
|
|
70
|
+
};
|
|
71
|
+
const targetBase = allowedPaths[rawPath];
|
|
72
|
+
if (!targetBase) {
|
|
68
73
|
res.writeHead(403, { 'Content-Type': 'application/json' });
|
|
69
|
-
res.end(JSON.stringify({ error: 'Forbidden', message:
|
|
74
|
+
res.end(JSON.stringify({ error: 'Forbidden', message: 'Path not allowed' }));
|
|
70
75
|
return;
|
|
71
76
|
}
|
|
72
|
-
// Only allow POST (Messages API) and GET (models
|
|
77
|
+
// Only allow POST (Messages API) and GET (models)
|
|
73
78
|
if (req.method !== 'POST' && req.method !== 'GET') {
|
|
74
79
|
res.writeHead(405, { 'Content-Type': 'application/json' });
|
|
75
80
|
res.end(JSON.stringify({ error: 'Method not allowed' }));
|
|
@@ -96,8 +101,8 @@ export async function startProxy(opts = {}) {
|
|
|
96
101
|
if (verbose) {
|
|
97
102
|
console.log(`[dario] #${requestCount} ${req.method} ${req.url}`);
|
|
98
103
|
}
|
|
99
|
-
//
|
|
100
|
-
const targetUrl =
|
|
104
|
+
// Build target URL from allowlist (no user input in URL construction)
|
|
105
|
+
const targetUrl = targetBase;
|
|
101
106
|
// Merge any client-provided beta flags with the required oauth flag
|
|
102
107
|
const clientBeta = req.headers['anthropic-beta'];
|
|
103
108
|
const betaFlags = new Set(['oauth-2025-04-20']);
|
|
@@ -173,9 +178,10 @@ export async function startProxy(opts = {}) {
|
|
|
173
178
|
}
|
|
174
179
|
}
|
|
175
180
|
catch (err) {
|
|
181
|
+
// Log full error server-side, return generic message to client
|
|
176
182
|
console.error('[dario] Proxy error:', sanitizeError(err));
|
|
177
183
|
res.writeHead(502, { 'Content-Type': 'application/json' });
|
|
178
|
-
res.end(JSON.stringify({ error: 'Proxy error', message:
|
|
184
|
+
res.end(JSON.stringify({ error: 'Proxy error', message: 'Failed to reach upstream API' }));
|
|
179
185
|
}
|
|
180
186
|
});
|
|
181
187
|
server.listen(port, LOCALHOST, () => {
|