Update JWT_SECRET handling

This commit is contained in:
decolua 2026-05-15 09:15:53 +07:00
parent 1fd3132647
commit fe3ce25ae3
8 changed files with 24 additions and 8 deletions

View file

@ -1096,7 +1096,7 @@ docker pull decolua/9router:latest # update to latest
| Variable | Default | Description |
|----------|---------|-------------|
| `JWT_SECRET` | `9router-default-secret-change-me` | JWT signing secret for dashboard auth cookie (**change in production**) |
| `JWT_SECRET` | Auto-generated (`~/.9router/jwt-secret`) | JWT signing secret for dashboard auth cookie (override to share across instances) |
| `INITIAL_PASSWORD` | `123456` | First login password when no saved hash exists |
| `DATA_DIR` | `~/.9router` | Main app data location (SQLite at `$DATA_DIR/db/data.sqlite`) |
| `PORT` | framework default | Service port (`20128` in examples) |

View file

@ -1089,7 +1089,7 @@ docker stop 9router && docker rm 9router
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `JWT_SECRET` | `9router-default-secret-change-me` | 用于控制面板 auth cookie 的 JWT 签名密钥(**生产环境请更改** |
| `JWT_SECRET` | 自动生成(`~/.9router/jwt-secret` | 用于控制面板 auth cookie 的 JWT 签名密钥(设置可在多实例间共享 |
| `INITIAL_PASSWORD` | `123456` | 当没有保存的哈希时首次登录的密码 |
| `DATA_DIR` | `~/.9router` | 主应用数据库位置(`db.json` |
| `PORT` | 框架默认值 | 服务端口(示例中为 `20128` |

View file

@ -1016,7 +1016,7 @@ docker stop 9router && docker rm 9router
| 変数 | デフォルト | 説明 |
|------|-----------|------|
| `JWT_SECRET` | `9router-default-secret-change-me` | ダッシュボード認証クッキーのJWT署名シークレット**本番環境では変更必須** |
| `JWT_SECRET` | 自動生成(`~/.9router/jwt-secret` | ダッシュボード認証クッキーのJWT署名シークレット複数インスタンス間で共有する場合に設定 |
| `INITIAL_PASSWORD` | `123456` | 保存されたハッシュがない場合の初回ログインパスワード |
| `DATA_DIR` | `~/.9router` | メインアプリのデータベース格納場所(`db.json` |
| `PORT` | フレームワークデフォルト | サービスポート(例では`20128` |

View file

@ -1018,7 +1018,7 @@ docker stop 9router && docker rm 9router
| Biến | Mặc định | Mô tả |
|----------|---------|-------------|
| `JWT_SECRET` | `9router-default-secret-change-me` | Bí mật ký JWT cho cookie xác thực bảng điều khiển (**thay đổi trong production**) |
| `JWT_SECRET` | Tự động sinh (`~/.9router/jwt-secret`) | Bí mật ký JWT cho cookie xác thực bảng điều khiển (đặt để chia sẻ giữa nhiều instance) |
| `INITIAL_PASSWORD` | `123456` | Mật khẩu đăng nhập đầu tiên khi không có hash đã lưu tồn tại |
| `DATA_DIR` | `~/.9router` |ị trí cơ sở dữ liệu ứng dụng chính (`db.json`) |
| `PORT` | framework default | Cổng dịch vụ (`20128` trong các ví dụ) |

View file

@ -1015,7 +1015,7 @@ docker stop 9router && docker rm 9router
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `JWT_SECRET` | `9router-default-secret-change-me` | 仪表板认证 cookie 的 JWT 签名密钥(**生产环境中请更改** |
| `JWT_SECRET` | 自动生成(`~/.9router/jwt-secret` | 仪表板认证 cookie 的 JWT 签名密钥(设置可在多实例间共享 |
| `INITIAL_PASSWORD | `123456` | 当没有保存的哈希时的首次登录密码 |
| `DATA_DIR` | `~/.9router` | 主应用数据库位置(`db.json` |
| `PORT` | 框架默认值 | 服务端口(示例中为 `20128` |

View file

@ -32,6 +32,7 @@ const PROTECTED_API_PATHS = [
"/api/provider-nodes/validate",
"/api/cli-tools",
"/api/mcp",
"/api/translator",
];
// Routes that spawn child processes — restrict to localhost regardless of auth.

View file

@ -1,8 +1,22 @@
import { SignJWT, jwtVerify } from "jose";
import fs from "node:fs";
import path from "node:path";
import crypto from "node:crypto";
import { DATA_DIR } from "@/lib/dataDir";
const SECRET = new TextEncoder().encode(
process.env.JWT_SECRET || "9router-default-secret-change-me"
);
function loadJwtSecret() {
if (process.env.JWT_SECRET) return process.env.JWT_SECRET;
const file = path.join(DATA_DIR, "jwt-secret");
try {
return fs.readFileSync(file, "utf8").trim();
} catch {}
fs.mkdirSync(DATA_DIR, { recursive: true });
const generated = crypto.randomBytes(32).toString("hex");
fs.writeFileSync(file, generated, { mode: 0o600 });
return generated;
}
const SECRET = new TextEncoder().encode(loadJwtSecret());
export function shouldUseSecureCookie(request) {
const forceSecureCookie = process.env.AUTH_COOKIE_SECURE === "true";

View file

@ -12,5 +12,6 @@ export const config = {
"/api/provider-nodes/validate",
"/api/cli-tools/:path*",
"/api/mcp/:path*",
"/api/translator/:path*",
],
};