Skip to content

Commit a4d78e1

Browse files
committed
[settings] allow to change cloud password
1 parent 6b44548 commit a4d78e1

13 files changed

+315
-140
lines changed

app/src/main/java/me/capcom/smsgateway/modules/gateway/GatewayApi.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ class GatewayApi(
8686
}.body()
8787
}
8888

89+
suspend fun changePassword(token: String, request: PasswordChangeRequest) {
90+
client.patch("$baseUrl/user/password") {
91+
auth(token)
92+
contentType(ContentType.Application.Json)
93+
setBody(request)
94+
}
95+
}
96+
8997
private fun HttpRequestBuilder.auth(token: String) {
9098
header(HttpHeaders.Authorization, "Bearer $token")
9199
}
@@ -118,6 +126,11 @@ class GatewayApi(
118126
val states: Map<ProcessingState, Date>
119127
)
120128

129+
data class PasswordChangeRequest(
130+
val currentPassword: String,
131+
val newPassword: String
132+
)
133+
121134
data class Message(
122135
val id: String,
123136
val message: String,

app/src/main/java/me/capcom/smsgateway/modules/gateway/GatewayService.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,27 @@ class GatewayService(
6363
this._api = null
6464
}
6565

66+
suspend fun changePassword(current: String, new: String) {
67+
val info = settings.registrationInfo
68+
?: throw IllegalStateException("The device is not registered on the server")
69+
70+
this.api.changePassword(
71+
info.token,
72+
GatewayApi.PasswordChangeRequest(current, new)
73+
)
74+
75+
settings.registrationInfo = info.copy(password = new)
76+
77+
events.emit(
78+
DeviceRegisteredEvent(
79+
api.hostname,
80+
info.login,
81+
new,
82+
)
83+
)
84+
}
85+
86+
///////////////////////////////////////////////////////////////////////////
6687
internal suspend fun getWebHooks(): List<GatewayApi.WebHook> {
6788
val settings = settings.registrationInfo
6889
return if (settings != null) {

app/src/main/java/me/capcom/smsgateway/modules/gateway/GatewaySettings.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ class GatewaySettings(
1717
get() = storage.get(REGISTRATION_INFO)
1818
set(value) = storage.set(REGISTRATION_INFO, value)
1919

20+
val username: String?
21+
get() = registrationInfo?.login
22+
val password: String?
23+
get() = registrationInfo?.password
24+
2025
val privateUrl: String?
2126
get() = storage.get<String?>(CLOUD_URL)
2227
val privateToken: String?

app/src/main/java/me/capcom/smsgateway/ui/SettingsFragment.kt

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,17 @@ import android.provider.Settings
1010
import android.text.InputType
1111
import android.widget.Toast
1212
import androidx.annotation.RequiresApi
13-
import androidx.core.content.edit
1413
import androidx.preference.EditTextPreference
1514
import androidx.preference.Preference
1615
import androidx.preference.PreferenceFragmentCompat
1716
import me.capcom.smsgateway.BuildConfig
1817
import me.capcom.smsgateway.R
19-
import me.capcom.smsgateway.modules.gateway.GatewaySettings
2018

2119
class SettingsFragment : PreferenceFragmentCompat() {
2220

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

26-
findPreference<EditTextPreference>("gateway.cloud_url")?.setSummaryProvider {
27-
val hostname = preferenceManager.sharedPreferences?.getString(it.key, null)
28-
if (hostname.isNullOrEmpty()) {
29-
preferenceManager.sharedPreferences?.edit(true) {
30-
putString(it.key, GatewaySettings.PUBLIC_URL)
31-
}
32-
return@setSummaryProvider GatewaySettings.PUBLIC_URL
33-
}
34-
return@setSummaryProvider hostname
35-
}
36-
3724
findPreference<Preference>("transient.app_version")?.summary =
3825
"${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})"
3926

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

5037
override fun onDisplayPreferenceDialog(preference: Preference) {
51-
if (preference.key == "encryption.passphrase"
52-
|| preference.key == "gateway.private_token"
53-
) {
38+
if (preference.key == "encryption.passphrase") {
5439
(preference as EditTextPreference).setOnBindEditTextListener {
5540
it.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
5641
it.setSelectAllOnFocus(true)
5742
it.selectAll()
5843
}
5944
}
6045

61-
if (preference.key == "gateway.cloud_url") {
62-
(preference as EditTextPreference).setOnBindEditTextListener {
63-
it.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI
64-
it.setSelectAllOnFocus(true)
65-
}
66-
}
67-
6846
if (preference.key == "ping.interval_seconds"
6947
|| preference.key == "logs.lifetime_days"
7048
|| preference.key == "webhooks.retry_count"
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package me.capcom.smsgateway.ui.settings
2+
3+
import android.os.Bundle
4+
import android.util.TypedValue
5+
import android.view.View
6+
import android.widget.Toast
7+
import androidx.preference.PreferenceFragmentCompat
8+
9+
abstract class BasePreferenceFragment : PreferenceFragmentCompat() {
10+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
11+
super.onViewCreated(view, savedInstanceState)
12+
13+
val backgroundValue = TypedValue()
14+
requireContext().theme.resolveAttribute(
15+
android.R.attr.colorBackground,
16+
backgroundValue,
17+
true
18+
)
19+
20+
view.setBackgroundColor(backgroundValue.data)
21+
}
22+
23+
protected fun showToast(message: String) {
24+
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
25+
}
26+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package me.capcom.smsgateway.ui.settings
2+
3+
import android.annotation.SuppressLint
4+
import android.os.Bundle
5+
import android.text.InputType
6+
import android.view.View
7+
import androidx.core.content.edit
8+
import androidx.core.view.isVisible
9+
import androidx.lifecycle.lifecycleScope
10+
import androidx.preference.EditTextPreference
11+
import androidx.preference.Preference
12+
import kotlinx.coroutines.launch
13+
import me.capcom.smsgateway.R
14+
import me.capcom.smsgateway.modules.gateway.GatewayService
15+
import me.capcom.smsgateway.modules.gateway.GatewaySettings
16+
import org.koin.android.ext.android.inject
17+
import java.net.URL
18+
19+
class CloudServerSettingsFragment : BasePreferenceFragment() {
20+
21+
private val settings: GatewaySettings by inject()
22+
private val service: GatewayService by inject()
23+
24+
@SuppressLint("NotifyDataSetChanged")
25+
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
26+
setPreferencesFromResource(R.xml.cloud_server_preferences, rootKey)
27+
28+
findPreference<EditTextPreference>("gateway.cloud_url")?.setSummaryProvider {
29+
val hostname = preferenceManager.sharedPreferences?.getString(it.key, null)
30+
if (hostname.isNullOrEmpty()) {
31+
preferenceManager.sharedPreferences?.edit(true) {
32+
putString(it.key, GatewaySettings.PUBLIC_URL)
33+
}
34+
return@setSummaryProvider GatewaySettings.PUBLIC_URL
35+
}
36+
return@setSummaryProvider hostname
37+
}
38+
39+
40+
findPreference<EditTextPreference>("gateway.cloud_url")?.setOnPreferenceChangeListener { _, newValue ->
41+
val value = newValue as? String
42+
if (value.isNullOrEmpty()) {
43+
return@setOnPreferenceChangeListener true
44+
}
45+
46+
try {
47+
URL(value)
48+
} catch (e: Exception) {
49+
showToast(getString(R.string.invalid_url))
50+
return@setOnPreferenceChangeListener false
51+
}
52+
53+
true
54+
}
55+
56+
findPreference<EditTextPreference>("gateway.username")?.setSummaryProvider {
57+
settings.username ?: getString(R.string.not_set)
58+
}
59+
findPreference<EditTextPreference>("gateway.password")?.apply {
60+
setSummaryProvider {
61+
settings.password ?: getString(R.string.not_set)
62+
}
63+
64+
setOnPreferenceChangeListener { _, newValue ->
65+
val value = newValue as? String
66+
if (value == null || value.length < 14) {
67+
showToast(getString(R.string.password_must_be_at_least_14_characters))
68+
return@setOnPreferenceChangeListener false
69+
}
70+
71+
this@CloudServerSettingsFragment.lifecycleScope.launch {
72+
try {
73+
requireActivity().findViewById<View>(R.id.progressBar).isVisible = true
74+
service.changePassword(settings.password ?: "", value)
75+
listView.adapter?.notifyDataSetChanged()
76+
showToast(getString(R.string.password_changed_successfully))
77+
} catch (e: Exception) {
78+
showToast(getString(R.string.failed_to_change_password, e.message))
79+
} finally {
80+
requireActivity().findViewById<View>(R.id.progressBar).isVisible = false
81+
}
82+
}
83+
84+
true
85+
}
86+
}
87+
}
88+
89+
override fun onDisplayPreferenceDialog(preference: Preference) {
90+
if (preference.key == "gateway.cloud_url") {
91+
(preference as EditTextPreference).setOnBindEditTextListener {
92+
it.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI
93+
it.setSelectAllOnFocus(true)
94+
it.selectAll()
95+
}
96+
}
97+
98+
if (preference.key == "gateway.private_token") {
99+
(preference as EditTextPreference).setOnBindEditTextListener {
100+
it.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
101+
it.setSelectAllOnFocus(true)
102+
it.selectAll()
103+
}
104+
}
105+
106+
if (preference.key == "gateway.password") {
107+
(preference as EditTextPreference).setOnBindEditTextListener {
108+
it.inputType = InputType.TYPE_CLASS_TEXT
109+
it.text = null
110+
}
111+
}
112+
113+
super.onDisplayPreferenceDialog(preference)
114+
}
115+
}

app/src/main/java/me/capcom/smsgateway/ui/settings/LocalServerSettingsFragment.kt

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,11 @@ package me.capcom.smsgateway.ui.settings
22

33
import android.os.Bundle
44
import android.text.InputType
5-
import android.util.TypedValue
6-
import android.view.View
7-
import android.widget.Toast
85
import androidx.preference.EditTextPreference
96
import androidx.preference.Preference
10-
import androidx.preference.PreferenceFragmentCompat
117
import me.capcom.smsgateway.R
128

13-
class LocalServerSettingsFragment : PreferenceFragmentCompat() {
14-
15-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
16-
super.onViewCreated(view, savedInstanceState)
17-
18-
val backgroundValue = TypedValue()
19-
requireContext().theme.resolveAttribute(
20-
android.R.attr.colorBackground,
21-
backgroundValue,
22-
true
23-
)
24-
25-
view.setBackgroundColor(backgroundValue.data)
26-
}
9+
class LocalServerSettingsFragment : BasePreferenceFragment() {
2710

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

8770
super.onDisplayPreferenceDialog(preference)
8871
}
89-
90-
private fun showToast(message: String) {
91-
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
92-
}
9372
}

app/src/main/java/me/capcom/smsgateway/ui/settings/MessagesSettingsFragment.kt

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,11 @@ package me.capcom.smsgateway.ui.settings
33
import android.content.SharedPreferences
44
import android.os.Bundle
55
import android.text.InputType
6-
import android.util.TypedValue
7-
import android.view.View
86
import androidx.preference.EditTextPreference
97
import androidx.preference.Preference
10-
import androidx.preference.PreferenceFragmentCompat
118
import me.capcom.smsgateway.R
129

13-
class MessagesSettingsFragment : PreferenceFragmentCompat() {
14-
15-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
16-
super.onViewCreated(view, savedInstanceState)
17-
18-
val backgroundValue = TypedValue()
19-
requireContext().theme.resolveAttribute(
20-
android.R.attr.colorBackground,
21-
backgroundValue,
22-
true
23-
)
24-
25-
view.setBackgroundColor(backgroundValue.data)
26-
}
10+
class MessagesSettingsFragment : BasePreferenceFragment() {
2711

2812
override fun onResume() {
2913
super.onResume()

app/src/main/res/layout/activity_main.xml

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,33 @@
1212
android:layout_width="match_parent"
1313
android:layout_height="wrap_content" />
1414

15-
<androidx.viewpager2.widget.ViewPager2
16-
android:id="@+id/viewPager"
15+
<FrameLayout
1716
android:layout_width="match_parent"
1817
android:layout_height="0dp"
19-
android:layout_weight="1" />
18+
android:layout_weight="1">
19+
20+
<androidx.viewpager2.widget.ViewPager2
21+
android:id="@+id/viewPager"
22+
android:layout_width="match_parent"
23+
android:layout_height="match_parent" />
24+
25+
<FrameLayout
26+
android:id="@+id/progressBar"
27+
android:layout_width="match_parent"
28+
android:layout_height="match_parent"
29+
android:background="@color/progressBarOverlay"
30+
android:clickable="true"
31+
android:focusable="true"
32+
android:visibility="gone"
33+
tools:visibility="visible">
34+
35+
<ProgressBar
36+
android:layout_width="wrap_content"
37+
android:layout_height="wrap_content"
38+
android:layout_gravity="center"
39+
android:indeterminate="true" />
40+
</FrameLayout>
41+
</FrameLayout>
42+
2043

2144
</androidx.appcompat.widget.LinearLayoutCompat>

app/src/main/res/values/colors.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77
<color name="teal_700">#FF018786</color>
88
<color name="black">#FF000000</color>
99
<color name="white">#FFFFFFFF</color>
10+
<color name="progressBarOverlay">#33FFFFFF</color>
1011
</resources>

0 commit comments

Comments
 (0)