Skip to content

Commit ef07560

Browse files
committed
fix: curl入口变量遮蔽bug + 增强日志 + SSH快捷复制按钮
- entry.go: 修复 fallback 路径中变量 h 遮蔽接收者的 bug - entry.go: 直接使用 HostSSHAuth 字段避免冗余查询 - entry.go: 添加详细日志记录解析路径和主机状态 - $hostId.tsx: SSH 直连区域增加"复制 SSH 命令"按钮 Made-with: Cursor
1 parent cb6d84a commit ef07560

2 files changed

Lines changed: 36 additions & 18 deletions

File tree

internal/controlplane/http/entry.go

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ type EntryStore interface {
2020
GetPrimaryHostByUserID(context.Context, string) (repository.Host, error)
2121
GetHostByShortID(context.Context, string) (repository.HostSSHAuth, error)
2222
GetUser(context.Context, string) (repository.User, error)
23-
GetHost(context.Context, string) (repository.Host, error)
2423
}
2524

2625
type EntryHandler struct {
@@ -100,24 +99,22 @@ func (h *EntryHandler) Auth() nethttp.Handler {
10099
}
101100

102101
var user repository.User
103-
var host repository.Host
102+
var hostShortID, hostEntryPassword, hostStatus string
104103

105104
hostAuth, hostErr := h.store.GetHostByShortID(r.Context(), shortID)
106105
if hostErr == nil {
106+
h.logger.Info("entry auth: resolved by host short_id",
107+
"short_id", shortID, "host_id", hostAuth.HostID, "host_status", hostAuth.HostStatus)
107108
u, err := h.store.GetUser(r.Context(), hostAuth.UserID)
108109
if err != nil {
109110
h.logger.Error("entry auth: lookup host owner failed", "host_id", hostAuth.HostID, "error", err)
110111
writeJSON(w, nethttp.StatusInternalServerError, map[string]string{"error": "internal error"})
111112
return
112113
}
113114
user = u
114-
fullHost, err := h.store.GetHost(r.Context(), hostAuth.HostID)
115-
if err != nil {
116-
h.logger.Error("entry auth: lookup host failed", "host_id", hostAuth.HostID, "error", err)
117-
writeJSON(w, nethttp.StatusInternalServerError, map[string]string{"error": "internal error"})
118-
return
119-
}
120-
host = fullHost
115+
hostShortID = hostAuth.HostShortID
116+
hostEntryPassword = hostAuth.EntryPassword
117+
hostStatus = hostAuth.HostStatus
121118
} else {
122119
u, err := h.store.GetUserByShortID(r.Context(), shortID)
123120
if err != nil {
@@ -130,7 +127,7 @@ func (h *EntryHandler) Auth() nethttp.Handler {
130127
return
131128
}
132129
user = u
133-
h, err := h.store.GetPrimaryHostByUserID(r.Context(), user.ID)
130+
primaryHost, err := h.store.GetPrimaryHostByUserID(r.Context(), user.ID)
134131
if err != nil {
135132
if errors.Is(err, pgx.ErrNoRows) {
136133
writeJSON(w, nethttp.StatusNotFound, map[string]string{
@@ -139,10 +136,15 @@ func (h *EntryHandler) Auth() nethttp.Handler {
139136
})
140137
return
141138
}
139+
h.logger.Error("entry auth: lookup primary host failed", "user_id", user.ID, "error", err)
142140
writeJSON(w, nethttp.StatusInternalServerError, map[string]string{"error": "internal error"})
143141
return
144142
}
145-
host = h
143+
h.logger.Info("entry auth: resolved by user short_id (fallback to primary host)",
144+
"short_id", shortID, "host_id", primaryHost.ID, "host_status", primaryHost.Status)
145+
hostShortID = primaryHost.ShortID
146+
hostEntryPassword = primaryHost.EntryPassword
147+
hostStatus = primaryHost.Status
146148
}
147149

148150
if user.Status != "active" {
@@ -155,7 +157,8 @@ func (h *EntryHandler) Auth() nethttp.Handler {
155157
return
156158
}
157159

158-
if host.Status != "running" {
160+
if hostStatus != "running" {
161+
h.logger.Warn("entry auth: host not running", "short_id", shortID, "host_status", hostStatus)
159162
writeJSON(w, nethttp.StatusOK, map[string]any{
160163
"status": "not_ready",
161164
"message": "Your machine is not running. Please contact admin.",
@@ -169,8 +172,8 @@ func (h *EntryHandler) Auth() nethttp.Handler {
169172
}
170173

171174
writeJSON(w, nethttp.StatusOK, map[string]any{
172-
"ssh_user": host.ShortID,
173-
"ssh_pass": host.EntryPassword,
175+
"ssh_user": hostShortID,
176+
"ssh_pass": hostEntryPassword,
174177
"ssh_host": sshHost,
175178
"ssh_port": 2222,
176179
"status": "ready",

web/admin/src/routes/_dashboard/hosts/$hostId.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,25 @@ function HostDetailPage() {
245245
label="一键连接(curl 入口)"
246246
command={data.connection_info.curl_command}
247247
/>
248-
<ConnectionBlock
249-
label="SSH 直连(需要这台主机的 SSH 密码)"
250-
command={data.connection_info.ssh_command}
251-
/>
248+
<div className="p-6 space-y-3">
249+
<ConnectionBlock
250+
label="SSH 直连(配置入站密钥后可免密登录)"
251+
command={data.connection_info.ssh_command}
252+
inline
253+
/>
254+
<Button
255+
type="button"
256+
variant="default"
257+
className="h-10 gap-2"
258+
onClick={() => {
259+
navigator.clipboard.writeText(data.connection_info!.ssh_command);
260+
toast.success("SSH 命令已复制,请在终端中粘贴执行");
261+
}}
262+
>
263+
<Terminal className="h-4 w-4" />
264+
复制 SSH 命令
265+
</Button>
266+
</div>
252267
{data.connection_info.vnc_url && (
253268
<div className="space-y-4 p-6">
254269
<ConnectionBlock

0 commit comments

Comments
 (0)