From 56d3d8270f58df3ed80f924a77aec78ca40c52cc Mon Sep 17 00:00:00 2001 From: fylorn <249551762+fylorn@users.noreply.github.com> Date: Tue, 15 Sep 2026 01:29:00 +0800 Subject: [PATCH] feat(control): generate a gateway key over the control plane MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `GET /keys/new` returns a freshly generated key without writing it anywhere. The UI needs a value to put in a new entry, and generating it there would mean a second copy of the alphabet and the length. Both are security decisions — the alphabet drops 0/O and 1/I/l because people read this string aloud and retype it into another config file — and two copies mean only one of them gets changed. Co-Authored-By: Claude Opus 5 --- crates/tw-api/src/lib.rs | 6 ++++++ crates/tw-control/src/lib.rs | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/crates/tw-api/src/lib.rs b/crates/tw-api/src/lib.rs index 3dec2051..59066261 100644 --- a/crates/tw-api/src/lib.rs +++ b/crates/tw-api/src/lib.rs @@ -620,6 +620,12 @@ pub struct ConfigText { pub version: String, } +/// 一把刚生成、还没写进配置的网关密钥(`GET /keys/new`)。 +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct NewKey { + pub key: String, +} + /// 这台机器上的一张网卡(`GET /interfaces`)。 /// /// **界面上「绑在哪张网卡」那个选单要的就是它。**没有它,用户只能自己 diff --git a/crates/tw-control/src/lib.rs b/crates/tw-control/src/lib.rs index 9abd69a2..45fce086 100644 --- a/crates/tw-control/src/lib.rs +++ b/crates/tw-control/src/lib.rs @@ -81,6 +81,7 @@ pub fn router(state: ControlState) -> Router { Router::new() .route("/status", get(status)) .route("/interfaces", get(interfaces)) + .route("/keys/new", get(new_key)) .route("/events", get(events)) .route("/overview", get(overview)) .route("/probe", post(probe)) @@ -140,6 +141,17 @@ pub fn router(state: ControlState) -> Router { .with_state(state) } +/// 生成一把新的网关密钥。**不写进配置** —— 只是给界面一个值去填。 +/// +/// **在这里生成,不在界面里。**字母表(去掉了 0/O、1/I/l 这些抄错的 +/// 字符)和长度是安全相关的决定,而用户要把这串东西读出来、抄进另一个 +/// 配置文件。两处各写一份的话,迟早只有一处被改。 +async fn new_key() -> Json { + Json(tw_api::NewKey { + key: tw_config::generate_key(), + }) +} + /// 这台机器上有哪些网卡。 /// /// 不带任何状态 —— 每次现问系统。**网卡是会变的**:插拔网线、连上另一