mirror of
https://github.com/android-password-store/Android-Password-Store
synced 2025-08-29 13:27:46 +00:00
show age for passwords in detail view (#339)
* show age for passwords in detail view Implements #330. This fetches the latest commit where the respective password file was changed from the current HEAD and outputs the relative time since the last change on the decrypt page. * Move lastChanged logic out of PgpActivity This nicely encapsulates the lastChanged logic (and thus separates it from dependencies like git). The last changed date is now passed as a timestamp using the Intent's extra info.
This commit is contained in:
parent
916d63f9be
commit
e41287cb16
@ -42,7 +42,9 @@ import com.zeapo.pwdstore.utils.PasswordRepository;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
@ -406,11 +408,40 @@ public class PasswordStore extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private String getRelativePath(String fullPath, String repositoryPath) {
|
||||
return fullPath.replace(repositoryPath, "").replaceAll("/+", "/");
|
||||
}
|
||||
|
||||
public int getLastChangedTimestamp(String fullPath) {
|
||||
File repoPath = PasswordRepository.getRepositoryDirectory(this);
|
||||
Repository repository = PasswordRepository.getRepository(repoPath);
|
||||
|
||||
if (repository == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Git git = new Git(repository);
|
||||
String relativePath = getRelativePath(fullPath, repoPath.getAbsolutePath()).substring(1);
|
||||
Iterable<RevCommit> iterable;
|
||||
|
||||
try {
|
||||
iterable = git.log().addPath(relativePath).call();
|
||||
} catch (GitAPIException e) {
|
||||
System.out.println("Exception caught :(");
|
||||
e.printStackTrace();
|
||||
return -1;
|
||||
}
|
||||
|
||||
RevCommit latestCommit = iterable.iterator().next();
|
||||
return latestCommit.getCommitTime();
|
||||
}
|
||||
|
||||
public void decryptPassword(PasswordItem item) {
|
||||
Intent intent = new Intent(this, PgpActivity.class);
|
||||
intent.putExtra("NAME", item.toString());
|
||||
intent.putExtra("FILE_PATH", item.getFile().getAbsolutePath());
|
||||
intent.putExtra("REPO_PATH", PasswordRepository.getRepositoryDirectory(getApplicationContext()).getAbsolutePath());
|
||||
intent.putExtra("LAST_CHANGED_TIMESTAMP", getLastChangedTimestamp(item.getFile().getAbsolutePath()));
|
||||
intent.putExtra("OPERATION", "DECRYPT");
|
||||
|
||||
// Adds shortcut
|
||||
|
@ -12,6 +12,7 @@ import android.os.SystemClock
|
||||
import android.preference.PreferenceManager
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.text.TextUtils
|
||||
import android.text.format.DateUtils
|
||||
import android.text.method.PasswordTransformationMethod
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
@ -20,6 +21,7 @@ import com.zeapo.pwdstore.PasswordEntry
|
||||
import com.zeapo.pwdstore.R
|
||||
import com.zeapo.pwdstore.UserPreference
|
||||
import com.zeapo.pwdstore.pwgenDialogFragment
|
||||
import com.zeapo.pwdstore.utils.PasswordRepository
|
||||
import com.zeapo.pwdstore.utils.Totp
|
||||
import kotlinx.android.synthetic.main.decrypt_layout.*
|
||||
import kotlinx.android.synthetic.main.encrypt_layout.*
|
||||
@ -47,6 +49,7 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
||||
|
||||
private val fullPath: String by lazy { intent.getStringExtra("FILE_PATH") }
|
||||
private val name: String by lazy { getName(fullPath, repoPath) }
|
||||
private val lastChangedString: CharSequence by lazy { getLastChangedString(intent.getIntExtra("LAST_CHANGED_TIMESTAMP", -1)) }
|
||||
private val relativeParentPath: String by lazy { getParentPath(fullPath, repoPath) }
|
||||
|
||||
private val settings: SharedPreferences by lazy { PreferenceManager.getDefaultSharedPreferences(this) }
|
||||
@ -76,6 +79,13 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
||||
setContentView(R.layout.decrypt_layout)
|
||||
crypto_password_category_decrypt.text = relativeParentPath
|
||||
crypto_password_file.text = name
|
||||
|
||||
crypto_password_last_changed.text = try {
|
||||
this.resources.getString(R.string.last_changed, lastChangedString)
|
||||
} catch (e: RuntimeException) {
|
||||
showToast(getString(R.string.get_last_changed_failed))
|
||||
""
|
||||
}
|
||||
}
|
||||
"ENCRYPT" -> {
|
||||
setContentView(R.layout.encrypt_layout)
|
||||
@ -514,6 +524,18 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound {
|
||||
delayTask?.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a relative string describing when this shape was last changed
|
||||
* (e.g. "one hour ago")
|
||||
*/
|
||||
private fun getLastChangedString(timeStamp: Int): CharSequence {
|
||||
if (timeStamp < 0) {
|
||||
throw RuntimeException()
|
||||
}
|
||||
|
||||
return DateUtils.getRelativeTimeSpanString(this, timeStamp.toLong() * 1000, true)
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
inner class DelayShow(val activity: PgpActivity) : AsyncTask<Void, Int, Boolean>() {
|
||||
private val pb: ProgressBar by lazy { pbLoading }
|
||||
|
@ -43,6 +43,19 @@
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/crypto_password_last_changed"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:text="LAST CHANGED HERE"
|
||||
android:textColor="@color/grey_500"
|
||||
android:textIsSelectable="false"
|
||||
android:textSize="18sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
|
@ -153,4 +153,5 @@
|
||||
<string name="no_repo_selected">Nebyl vybrát externí repozitář</string>
|
||||
<string name="send_plaintext_password_to">Odeslat heslo jako plaintext za použití…</string>
|
||||
<string name="show_password">Pokaż hasło</string>
|
||||
<string name="get_last_changed_failed">Failed to get last changed date</string>
|
||||
</resources>
|
@ -194,4 +194,6 @@
|
||||
<string name="autofill_ins_1_hint">Bildschirmfoto Accessibility Services</string>
|
||||
<string name="autofill_ins_2_hint">Bildschirmfoto des Schalters in Accessibility Services</string>
|
||||
<string name="autofill_ins_3_hint">Bildschirmfoto von Autofill in Aktion</string>
|
||||
<string name="last_changed">Zuletzt geändert %s</string>
|
||||
<string name="get_last_changed_failed">Das Abrufen des letzten Änderungsdatums ist fehlgeschlagen.</string>
|
||||
</resources>
|
||||
|
@ -186,4 +186,5 @@
|
||||
<string name="show_extra_content_pref_title">Afficher le contenu supplémentaire</string>
|
||||
<string name="username">Nom d\'utilisateur</string>
|
||||
<string name="ssh_key_does_not_exist">Impossible d\'ouvrir la clef ssh, merci de vérifier que le ficher existe</string>
|
||||
<string name="get_last_changed_failed">Failed to get last changed date</string>
|
||||
</resources>
|
||||
|
@ -157,4 +157,5 @@
|
||||
<string name="no_repo_selected">外部リポジトリが選択されていません</string>
|
||||
<string name="send_plaintext_password_to">パスワードをプレーンテキストとして送信…</string>
|
||||
<string name="show_password">パスワードを表示</string>
|
||||
<string name="get_last_changed_failed">Failed to get last changed date</string>
|
||||
</resources>
|
||||
|
@ -188,4 +188,5 @@
|
||||
<string name="autofill_paste">Вставить</string>
|
||||
<string name="autofill_paste_username">Вставить имя пользователя?\n\n%s</string>
|
||||
<string name="autofill_toast_username">Выберите поле ввода для вставки имени пользователя.\nИмя пользователя можно вставить в течение %d секунд.</string>
|
||||
<string name="get_last_changed_failed">Failed to get last changed date</string>
|
||||
</resources>
|
||||
|
@ -121,4 +121,5 @@
|
||||
<string name="server_resulting_url">生成的 URL</string>
|
||||
<string name="autofill_apps_match_ellipsis">匹配…</string>
|
||||
<string name="pref_crypto_title">加密</string>
|
||||
<string name="get_last_changed_failed">Failed to get last changed date</string>
|
||||
</resources>
|
@ -121,4 +121,5 @@
|
||||
<string name="server_resulting_url">生成的 URL</string>
|
||||
<string name="autofill_apps_match_ellipsis">匹配…</string>
|
||||
<string name="pref_crypto_title">加密</string>
|
||||
<string name="get_last_changed_failed">Failed to get last changed date</string>
|
||||
</resources>
|
||||
|
@ -98,6 +98,7 @@
|
||||
<string name="copy_password">Copy password</string>
|
||||
<string name="copy_username">Copy username</string>
|
||||
<string name="share_as_plaintext">Share as plaintext</string>
|
||||
<string name="last_changed">Last changed %s</string>
|
||||
|
||||
<!-- Preferences -->
|
||||
<string name="pref_git_title">Git</string>
|
||||
@ -217,4 +218,5 @@
|
||||
<string name="commit_hash">Commit hash</string>
|
||||
<string name="crypto_password_edit_hint">p@ssw0rd!</string>
|
||||
<string name="crypto_extra_edit_hint">username: something other extra content</string>
|
||||
<string name="get_last_changed_failed">Failed to get last changed date</string>
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user