Skip to content

Commit

Permalink
[settings] allow to change cloud password
Browse files Browse the repository at this point in the history
  • Loading branch information
capcom6 committed Dec 4, 2024
1 parent 6b44548 commit a4d78e1
Show file tree
Hide file tree
Showing 13 changed files with 315 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ class GatewayApi(
}.body()
}

suspend fun changePassword(token: String, request: PasswordChangeRequest) {
client.patch("$baseUrl/user/password") {
auth(token)
contentType(ContentType.Application.Json)
setBody(request)
}
}

private fun HttpRequestBuilder.auth(token: String) {
header(HttpHeaders.Authorization, "Bearer $token")
}
Expand Down Expand Up @@ -118,6 +126,11 @@ class GatewayApi(
val states: Map<ProcessingState, Date>
)

data class PasswordChangeRequest(
val currentPassword: String,
val newPassword: String
)

data class Message(
val id: String,
val message: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,27 @@ class GatewayService(
this._api = null
}

suspend fun changePassword(current: String, new: String) {
val info = settings.registrationInfo
?: throw IllegalStateException("The device is not registered on the server")

this.api.changePassword(
info.token,
GatewayApi.PasswordChangeRequest(current, new)
)

settings.registrationInfo = info.copy(password = new)

events.emit(
DeviceRegisteredEvent(
api.hostname,
info.login,
new,
)
)
}

///////////////////////////////////////////////////////////////////////////
internal suspend fun getWebHooks(): List<GatewayApi.WebHook> {
val settings = settings.registrationInfo
return if (settings != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ class GatewaySettings(
get() = storage.get(REGISTRATION_INFO)
set(value) = storage.set(REGISTRATION_INFO, value)

val username: String?
get() = registrationInfo?.login
val password: String?
get() = registrationInfo?.password

val privateUrl: String?
get() = storage.get<String?>(CLOUD_URL)
val privateToken: String?
Expand Down
24 changes: 1 addition & 23 deletions app/src/main/java/me/capcom/smsgateway/ui/SettingsFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,17 @@ import android.provider.Settings
import android.text.InputType
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.core.content.edit
import androidx.preference.EditTextPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import me.capcom.smsgateway.BuildConfig
import me.capcom.smsgateway.R
import me.capcom.smsgateway.modules.gateway.GatewaySettings

class SettingsFragment : PreferenceFragmentCompat() {

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)

findPreference<EditTextPreference>("gateway.cloud_url")?.setSummaryProvider {
val hostname = preferenceManager.sharedPreferences?.getString(it.key, null)
if (hostname.isNullOrEmpty()) {
preferenceManager.sharedPreferences?.edit(true) {
putString(it.key, GatewaySettings.PUBLIC_URL)
}
return@setSummaryProvider GatewaySettings.PUBLIC_URL
}
return@setSummaryProvider hostname
}

findPreference<Preference>("transient.app_version")?.summary =
"${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})"

Expand All @@ -48,23 +35,14 @@ class SettingsFragment : PreferenceFragmentCompat() {
}

override fun onDisplayPreferenceDialog(preference: Preference) {
if (preference.key == "encryption.passphrase"
|| preference.key == "gateway.private_token"
) {
if (preference.key == "encryption.passphrase") {
(preference as EditTextPreference).setOnBindEditTextListener {
it.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
it.setSelectAllOnFocus(true)
it.selectAll()
}
}

if (preference.key == "gateway.cloud_url") {
(preference as EditTextPreference).setOnBindEditTextListener {
it.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI
it.setSelectAllOnFocus(true)
}
}

if (preference.key == "ping.interval_seconds"
|| preference.key == "logs.lifetime_days"
|| preference.key == "webhooks.retry_count"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package me.capcom.smsgateway.ui.settings

import android.os.Bundle
import android.util.TypedValue
import android.view.View
import android.widget.Toast
import androidx.preference.PreferenceFragmentCompat

abstract class BasePreferenceFragment : PreferenceFragmentCompat() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val backgroundValue = TypedValue()
requireContext().theme.resolveAttribute(
android.R.attr.colorBackground,
backgroundValue,
true
)

view.setBackgroundColor(backgroundValue.data)
}

protected fun showToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package me.capcom.smsgateway.ui.settings

import android.annotation.SuppressLint
import android.os.Bundle
import android.text.InputType
import android.view.View
import androidx.core.content.edit
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.preference.EditTextPreference
import androidx.preference.Preference
import kotlinx.coroutines.launch
import me.capcom.smsgateway.R
import me.capcom.smsgateway.modules.gateway.GatewayService
import me.capcom.smsgateway.modules.gateway.GatewaySettings
import org.koin.android.ext.android.inject
import java.net.URL

class CloudServerSettingsFragment : BasePreferenceFragment() {

private val settings: GatewaySettings by inject()
private val service: GatewayService by inject()

@SuppressLint("NotifyDataSetChanged")
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.cloud_server_preferences, rootKey)

findPreference<EditTextPreference>("gateway.cloud_url")?.setSummaryProvider {
val hostname = preferenceManager.sharedPreferences?.getString(it.key, null)
if (hostname.isNullOrEmpty()) {
preferenceManager.sharedPreferences?.edit(true) {
putString(it.key, GatewaySettings.PUBLIC_URL)
}
return@setSummaryProvider GatewaySettings.PUBLIC_URL
}
return@setSummaryProvider hostname
}


findPreference<EditTextPreference>("gateway.cloud_url")?.setOnPreferenceChangeListener { _, newValue ->
val value = newValue as? String
if (value.isNullOrEmpty()) {
return@setOnPreferenceChangeListener true
}

try {
URL(value)
} catch (e: Exception) {
showToast(getString(R.string.invalid_url))
return@setOnPreferenceChangeListener false
}

true
}

findPreference<EditTextPreference>("gateway.username")?.setSummaryProvider {
settings.username ?: getString(R.string.not_set)
}
findPreference<EditTextPreference>("gateway.password")?.apply {
setSummaryProvider {
settings.password ?: getString(R.string.not_set)
}

setOnPreferenceChangeListener { _, newValue ->
val value = newValue as? String
if (value == null || value.length < 14) {
showToast(getString(R.string.password_must_be_at_least_14_characters))
return@setOnPreferenceChangeListener false
}

this@CloudServerSettingsFragment.lifecycleScope.launch {
try {
requireActivity().findViewById<View>(R.id.progressBar).isVisible = true
service.changePassword(settings.password ?: "", value)
listView.adapter?.notifyDataSetChanged()
showToast(getString(R.string.password_changed_successfully))
} catch (e: Exception) {
showToast(getString(R.string.failed_to_change_password, e.message))
} finally {
requireActivity().findViewById<View>(R.id.progressBar).isVisible = false
}
}

true
}
}
}

override fun onDisplayPreferenceDialog(preference: Preference) {
if (preference.key == "gateway.cloud_url") {
(preference as EditTextPreference).setOnBindEditTextListener {
it.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI
it.setSelectAllOnFocus(true)
it.selectAll()
}
}

if (preference.key == "gateway.private_token") {
(preference as EditTextPreference).setOnBindEditTextListener {
it.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
it.setSelectAllOnFocus(true)
it.selectAll()
}
}

if (preference.key == "gateway.password") {
(preference as EditTextPreference).setOnBindEditTextListener {
it.inputType = InputType.TYPE_CLASS_TEXT
it.text = null
}
}

super.onDisplayPreferenceDialog(preference)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,11 @@ package me.capcom.smsgateway.ui.settings

import android.os.Bundle
import android.text.InputType
import android.util.TypedValue
import android.view.View
import android.widget.Toast
import androidx.preference.EditTextPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import me.capcom.smsgateway.R

class LocalServerSettingsFragment : PreferenceFragmentCompat() {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val backgroundValue = TypedValue()
requireContext().theme.resolveAttribute(
android.R.attr.colorBackground,
backgroundValue,
true
)

view.setBackgroundColor(backgroundValue.data)
}
class LocalServerSettingsFragment : BasePreferenceFragment() {

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.local_server_preferences, rootKey)
Expand Down Expand Up @@ -86,8 +69,4 @@ class LocalServerSettingsFragment : PreferenceFragmentCompat() {

super.onDisplayPreferenceDialog(preference)
}

private fun showToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,11 @@ package me.capcom.smsgateway.ui.settings
import android.content.SharedPreferences
import android.os.Bundle
import android.text.InputType
import android.util.TypedValue
import android.view.View
import androidx.preference.EditTextPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import me.capcom.smsgateway.R

class MessagesSettingsFragment : PreferenceFragmentCompat() {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val backgroundValue = TypedValue()
requireContext().theme.resolveAttribute(
android.R.attr.colorBackground,
backgroundValue,
true
)

view.setBackgroundColor(backgroundValue.data)
}
class MessagesSettingsFragment : BasePreferenceFragment() {

override fun onResume() {
super.onResume()
Expand Down
29 changes: 26 additions & 3 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,33 @@
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
android:layout_weight="1">

<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<FrameLayout
android:id="@+id/progressBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/progressBarOverlay"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
tools:visibility="visible">

<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true" />
</FrameLayout>
</FrameLayout>


</androidx.appcompat.widget.LinearLayoutCompat>
1 change: 1 addition & 0 deletions app/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="progressBarOverlay">#33FFFFFF</color>
</resources>
Loading

0 comments on commit a4d78e1

Please sign in to comment.