From ac6e36f96b8d6f59eefc09dab079bef402c67710 Mon Sep 17 00:00:00 2001 From: wucm667 Date: Fri, 26 Jun 2026 14:11:25 +0800 Subject: [PATCH] =?UTF-8?q?feat(cli):=20sub2api-admin=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=20SUB2API=5FJWT=20=E8=AE=A4=E8=AF=81=E5=9B=9E=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skills/sub2api-admin/SKILL.md | 8 +++++--- skills/sub2api-admin/references/admin-cli.md | 10 +++++++++- skills/sub2api-admin/scripts/sub2api-admin.js | 4 +++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/skills/sub2api-admin/SKILL.md b/skills/sub2api-admin/SKILL.md index 7fcb17f369..5b36280b77 100644 --- a/skills/sub2api-admin/SKILL.md +++ b/skills/sub2api-admin/SKILL.md @@ -10,6 +10,8 @@ Use the bundled CLI instead of ad hoc `curl`. Run examples from this skill direc ```bash export SUB2API_BASE_URL='https://your-sub2api-host' export SUB2API_ADMIN_API_KEY='' +# Or, when the deployment uses admin JWT login instead of an admin API key: +# export SUB2API_JWT='' node scripts/sub2api-admin.js accounts list ``` @@ -17,7 +19,7 @@ For all commands and payload examples, read [references/admin-cli.md](references ## 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 `, `groups all`, or `proxies all`. 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. @@ -40,8 +42,8 @@ node scripts/sub2api-admin.js tls-profiles list ## Safety Notes -- Authentication uses only `x-api-key`. -- If the API returns `INVALID_ADMIN_KEY`, ask the user to regenerate the admin API key. +- Authentication uses `x-api-key` from `SUB2API_ADMIN_API_KEY` first, then falls back to `Authorization: Bearer ` from `SUB2API_JWT`. +- 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. - Redeem code create/redeem commands should use `--idempotency-key` for payment or recharge workflows. - For uncertain or newly added backend APIs, use `api ` after a read-only check. diff --git a/skills/sub2api-admin/references/admin-cli.md b/skills/sub2api-admin/references/admin-cli.md index 37a48066f7..0ffaff1206 100644 --- a/skills/sub2api-admin/references/admin-cli.md +++ b/skills/sub2api-admin/references/admin-cli.md @@ -5,9 +5,17 @@ ```bash export SUB2API_BASE_URL='https://your-sub2api-host' export SUB2API_ADMIN_API_KEY='' +# 或者,未配置管理员 API Key 时使用管理员 JWT: +# export SUB2API_JWT='' ``` -后台鉴权只使用 `x-api-key`。如果返回 `INVALID_ADMIN_KEY`,重新生成管理员 API Key。 +后台鉴权优先使用 `SUB2API_ADMIN_API_KEY` 发送 `x-api-key`,未设置时使用 `SUB2API_JWT` 发送 `Authorization: Bearer `。如果返回 `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 diff --git a/skills/sub2api-admin/scripts/sub2api-admin.js b/skills/sub2api-admin/scripts/sub2api-admin.js index 4ac5e38159..5891ae899d 100755 --- a/skills/sub2api-admin/scripts/sub2api-admin.js +++ b/skills/sub2api-admin/scripts/sub2api-admin.js @@ -5,6 +5,7 @@ const path = require("path"); const BASE_URL = (process.env.SUB2API_BASE_URL || "").replace(/\/$/, ""); const ADMIN_API_KEY = process.env.SUB2API_ADMIN_API_KEY || ""; +const ADMIN_JWT = process.env.SUB2API_JWT || ""; function usage() { console.log(`Usage: @@ -91,7 +92,8 @@ function parseArgs(argv) { function authHeaders() { if (!BASE_URL) throw new Error("Missing SUB2API_BASE_URL"); 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 = {}) {