diff --git a/src/main/kotlin/ca/gosyer/data/server/ServerHostPreferences.kt b/src/main/kotlin/ca/gosyer/data/server/ServerHostPreferences.kt index 7798a6a7..6586856e 100644 --- a/src/main/kotlin/ca/gosyer/data/server/ServerHostPreferences.kt +++ b/src/main/kotlin/ca/gosyer/data/server/ServerHostPreferences.kt @@ -49,6 +49,20 @@ class ServerHostPreferences(preferenceStore: PreferenceStore) { return openInBrowserEnabled.preference() } + // Authentication + private val basicAuthEnabled = ServerHostPreference.BasicAuthEnabled(preferenceStore) + fun basicAuthEnabled(): Preference { + return basicAuthEnabled.preference() + } + private val basicAuthUsername = ServerHostPreference.BasicAuthUsername(preferenceStore) + fun basicAuthUsername(): Preference { + return basicAuthUsername.preference() + } + private val basicAuthPassword = ServerHostPreference.BasicAuthPassword(preferenceStore) + fun basicAuthPassword(): Preference { + return basicAuthPassword.preference() + } + fun properties(): Array { return listOf( ip, @@ -59,7 +73,10 @@ class ServerHostPreferences(preferenceStore: PreferenceStore) { debugLogsEnabled, systemTrayEnabled, webUIEnabled, - openInBrowserEnabled + openInBrowserEnabled, + basicAuthEnabled, + basicAuthUsername, + basicAuthPassword ).mapNotNull { it.getProperty() }.toTypedArray() diff --git a/src/main/kotlin/ca/gosyer/data/server/host/ServerHostPreference.kt b/src/main/kotlin/ca/gosyer/data/server/host/ServerHostPreference.kt index 75fab668..a4026af9 100644 --- a/src/main/kotlin/ca/gosyer/data/server/host/ServerHostPreference.kt +++ b/src/main/kotlin/ca/gosyer/data/server/host/ServerHostPreference.kt @@ -114,4 +114,21 @@ sealed class ServerHostPreference { false, true ) + + // Authentication + class BasicAuthEnabled(preferenceStore: PreferenceStore) : BooleanServerHostPreference( + preferenceStore, + "basicAuthEnabled", + false + ) + class BasicAuthUsername(preferenceStore: PreferenceStore) : StringServerHostPreference( + preferenceStore, + "basicAuthUsername", + "" + ) + class BasicAuthPassword(preferenceStore: PreferenceStore) : StringServerHostPreference( + preferenceStore, + "basicAuthPassword", + "" + ) } diff --git a/src/main/kotlin/ca/gosyer/ui/settings/SettingsServerScreen.kt b/src/main/kotlin/ca/gosyer/ui/settings/SettingsServerScreen.kt index f997919d..0de3107a 100644 --- a/src/main/kotlin/ca/gosyer/ui/settings/SettingsServerScreen.kt +++ b/src/main/kotlin/ca/gosyer/ui/settings/SettingsServerScreen.kt @@ -33,8 +33,11 @@ import ca.gosyer.ui.base.prefs.asStringStateIn import ca.gosyer.ui.base.resources.stringResource import ca.gosyer.ui.base.vm.ViewModel import ca.gosyer.ui.base.vm.viewModel +import ca.gosyer.util.system.CKLogger import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.launchIn import javax.inject.Inject class SettingsServerViewModel @Inject constructor( @@ -59,6 +62,11 @@ class SettingsServerViewModel @Inject constructor( val webUIEnabled = serverHostPreferences.webUIEnabled().asStateIn(scope) val openInBrowserEnabled = serverHostPreferences.openInBrowserEnabled().asStateIn(scope) + // Authentication + val basicAuthEnabled = serverHostPreferences.basicAuthEnabled().asStateIn(scope) + val basicAuthUsername = serverHostPreferences.basicAuthUsername().asStateIn(scope) + val basicAuthPassword = serverHostPreferences.basicAuthPassword().asStateIn(scope) + // JUI connection val serverUrl = serverPreferences.server().asStateIn(scope) val serverPort = serverPreferences.port().asStringStateIn(scope) @@ -99,12 +107,24 @@ class SettingsServerViewModel @Inject constructor( serverService.restartServer() } } + + init { + combine(basicAuthEnabled, basicAuthUsername, basicAuthPassword) { enabled, username, password -> + if (enabled) { + auth.value = Auth.BASIC + authUsername.value = username + authPassword.value = password + } + }.launchIn(scope) + } + private companion object : CKLogger({}) } @Composable fun SettingsServerScreen(menuController: MenuController) { val vm = viewModel() val host by vm.host.collectAsState() + val basicAuthEnabled by vm.basicAuthEnabled.collectAsState() val proxy by vm.proxy.collectAsState() val auth by vm.auth.collectAsState() DisposableEffect(Unit) { @@ -203,6 +223,31 @@ fun SettingsServerScreen(menuController: MenuController) { enabled = webUIEnabled ) } + item { + SwitchPreference( + preference = vm.basicAuthEnabled, + title = stringResource("basic_auth"), + subtitle = stringResource("host_basic_auth_sub"), + changeListener = vm::serverSettingChanged + ) + } + item { + EditTextPreference( + preference = vm.basicAuthUsername, + title = stringResource("host_basic_auth_username"), + changeListener = vm::serverSettingChanged, + enabled = basicAuthEnabled + ) + } + item { + EditTextPreference( + preference = vm.basicAuthPassword, + title = stringResource("host_basic_auth_password"), + changeListener = vm::serverSettingChanged, + visualTransformation = PasswordVisualTransformation(), + enabled = basicAuthEnabled + ) + } } item { Divider() diff --git a/src/main/resources/values/values/strings.xml b/src/main/resources/values/values/strings.xml index 42b8553a..2389e0d8 100644 --- a/src/main/resources/values/values/strings.xml +++ b/src/main/resources/values/values/strings.xml @@ -193,6 +193,9 @@ Whether the server's default WebUI is enabled, makes you able to use Tachidesk in your browser Open Server WebUI on startup Open the WebUI inside your browser on server startup. Requires the WebUI be enabled + Use basic auth to protect your library, requires username and password + Basic auth username + Basic auth password Server URL Server PORT Warning