codex-claude-proxy 1.0.1 → 1.0.2
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 +5 -23
- package/docs/ARCHITECTURE.md +1 -1
- package/images/demo-screenshot.png +0 -0
- package/package.json +1 -1
- package/public/js/app.js +1 -1
- package/src/account-manager.js +5 -5
- package/src/claude-config.js +2 -2
- package/src/cli/accounts.js +2 -2
- package/src/index.js +1 -1
- package/src/server-settings.js +2 -2
- package/src/server.js +28 -1
package/README.md
CHANGED
|
@@ -14,7 +14,6 @@ It is designed primarily for **Claude Code CLI** (Anthropic-format client) while
|
|
|
14
14
|
- [Quick Start](#quick-start)
|
|
15
15
|
- [Authentication](#authenticate-codex--chatgpt)
|
|
16
16
|
- [Claude Code Integration](#configure-claude-code-to-use-the-proxy)
|
|
17
|
-
- [API Reference](#api-surface-high-level)
|
|
18
17
|
- [Documentation](#documentation)
|
|
19
18
|
- [Legal](#legal)
|
|
20
19
|
|
|
@@ -59,7 +58,7 @@ This proxy accepts Claude-style model IDs (what Claude Code expects) and maps th
|
|
|
59
58
|
|---|---|---:|---|
|
|
60
59
|
| `claude-sonnet-4-5` | **GPT-5.2 Codex** | Yes | Default “Sonnet” lane |
|
|
61
60
|
| `claude-opus-4-5` | **GPT-5.3 Codex** | Yes | Default “Opus” lane |
|
|
62
|
-
| `claude-haiku-4` | **
|
|
61
|
+
| `claude-haiku-4` | **GLM-5 / MiniMax M2.5** | No | Unlimited / No Auth required |
|
|
63
62
|
|
|
64
63
|
---
|
|
65
64
|
|
|
@@ -198,31 +197,14 @@ More details: [Claude Code Integration](./docs/CLAUDE_INTEGRATION.md).
|
|
|
198
197
|
|
|
199
198
|
---
|
|
200
199
|
|
|
201
|
-
##
|
|
200
|
+
## Security
|
|
202
201
|
|
|
203
|
-
-
|
|
204
|
-
|
|
205
|
-
- `GET /v1/models`
|
|
206
|
-
- `POST /v1/messages/count_tokens`
|
|
207
|
-
|
|
208
|
-
- OpenAI-compatible:
|
|
209
|
-
- `POST /v1/chat/completions`
|
|
210
|
-
|
|
211
|
-
- Accounts:
|
|
212
|
-
- `GET /accounts`
|
|
213
|
-
- `POST /accounts/add`
|
|
214
|
-
- `POST /accounts/add/manual`
|
|
215
|
-
- `POST /accounts/switch`
|
|
216
|
-
- `POST /accounts/refresh`, `POST /accounts/refresh/all`
|
|
217
|
-
|
|
218
|
-
- Logs:
|
|
219
|
-
- `GET /api/logs`
|
|
220
|
-
- `GET /api/logs/stream?history=true`
|
|
221
|
-
|
|
222
|
-
Full reference: [API Reference](./docs/API.md).
|
|
202
|
+
- **Localhost Only**: CORS is strictly restricted to `localhost` and `127.0.0.1` to prevent unauthorized cross-origin requests from external websites.
|
|
203
|
+
- **Credential Safety**: Credentials are not allowed in cross-origin requests.
|
|
223
204
|
|
|
224
205
|
---
|
|
225
206
|
|
|
207
|
+
|
|
226
208
|
## Documentation
|
|
227
209
|
|
|
228
210
|
- [**Architecture**](./docs/ARCHITECTURE.md) - Design and flow
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -51,7 +51,7 @@ codex-claude-proxy/
|
|
|
51
51
|
| File | Purpose |
|
|
52
52
|
|------|---------|
|
|
53
53
|
| `index.js` | Entry point (starts server) |
|
|
54
|
-
| `server.js` | Express server, routes, request handling |
|
|
54
|
+
| `server.js` | Express server, routes, request handling (CORS restricted) |
|
|
55
55
|
| `routes/api-routes.js` | API route registrations (mounted by server) |
|
|
56
56
|
| `oauth.js` | OAuth 2.0 PKCE flow, token exchange |
|
|
57
57
|
| `account-manager.js` | Account persistence, switching, token refresh |
|
|
Binary file
|
package/package.json
CHANGED
package/public/js/app.js
CHANGED
package/src/account-manager.js
CHANGED
|
@@ -26,10 +26,10 @@ const tokenCache = new Map();
|
|
|
26
26
|
|
|
27
27
|
function ensureConfigDir() {
|
|
28
28
|
if (!existsSync(CONFIG_DIR)) {
|
|
29
|
-
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
29
|
+
mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
30
30
|
}
|
|
31
31
|
if (!existsSync(ACCOUNTS_DIR)) {
|
|
32
|
-
mkdirSync(ACCOUNTS_DIR, { recursive: true });
|
|
32
|
+
mkdirSync(ACCOUNTS_DIR, { recursive: true, mode: 0o700 });
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -64,7 +64,7 @@ function loadAccounts() {
|
|
|
64
64
|
|
|
65
65
|
function saveAccounts(data) {
|
|
66
66
|
ensureConfigDir();
|
|
67
|
-
writeFileSync(ACCOUNTS_FILE, JSON.stringify(data, null, 2));
|
|
67
|
+
writeFileSync(ACCOUNTS_FILE, JSON.stringify(data, null, 2), { mode: 0o600 });
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
function getActiveAccount() {
|
|
@@ -80,7 +80,7 @@ function updateAccountAuth(account) {
|
|
|
80
80
|
const authFile = getAccountAuthFile(account.email);
|
|
81
81
|
|
|
82
82
|
if (!existsSync(accountDir)) {
|
|
83
|
-
mkdirSync(accountDir, { recursive: true });
|
|
83
|
+
mkdirSync(accountDir, { recursive: true, mode: 0o700 });
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
const authData = {
|
|
@@ -96,7 +96,7 @@ function updateAccountAuth(account) {
|
|
|
96
96
|
};
|
|
97
97
|
|
|
98
98
|
try {
|
|
99
|
-
writeFileSync(authFile, JSON.stringify(authData, null, 2));
|
|
99
|
+
writeFileSync(authFile, JSON.stringify(authData, null, 2), { mode: 0o600 });
|
|
100
100
|
console.log(`[AccountManager] Updated auth for: ${account.email}`);
|
|
101
101
|
} catch (e) {
|
|
102
102
|
console.error('[AccountManager] Failed to update auth:', e.message);
|
package/src/claude-config.js
CHANGED
|
@@ -60,13 +60,13 @@ export async function updateClaudeConfig(updates) {
|
|
|
60
60
|
|
|
61
61
|
const configDir = path.dirname(configPath);
|
|
62
62
|
try {
|
|
63
|
-
await fs.mkdir(configDir, { recursive: true });
|
|
63
|
+
await fs.mkdir(configDir, { recursive: true, mode: 0o700 });
|
|
64
64
|
} catch (error) {
|
|
65
65
|
// Ignore if exists
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
try {
|
|
69
|
-
await fs.writeFile(configPath, JSON.stringify(newConfig, null, 2), 'utf8');
|
|
69
|
+
await fs.writeFile(configPath, JSON.stringify(newConfig, null, 2), { encoding: 'utf8', mode: 0o600 });
|
|
70
70
|
console.log(`[ClaudeConfig] Updated config at ${configPath}`);
|
|
71
71
|
return newConfig;
|
|
72
72
|
} catch (error) {
|
package/src/cli/accounts.js
CHANGED
|
@@ -39,9 +39,9 @@ function saveAccounts(data) {
|
|
|
39
39
|
try {
|
|
40
40
|
const dir = dirname(ACCOUNTS_FILE);
|
|
41
41
|
if (!existsSync(dir)) {
|
|
42
|
-
mkdirSync(dir, { recursive: true });
|
|
42
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
43
43
|
}
|
|
44
|
-
writeFileSync(ACCOUNTS_FILE, JSON.stringify(data, null, 2));
|
|
44
|
+
writeFileSync(ACCOUNTS_FILE, JSON.stringify(data, null, 2), { mode: 0o600 });
|
|
45
45
|
console.log(`\n✓ Saved ${data.accounts.length} account(s) to ${ACCOUNTS_FILE}`);
|
|
46
46
|
} catch (error) {
|
|
47
47
|
console.error('Error saving accounts:', error.message);
|
package/src/index.js
CHANGED
|
@@ -13,7 +13,7 @@ startServer({ port: PORT });
|
|
|
13
13
|
|
|
14
14
|
console.log(`
|
|
15
15
|
╔══════════════════════════════════════════════════════════════╗
|
|
16
|
-
║ Codex Claude Proxy v1.0.
|
|
16
|
+
║ Codex Claude Proxy v1.0.2 ║
|
|
17
17
|
║ (Direct API Mode) ║
|
|
18
18
|
╠══════════════════════════════════════════════════════════════╣
|
|
19
19
|
║ Server: http://localhost:${PORT} ║
|
package/src/server-settings.js
CHANGED
|
@@ -10,7 +10,7 @@ const DEFAULT_SETTINGS = {
|
|
|
10
10
|
|
|
11
11
|
function ensureConfigDir() {
|
|
12
12
|
if (!existsSync(CONFIG_DIR)) {
|
|
13
|
-
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
13
|
+
mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -35,7 +35,7 @@ export function setServerSettings(patch = {}) {
|
|
|
35
35
|
const next = { ...current, ...patch };
|
|
36
36
|
|
|
37
37
|
ensureConfigDir();
|
|
38
|
-
writeFileSync(SETTINGS_FILE, JSON.stringify(next, null, 2));
|
|
38
|
+
writeFileSync(SETTINGS_FILE, JSON.stringify(next, null, 2), { mode: 0o600 });
|
|
39
39
|
return next;
|
|
40
40
|
}
|
|
41
41
|
|
package/src/server.js
CHANGED
|
@@ -14,7 +14,34 @@ export function createServer({ port }) {
|
|
|
14
14
|
startAutoRefresh();
|
|
15
15
|
|
|
16
16
|
const app = express();
|
|
17
|
-
app.
|
|
17
|
+
app.disable('x-powered-by');
|
|
18
|
+
|
|
19
|
+
// High-level request logging
|
|
20
|
+
app.use((req, res, next) => {
|
|
21
|
+
const start = Date.now();
|
|
22
|
+
res.on('finish', () => {
|
|
23
|
+
const duration = Date.now() - start;
|
|
24
|
+
const msg = `[${req.method}] ${req.originalUrl} ${res.statusCode} (${duration}ms)`;
|
|
25
|
+
if (res.statusCode >= 400) {
|
|
26
|
+
console.log(`\x1b[31m${msg}\x1b[0m`); // Red for error
|
|
27
|
+
} else if (req.originalUrl !== '/health') { // Skip health check logs to reduce noise
|
|
28
|
+
console.log(`\x1b[36m${msg}\x1b[0m`); // Cyan for success
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
next();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
app.use(cors({
|
|
35
|
+
origin: [
|
|
36
|
+
`http://localhost:${port}`,
|
|
37
|
+
`http://127.0.0.1:${port}`,
|
|
38
|
+
'http://localhost',
|
|
39
|
+
'http://127.0.0.1'
|
|
40
|
+
],
|
|
41
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
42
|
+
allowedHeaders: ['Content-Type', 'Authorization'],
|
|
43
|
+
credentials: false
|
|
44
|
+
}));
|
|
18
45
|
app.use(express.json({ limit: '10mb' }));
|
|
19
46
|
|
|
20
47
|
registerApiRoutes(app, { port });
|