feat(cli): sub2api-admin 支持 SUB2API_JWT 认证回退

This commit is contained in:
wucm667
2026-06-26 14:11:25 +08:00
parent 5f022663ac
commit ac6e36f96b
3 changed files with 17 additions and 5 deletions
+5 -3
View File
@@ -10,6 +10,8 @@ Use the bundled CLI instead of ad hoc `curl`. Run examples from this skill direc
```bash ```bash
export SUB2API_BASE_URL='https://your-sub2api-host' export SUB2API_BASE_URL='https://your-sub2api-host'
export SUB2API_ADMIN_API_KEY='<admin api key>' export SUB2API_ADMIN_API_KEY='<admin api key>'
# Or, when the deployment uses admin JWT login instead of an admin API key:
# export SUB2API_JWT='<admin access_token>'
node scripts/sub2api-admin.js accounts list node scripts/sub2api-admin.js accounts list
``` ```
@@ -17,7 +19,7 @@ For all commands and payload examples, read [references/admin-cli.md](references
## Workflow ## Workflow
1. Reuse `SUB2API_BASE_URL` and `SUB2API_ADMIN_API_KEY` from the environment. 1. Reuse `SUB2API_BASE_URL` and either `SUB2API_ADMIN_API_KEY` or `SUB2API_JWT` from the environment.
2. Run read-only commands first: `accounts list`, `accounts get <id>`, `groups all`, or `proxies all`. 2. Run read-only commands first: `accounts list`, `accounts get <id>`, `groups all`, or `proxies all`.
3. Before destructive or bulk writes, print the target account names and IDs. 3. Before destructive or bulk writes, print the target account names and IDs.
4. Execute the write command only after the target set is clear. 4. Execute the write command only after the target set is clear.
@@ -40,8 +42,8 @@ node scripts/sub2api-admin.js tls-profiles list
## Safety Notes ## Safety Notes
- Authentication uses only `x-api-key`. - Authentication uses `x-api-key` from `SUB2API_ADMIN_API_KEY` first, then falls back to `Authorization: Bearer <jwt>` from `SUB2API_JWT`.
- If the API returns `INVALID_ADMIN_KEY`, ask the user to regenerate the admin API key. - If the API returns `INVALID_ADMIN_KEY`, ask the user to regenerate the admin API key. If using JWT, log in as an admin user and copy the `access_token` from `POST /api/v1/auth/login`.
- `accounts export` includes credentials and tokens. Prefer `--file` and avoid printing exports in chat. - `accounts export` includes credentials and tokens. Prefer `--file` and avoid printing exports in chat.
- Redeem code create/redeem commands should use `--idempotency-key` for payment or recharge workflows. - Redeem code create/redeem commands should use `--idempotency-key` for payment or recharge workflows.
- For uncertain or newly added backend APIs, use `api <METHOD> <admin-path>` after a read-only check. - For uncertain or newly added backend APIs, use `api <METHOD> <admin-path>` after a read-only check.
+9 -1
View File
@@ -5,9 +5,17 @@
```bash ```bash
export SUB2API_BASE_URL='https://your-sub2api-host' export SUB2API_BASE_URL='https://your-sub2api-host'
export SUB2API_ADMIN_API_KEY='<admin api key>' export SUB2API_ADMIN_API_KEY='<admin api key>'
# 或者,未配置管理员 API Key 时使用管理员 JWT:
# export SUB2API_JWT='<admin access_token>'
``` ```
后台鉴权只使用 `x-api-key`。如果返回 `INVALID_ADMIN_KEY`,重新生成管理员 API Key。 后台鉴权优先使用 `SUB2API_ADMIN_API_KEY` 发送 `x-api-key`,未设置时使用 `SUB2API_JWT` 发送 `Authorization: Bearer <jwt>`。如果返回 `INVALID_ADMIN_KEY`,重新生成管理员 API Key;如果使用 JWT,先用管理员邮箱密码登录并从响应的 `data.access_token` 复制 token:
```bash
curl -sS "$SUB2API_BASE_URL/api/v1/auth/login" \
-H 'Content-Type: application/json' \
-d '{"email":"admin@example.com","password":"your-password"}'
```
## CLI ## CLI
@@ -5,6 +5,7 @@ const path = require("path");
const BASE_URL = (process.env.SUB2API_BASE_URL || "").replace(/\/$/, ""); const BASE_URL = (process.env.SUB2API_BASE_URL || "").replace(/\/$/, "");
const ADMIN_API_KEY = process.env.SUB2API_ADMIN_API_KEY || ""; const ADMIN_API_KEY = process.env.SUB2API_ADMIN_API_KEY || "";
const ADMIN_JWT = process.env.SUB2API_JWT || "";
function usage() { function usage() {
console.log(`Usage: console.log(`Usage:
@@ -91,7 +92,8 @@ function parseArgs(argv) {
function authHeaders() { function authHeaders() {
if (!BASE_URL) throw new Error("Missing SUB2API_BASE_URL"); if (!BASE_URL) throw new Error("Missing SUB2API_BASE_URL");
if (ADMIN_API_KEY) return { "x-api-key": ADMIN_API_KEY }; if (ADMIN_API_KEY) return { "x-api-key": ADMIN_API_KEY };
throw new Error("Missing SUB2API_ADMIN_API_KEY"); if (ADMIN_JWT) return { Authorization: `Bearer ${ADMIN_JWT}` };
throw new Error("Missing SUB2API_ADMIN_API_KEY or SUB2API_JWT");
} }
async function apiRequest(method, pathname, body, extraHeaders = {}) { async function apiRequest(method, pathname, body, extraHeaders = {}) {