Skip to content
This repository was archived by the owner on Oct 15, 2024. It is now read-only.

Commit 92f1aab

Browse files
Add option to automatically sync repository on app launch (#1137)
* Add option to automatically sync repository on app launch Signed-off-by: Aditya Wasan <[email protected]> * Pull repo if user is not authenticated Signed-off-by: Aditya Wasan <[email protected]> * Address review comments Signed-off-by: Harsh Shandilya <[email protected]> * Hijack incoming intent rather than copying it Signed-off-by: Harsh Shandilya <[email protected]> * Initialize password repository before using it Signed-off-by: Aditya Wasan <[email protected]> Co-authored-by: Harsh Shandilya <[email protected]>
1 parent a025ecf commit 92f1aab

File tree

7 files changed

+119
-14
lines changed

7 files changed

+119
-14
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@
4242
<activity
4343
android:name=".LaunchActivity"
4444
android:configChanges="orientation|screenSize"
45-
android:label="@string/app_name"
46-
android:theme="@style/NoBackgroundTheme">
45+
android:label="@string/app_name">
4746
<intent-filter>
4847
<action android:name="android.intent.action.MAIN" />
4948
<category android:name="android.intent.category.LAUNCHER" />

app/src/main/java/com/zeapo/pwdstore/LaunchActivity.kt

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,34 @@
44
*/
55
package com.zeapo.pwdstore
66

7+
import android.content.ComponentName
78
import android.content.Intent
89
import android.os.Bundle
910
import android.os.Handler
10-
import androidx.appcompat.app.AppCompatActivity
1111
import androidx.core.content.edit
12+
import androidx.core.view.isVisible
13+
import androidx.lifecycle.lifecycleScope
14+
import com.github.michaelbull.result.fold
1215
import com.zeapo.pwdstore.crypto.DecryptActivity
16+
import com.zeapo.pwdstore.databinding.ActivityLaunchBinding
17+
import com.zeapo.pwdstore.git.BaseGitActivity
18+
import com.zeapo.pwdstore.git.config.AuthMode
19+
import com.zeapo.pwdstore.git.config.GitSettings
1320
import com.zeapo.pwdstore.utils.BiometricAuthenticator
21+
import com.zeapo.pwdstore.utils.PasswordRepository
1422
import com.zeapo.pwdstore.utils.PreferenceKeys
1523
import com.zeapo.pwdstore.utils.sharedPrefs
24+
import com.zeapo.pwdstore.utils.viewBinding
25+
import kotlinx.coroutines.launch
1626

17-
class LaunchActivity : AppCompatActivity() {
27+
class LaunchActivity : BaseGitActivity() {
28+
29+
private val binding by viewBinding(ActivityLaunchBinding::inflate)
1830

1931
override fun onCreate(savedInstanceState: Bundle?) {
2032
super.onCreate(savedInstanceState)
33+
setContentView(binding.root)
34+
supportActionBar?.hide()
2135
val prefs = sharedPrefs
2236
if (prefs.getBoolean(PreferenceKeys.BIOMETRIC_AUTH, false)) {
2337
BiometricAuthenticator.authenticate(this) {
@@ -40,18 +54,38 @@ class LaunchActivity : AppCompatActivity() {
4054
}
4155

4256
private fun startTargetActivity(noAuth: Boolean) {
43-
val intentToStart = if (intent.action == ACTION_DECRYPT_PASS)
44-
Intent(this, DecryptActivity::class.java).apply {
45-
putExtra("NAME", intent.getStringExtra("NAME"))
46-
putExtra("FILE_PATH", intent.getStringExtra("FILE_PATH"))
47-
putExtra("REPO_PATH", intent.getStringExtra("REPO_PATH"))
48-
putExtra("LAST_CHANGED_TIMESTAMP", intent.getLongExtra("LAST_CHANGED_TIMESTAMP", 0L))
57+
if (intent.action == ACTION_DECRYPT_PASS) {
58+
intent.component = ComponentName(this, DecryptActivity::class.java)
59+
startPasswordStoreActivity(intent, noAuth)
60+
} else {
61+
val intent = Intent(this, PasswordStore::class.java)
62+
val repo = PasswordRepository.initialize()
63+
// if repo is null, let PasswordStore handle it.
64+
if (repo != null &&
65+
!GitSettings.url.isNullOrEmpty() &&
66+
sharedPrefs.getBoolean(PreferenceKeys.SYNC_ON_LAUNCH, false)) {
67+
binding.progressBar.isVisible = true
68+
binding.sync.isVisible = true
69+
runGitOperation { startPasswordStoreActivity(intent, noAuth) }
70+
} else {
71+
startPasswordStoreActivity(intent, noAuth)
4972
}
50-
else
51-
Intent(this, PasswordStore::class.java)
52-
startActivity(intentToStart)
73+
}
74+
}
75+
76+
private fun startPasswordStoreActivity(intent: Intent, noAuth: Boolean) {
77+
Handler().postDelayed({
78+
startActivity(intent)
79+
finish()
80+
}, if (noAuth) 500L else 0L)
81+
}
5382

54-
Handler().postDelayed({ finish() }, if (noAuth) 0L else 500L)
83+
private fun runGitOperation(onCompletion: () -> Unit) = lifecycleScope.launch {
84+
val gitOp = if (GitSettings.authMode == AuthMode.None) GitOp.PULL else GitOp.SYNC
85+
launchGitOperation(gitOp).fold(
86+
success = { onCompletion.invoke() },
87+
failure = { promptOnErrorHandler(it) { onCompletion.invoke() } },
88+
)
5589
}
5690

5791
companion object {

app/src/main/java/com/zeapo/pwdstore/UserPreference.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import com.zeapo.pwdstore.autofill.AutofillPreferenceActivity
4646
import com.zeapo.pwdstore.crypto.BasePgpActivity
4747
import com.zeapo.pwdstore.git.GitConfigActivity
4848
import com.zeapo.pwdstore.git.GitServerConfigActivity
49+
import com.zeapo.pwdstore.git.config.GitSettings
4950
import com.zeapo.pwdstore.git.sshj.SshKey
5051
import com.zeapo.pwdstore.pwgenxkpwd.XkpwdDictionary
5152
import com.zeapo.pwdstore.sshkeygen.ShowSshKeyFragment
@@ -424,6 +425,8 @@ class UserPreference : AppCompatActivity() {
424425
true
425426
}
426427

428+
findPreference<CheckBoxPreference>(PreferenceKeys.SYNC_ON_LAUNCH)?.isVisible = !GitSettings.url.isNullOrEmpty()
429+
427430
val prefCustomXkpwdDictionary = findPreference<Preference>(PreferenceKeys.PREF_KEY_CUSTOM_DICT)
428431
prefCustomXkpwdDictionary?.onPreferenceClickListener = ClickListener {
429432
prefsActivity.storeCustomDictionaryPath()

app/src/main/java/com/zeapo/pwdstore/utils/PreferenceKeys.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ object PreferenceKeys {
7777
const val SSH_OPENKEYSTORE_CLEAR_KEY_ID = "ssh_openkeystore_clear_keyid"
7878
const val SSH_OPENKEYSTORE_KEYID = "ssh_openkeystore_keyid"
7979
const val SSH_SEE_KEY = "ssh_see_key"
80+
const val SYNC_ON_LAUNCH = "sync_on_launch"
8081

8182
@Deprecated("To be used only in Migrations.kt")
8283
const val USE_GENERATED_KEY = "use_generated_key"
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
2+
xmlns:app="http://schemas.android.com/apk/res-auto"
3+
android:layout_width="match_parent"
4+
android:layout_height="match_parent"
5+
android:background="?attr/colorPrimary"
6+
android:orientation="vertical">
7+
8+
<androidx.appcompat.widget.AppCompatImageView
9+
android:id="@+id/app_icon"
10+
android:layout_width="100dp"
11+
android:layout_height="100dp"
12+
android:contentDescription="@string/app_icon_hint"
13+
android:src="@mipmap/ic_launcher"
14+
android:transitionName="transition_first_app_icon"
15+
app:layout_constraintBottom_toBottomOf="parent"
16+
app:layout_constraintEnd_toEndOf="parent"
17+
app:layout_constraintStart_toStartOf="parent"
18+
app:layout_constraintTop_toTopOf="parent" />
19+
20+
<androidx.appcompat.widget.AppCompatTextView
21+
android:id="@+id/app_name"
22+
android:layout_width="wrap_content"
23+
android:layout_height="wrap_content"
24+
android:layout_centerHorizontal="true"
25+
android:layout_marginTop="16dp"
26+
android:text="@string/app_name"
27+
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5"
28+
android:textColor="@color/color_control_normal"
29+
android:textStyle="bold"
30+
android:transitionName="transition_first_run_app_name"
31+
app:layout_constraintEnd_toEndOf="parent"
32+
app:layout_constraintStart_toStartOf="parent"
33+
app:layout_constraintTop_toBottomOf="@+id/app_icon" />
34+
35+
<ProgressBar
36+
android:id="@+id/progress_bar"
37+
android:layout_width="wrap_content"
38+
android:layout_height="wrap_content"
39+
android:visibility="invisible"
40+
app:layout_constraintBottom_toBottomOf="parent"
41+
app:layout_constraintEnd_toEndOf="parent"
42+
app:layout_constraintStart_toStartOf="parent"
43+
app:layout_constraintTop_toTopOf="parent"
44+
app:layout_constraintVertical_bias="0.85" />
45+
46+
<androidx.appcompat.widget.AppCompatTextView
47+
android:id="@+id/sync"
48+
android:layout_width="wrap_content"
49+
android:layout_height="wrap_content"
50+
android:layout_marginTop="8dp"
51+
android:text="@string/syncing"
52+
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
53+
android:textColor="@color/color_control_normal"
54+
android:visibility="invisible"
55+
app:layout_constraintEnd_toEndOf="parent"
56+
app:layout_constraintStart_toStartOf="parent"
57+
app:layout_constraintTop_toBottomOf="@id/progress_bar" />
58+
59+
</androidx.constraintlayout.widget.ConstraintLayout>

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,9 @@
407407
<!-- SSH port validation -->
408408
<string name="ssh_scheme_needed_title">Potentially incorrect URL</string>
409409
<string name="ssh_scheme_needed_message">It appears that your URL contains a custom port, but does not specify the ssh:// scheme.\nThis can cause the port to be considered a part of your path. Press OK here to fix the URL.</string>
410+
<string name="sync_on_launch_title">Sync on launch</string>
411+
<string name="sync_on_launch_summary">Sync passwords when application is launched</string>
412+
<string name="syncing">Syncing…</string>
410413

411414
<!-- Proxy configuration activity -->
412415
<string name="proxy_hostname">Proxy hostname</string>

app/src/main/res/xml/preference.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@
138138
app:key="biometric_auth"
139139
app:summary="@string/biometric_auth_summary"
140140
app:title="@string/biometric_auth_title" />
141+
<CheckBoxPreference
142+
app:defaultValue="false"
143+
app:key="sync_on_launch"
144+
app:persistent="true"
145+
app:summary="@string/sync_on_launch_summary"
146+
app:title="@string/sync_on_launch_title" />
141147
</PreferenceCategory>
142148
<PreferenceCategory app:title="@string/pref_category_title_passwords">
143149
<EditTextPreference

0 commit comments

Comments
 (0)