feat: 全面优化 — UI/UX重构 + 流量审计与会话管理 + 协议部署
UI/UX 优化: - 登录页分屏布局 + 可访问性修复 + 内联错误提示 - 侧栏菜单分组(专线运维/资源管理/系统) + 图标修正 + 子路由高亮 - Dashboard 统计卡渐变图标 + 空状态引导 + 统计卡可点击 - 创建向导: 依赖检测门控 + 高级折叠 + 必填校验 + WireGuard推荐标 - 专线列表: 空状态CTA + 操作列「更多」下拉 + 状态筛选 + SSE日志流 - 协议品牌SVG图标(ProtocolIcon组件)替换emoji - 设计令牌系统(tokens.css)统一颜色/间距/圆角/阴影 功能增强: - 在线会话管理(sessionmgr): 跨协议会话同步 + 踢下线 + 连接审计日志 - 流量配额引擎(trafficmgr): 配额检查 + 超额动作(block/warn/throttle) + 周期重置 - 异常流量告警: 突发流量检测(>90MB/15s) + 审计记录 - 节点SSH凭证管理: 密码/私钥认证 + 即时测试连接 + AES-GCM加密存储 - 协议二进制管理(binmgr): FRP/OpenVPN GitHub下载 + 系统包安装引导(apt/yum/dnf) - 右上角修改密码弹窗 + MFA独立验证页 + 密码强度提示 - 用户管理: 批量导入 + LDAP浏览导入 + 平台用户导入VPN拨号用户 - 404路由 + IPSec对接页可达性修复 - MFA备用码持久化弹窗(替代Toast) - 轮询可见性守卫 + ECharts resize修复 后端: - 3张新表: VPNSession/ConnectionLog/TrafficPolicy - monitor增强: 会话同步+配额检查+异常告警+到期审计 - changePassword统一8位+新旧不同校验 - openvpn-otp文案专业化(移除抄袭感) - SSE日志流(token降级query参数)
This commit is contained in:
1 parent
58c036c34c
commit
1e2f8ef24f
43 files changed
+6783
-460
No files matched your search
@@ -5,15 +5,16 @@ import "time"
|
||||
|
||||
// User 平台账号
|
||||
type User struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Username string `gorm:"uniqueIndex;size:64" json:"username"`
|
||||
Email string `gorm:"size:128" json:"email"`
|
||||
Password string `gorm:"size:128" json:"-"` // 仅本地用户保存 bcrypt 哈希
|
||||
Role string `gorm:"size:16;default:viewer" json:"role"` // admin / operator / viewer
|
||||
Source string `gorm:"size:16;default:local" json:"source"` // local / ldap
|
||||
Enabled bool `gorm:"default:true" json:"enabled"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Username string `gorm:"uniqueIndex;size:64" json:"username"`
|
||||
Email string `gorm:"size:128" json:"email"`
|
||||
Password string `gorm:"size:128" json:"-"` // 仅本地用户保存 bcrypt 哈希
|
||||
Role string `gorm:"size:16;default:viewer" json:"role"` // admin / operator / viewer
|
||||
Source string `gorm:"size:16;default:local" json:"source"` // local / ldap
|
||||
Enabled bool `gorm:"default:true" json:"enabled"`
|
||||
MustChangePassword bool `gorm:"default:false" json:"must_change_password"` // 首登/被重置后强制改密
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// LDAPConfig LDAP 身份源配置。BindPassword 由 store.EncryptSecret 加密后保存。
|
||||
@@ -25,6 +26,7 @@ type LDAPConfig struct {
|
||||
BaseDN string `gorm:"size:256" json:"base_dn"`
|
||||
UserFilter string `gorm:"size:512" json:"user_filter"`
|
||||
UsernameAttribute string `gorm:"size:64" json:"username_attribute"`
|
||||
StartTLS bool `gorm:"default:false" json:"starttls"` // ldap:// 时升级为 StartTLS
|
||||
Enabled bool `gorm:"default:false" json:"enabled"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
@@ -42,22 +44,35 @@ type MFADevice struct {
|
||||
}
|
||||
|
||||
// VPNUser 是拨号身份,不等同于管理平台登录账号;可来自本地或 LDAP。
|
||||
// Password 保存 bcrypt(OpenVPN 校验);DialSecret 保存 AES-GCM 可逆密文,
|
||||
// 供 L2TP/IKEv2 等需要明文 CHAP/EAP 的协议重新生成认证文件。
|
||||
// MFASecret / MFABackupCodes 为 OpenVPN 拨号 TOTP(AES-GCM 加密)。
|
||||
type VPNUser struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
TunnelID uint `gorm:"index" json:"tunnel_id"`
|
||||
Username string `gorm:"size:128;uniqueIndex:idx_vpn_user" json:"username"`
|
||||
DisplayName string `gorm:"size:128" json:"display_name"`
|
||||
Email string `gorm:"size:128" json:"email"`
|
||||
Source string `gorm:"size:16;default:local" json:"source"` // local / ldap
|
||||
LDAPDN string `gorm:"size:512" json:"ldap_dn"`
|
||||
Password string `gorm:"size:128" json:"-"`
|
||||
Enabled bool `gorm:"default:true" json:"enabled"`
|
||||
Certificate string `gorm:"size:128" json:"certificate"`
|
||||
RxBytes int64 `gorm:"default:0" json:"rx_bytes"`
|
||||
TxBytes int64 `gorm:"default:0" json:"tx_bytes"`
|
||||
LastSeenAt *time.Time `json:"last_seen_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
TunnelID uint `gorm:"index;uniqueIndex:idx_vpn_user" json:"tunnel_id"`
|
||||
Username string `gorm:"size:128;uniqueIndex:idx_vpn_user" json:"username"`
|
||||
DisplayName string `gorm:"size:128" json:"display_name"`
|
||||
Email string `gorm:"size:128" json:"email"`
|
||||
Source string `gorm:"size:16;default:local" json:"source"` // local / ldap
|
||||
LDAPDN string `gorm:"size:512" json:"ldap_dn"`
|
||||
Password string `gorm:"size:128" json:"-"`
|
||||
DialSecret string `gorm:"type:text" json:"-"` // AES-GCM,L2TP/IKEv2 拨号用
|
||||
MFASecret string `gorm:"type:text" json:"-"` // AES-GCM TOTP secret(base32,兼容主流 Authenticator 应用)
|
||||
MFABackupCodes string `gorm:"type:text" json:"-"` // AES-GCM JSON 数组
|
||||
MFAPin string `gorm:"type:text" json:"-"` // AES-GCM,可选静态 PIN(连接时第二因子 PIN+OTP)
|
||||
MFAEnabled bool `gorm:"default:false" json:"mfa_enabled"`
|
||||
MFAHasPin bool `gorm:"default:false" json:"mfa_has_pin"` // 是否设置了 PIN(不回显明文)
|
||||
MFAFailCount int `gorm:"default:0" json:"mfa_fail_count"`
|
||||
MFALockedUntil *time.Time `json:"mfa_locked_until"`
|
||||
MFALastUsedAt *time.Time `json:"mfa_last_used_at"`
|
||||
MFALastCounter int64 `gorm:"default:0" json:"-"` // 上次成功 TOTP 时间窗,防重放
|
||||
Enabled bool `gorm:"default:true" json:"enabled"`
|
||||
Certificate string `gorm:"size:128" json:"certificate"`
|
||||
RxBytes int64 `gorm:"default:0" json:"rx_bytes"`
|
||||
TxBytes int64 `gorm:"default:0" json:"tx_bytes"`
|
||||
LastSeenAt *time.Time `json:"last_seen_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// Tunnel 专线实例(所有协议统一存储,协议参数存 Config JSON)
|
||||
@@ -80,13 +95,19 @@ type Tunnel struct {
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// Node 中继节点(本机为内置节点)
|
||||
// Node 中继节点(本机为内置节点),remote 节点支持 SSH 凭证验证 // Logan.Li
|
||||
type Node struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Name string `gorm:"size:128" json:"name"`
|
||||
Address string `gorm:"size:256" json:"address"` // 节点地址(API 或 SSH)
|
||||
Kind string `gorm:"size:32;default:local" json:"kind"` // local / remote
|
||||
Address string `gorm:"size:256" json:"address"` // 节点地址(IP 或域名)
|
||||
Port int `gorm:"default:22" json:"port"` // SSH 端口
|
||||
Kind string `gorm:"size:32;default:local" json:"kind"` // local / remote
|
||||
Username string `gorm:"size:64" json:"username"` // SSH 登录用户
|
||||
AuthType string `gorm:"size:16;default:password" json:"auth_type"` // password / key
|
||||
Secrets string `gorm:"type:text" json:"-"` // AES-GCM 加密的 {password, private_key} JSON
|
||||
Status string `gorm:"size:16;default:unknown" json:"status"` // verified / failed / unknown
|
||||
Remark string `gorm:"size:512" json:"remark"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
@@ -115,3 +136,42 @@ type AuditLog struct {
|
||||
Detail string `gorm:"size:1024" json:"detail"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// VPNSession 在线会话(跨协议统一记录拨号用户的连接状态) // Logan.Li
|
||||
type VPNSession struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
TunnelID uint `gorm:"index" json:"tunnel_id"`
|
||||
VPNUserID uint `gorm:"index" json:"vpn_user_id"`
|
||||
Username string `gorm:"size:128" json:"username"`
|
||||
Protocol string `gorm:"size:32" json:"protocol"`
|
||||
RealAddress string `gorm:"size:64" json:"real_address"` // 客户端公网 IP:Port
|
||||
VirtualAddress string `gorm:"size:64" json:"virtual_address"` // 分配的 VPN IP
|
||||
ConnectedAt time.Time `json:"connected_at"`
|
||||
DisconnectedAt *time.Time `json:"disconnected_at"`
|
||||
RxBytes int64 `gorm:"default:0" json:"rx_bytes"`
|
||||
TxBytes int64 `gorm:"default:0" json:"tx_bytes"`
|
||||
Status string `gorm:"size:16;default:active" json:"status"` // active / disconnected
|
||||
}
|
||||
|
||||
// ConnectionLog 连接审计日志(连接/断开/认证失败/配额超额/异常流量) // Logan.Li
|
||||
type ConnectionLog struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
TunnelID uint `gorm:"index" json:"tunnel_id"`
|
||||
Username string `gorm:"size:128" json:"username"`
|
||||
Event string `gorm:"size:32" json:"event"` // connect / disconnect / auth_fail / quota_exceed / rate_alert
|
||||
IPAddress string `gorm:"size:64" json:"ip_address"`
|
||||
Detail string `gorm:"size:1024" json:"detail"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// TrafficPolicy 流量配额与限速策略(挂在 Tunnel 上) // Logan.Li
|
||||
type TrafficPolicy struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
TunnelID uint `gorm:"uniqueIndex" json:"tunnel_id"`
|
||||
QuotaBytes int64 `gorm:"default:0" json:"quota_bytes"` // 总配额,0=不限
|
||||
RateLimitMbps int `gorm:"default:0" json:"rate_limit_mbps"` // 限速 Mbps,0=不限
|
||||
UsedBytes int64 `gorm:"default:0" json:"used_bytes"`
|
||||
ResetCycle string `gorm:"size:16;default:none" json:"reset_cycle"` // daily / monthly / none
|
||||
LastResetAt time.Time `json:"last_reset_at"`
|
||||
ActionOnExceed string `gorm:"size:16;default:block" json:"action_on_exceed"` // warn / block / throttle
|
||||
}
|
||||
Reference in new issue
Block a user