mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-06-04 21:49:36 +08:00
- 密文存储:新增 dailysecret 本地存储引擎,连接/代理/AI 密钥不再依赖系统钥匙串 - 启动迁移:自动将已有钥匙串密文迁移到本地 JSON,用户无感知 - WebKit 迁移:从旧版 Wails WebKit LocalStorage 中恢复连接与代理数据 - DMG 修复:移除 --sandbox-safe 避免扩展属性污染签名,新增 xattr 清理与签名校验 - 安全适配:钥匙串不可用时标记完成而非回滚,消除无钥匙串环境下的阻塞 - 出口脱敏:所有连接/代理 API 返回前统一 sanitize 防止密文泄漏
108 lines
3.3 KiB
Go
108 lines
3.3 KiB
Go
package app
|
|
|
|
import (
|
|
stdRuntime "runtime"
|
|
|
|
"GoNavi-Wails/internal/connection"
|
|
"GoNavi-Wails/internal/dailysecret"
|
|
)
|
|
|
|
var runtimeGOOS = func() string {
|
|
return stdRuntime.GOOS
|
|
}
|
|
|
|
func extractConnectionSecretBundle(config connection.ConnectionConfig) connectionSecretBundle {
|
|
return connectionSecretBundle{
|
|
Password: config.Password,
|
|
SSHPassword: config.SSH.Password,
|
|
ProxyPassword: config.Proxy.Password,
|
|
HTTPTunnelPassword: config.HTTPTunnel.Password,
|
|
MySQLReplicaPassword: config.MySQLReplicaPassword,
|
|
MongoReplicaPassword: config.MongoReplicaPassword,
|
|
OpaqueURI: config.URI,
|
|
OpaqueDSN: config.DSN,
|
|
}
|
|
}
|
|
|
|
func toDailyConnectionBundle(bundle connectionSecretBundle) dailysecret.ConnectionBundle {
|
|
return dailysecret.ConnectionBundle{
|
|
Password: bundle.Password,
|
|
SSHPassword: bundle.SSHPassword,
|
|
ProxyPassword: bundle.ProxyPassword,
|
|
HTTPTunnelPassword: bundle.HTTPTunnelPassword,
|
|
MySQLReplicaPassword: bundle.MySQLReplicaPassword,
|
|
MongoReplicaPassword: bundle.MongoReplicaPassword,
|
|
OpaqueURI: bundle.OpaqueURI,
|
|
OpaqueDSN: bundle.OpaqueDSN,
|
|
}
|
|
}
|
|
|
|
func fromDailyConnectionBundle(bundle dailysecret.ConnectionBundle) connectionSecretBundle {
|
|
return connectionSecretBundle{
|
|
Password: bundle.Password,
|
|
SSHPassword: bundle.SSHPassword,
|
|
ProxyPassword: bundle.ProxyPassword,
|
|
HTTPTunnelPassword: bundle.HTTPTunnelPassword,
|
|
MySQLReplicaPassword: bundle.MySQLReplicaPassword,
|
|
MongoReplicaPassword: bundle.MongoReplicaPassword,
|
|
OpaqueURI: bundle.OpaqueURI,
|
|
OpaqueDSN: bundle.OpaqueDSN,
|
|
}
|
|
}
|
|
|
|
func stripConnectionSecretFields(config connection.ConnectionConfig) connection.ConnectionConfig {
|
|
stripped := config
|
|
stripped.Password = ""
|
|
stripped.SSH.Password = ""
|
|
stripped.Proxy.Password = ""
|
|
stripped.HTTPTunnel.Password = ""
|
|
stripped.MySQLReplicaPassword = ""
|
|
stripped.MongoReplicaPassword = ""
|
|
stripped.URI = ""
|
|
stripped.DSN = ""
|
|
return stripped
|
|
}
|
|
|
|
func sanitizeSavedConnectionView(view connection.SavedConnectionView) connection.SavedConnectionView {
|
|
view.Config = stripConnectionSecretFields(view.Config)
|
|
return view
|
|
}
|
|
|
|
func sanitizeSavedConnectionViews(items []connection.SavedConnectionView) []connection.SavedConnectionView {
|
|
if len(items) == 0 {
|
|
return items
|
|
}
|
|
result := make([]connection.SavedConnectionView, 0, len(items))
|
|
for _, item := range items {
|
|
result = append(result, sanitizeSavedConnectionView(item))
|
|
}
|
|
return result
|
|
}
|
|
|
|
func extractGlobalProxySecretBundle(view connection.GlobalProxyView) globalProxySecretBundle {
|
|
return globalProxySecretBundle{
|
|
Password: view.Password,
|
|
}
|
|
}
|
|
|
|
func toDailyGlobalProxyBundle(bundle globalProxySecretBundle) dailysecret.GlobalProxyBundle {
|
|
return dailysecret.GlobalProxyBundle{Password: bundle.Password}
|
|
}
|
|
|
|
func fromDailyGlobalProxyBundle(bundle dailysecret.GlobalProxyBundle) globalProxySecretBundle {
|
|
return globalProxySecretBundle{Password: bundle.Password}
|
|
}
|
|
|
|
func sanitizeGlobalProxyView(view connection.GlobalProxyView) connection.GlobalProxyView {
|
|
view.Password = ""
|
|
return view
|
|
}
|
|
|
|
func shouldReadLegacySecretStoreForDailySecrets() bool {
|
|
return runtimeGOOS() != "darwin"
|
|
}
|
|
|
|
func (a *App) dailySecretStore() *dailysecret.Store {
|
|
return dailysecret.NewStore(a.configDir)
|
|
}
|