Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/passman-android.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbinsky08 <timo@binsky.org>2022-07-10 19:00:48 +0300
committerbinsky08 <timo@binsky.org>2022-07-10 19:00:48 +0300
commit9647ecb4d5815067a4c593940b961c512db48638 (patch)
tree4facb551ee89dbddd3da23c6d022b0f209e2239d
parente4e4b32d44f63742f7b6817c6ef858f5ed552a0b (diff)
parent6b76cf2c76922d000558019894637ff18c56293e (diff)
Merge branch 'master' of github.com:nextcloud/passman-android into sso-3-backport
Signed-off-by: binsky08 <timo@binsky.org>
-rw-r--r--FAQ.md79
-rw-r--r--PRIVACY.md28
-rw-r--r--README.md61
-rw-r--r--app/build.gradle4
-rw-r--r--app/src/main/java/es/wolfi/app/passman/activities/PasswordListActivity.java27
-rw-r--r--app/src/main/java/es/wolfi/app/passman/fragments/CredentialDisplayFragment.java25
-rw-r--r--app/src/main/java/es/wolfi/app/passman/fragments/SettingsFragment.java37
-rw-r--r--app/src/main/java/es/wolfi/app/passman/fragments/VaultFragment.java5
-rw-r--r--app/src/main/java/es/wolfi/app/passman/fragments/VaultLockScreenFragment.java1
-rw-r--r--app/src/main/java/es/wolfi/passman/API/Core.java30
-rw-r--r--app/src/main/java/es/wolfi/utils/KeyStoreUtils.java4
-rw-r--r--app/src/main/res/values-gl/strings.xml2
-rw-r--r--fastlane/metadata/android/en-US/changelogs/15.txt4
13 files changed, 201 insertions, 106 deletions
diff --git a/FAQ.md b/FAQ.md
new file mode 100644
index 0000000..5c4dbf8
--- /dev/null
+++ b/FAQ.md
@@ -0,0 +1,79 @@
+# Frequently asked questions
+
+- [How do I setup the app correctly after installation?](#how-do-i-setup-the-app-correctly-after-installation)
+- [What is the design (intention) for log out on the vaults?](#what-is-the-design-intention-for-log-out-on-the-vaults)
+- [How does the back button work?](#how-does-the-back-button-work)
+- [How does the refresh button work?](#how-does-the-refresh-button-work)
+- [How can I use the autofill feature?](#how-can-i-use-the-autofill-feature)
+- [How does deleting credentials work?](#how-does-deleting-credentials-work)
+- [Is there a smaller apk to download?](#i-dont-have-enough-storage-on-my-phone-to-install-passman-android-from-an-app-store-what-can-i-do)
+- [What means "Encrypted offline cache"?](#what-means-encrypted-offline-cache)
+- [How far can I trust the local storage encryption?](#how-far-can-i-trust-the-local-storage-encryption-is-it-save-to-store-my-vault-password-on-the-device)
+- [How can I use a self signed certificate to connect the my Nextcloud server?](#how-can-i-use-a-self-signed-certificate-to-connect-the-my-nextcloud-server)
+
+
+## How do I setup the app correctly after installation?
+- Choose whether you want to use https or http for the server connection (recommended is using https, but it depends on your server setup)
+- Fill in your Nextclouds hostname or IP address, and also the port if it's not the protocols default (443 for https; 80 for http)
+ - Examples for allowed hostnames:
+ - 10.0.2.2
+ - 10.0.2.2:8080
+ - mycloud.example.com/
+- Fill in your Nextcloud user and password (will be stored encrypted)
+- Press the connect button
+
+## What is the design (intention) for log out on the vaults?
+- If you unlocked a vault and the app is still running in the background, the vault stays open (so that you easily can switch between apps)
+- If you close the app all vaults will be locked
+- As long as the app is running you can switch between vaults (and they remain unlocked)
+- If you set a tick to save the vault password, technically the "vault is locked" if the app is closed but you don't have to manually unlock it until you press (manually!) the lock button
+- Pressing the lock button will lock the vault and also remove a saved vault password (if it was saved before)
+
+## How does the back button work?
+- Hitting the back button from where ever you are, ends in going back to the "parent" place (that's usually the page you have seen before)
+- If you press back in the vaults overview, the app remains in the background
+
+## How does the refresh button work?
+- If you are in an opened vault, the refresh button will refresh the current vault. And thus also the password list.
+ - If the vaults encryption key did not change the vault remains unlocked
+- If you are in the vaults overview, the refresh button will clear and refresh the complete vaults storage
+ - This does not affect the offline cache of an explicitly selected autofill vault
+
+## How can I use the autofill feature?
+- It requires at least Android 8
+- Passman Android currently offers the autofill feature automatically to the system.
+- To use Passman as autofill service, you need to select the app in the Android settings as autofill service
+ - where to find that setting is different on any Android device
+ - an example path in the Android settings could be `More Settings` -> `Language and Input` -> `Additional Keyboard Settings` -> `Autofill Service`
+- If you select a custom vault in the Passman Android settings as autofill vault, it will be cached offline, and if you also save the vault password, you won't need a network connection or manually open the Passman app before using autofill in an other app.
+- By default in the Passman Android settings the autofill vault is set to automatically, so that Passman needs to run in the background and the currently unlocked vault is used for the autofill service
+
+## How does deleting credentials work?
+- If you delete a credential in the Passman Android app, it will be moved to the trash on the server side ("Deleted credentials" section in the web view)
+- You don't have to be anxious to accidentally delete it, you have to confirm the operation
+- You can't access the deleted credentials with the Passman Android app at the moment
+
+## I don't have enough storage on my phone to install Passman Android from an App Store, what can I do?
+- You could try to install the apk from the GitHub release which matches to your phones CPU architecture and is usually smaller than the App Stores version
+ - https://github.com/nextcloud/passman-android/releases/latest
+- The apks that are delivered from the App Stores combines the required files for all supported architectures
+
+## What means "Encrypted offline cache"?
+- By default vaults and credentials are stored in the offline cache
+- If your device has at least Android 6 / API 23 the offline cache will be stored encrypted
+ - Since credentials are already encrypted with the vault password, they will be encrypted twice
+- It's called cache because it works like a read-only fallback mode in case your cloud is not reachable over the network
+ - that means vaults and credentials can not be edited without a working cloud connection
+
+## How far can I trust the local storage encryption? Is it save to store my vault password on the device?
+- The [Android keystore system](https://developer.android.com/training/articles/keystore) is used to encrypt a random generated password with AES/GCM
+ - The Android keystore system uses special hardware mechanisms to protect the key
+- This random generated password is used to encrypt all locally stored sensitive data (like the offline cache and stored vault passwords) with the AES-256 encryption that is already used to encrypt credentials
+- If you trust the Android keystore system it should be safe to store your vault password on the device
+ - But don't forget that the security of the saved passwords depends on the access protection of your Android phone if you store your vault password on the device!
+
+## How can I use a self signed certificate to connect the my Nextcloud server?
+- Since version 1.0.0 the app supports user CA (certificate authority) certificates (requires at least Android 7 / API level 24).
+- The custom CA has to be imported in the Android trusted certificates section.
+ - It should be somewhere like `Android Settings -> Security -> Install certificate from storage`
+
diff --git a/PRIVACY.md b/PRIVACY.md
new file mode 100644
index 0000000..92bdac0
--- /dev/null
+++ b/PRIVACY.md
@@ -0,0 +1,28 @@
+# Passman Android - Privacy Policy
+
+The "Passman" Android-App (in the following referred to as "App") does not collect or send any data from you or your device to a server of the developers or the [Nextcloud GmbH](https://nextcloud.com/). The App sends all data exclusively to the server(s) configured by you with the intention to synchronize the contents of the App with those of the server. This data can contain IP-addresses, timestamps and further information as meta data.
+Data entered into the app (e.g. when saving) is necessarily transferred to the configured server(s). This contents can also contain personal information depending on the use. The server(s) you configured are technically outside the access area of this App developers, so that we neither know nor can prevent what happens to your data there. Please consult the privacy policy of the respective server operator.
+
+## Permissions
+
+This is a list of permissions required and asked by the App in order to properly work on your device:
+
+- `android.permission.INTERNET`
+
+ Used to communicate with your Nextcloud instance and synchronize contents.
+
+- `android.permission.READ_EXTERNAL_STORAGE`
+
+ Used to select and add files to a credential.
+
+- `android.permission.WRITE_EXTERNAL_STORAGE`
+
+ Used to store downloaded files from a credential on your device.
+
+- `android.permission.BIND_AUTOFILL_SERVICE`
+
+ Used to provide a autofill service for known access data.
+
+## Nextcloud privacy policy
+
+You can get more information on Nextcloud general privacy policy which is accessible at [nextcloud.com/privacy](https://nextcloud.com/privacy/).
diff --git a/README.md b/README.md
index a8b93de..9e31e3a 100644
--- a/README.md
+++ b/README.md
@@ -30,66 +30,7 @@ The passwords will be provided by [Passman](https://github.com/nextcloud/passman
- Encrypted stored vault and cloud connection passwords
## FAQ
-
-### How do I setup the app correctly after installation?
-- Choose whether you want to use https or http for the server connection (recommended is using https, but it depends on your server setup)
-- Fill in your Nextclouds hostname or IP address, and also the port if it's not the protocols default (443 for https; 80 for http)
- - Examples for allowed hostnames:
- - 10.0.2.2
- - 10.0.2.2:8080
- - mycloud.example.com/
-- Fill in your Nextcloud user and password (will be stored encrypted)
-- Press the connect button
-
-### What is the design (intention) for log out on the vaults?
-- If you unlocked a vault and the app is still running in the background, the vault stays open (so that you easily can switch between apps)
-- If you close the app all vaults will be locked
-- As long as the app is running you can switch between vaults (and they remain unlocked)
-- If you set a tick to save the vault password, technically the "vault is locked" if the app is closed but you don't have to manually unlock it until you press (manually!) the lock button
-- Pressing the lock button will lock the vault and also remove a saved vault password (if it was saved before)
-
-### How does the back button work?
-- Hitting the back button from where ever you are, ends in going back to the "parent" place (that's usually the page you have seen before)
-- If you press back in the vaults overview, the app remains in the background
-
-### How does the refresh button work?
-- If you are in an opened vault, the refresh button will refresh the current vault. And thus also the password list.
- - If the vaults encryption key did not change the vault remains unlocked
-- If you are in the vaults overview, the refresh button will clear and refresh the complete vaults storage
- - This does not affect the offline cache of an explicitly selected autofill vault
-
-### How can I use the autofill feature?
-- It requires at least Android 8
-- Passman Android currently offers the autofill feature automatically to the system.
-- To use Passman as autofill service, you need to select the app in the Android settings as autofill service
- - where to find that setting is different on any Android device
- - an example path in the Android settings could be `More Settings` -> `Language and Input` -> `Additional Keyboard Settings` -> `Autofill Service`
-- If you select a custom vault in the Passman Android settings as autofill vault, it will be cached offline, and if you also save the vault password, you won't need a network connection or manually open the Passman app before using autofill in an other app.
-- By default in the Passman Android settings the autofill vault is set to automatically, so that Passman needs to run in the background and the currently unlocked vault is used for the autofill service
-
-### How does deleting credentials work?
-- If you delete a credential in the Passman Android app, it will be moved to the trash on the server side ("Deleted credentials" section in the web view)
-- You don't have to be anxious to accidentally delete it, you have to confirm the operation
-- You can't access the deleted credentials with the Passman Android app at the moment
-
-### I don't have enough storage on my phone to install Passman Android from an App Store, what can I do?
-- You could try to install the apk from the GitHub release which matches to your phones CPU architecture and is usually smaller than the App Stores version
- - https://github.com/nextcloud/passman-android/releases/latest
-- The apks that are delivered from the App Stores combines the required files for all supported architectures
-
-### What means "Encrypted offline cache"?
-- By default vaults and credentials are stored in the offline cache
-- If your device has at least Android 6 / API 23 the offline cache will be stored encrypted
- - Since credentials are already encrypted with the vault password, they will be encrypted twice
-- It's called cache because it works like a read-only fallback mode in case your cloud is not reachable over the network
- - that means vaults and credentials can not be edited without a working cloud connection
-
-### How far can I trust the local storage encryption? Is it save to store my vault password on the device?
-- The [Android keystore system](https://developer.android.com/training/articles/keystore) is used to encrypt a random generated password with AES/GCM
- - The Android keystore system uses special hardware mechanisms to protect the key
-- This random generated password is used to encrypt all locally stored sensitive data (like the offline cache and stored vault passwords) with the AES-256 encryption that is already used to encrypt credentials
-- If you trust the Android keystore system it should be safe to store your vault password on the device
- - But don't forget that the security of the saved passwords depends on the access protection of your Android phone if you store your vault password on the device!
+Read our [frequently asked questions article](FAQ.md)
## Build locally
diff --git a/app/build.gradle b/app/build.gradle
index 6a8b4de..3a55966 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -32,8 +32,8 @@ android {
applicationId "es.wolfi.app.passman"
minSdkVersion 21
targetSdkVersion 31
- versionCode 14
- versionName "1.3.0"
+ versionCode 15
+ versionName "1.3.1"
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
externalNativeBuild {
cmake {
diff --git a/app/src/main/java/es/wolfi/app/passman/activities/PasswordListActivity.java b/app/src/main/java/es/wolfi/app/passman/activities/PasswordListActivity.java
index 2e6e71c..61bad4b 100644
--- a/app/src/main/java/es/wolfi/app/passman/activities/PasswordListActivity.java
+++ b/app/src/main/java/es/wolfi/app/passman/activities/PasswordListActivity.java
@@ -259,7 +259,8 @@ public class PasswordListActivity extends AppCompatActivity implements
.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right)
.replace(R.id.content_password_list, new VaultFragment(), "vaults")
.addToBackStack(null)
- .commit();
+ .commitAllowingStateLoss();
+ Log.d("PL", "committed transaction");
} else {
this.runOnUiThread(() -> {
final ProgressDialog progress = ProgressUtils.showLoadingSequence(this);
@@ -305,7 +306,7 @@ public class PasswordListActivity extends AppCompatActivity implements
.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_in_left, R.anim.slide_out_right)
.replace(R.id.content_password_list, new CredentialItemFragment(), "vault")
.addToBackStack(null)
- .commit();
+ .commitAllowingStateLoss();
} else {
showUnlockVault();
}
@@ -335,7 +336,10 @@ public class PasswordListActivity extends AppCompatActivity implements
}
// Update the vault record to avoid future loads
- ((HashMap<String, Vault>) ton.getExtra(SettingValues.VAULTS.toString())).put(result.guid, result);
+ HashMap<String, Vault> vaults = (HashMap<String, Vault>) ton.getExtra(SettingValues.VAULTS.toString());
+ if (vaults != null) {
+ vaults.put(result.guid, result);
+ }
ton.addExtra(SettingValues.ACTIVE_VAULT.toString(), result);
self.runOnUiThread(() -> {
@@ -358,9 +362,9 @@ public class PasswordListActivity extends AppCompatActivity implements
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, R.anim.slide_out_left, R.anim.slide_out_left)
- .replace(R.id.content_password_list, new VaultLockScreenFragment(), "vault")
+ .replace(R.id.content_password_list, VaultLockScreenFragment.newInstance(v), "vault")
.addToBackStack(null)
- .commit();
+ .commitAllowingStateLoss();
}
void lockVault() {
@@ -390,6 +394,7 @@ public class PasswordListActivity extends AppCompatActivity implements
Vault.updateAutofillVault(v, settings);
try {
OfflineStorage.getInstance().putObject(v.guid, Vault.asJson(v));
+ OfflineStorage.getInstance().commit();
} catch (JSONException e) {
e.printStackTrace();
}
@@ -415,19 +420,26 @@ public class PasswordListActivity extends AppCompatActivity implements
Vault.updateAutofillVault(v, settings);
try {
OfflineStorage.getInstance().putObject(v.guid, Vault.asJson(v));
+ OfflineStorage.getInstance().commit();
} catch (JSONException e) {
e.printStackTrace();
}
Fragment vaultFragment = getSupportFragmentManager().findFragmentByTag("vault");
-
if (vaultFragment != null && vaultFragment.isVisible()) {
- Log.e("refreshVault", "load credentials into content password list");
+ Log.d("refreshVault", "load credentials into content password list");
CredentialItemFragment credentialItems = (CredentialItemFragment)
getSupportFragmentManager().findFragmentById(R.id.content_password_list);
assert credentialItems != null;
credentialItems.loadCredentialList(findViewById(R.id.content_password_list));
}
+
+ CredentialDisplayFragment credentialDisplayFragment = (CredentialDisplayFragment) getSupportFragmentManager().findFragmentByTag("credential");
+ if (credentialDisplayFragment != null) {
+ Log.d("refreshCredential", "load credential into current credential display fragment");
+ credentialDisplayFragment.reloadCredentialFromActiveVaultIfPossible();
+ credentialDisplayFragment.updateViewContent();
+ }
}
public void deleteCredentialInCurrentLocalVaultList(Credential credential) {
@@ -440,6 +452,7 @@ public class PasswordListActivity extends AppCompatActivity implements
Vault.updateAutofillVault(v, settings);
try {
OfflineStorage.getInstance().putObject(v.guid, Vault.asJson(v));
+ OfflineStorage.getInstance().commit();
} catch (JSONException e) {
e.printStackTrace();
}
diff --git a/app/src/main/java/es/wolfi/app/passman/fragments/CredentialDisplayFragment.java b/app/src/main/java/es/wolfi/app/passman/fragments/CredentialDisplayFragment.java
index a63f5d9..c150c0c 100644
--- a/app/src/main/java/es/wolfi/app/passman/fragments/CredentialDisplayFragment.java
+++ b/app/src/main/java/es/wolfi/app/passman/fragments/CredentialDisplayFragment.java
@@ -97,6 +97,7 @@ public class CredentialDisplayFragment extends Fragment {
private Credential credential;
private Handler handler;
private Runnable otp_refresh = null;
+ private View fragmentView;
private OnCredentialFragmentInteraction mListener;
private OnListFragmentInteractionListener filelistListener;
@@ -122,16 +123,20 @@ public class CredentialDisplayFragment extends Fragment {
return fragment;
}
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
+ public void reloadCredentialFromActiveVaultIfPossible() {
if (getArguments() != null) {
Vault v = (Vault) SingleTon.getTon().getExtra(SettingValues.ACTIVE_VAULT.toString());
if (v != null) {
credential = v.findCredentialByGUID(getArguments().getString(CREDENTIAL));
}
}
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ reloadCredentialFromActiveVaultIfPossible();
if (credential != null) {
handler = new Handler();
@@ -212,9 +217,13 @@ public class CredentialDisplayFragment extends Fragment {
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
+ fragmentView = view;
+ updateViewContent();
+ }
+ public void updateViewContent() {
if (credential != null) {
- FloatingActionButton editCredentialButton = view.findViewById(R.id.editCredentialButton);
+ FloatingActionButton editCredentialButton = fragmentView.findViewById(R.id.editCredentialButton);
editCredentialButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
@@ -229,16 +238,16 @@ public class CredentialDisplayFragment extends Fragment {
editCredentialButton.setVisibility(View.VISIBLE);
- RecyclerView filesListRecyclerView = (RecyclerView) view.findViewById(R.id.filesList);
+ RecyclerView filesListRecyclerView = (RecyclerView) fragmentView.findViewById(R.id.filesList);
filesListRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
filesListRecyclerView.setAdapter(new FileViewAdapter(credential.getFilesList(), filelistListener));
- RecyclerView customFieldsListRecyclerView = (RecyclerView) view.findViewById(R.id.customFieldsList);
+ RecyclerView customFieldsListRecyclerView = (RecyclerView) fragmentView.findViewById(R.id.customFieldsList);
customFieldsListRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
customFieldsListRecyclerView.setAdapter(new CustomFieldViewAdapter(credential.getCustomFieldsList(), filelistListener));
if (credential.getCompromised().equals("true")) {
- TextView passwordLabel = view.findViewById(R.id.credential_password_label);
+ TextView passwordLabel = fragmentView.findViewById(R.id.credential_password_label);
passwordLabel.setBackgroundColor(getResources().getColor(R.color.compromised));
}
diff --git a/app/src/main/java/es/wolfi/app/passman/fragments/SettingsFragment.java b/app/src/main/java/es/wolfi/app/passman/fragments/SettingsFragment.java
index 8576372..45bb1b6 100644
--- a/app/src/main/java/es/wolfi/app/passman/fragments/SettingsFragment.java
+++ b/app/src/main/java/es/wolfi/app/passman/fragments/SettingsFragment.java
@@ -222,12 +222,13 @@ public class SettingsFragment extends Fragment {
enable_credential_list_icons_switch.setChecked(settings.getBoolean(SettingValues.ENABLE_CREDENTIAL_LIST_ICONS.toString(), true));
enable_offline_cache_switch.setChecked(settings.getBoolean(SettingValues.ENABLE_OFFLINE_CACHE.toString(), true));
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
+ Set<Map.Entry<String, Vault>> vaults = getVaultsEntrySet();
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O && vaults != null) {
String last_selected_guid = "";
if (settings.getString(SettingValues.AUTOFILL_VAULT_GUID.toString(), null) != null) {
last_selected_guid = settings.getString(SettingValues.AUTOFILL_VAULT_GUID.toString(), null);
}
- Set<Map.Entry<String, Vault>> vaults = getVaultsEntrySet();
+
String[] vault_names = new String[vaults.size() + 1];
vault_names[0] = getContext().getString(R.string.automatically);
int i = 1;
@@ -257,7 +258,7 @@ public class SettingsFragment extends Fragment {
private Set<Map.Entry<String, Vault>> getVaultsEntrySet() {
HashMap<String, Vault> vaults = (HashMap<String, Vault>) SingleTon.getTon().getExtra(SettingValues.VAULTS.toString());
- return vaults.entrySet();
+ return vaults != null ? vaults.entrySet() : null;
}
@Override
@@ -334,22 +335,24 @@ public class SettingsFragment extends Fragment {
settings.edit().putString(SettingValues.AUTOFILL_VAULT_GUID.toString(), "").commit();
} else {
Set<Map.Entry<String, Vault>> vaults = getVaultsEntrySet();
- for (Map.Entry<String, Vault> vault_entry : vaults) {
- if (vault_entry.getValue().name.equals(default_autofill_vault.getSelectedItem().toString())) {
- ton.addExtra(SettingValues.AUTOFILL_VAULT_GUID.toString(), vault_entry.getValue().guid);
- settings.edit().putString(SettingValues.AUTOFILL_VAULT_GUID.toString(), vault_entry.getValue().guid).commit();
-
- Vault.getVault(getContext(), vault_entry.getValue().guid, new FutureCallback<Vault>() {
- @Override
- public void onCompleted(Exception e, Vault result) {
- if (e != null) {
- return;
+ if (vaults != null) {
+ for (Map.Entry<String, Vault> vault_entry : vaults) {
+ if (vault_entry.getValue().name.equals(default_autofill_vault.getSelectedItem().toString())) {
+ ton.addExtra(SettingValues.AUTOFILL_VAULT_GUID.toString(), vault_entry.getValue().guid);
+ settings.edit().putString(SettingValues.AUTOFILL_VAULT_GUID.toString(), vault_entry.getValue().guid).commit();
+
+ Vault.getVault(getContext(), vault_entry.getValue().guid, new FutureCallback<Vault>() {
+ @Override
+ public void onCompleted(Exception e, Vault result) {
+ if (e != null) {
+ return;
+ }
+ Vault.updateAutofillVault(result, settings);
}
- Vault.updateAutofillVault(result, settings);
- }
- });
+ });
- break;
+ break;
+ }
}
}
}
diff --git a/app/src/main/java/es/wolfi/app/passman/fragments/VaultFragment.java b/app/src/main/java/es/wolfi/app/passman/fragments/VaultFragment.java
index ce4e54c..922c076 100644
--- a/app/src/main/java/es/wolfi/app/passman/fragments/VaultFragment.java
+++ b/app/src/main/java/es/wolfi/app/passman/fragments/VaultFragment.java
@@ -97,7 +97,10 @@ public class VaultFragment extends Fragment {
}
HashMap<String, Vault> vaults = (HashMap<String, Vault>) SingleTon.getTon().getExtra(SettingValues.VAULTS.toString());
- ArrayList<Vault> l = new ArrayList<Vault>(vaults.values());
+ ArrayList<Vault> l = new ArrayList<Vault>();
+ if (vaults != null) {
+ l = new ArrayList<Vault>(vaults.values());
+ }
recyclerView.setAdapter(new VaultViewAdapter(l, mListener, getParentFragmentManager()));
view.findViewById(R.id.add_vault_button).setOnClickListener(new View.OnClickListener() {
diff --git a/app/src/main/java/es/wolfi/app/passman/fragments/VaultLockScreenFragment.java b/app/src/main/java/es/wolfi/app/passman/fragments/VaultLockScreenFragment.java
index 8a4a612..bb157e9 100644
--- a/app/src/main/java/es/wolfi/app/passman/fragments/VaultLockScreenFragment.java
+++ b/app/src/main/java/es/wolfi/app/passman/fragments/VaultLockScreenFragment.java
@@ -111,7 +111,6 @@ public class VaultLockScreenFragment extends Fragment {
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
- vault = (Vault) SingleTon.getTon().getExtra(SettingValues.ACTIVE_VAULT.toString());
Log.e("VaultLockScreenFragment", "Vault guid: ".concat(vault.guid));
vault_name.setText(vault.name);
}
diff --git a/app/src/main/java/es/wolfi/passman/API/Core.java b/app/src/main/java/es/wolfi/passman/API/Core.java
index 94326a1..01572e0 100644
--- a/app/src/main/java/es/wolfi/passman/API/Core.java
+++ b/app/src/main/java/es/wolfi/passman/API/Core.java
@@ -156,7 +156,12 @@ public abstract class Core {
client.setResponseTimeout(getResponseTimeout(c));
client.setMaxRetriesAndTimeout(getConnectRetries(c), getConnectTimeout(c));
client.addHeader("Content-Type", JSON_CONTENT_TYPE);
- client.get(host_internal.concat(endpoint), responseHandler);
+
+ try {
+ client.get(host_internal.concat(endpoint), responseHandler);
+ } catch (Exception e) {
+ responseHandler.onFailure(0, null, null, e);
+ }
}
}
@@ -178,7 +183,12 @@ public abstract class Core {
client.setResponseTimeout(getResponseTimeout(c));
client.setMaxRetriesAndTimeout(getConnectRetries(c), getConnectTimeout(c));
client.addHeader("Content-Type", JSON_CONTENT_TYPE);
- client.get(host.concat(endpoint), responseHandler);
+
+ try {
+ client.get(host.concat(endpoint), responseHandler);
+ } catch (Exception e) {
+ responseHandler.onFailure(0, null, null, e);
+ }
}
}
@@ -209,12 +219,16 @@ public abstract class Core {
StringEntity entity = new StringEntity(jsonPostData.toString());
- if (requestType.equals("POST")) {
- client.post(c, url.toString(), entity, JSON_CONTENT_TYPE, responseHandler);
- } else if (requestType.equals("PATCH")) {
- client.patch(c, url.toString(), entity, JSON_CONTENT_TYPE, responseHandler);
- } else if (requestType.equals("DELETE")) {
- client.delete(c, url.toString(), entity, JSON_CONTENT_TYPE, responseHandler);
+ try {
+ if (requestType.equals("POST")) {
+ client.post(c, url.toString(), entity, JSON_CONTENT_TYPE, responseHandler);
+ } else if (requestType.equals("PATCH")) {
+ client.patch(c, url.toString(), entity, JSON_CONTENT_TYPE, responseHandler);
+ } else if (requestType.equals("DELETE")) {
+ client.delete(c, url.toString(), entity, JSON_CONTENT_TYPE, responseHandler);
+ }
+ } catch (Exception e) {
+ responseHandler.onFailure(0, null, null, e);
}
}
}
diff --git a/app/src/main/java/es/wolfi/utils/KeyStoreUtils.java b/app/src/main/java/es/wolfi/utils/KeyStoreUtils.java
index abf7a49..cc72fee 100644
--- a/app/src/main/java/es/wolfi/utils/KeyStoreUtils.java
+++ b/app/src/main/java/es/wolfi/utils/KeyStoreUtils.java
@@ -103,8 +103,8 @@ public class KeyStoreUtils {
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setRandomizedEncryptionRequired(false)
.build());
- SecretKey key = keyGenerator.generateKey();
- keyStore.setKeyEntry(KEY_ALIAS, key, null, null);
+
+ keyGenerator.generateKey();
SecureRandom random = SecureRandom.getInstance(RANDOM_ALGORITHM);
byte[] encryptionKeyBytes = new byte[4096];
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index fa5fb58..ed44ae3 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -33,6 +33,8 @@
<string name="error_downloading_file">Produciuse un erro ao descargar o ficheiro</string>
<string name="error_writing_file">Produciuse un erro ao gravar o ficheiro</string>
<string name="files">Ficheiros</string>
+ <string name="add_file">Engadir ficheiro</string>
+ <string name="add_custom_field">Engadir campo personalizado</string>
<string name="expert_settings">Axustes para expertos</string>
<string name="yes">Si</string>
<string name="cancel">Cancelar</string>
diff --git a/fastlane/metadata/android/en-US/changelogs/15.txt b/fastlane/metadata/android/en-US/changelogs/15.txt
new file mode 100644
index 0000000..7a973a6
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/15.txt
@@ -0,0 +1,4 @@
+- fix KeyStore initialization
+- fix reloading credential in the fragment view after editing
+- fix some null pointer exceptions
+- add privacy policy to the repository