mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-27 15:17:38 +00:00
Ensure server restarts on password change.
This commit is contained in:
parent
99392b53a4
commit
2c276fc67c
3 changed files with 110 additions and 36 deletions
|
|
@ -32,7 +32,15 @@ struct LazyBasicAuthMiddleware<Context: RequestContext>: RouterMiddleware where
|
|||
}
|
||||
|
||||
// Check if password protection is enabled
|
||||
guard UserDefaults.standard.bool(forKey: "dashboardPasswordEnabled") else {
|
||||
let passwordEnabled = UserDefaults.standard.bool(forKey: "dashboardPasswordEnabled")
|
||||
|
||||
// Check if enabled state changed and clear cache if needed
|
||||
if await passwordCache.shouldRecache(currentEnabledState: passwordEnabled) {
|
||||
await passwordCache.clear()
|
||||
logger.info("Password enabled state changed, cleared cache")
|
||||
}
|
||||
|
||||
guard passwordEnabled else {
|
||||
// No password protection, allow request
|
||||
return try await next(request, context)
|
||||
}
|
||||
|
|
@ -112,6 +120,7 @@ struct LazyBasicAuthMiddleware<Context: RequestContext>: RouterMiddleware where
|
|||
/// Actor to manage password caching in a thread-safe way
|
||||
private actor PasswordCache {
|
||||
private var cachedPassword: String?
|
||||
private var lastEnabledState: Bool?
|
||||
|
||||
func getPassword() -> String? {
|
||||
cachedPassword
|
||||
|
|
@ -123,5 +132,14 @@ private actor PasswordCache {
|
|||
|
||||
func clear() {
|
||||
cachedPassword = nil
|
||||
lastEnabledState = nil
|
||||
}
|
||||
|
||||
func shouldRecache(currentEnabledState: Bool) -> Bool {
|
||||
if lastEnabledState != currentEnabledState {
|
||||
lastEnabledState = currentEnabledState
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,34 @@ struct DashboardSettingsView: View {
|
|||
DashboardAccessMode(rawValue: accessModeString) ?? .localhost
|
||||
}
|
||||
|
||||
// MARK: - Helper Methods
|
||||
|
||||
/// Handles server-specific password updates (adding, changing, or removing passwords)
|
||||
static func updateServerForPasswordChange(action: PasswordAction, logger: Logger) async {
|
||||
let serverManager = ServerManager.shared
|
||||
|
||||
if serverManager.serverMode == .rust {
|
||||
// Rust server requires restart to apply password changes
|
||||
logger.info("Restarting Rust server to \(action.logMessage)")
|
||||
await serverManager.restart()
|
||||
} else {
|
||||
// Hummingbird server just needs cache clear
|
||||
await serverManager.clearAuthCache()
|
||||
}
|
||||
}
|
||||
|
||||
enum PasswordAction {
|
||||
case apply
|
||||
case remove
|
||||
|
||||
var logMessage: String {
|
||||
switch self {
|
||||
case .apply: "apply new password"
|
||||
case .remove: "remove password protection"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
Form {
|
||||
|
|
@ -54,7 +82,8 @@ struct DashboardSettingsView: View {
|
|||
passwordError: $passwordError,
|
||||
passwordSaved: $passwordSaved,
|
||||
dashboardKeychain: dashboardKeychain,
|
||||
savePassword: savePassword
|
||||
savePassword: savePassword,
|
||||
logger: logger
|
||||
)
|
||||
|
||||
ServerConfigurationSection(
|
||||
|
|
@ -156,15 +185,37 @@ struct DashboardSettingsView: View {
|
|||
password = ""
|
||||
confirmPassword = ""
|
||||
|
||||
// Clear cached password in LazyBasicAuthMiddleware
|
||||
Task {
|
||||
await ServerManager.shared.clearAuthCache()
|
||||
// Check if we need to switch to network mode
|
||||
let needsNetworkModeSwitch = accessMode == .localhost
|
||||
|
||||
if needsNetworkModeSwitch {
|
||||
// Switch to network mode first (this updates ServerManager.bindAddress)
|
||||
accessModeString = DashboardAccessMode.network.rawValue
|
||||
}
|
||||
|
||||
// When password is set for the first time, automatically switch to network mode
|
||||
if accessMode == .localhost {
|
||||
accessModeString = DashboardAccessMode.network.rawValue
|
||||
restartServerWithNewBindAddress()
|
||||
// Handle server-specific password update
|
||||
Task {
|
||||
let serverManager = ServerManager.shared
|
||||
|
||||
if needsNetworkModeSwitch {
|
||||
// If switching to network mode, update bind address before restart
|
||||
serverManager.bindAddress = DashboardAccessMode.network.bindAddress
|
||||
|
||||
// Always restart when switching to network mode (both server types need it)
|
||||
logger.info("Restarting server to apply new password and network mode")
|
||||
await serverManager.restart()
|
||||
|
||||
// Wait for server to be ready
|
||||
try? await Task.sleep(for: .seconds(1))
|
||||
|
||||
await MainActor.run {
|
||||
SessionMonitor.shared.stopMonitoring()
|
||||
SessionMonitor.shared.startMonitoring()
|
||||
}
|
||||
} else {
|
||||
// Just password change, no network mode switch
|
||||
await DashboardSettingsView.updateServerForPasswordChange(action: .apply, logger: logger)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
passwordError = "Failed to save password to keychain"
|
||||
|
|
@ -302,6 +353,7 @@ private struct SecuritySection: View {
|
|||
@Binding var passwordSaved: Bool
|
||||
let dashboardKeychain: DashboardKeychain
|
||||
let savePassword: () -> Void
|
||||
let logger: Logger
|
||||
|
||||
var body: some View {
|
||||
Section {
|
||||
|
|
@ -315,9 +367,13 @@ private struct SecuritySection: View {
|
|||
_ = dashboardKeychain.deletePassword()
|
||||
showPasswordFields = false
|
||||
passwordSaved = false
|
||||
// Clear cached password in LazyBasicAuthMiddleware
|
||||
|
||||
// Handle server-specific password removal
|
||||
Task {
|
||||
await ServerManager.shared.clearAuthCache()
|
||||
await DashboardSettingsView.updateServerForPasswordChange(
|
||||
action: .remove,
|
||||
logger: logger
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue