feat: show server Reality keypair on node edit form (item 17)
New read-only GET /api/nodes/:id/reality-keys returns the panel-hosted keypair for the node's server from keyStore (display only — it never mints a pair; a missing entry reports nulls). The node edit form shows public and private key rows with copy buttons for Reality protocols.
This commit is contained in:
@@ -2580,6 +2580,27 @@ func (a *App) handleAdminApi(w http.ResponseWriter, r *http.Request, pathname st
|
||||
SendJSON(w, 201, map[string]any{"node": PublicNode(nodeAny.(*Node))}, nil)
|
||||
return true, nil
|
||||
}
|
||||
if params, ok := RoutePattern("/api/nodes/:id/reality-keys", pathname); ok && r.Method == http.MethodGet {
|
||||
// Round-3 item 17: display-only view of the panel-hosted Reality
|
||||
// keypair for the node's server. This NEVER generates a pair —
|
||||
// a missing entry simply reports nulls (the pair is minted by
|
||||
// EnsureRealityKey at deploy time).
|
||||
data := a.store.Snapshot()
|
||||
node := findNode(data, params["id"])
|
||||
if node == nil {
|
||||
return true, httpErr(404, "节点不存在")
|
||||
}
|
||||
if !IsRealityProtocol(node.Protocol) {
|
||||
return true, httpErr(400, "该节点不是 Reality 协议")
|
||||
}
|
||||
keyID := RealityKeyIDForNode(node)
|
||||
var publicKey, privateKey any
|
||||
if entry := data.KeyStore[keyID]; entry != nil {
|
||||
publicKey, privateKey = entry.PublicKey, entry.PrivateKey
|
||||
}
|
||||
SendJSON(w, 200, map[string]any{"keyId": keyID, "publicKey": publicKey, "privateKey": privateKey}, nil)
|
||||
return true, nil
|
||||
}
|
||||
if params, ok := RoutePattern("/api/nodes/:id", pathname); ok && r.Method == http.MethodPatch {
|
||||
body, err := ReadJSON(r, defaultMaxBody)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user