diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 7baabb71e..b45e206d7 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -4,7 +4,7 @@ - Ensure you're running the latest version of Cryptomator. - Ensure the bug is related to the Android version of Cryptomator. Bugs concerning the Cryptomator desktop application and iOS app can be reported on the [Cryptomator issues list](https://github.com/cryptomator/cryptomator/issues) and [Cryptomator for iOS issues list](https://github.com/cryptomator/cryptomator-ios/issues) respectively. -- Ensure the bug was not [already reported](https://github.com/cryptomator/android/issues). You can also check out our [FAQ](https://community.cryptomator.org/c/faq). +- Ensure the bug was not [already reported](https://github.com/cryptomator/android/issues). You can also check out our [FAQ](https://community.cryptomator.org/c/kb/faq). - If you're unable to find an open issue addressing the problem, [submit a new one](https://github.com/cryptomator/android/issues/new). ## Code of Conduct diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md index cd45ed28d..09b9ff159 100644 --- a/.github/SUPPORT.md +++ b/.github/SUPPORT.md @@ -14,5 +14,5 @@ For _everything else_, please visit our official [Cryptomator Community](https:/ - Discussions about the apps - [Development discussions](https://community.cryptomator.org/c/development) - General questions - - Discussions regarding our design decissions + - Discussions regarding our design decisions - Our roadmap diff --git a/Gemfile.lock b/Gemfile.lock index 2a50fd372..b97c737e8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,27 +5,27 @@ GEM base64 nkf rexml - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) apktools (0.7.5) rubyzip (~> 2.0) artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.933.0) - aws-sdk-core (3.196.1) + aws-partitions (1.1027.0) + aws-sdk-core (3.214.0) aws-eventstream (~> 1, >= 1.3.0) - aws-partitions (~> 1, >= 1.651.0) - aws-sigv4 (~> 1.8) + aws-partitions (~> 1, >= 1.992.0) + aws-sigv4 (~> 1.9) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.82.0) - aws-sdk-core (~> 3, >= 3.193.0) - aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.151.0) - aws-sdk-core (~> 3, >= 3.194.0) + aws-sdk-kms (1.96.0) + aws-sdk-core (~> 3, >= 3.210.0) + aws-sigv4 (~> 1.5) + aws-sdk-s3 (1.176.1) + aws-sdk-core (~> 3, >= 3.210.0) aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.8) - aws-sigv4 (1.8.0) + aws-sigv4 (~> 1.5) + aws-sigv4 (1.10.1) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) base64 (0.2.0) @@ -42,8 +42,8 @@ GEM dotenv (2.8.1) ed25519 (1.3.0) emoji_regex (3.2.3) - excon (0.110.0) - faraday (1.10.3) + excon (0.112.0) + faraday (1.10.4) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -62,17 +62,17 @@ GEM faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) faraday-httpclient (1.0.1) - faraday-multipart (1.0.4) - multipart-post (~> 2) - faraday-net_http (1.0.1) + faraday-multipart (1.1.0) + multipart-post (~> 2.0) + faraday-net_http (1.0.2) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) faraday-retry (1.0.3) - faraday_middleware (1.2.0) + faraday_middleware (1.2.1) faraday (~> 1.0) fastimage (2.3.1) - fastlane (2.220.0) + fastlane (2.226.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -88,6 +88,7 @@ GEM faraday-cookie_jar (~> 0.0.6) faraday_middleware (~> 1.0) fastimage (>= 2.1.0, < 3.0.0) + fastlane-sirp (>= 1.0.0) gh_inspector (>= 1.1.2, < 2.0.0) google-apis-androidpublisher_v3 (~> 0.3) google-apis-playcustomapp_v1 (~> 0.1) @@ -111,13 +112,15 @@ GEM tty-spinner (>= 0.8.0, < 1.0.0) word_wrap (~> 1.0.0) xcodeproj (>= 1.13.0, < 2.0.0) - xcpretty (~> 0.3.0) + xcpretty (~> 0.4.0) xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) fastlane-plugin-aws_s3 (2.1.0) apktools (~> 0.7) aws-sdk-s3 (~> 1) mime-types (~> 3.3) fastlane-plugin-get_version_name (0.2.2) + fastlane-sirp (1.0.0) + sysrandom (~> 1.0) gh_inspector (1.1.3) google-apis-androidpublisher_v3 (0.54.0) google-apis-core (>= 0.11.0, < 2.a) @@ -135,7 +138,7 @@ GEM google-apis-core (>= 0.11.0, < 2.a) google-apis-storage_v1 (0.31.0) google-apis-core (>= 0.11.0, < 2.a) - google-cloud-core (1.7.0) + google-cloud-core (1.7.1) google-cloud-env (>= 1.0, < 3.a) google-cloud-errors (~> 1.0) google-cloud-env (1.6.0) @@ -156,39 +159,40 @@ GEM os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) highline (2.0.3) - http-cookie (1.0.5) + http-cookie (1.0.8) domain_name (~> 0.5) httpclient (2.8.3) jmespath (1.6.2) - json (2.7.2) - jwt (2.8.1) + json (2.9.1) + jwt (2.9.3) base64 - mime-types (3.5.2) + logger (1.6.4) + mime-types (3.6.0) + logger mime-types-data (~> 3.2015) - mime-types-data (3.2024.0507) - mini_magick (4.12.0) + mime-types-data (3.2024.1203) + mini_magick (4.13.2) mini_mime (1.1.5) multi_json (1.15.0) multipart-post (2.4.1) - nanaimo (0.3.0) + nanaimo (0.4.0) naturally (2.2.1) net-sftp (4.0.0) net-ssh (>= 5.0.0, < 8.0.0) - net-ssh (7.2.3) + net-ssh (7.3.0) nkf (0.2.0) - optparse (0.5.0) + optparse (0.6.0) os (1.1.4) plist (3.7.1) - public_suffix (5.0.5) + public_suffix (6.0.1) rake (13.2.1) representable (3.2.0) declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) retriable (3.1.2) - rexml (3.2.8) - strscan (>= 3.0.9) - rouge (2.0.7) + rexml (3.4.0) + rouge (3.28.0) ruby2_keywords (0.0.5) rubyzip (2.3.2) security (0.1.5) @@ -200,7 +204,7 @@ GEM simctl (1.6.10) CFPropertyList naturally - strscan (3.1.0) + sysrandom (1.0.5) terminal-notifier (2.0.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) @@ -210,17 +214,17 @@ GEM tty-spinner (0.9.3) tty-cursor (~> 0.7) uber (0.1.0) - unicode-display_width (2.5.0) + unicode-display_width (2.6.0) word_wrap (1.0.0) - xcodeproj (1.24.0) + xcodeproj (1.27.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) - nanaimo (~> 0.3.0) - rexml (~> 3.2.4) - xcpretty (0.3.0) - rouge (~> 2.0.7) + nanaimo (~> 0.4.0) + rexml (>= 3.3.6, < 4.0) + xcpretty (0.4.0) + rouge (~> 3.28.0) xcpretty-travis-formatter (1.0.1) xcpretty (~> 0.2, >= 0.0.7) @@ -236,4 +240,4 @@ DEPENDENCIES net-sftp BUNDLED WITH - 2.2.5 + 2.6.0 diff --git a/build.gradle b/build.gradle index a9acecd34..79be00628 100644 --- a/build.gradle +++ b/build.gradle @@ -36,8 +36,8 @@ def getVersionCode = { -> allprojects { ext { androidApplicationId = 'org.cryptomator' - androidVersionCode = 2939 // must be getVersionCode(). only at release tag set the actual value - androidVersionName = '1.10.3' + androidVersionCode = 2971 // must be getVersionCode(). only at release tag set the actual value + androidVersionName = '1.10.4' } repositories { mavenCentral() diff --git a/buildsystem/dependencies.gradle b/buildsystem/dependencies.gradle index 387a69409..5280d94f3 100644 --- a/buildsystem/dependencies.gradle +++ b/buildsystem/dependencies.gradle @@ -60,14 +60,18 @@ ext { rxAndroidVersion = '2.1.1' rxBindingVersion = '2.2.0' - daggerVersion = '2.51.1' + daggerVersion = '2.54' gsonVersion = '2.11.0' + joseJwtVersion = '9.48' + + appauthVersion = '0.11.1' + okHttpVersion = '4.12.0' - okHttpDigestVersion = '3.1.0' + okHttpDigestVersion = '3.1.1' - velocityVersion = '2.3' + velocityVersion = '2.4.1' timberVersion = '5.0.1' @@ -81,7 +85,7 @@ ext { greenDaoVersion = '3.3.0' // cloud provider libs - cryptolibVersion = '2.1.2' + cryptolibVersion = '2.2.0' dropboxVersion = '7.0.0' @@ -93,20 +97,21 @@ ext { msgraphVersion = '5.47.0' msgraphAuthVersion = '4.0.5' // contains com.microsoft.identity:common lib which added opentelemetry in 9.0.0, do we need to fork another lib before updating to >=4.2.0 ??? - minIoVersion = '8.5.10' + minIoVersion = '8.5.14' pcloudVersion = '1.9.2-dev.0001' staxVersion = '1.2.0' // needed for minIO - commonsCodecVersion = '1.17.0' + commonsCodecVersion = '1.17.1' recyclerViewFastScrollVersion = '2.0.1' // testing dependencies - jUnitVersion = '5.10.2' + jUnitVersion = '5.11.4' assertJVersion = '1.7.1' - mockitoVersion = '5.12.0' - mockitoKotlinVersion = '5.3.1' + mockitoVersion = '5.14.2' + mockitoKotlinVersion = '5.4.0' mockitoInlineVersion = '5.2.0' + mockitoAndroidVersion = '5.14.2' hamcrestVersion = '1.3' dexmakerVersion = '1.0' espressoVersion = '3.4.0' @@ -140,6 +145,7 @@ ext { androidxViewpager : "androidx.viewpager:viewpager:${androidxViewpagerVersion}", androidxSwiperefresh : "androidx.swiperefreshlayout:swiperefreshlayout:${androidxSwiperefreshVersion}", androidxPreference : "androidx.preference:preference:${androidxPreferenceVersion}", + appauth : "net.openid:appauth:${appauthVersion}", documentFile : "androidx.documentfile:documentfile:${androidxDocumentfileVersion}", recyclerView : "androidx.recyclerview:recyclerview:${androidxRecyclerViewVersion}", androidxSplashscreen : "androidx.core:core-splashscreen:${androidxSplashscreenVersion}", @@ -163,6 +169,7 @@ ext { gson : "com.google.code.gson:gson:${gsonVersion}", hamcrest : "org.hamcrest:hamcrest-all:${hamcrestVersion}", javaxAnnotation : "javax.annotation:jsr250-api:${javaxAnnotationVersion}", + joseJwt : "com.nimbusds:nimbus-jose-jwt:${joseJwtVersion}", junit : "org.junit.jupiter:junit-jupiter:${jUnitVersion}", junitApi : "org.junit.jupiter:junit-jupiter-api:${jUnitVersion}", junitEngine : "org.junit.jupiter:junit-jupiter-engine:${jUnitVersion}", @@ -172,6 +179,7 @@ ext { mockito : "org.mockito:mockito-core:${mockitoVersion}", mockitoInline : "org.mockito:mockito-inline:${mockitoInlineVersion}", mockitoKotlin : "org.mockito.kotlin:mockito-kotlin:${mockitoKotlinVersion}", + mockitoAndroid : "org.mockito:mockito-android:${mockitoAndroidVersion}", msgraph : "com.microsoft.graph:microsoft-graph:${msgraphVersion}", msgraphAuth : "com.microsoft.identity.client:msal:${msgraphAuthVersion}", multidex : "androidx.multidex:multidex:${multidexVersion}", diff --git a/data/build.gradle b/data/build.gradle index 4e3014675..f841e558f 100644 --- a/data/build.gradle +++ b/data/build.gradle @@ -196,6 +196,8 @@ dependencies { compileOnly dependencies.javaxAnnotation implementation dependencies.gson + implementation dependencies.joseJwt + implementation dependencies.commonsCodec implementation dependencies.documentFile diff --git a/data/src/androidTest/java/org/cryptomator/data/db/UpgradeDatabaseTest.kt b/data/src/androidTest/java/org/cryptomator/data/db/UpgradeDatabaseTest.kt index 8f79d67cc..b50776a8d 100644 --- a/data/src/androidTest/java/org/cryptomator/data/db/UpgradeDatabaseTest.kt +++ b/data/src/androidTest/java/org/cryptomator/data/db/UpgradeDatabaseTest.kt @@ -102,7 +102,7 @@ class UpgradeDatabaseTest { private fun checkUpgrade2to3ResultForCloud(cloudName: String, accessToken: String, url: String, username: String, webdavCertificate: String) { Sql.query("CLOUD_ENTITY").where("TYPE", Sql.eq(cloudName)).executeOn(db).use { it.moveToFirst() - Assert.assertThat(CredentialCryptor.getInstance(context).decrypt(it.getString(it.getColumnIndex("ACCESS_TOKEN"))), CoreMatchers.`is`(accessToken)) + Assert.assertThat(CredentialCryptor.getInstance(context, CryptoMode.CBC).decrypt(it.getString(it.getColumnIndex("ACCESS_TOKEN"))), CoreMatchers.`is`(accessToken)) Assert.assertThat(it.getString(it.getColumnIndex("WEBDAV_URL")), CoreMatchers.`is`(url)) Assert.assertThat(it.getString(it.getColumnIndex("USERNAME")), CoreMatchers.`is`(username)) Assert.assertThat(it.getString(it.getColumnIndex("WEBDAV_CERTIFICATE")), CoreMatchers.`is`(webdavCertificate)) @@ -918,17 +918,6 @@ class UpgradeDatabaseTest { @Test fun upgrade12To13Webdav() { Upgrade0To1().applyTo(db, 0) - Upgrade1To2().applyTo(db, 1) - Upgrade2To3(context).applyTo(db, 2) - Upgrade3To4().applyTo(db, 3) - Upgrade4To5().applyTo(db, 4) - Upgrade5To6().applyTo(db, 5) - Upgrade6To7().applyTo(db, 6) - Upgrade7To8().applyTo(db, 7) - Upgrade8To9(sharedPreferencesHandler).applyTo(db, 8) - Upgrade9To10(sharedPreferencesHandler).applyTo(db, 9) - Upgrade10To11().applyTo(db, 10) - Upgrade11To12(sharedPreferencesHandler).applyTo(db, 11) val gcmCryptor = CredentialCryptor.getInstance(context, CryptoMode.GCM) val cbcCryptor = CredentialCryptor.getInstance(context, CryptoMode.CBC) @@ -941,9 +930,19 @@ class UpgradeDatabaseTest { .text("TYPE", CloudType.WEBDAV.name) // .text("USERNAME", "username") // .text("ACCESS_TOKEN", accessTokenCiphertext) // - .text("URL", "url") // .executeOn(db) + Upgrade1To2().applyTo(db, 1) + Upgrade2To3(context).applyTo(db, 2) + Upgrade3To4().applyTo(db, 3) + Upgrade4To5().applyTo(db, 4) + Upgrade5To6().applyTo(db, 5) + Upgrade6To7().applyTo(db, 6) + Upgrade7To8().applyTo(db, 7) + Upgrade8To9(sharedPreferencesHandler).applyTo(db, 8) + Upgrade9To10(sharedPreferencesHandler).applyTo(db, 9) + Upgrade10To11().applyTo(db, 10) + Upgrade11To12(sharedPreferencesHandler).applyTo(db, 11) Upgrade12To13(context).applyTo(db, 12) Sql.query("CLOUD_ENTITY").where("_id", Sql.eq(15)).executeOn(db).use { diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudFactory.java b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudFactory.java index 727b292bd..eb4f65eeb 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudFactory.java +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudFactory.java @@ -9,6 +9,7 @@ import org.cryptomator.domain.UnverifiedVaultConfig; import org.cryptomator.domain.Vault; import org.cryptomator.domain.exception.BackendException; +import org.cryptomator.domain.exception.FatalBackendException; import org.cryptomator.domain.repository.CloudContentRepository; import org.cryptomator.domain.usecases.ProgressAware; import org.cryptomator.domain.usecases.cloud.Flag; @@ -16,12 +17,12 @@ import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; +import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import javax.inject.Inject; import javax.inject.Singleton; -import static org.cryptomator.data.cloud.crypto.CryptoConstants.MASTERKEY_SCHEME; import static org.cryptomator.data.cloud.crypto.CryptoConstants.VAULT_FILE_NAME; import static org.cryptomator.domain.Vault.aCopyOf; @@ -30,7 +31,6 @@ public class CryptoCloudFactory { private final CloudContentRepository cloudContentRepository; private final CryptoCloudContentRepositoryFactory cryptoCloudContentRepositoryFactory; - private final SecureRandom secureRandom = new SecureRandom(); @Inject public CryptoCloudFactory(CloudContentRepository/**/ cloudContentRepository, // @@ -40,7 +40,7 @@ public CryptoCloudFactory(CloudContentRepository/* unverifie return cryptoCloudProvider(unverifiedVaultConfig).unlock(token, unverifiedVaultConfig, password, cancelledFlag); } + public Vault unlock(Vault vault, UnverifiedVaultConfig unverifiedVaultConfig, String vaultKeyJwe, String userKeyJwe, Flag cancelledFlag) throws BackendException { + return cryptoCloudProvider(unverifiedVaultConfig).unlock(vault, unverifiedVaultConfig, vaultKeyJwe, userKeyJwe, cancelledFlag); + } + public UnlockToken createUnlockToken(Vault vault, Optional unverifiedVaultConfig) throws BackendException { return cryptoCloudProvider(unverifiedVaultConfig).createUnlockToken(vault, unverifiedVaultConfig); } @@ -84,14 +88,30 @@ public void changePassword(Vault vault, Optional unverifi cryptoCloudProvider(unverifiedVaultConfig).changePassword(vault, unverifiedVaultConfig, oldPassword, newPassword); } + private CryptoCloudProvider masterkeyCryptoCloudProvider() { + return cryptoCloudProvider(Optional.absent()); + } + + private CryptoCloudProvider cryptoCloudProvider(UnverifiedVaultConfig unverifiedVaultConfigOptional) { + return cryptoCloudProvider(Optional.of(unverifiedVaultConfigOptional)); + } + private CryptoCloudProvider cryptoCloudProvider(Optional unverifiedVaultConfigOptional) { if (unverifiedVaultConfigOptional.isPresent()) { - if (MASTERKEY_SCHEME.equals(unverifiedVaultConfigOptional.get().getKeyId().getScheme())) { - return new MasterkeyCryptoCloudProvider(cloudContentRepository, cryptoCloudContentRepositoryFactory, secureRandom); - } - throw new IllegalStateException(String.format("Provider with scheme %s not supported", unverifiedVaultConfigOptional.get().getKeyId().getScheme())); + return switch (unverifiedVaultConfigOptional.get().keyLoadingStrategy()) { + case MASTERKEY -> new MasterkeyCryptoCloudProvider(cloudContentRepository, cryptoCloudContentRepositoryFactory, secureRandom()); + case HUB -> new HubkeyCryptoCloudProvider(cryptoCloudContentRepositoryFactory, secureRandom()); + }; } else { - return new MasterkeyCryptoCloudProvider(cloudContentRepository, cryptoCloudContentRepositoryFactory, secureRandom); + return new MasterkeyCryptoCloudProvider(cloudContentRepository, cryptoCloudContentRepositoryFactory, secureRandom()); + } + } + + private SecureRandom secureRandom() { + try { + return SecureRandom.getInstanceStrong(); + } catch (NoSuchAlgorithmException e) { + throw new FatalBackendException("A strong algorithm must exist in every Java platform.", e); } } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudProvider.java b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudProvider.java index 83a92dfca..818ac58e3 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudProvider.java +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudProvider.java @@ -19,6 +19,8 @@ public interface CryptoCloudProvider { Vault unlock(UnlockToken token, Optional unverifiedVaultConfig, CharSequence password, Flag cancelledFlag) throws BackendException; + Vault unlock(Vault vault, UnverifiedVaultConfig unverifiedVaultConfig, String vaultKeyJwe, String userKeyJwe, Flag cancelledFlag) throws BackendException; + boolean isVaultPasswordValid(Vault vault, Optional unverifiedVaultConfig, CharSequence password) throws BackendException; void lock(Vault vault); diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoConstants.kt b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoConstants.kt index 3820bf3a9..5db0f9c4e 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoConstants.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoConstants.kt @@ -6,6 +6,7 @@ object CryptoConstants { const val MASTERKEY_SCHEME = "masterkeyfile" const val MASTERKEY_FILE_NAME = "masterkey.cryptomator" + const val HUB_REDIRECT_URL = "org.cryptomator.android:/hub/auth" const val ROOT_DIR_ID = "" const val DATA_DIR_NAME = "d" const val VAULT_FILE_NAME = "vault.cryptomator" @@ -15,6 +16,7 @@ object CryptoConstants { const val MAX_VAULT_VERSION_WITHOUT_VAULT_CONFIG = 7 const val VERSION_WITH_NORMALIZED_PASSWORDS = 6 const val MIN_VAULT_VERSION = 5 + const val MIN_HUB_VAULT_VERSION = 8 const val DEFAULT_MAX_FILE_NAME = 220 const val DIR_ID_FILE = "dirid.c9r" val PEPPER = ByteArray(0) diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/HubkeyCryptoCloudProvider.kt b/data/src/main/java/org/cryptomator/data/cloud/crypto/HubkeyCryptoCloudProvider.kt new file mode 100644 index 000000000..c4f88e1c8 --- /dev/null +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/HubkeyCryptoCloudProvider.kt @@ -0,0 +1,101 @@ +package org.cryptomator.data.cloud.crypto + +import com.google.common.base.Optional +import com.nimbusds.jose.JWEObject +import org.cryptomator.cryptolib.api.Cryptor +import org.cryptomator.cryptolib.api.CryptorProvider +import org.cryptomator.cryptolib.api.Masterkey +import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException +import org.cryptomator.data.cloud.crypto.VaultConfig.Companion.verify +import org.cryptomator.domain.CloudFolder +import org.cryptomator.domain.UnverifiedVaultConfig +import org.cryptomator.domain.Vault +import org.cryptomator.domain.exception.BackendException +import org.cryptomator.domain.exception.CancellationException +import org.cryptomator.domain.exception.FatalBackendException +import org.cryptomator.domain.usecases.cloud.Flag +import org.cryptomator.domain.usecases.vault.UnlockToken +import org.cryptomator.util.crypto.HubDeviceCryptor +import java.security.SecureRandom +import java.text.ParseException + +class HubkeyCryptoCloudProvider( + private val cryptoCloudContentRepositoryFactory: CryptoCloudContentRepositoryFactory, // + private val secureRandom: SecureRandom +) : CryptoCloudProvider { + + @Throws(BackendException::class) + override fun create(location: CloudFolder, password: CharSequence) { + throw UnsupportedOperationException("This app can not (yet) create Hub vaults") + } + + @Throws(BackendException::class) + override fun unlock(vault: Vault, unverifiedVaultConfig: Optional, password: CharSequence, cancelledFlag: Flag): Vault { + throw UnsupportedOperationException("Hub vaults do not support password based unlock") + } + + @Throws(BackendException::class) + override fun unlock(token: UnlockToken, unverifiedVaultConfig: Optional, password: CharSequence, cancelledFlag: Flag): Vault { + throw UnsupportedOperationException("Hub vaults do not support password based unlock") + } + + override fun unlock(vault: Vault, unverifiedVaultConfig: UnverifiedVaultConfig, vaultKeyJwe: String, userKeyJwe: String, cancelledFlag: Flag): Vault { + val vaultKey: JWEObject + val userKey: JWEObject + try { + vaultKey = JWEObject.parse(vaultKeyJwe) + userKey = JWEObject.parse(userKeyJwe) + } catch (e: ParseException) { + throw FatalBackendException("Failed to parse JWE strings", e) + } + val masterkey = HubDeviceCryptor.getInstance().decryptVaultKey(vaultKey, userKey) + val vaultConfig = verify(masterkey.encoded, unverifiedVaultConfig) + val vaultFormat = vaultConfig.vaultFormat + assertVaultVersionIsSupported(vaultConfig.vaultFormat) + val shorteningThreshold = vaultConfig.shorteningThreshold + val cryptor = cryptorFor(masterkey, vaultConfig.cipherCombo) + if (cancelledFlag.get()) { + throw CancellationException() + } + val unlockedVault = Vault.aCopyOf(vault) // + .withUnlocked(true) // + .withFormat(vaultFormat) // + .withShorteningThreshold(shorteningThreshold) // + .build() + cryptoCloudContentRepositoryFactory.registerCryptor(unlockedVault, cryptor) + return unlockedVault + } + + @Throws(BackendException::class) + override fun createUnlockToken(vault: Vault, unverifiedVaultConfig: Optional): UnlockToken { + throw UnsupportedOperationException("Hub vaults do not support password based unlock") + } + + // Visible for testing + fun cryptorFor(masterkey: Masterkey, vaultCipherCombo: CryptorProvider.Scheme): Cryptor { + return CryptorProvider.forScheme(vaultCipherCombo).provide(masterkey, secureRandom) + } + + @Throws(BackendException::class) + override fun isVaultPasswordValid(vault: Vault, unverifiedVaultConfig: Optional, password: CharSequence): Boolean { + throw UnsupportedOperationException("Hub vaults do not support password based unlock") + } + + override fun lock(vault: Vault) { + cryptoCloudContentRepositoryFactory.deregisterCryptor(vault) + } + + private fun assertVaultVersionIsSupported(version: Int) { + if (version < CryptoConstants.MIN_HUB_VAULT_VERSION) { + throw UnsupportedVaultFormatException(version, CryptoConstants.MIN_HUB_VAULT_VERSION) + } else if (version > CryptoConstants.MAX_VAULT_VERSION) { + throw UnsupportedVaultFormatException(version, CryptoConstants.MAX_VAULT_VERSION) + } + } + + @Throws(BackendException::class) + override fun changePassword(vault: Vault, unverifiedVaultConfig: Optional, oldPassword: String, newPassword: String) { + throw UnsupportedOperationException("Hub vaults do not support password based unlock") + } + +} diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/MasterkeyCryptoCloudProvider.kt b/data/src/main/java/org/cryptomator/data/cloud/crypto/MasterkeyCryptoCloudProvider.kt index 5699a95b4..60631e7a0 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/MasterkeyCryptoCloudProvider.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/MasterkeyCryptoCloudProvider.kt @@ -126,6 +126,10 @@ class MasterkeyCryptoCloudProvider( } } + override fun unlock(vault: Vault, unverifiedVaultConfig: UnverifiedVaultConfig, vaultKeyJwe: String, userKeyJwe: String, cancelledFlag: Flag): Vault { + throw UnsupportedOperationException("Password based vaults do not support hub unlock") + } + @Throws(BackendException::class) override fun createUnlockToken(vault: Vault, unverifiedVaultConfig: Optional): UnlockTokenImpl { val vaultLocation = vaultLocation(vault) @@ -153,7 +157,7 @@ class MasterkeyCryptoCloudProvider( @Throws(BackendException::class) private fun createUnlockToken(vault: Vault, location: CloudFile): UnlockTokenImpl { val keyFileData = readKeyFileData(location) - return UnlockTokenImpl(vault, keyFileData) + return UnlockTokenImpl(vault, secureRandom, keyFileData) } @Throws(BackendException::class) @@ -286,7 +290,7 @@ class MasterkeyCryptoCloudProvider( } } - class UnlockTokenImpl(private val vault: Vault, val keyFileData: ByteArray) : UnlockToken { + class UnlockTokenImpl(private val vault: Vault, private val secureRandom: SecureRandom, val keyFileData: ByteArray) : UnlockToken { override fun getVault(): Vault { return vault @@ -294,7 +298,7 @@ class MasterkeyCryptoCloudProvider( @Throws(IOException::class) fun getKeyFile(password: CharSequence?): Masterkey { - return MasterkeyFileAccess(CryptoConstants.PEPPER, SecureRandom()).load(ByteArrayInputStream(keyFileData), password) + return MasterkeyFileAccess(CryptoConstants.PEPPER, secureRandom).load(ByteArrayInputStream(keyFileData), password) } } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/VaultConfig.kt b/data/src/main/java/org/cryptomator/data/cloud/crypto/VaultConfig.kt index 2a324f142..7beba5d3c 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/VaultConfig.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/VaultConfig.kt @@ -7,7 +7,10 @@ import com.auth0.jwt.exceptions.JWTVerificationException import com.auth0.jwt.exceptions.SignatureVerificationException import com.auth0.jwt.interfaces.DecodedJWT import org.cryptomator.cryptolib.api.CryptorProvider +import org.cryptomator.domain.KeyLoadingStrategy +import org.cryptomator.domain.UnverifiedHubVaultConfig import org.cryptomator.domain.UnverifiedVaultConfig +import org.cryptomator.domain.exception.vaultconfig.HubNotSupportedOnPreAndroid31Exception import org.cryptomator.domain.exception.vaultconfig.VaultConfigLoadException import org.cryptomator.domain.exception.vaultconfig.VaultKeyInvalidException import org.cryptomator.domain.exception.vaultconfig.VaultVersionMismatchException @@ -82,8 +85,48 @@ class VaultConfig private constructor(builder: VaultConfigBuilder) { fun decode(token: String): UnverifiedVaultConfig { val unverifiedJwt = JWT.decode(token) val vaultFormat = unverifiedJwt.getClaim(JSON_KEY_VAULTFORMAT).asInt() - val keyId = URI.create(unverifiedJwt.keyId) - return UnverifiedVaultConfig(token, keyId, vaultFormat) + val keyId = try { + URI.create(unverifiedJwt.keyId) + } catch (e: IllegalArgumentException) { + throw VaultConfigLoadException("Invalid 'keyId' in JWT: ${e.message}", e) + } + return when (KeyLoadingStrategy.fromKeyId(keyId)) { + KeyLoadingStrategy.MASTERKEY -> UnverifiedVaultConfig(token, keyId, vaultFormat) + KeyLoadingStrategy.HUB -> { + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.S) { + throw HubNotSupportedOnPreAndroid31Exception() + } + val hubClaim = unverifiedJwt.getHeaderClaim("hub").asMap() + val clientId = hubClaim["clientId"] as? String ?: throw VaultConfigLoadException("Missing or invalid 'clientId' claim in JWT header") + val authEndpoint = parseUri(hubClaim, "authEndpoint") + val tokenEndpoint = parseUri(hubClaim, "tokenEndpoint") + val apiBaseUrl = getApiBaseUrl(hubClaim) + return UnverifiedHubVaultConfig(token, keyId, vaultFormat, clientId, authEndpoint, tokenEndpoint, apiBaseUrl) + } + } + } + + private fun parseUri(uriValue: Map, fieldName: String, ensureTrailingSlash: Boolean = false): URI { + val uriString = uriValue[fieldName] as? String ?: throw VaultConfigLoadException("Missing or invalid '$fieldName' claim in JWT header") + val adjustedUriString = if (ensureTrailingSlash && !uriString.endsWith("/")) { + "$uriString/" + } else { + uriString + } + return try { + URI.create(adjustedUriString) + } catch (e: IllegalArgumentException) { + throw VaultConfigLoadException("Invalid '$fieldName' URI: ${e.message}", e) + } + } + + private fun getApiBaseUrl(hubClaim: Map): URI { + val apiBaseUrlKey = "apiBaseUrl" + return if (hubClaim.containsKey(apiBaseUrlKey)) { + parseUri(hubClaim, apiBaseUrlKey, ensureTrailingSlash = true) + } else { + parseUri(hubClaim, "devicesResourceUrl", ensureTrailingSlash = true).resolve("..") + } } @JvmStatic diff --git a/data/src/main/java/org/cryptomator/data/db/Upgrade2To3.kt b/data/src/main/java/org/cryptomator/data/db/Upgrade2To3.kt index 7938f5d27..680dbdda4 100644 --- a/data/src/main/java/org/cryptomator/data/db/Upgrade2To3.kt +++ b/data/src/main/java/org/cryptomator/data/db/Upgrade2To3.kt @@ -3,6 +3,7 @@ package org.cryptomator.data.db import android.content.Context import android.content.SharedPreferences import org.cryptomator.util.crypto.CredentialCryptor +import org.cryptomator.util.crypto.CryptoMode import org.greenrobot.greendao.database.Database import javax.inject.Inject import javax.inject.Singleton @@ -38,7 +39,7 @@ internal class Upgrade2To3 @Inject constructor(private val context: Context) : D private fun encrypt(token: String?): String? { return if (token == null) null else CredentialCryptor // - .getInstance(context) // + .getInstance(context, CryptoMode.CBC) // .encrypt(token) } diff --git a/data/src/main/java/org/cryptomator/data/repository/CloudRepositoryImpl.java b/data/src/main/java/org/cryptomator/data/repository/CloudRepositoryImpl.java index f08137f2f..bcda1f3a2 100644 --- a/data/src/main/java/org/cryptomator/data/repository/CloudRepositoryImpl.java +++ b/data/src/main/java/org/cryptomator/data/repository/CloudRepositoryImpl.java @@ -109,6 +109,13 @@ public Cloud unlock(UnlockToken token, Optional unverifie return decryptedViewOf(vaultWithVersion); } + + @Override + public Cloud unlock(Vault vault, UnverifiedVaultConfig unverifiedVaultConfig, String vaultKeyJwe, String userKeyJwe, Flag cancelledFlag) throws BackendException { + Vault vaultWithVersion = cryptoCloudFactory.unlock(vault, unverifiedVaultConfig, vaultKeyJwe, userKeyJwe, cancelledFlag); + return decryptedViewOf(vaultWithVersion); + } + @Override public UnlockToken prepareUnlock(Vault vault, Optional unverifiedVaultConfig) throws BackendException { return cryptoCloudFactory.createUnlockToken(vault, unverifiedVaultConfig); diff --git a/data/src/main/java/org/cryptomator/data/repository/HubRepositoryImpl.java b/data/src/main/java/org/cryptomator/data/repository/HubRepositoryImpl.java new file mode 100644 index 000000000..d7458ea06 --- /dev/null +++ b/data/src/main/java/org/cryptomator/data/repository/HubRepositoryImpl.java @@ -0,0 +1,223 @@ +package org.cryptomator.data.repository; + +import android.content.Context; + +import com.google.common.io.BaseEncoding; +import com.nimbusds.jose.JWEObject; + +import org.cryptomator.data.cloud.okhttplogging.HttpLoggingInterceptor; +import org.cryptomator.data.util.NetworkTimeout; +import org.cryptomator.domain.UnverifiedHubVaultConfig; +import org.cryptomator.domain.exception.BackendException; +import org.cryptomator.domain.exception.FatalBackendException; +import org.cryptomator.domain.exception.hub.HubDeviceAlreadyRegisteredForOtherUserException; +import org.cryptomator.domain.exception.hub.HubDeviceSetupRequiredException; +import org.cryptomator.domain.exception.hub.HubInvalidSetupCodeException; +import org.cryptomator.domain.exception.hub.HubLicenseUpgradeRequiredException; +import org.cryptomator.domain.exception.hub.HubUserSetupRequiredException; +import org.cryptomator.domain.exception.hub.HubVaultAccessForbiddenException; +import org.cryptomator.domain.exception.hub.HubVaultIsArchivedException; +import org.cryptomator.domain.repository.HubRepository; +import org.cryptomator.util.crypto.HubDeviceCryptor; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.text.ParseException; +import java.time.Instant; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import okhttp3.Interceptor; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import timber.log.Timber; + +@Singleton +public class HubRepositoryImpl implements HubRepository { + + private final Context context; + private OkHttpClient httpClient; + private HubDeviceCryptor hubDeviceCryptor; + + @Inject + public HubRepositoryImpl(Context context) { + this.context = context; + } + + private Interceptor httpLoggingInterceptor(Context context) { + HttpLoggingInterceptor.Logger logger = message -> Timber.tag("OkHttp").d(message); + return new HttpLoggingInterceptor(logger, context); + } + + @Override + public String getVaultKeyJwe(UnverifiedHubVaultConfig unverifiedHubVaultConfig, String accessToken) throws BackendException { + var request = new Request.Builder().get() // + .header("Authorization", "Bearer " + accessToken) // + .url(unverifiedHubVaultConfig.getApiBaseUrl() + "vaults/" + unverifiedHubVaultConfig.vaultId() + "/access-token") // + .build(); + try (var response = getHttpClient().newCall(request).execute()) { + switch (response.code()) { + case HttpURLConnection.HTTP_OK: + if (response.body() != null) { + return response.body().string(); + } else { + throw new FatalBackendException("Failed to load JWE, response code good but no body"); + } + case HttpURLConnection.HTTP_PAYMENT_REQUIRED: + throw new HubLicenseUpgradeRequiredException(); + case HttpURLConnection.HTTP_FORBIDDEN: + throw new HubVaultAccessForbiddenException(); + case HttpURLConnection.HTTP_GONE: + throw new HubVaultIsArchivedException(); + case 449: + throw new HubUserSetupRequiredException(); + default: + throw new FatalBackendException("Failed with response code " + response.code()); + } + } catch (IOException e) { + throw new FatalBackendException(e); + } + } + + @Override + public UserDto getUser(UnverifiedHubVaultConfig unverifiedHubVaultConfig, String accessToken) throws FatalBackendException { + var request = new Request.Builder().get() // + .header("Authorization", "Bearer " + accessToken) // + .url(unverifiedHubVaultConfig.getApiBaseUrl() + "users/me") // + .build(); + try (var response = getHttpClient().newCall(request).execute()) { + if (response.code() == HttpURLConnection.HTTP_OK) { + if (response.body() != null) { + JSONObject jsonObject = new JSONObject(response.body().string()); + return new UserDto( // + jsonObject.getString("id"), // + jsonObject.getString("name"), // + jsonObject.getString("publicKey"), // + jsonObject.getString("privateKey"), // + jsonObject.getString("setupCode") // + ); + } else { + throw new FatalBackendException("Failed to load user, response code good but no body"); + } + } else { + throw new FatalBackendException("Failed to load user with response code " + response.code()); + } + } catch (IOException | JSONException e) { + throw new FatalBackendException("Failed to load user", e); + } + } + + @Override + public DeviceDto getDevice(UnverifiedHubVaultConfig unverifiedHubVaultConfig, String accessToken) throws BackendException { + var request = new Request.Builder().get() // + .header("Authorization", "Bearer " + accessToken) // + .url(unverifiedHubVaultConfig.getApiBaseUrl() + "devices/" + getHubDeviceCryptor().getDeviceId()).build(); + try (var response = getHttpClient().newCall(request).execute()) { + switch (response.code()) { + case HttpURLConnection.HTTP_OK: + if (response.body() != null) { + JSONObject jsonObject = new JSONObject(response.body().string()); + return new DeviceDto(jsonObject.getString("userPrivateKey")); + } else { + throw new FatalBackendException("Failed to load device, response code good but no body"); + } + case HttpURLConnection.HTTP_NOT_FOUND: + throw new HubDeviceSetupRequiredException(); + default: + throw new FatalBackendException("Failed to load device with response code " + response.code()); + } + } catch (IOException | JSONException e) { + throw new FatalBackendException("Failed to load device", e); + } + } + + @Override + public void createDevice(UnverifiedHubVaultConfig unverifiedHubVaultConfig, String accessToken, String deviceName, String setupCode, String userPrivateKey) throws BackendException { + var deviceId = getHubDeviceCryptor().getDeviceId(); + var devicePublicKey = getHubDeviceCryptor().getDevicePublicKeyEncoded(); + var publicKey = BaseEncoding.base64().encode(devicePublicKey); + JWEObject encryptedUserKey; + try { + encryptedUserKey = getHubDeviceCryptor().reEncryptUserKey(JWEObject.parse(userPrivateKey), setupCode); + } catch (HubDeviceCryptor.InvalidJweKeyException e) { + throw new HubInvalidSetupCodeException(e); + } catch (ParseException e) { + throw new FatalBackendException("Failed to parse user private key", e); + } + var dto = new JSONObject(); + try { + dto.put("id", deviceId); + dto.put("name", deviceName); + dto.put("publicKey", publicKey); + dto.put("type", "MOBILE"); + dto.put("userPrivateKey", encryptedUserKey.serialize()); + dto.put("creationTime", Instant.now().toString()); + } catch (JSONException e) { + throw new FatalBackendException("Failed to parse user private key", e); + } + + var request = new Request.Builder() // + .put(RequestBody.create(dto.toString(), MediaType.parse("application/json; charset=utf-8"))) // + .header("Authorization", "Bearer " + accessToken) // + .url(unverifiedHubVaultConfig.getApiBaseUrl() + "devices/" + deviceId) // + .build(); + try (var response = getHttpClient().newCall(request).execute()) { + switch (response.code()) { + case HttpURLConnection.HTTP_CREATED: + Timber.tag("HubRepositoryImpl").i("Device created"); + break; + case HttpURLConnection.HTTP_CONFLICT: + throw new HubDeviceAlreadyRegisteredForOtherUserException(); + default: + throw new FatalBackendException("Failed to load device with response code " + response.code()); + } + } catch (IOException e) { + throw new FatalBackendException(e); + } + } + + @Override + public ConfigDto getConfig(UnverifiedHubVaultConfig unverifiedHubVaultConfig, String accessToken) throws BackendException { + var request = new Request.Builder().get() // + .header("Authorization", "Bearer " + accessToken) // + .url(unverifiedHubVaultConfig.getApiBaseUrl() + "config").build(); + try (var response = getHttpClient().newCall(request).execute()) { + if (response.code() == HttpURLConnection.HTTP_OK) { + if (response.body() != null) { + JSONObject jsonObject = new JSONObject(response.body().string()); + return new ConfigDto(jsonObject.getInt("apiLevel")); + } else { + throw new FatalBackendException("Failed to load device, response code good but no body"); + } + } else { + throw new FatalBackendException("Failed to load device with response code " + response.code()); + } + } catch (IOException | JSONException e) { + throw new FatalBackendException("Failed to load device", e); + } + } + + private HubDeviceCryptor getHubDeviceCryptor() { + if (hubDeviceCryptor == null) { + hubDeviceCryptor = HubDeviceCryptor.getInstance(); + } + return hubDeviceCryptor; + } + + private OkHttpClient getHttpClient() { + if (httpClient == null) { + httpClient = new OkHttpClient.Builder() // + .addInterceptor(httpLoggingInterceptor(context)) // + .connectTimeout(NetworkTimeout.CONNECTION.getTimeout(), NetworkTimeout.CONNECTION.getUnit()) // + .readTimeout(NetworkTimeout.READ.getTimeout(), NetworkTimeout.READ.getUnit()) // + .writeTimeout(NetworkTimeout.WRITE.getTimeout(), NetworkTimeout.WRITE.getUnit()) // + .build(); + } + return httpClient; + } +} diff --git a/data/src/main/java/org/cryptomator/data/repository/RepositoryModule.java b/data/src/main/java/org/cryptomator/data/repository/RepositoryModule.java index 7bd1fff98..13799da4b 100644 --- a/data/src/main/java/org/cryptomator/data/repository/RepositoryModule.java +++ b/data/src/main/java/org/cryptomator/data/repository/RepositoryModule.java @@ -2,6 +2,7 @@ import org.cryptomator.domain.repository.CloudContentRepository; import org.cryptomator.domain.repository.CloudRepository; +import org.cryptomator.domain.repository.HubRepository; import org.cryptomator.domain.repository.UpdateCheckRepository; import org.cryptomator.domain.repository.VaultRepository; @@ -31,6 +32,12 @@ public CloudContentRepository provideCloudContentRepository(DispatchingCloudCont return cloudContentRepository; } + @Singleton + @Provides + public HubRepository provideHubRepositoryRepository(HubRepositoryImpl hubRepository) { + return hubRepository; + } + @Singleton @Provides public UpdateCheckRepository provideBetaStatusRepository(UpdateCheckRepositoryImpl updateCheckRepository) { diff --git a/data/src/test/java/org/cryptomator/data/cloud/crypto/MasterkeyCryptoCloudProviderTest.kt b/data/src/test/java/org/cryptomator/data/cloud/crypto/MasterkeyCryptoCloudProviderTest.kt index bc668c8c8..35e45fc97 100644 --- a/data/src/test/java/org/cryptomator/data/cloud/crypto/MasterkeyCryptoCloudProviderTest.kt +++ b/data/src/test/java/org/cryptomator/data/cloud/crypto/MasterkeyCryptoCloudProviderTest.kt @@ -165,7 +165,7 @@ internal class MasterkeyCryptoCloudProviderTest { whenever(vault.path).thenReturn("/foo") whenever(vault.isUnlocked).thenReturn(true) - val unlockToken = UnlockTokenImpl(vault, masterkeyV7.toByteArray(StandardCharsets.UTF_8)) + val unlockToken = UnlockTokenImpl(vault, secureRandom, masterkeyV7.toByteArray(StandardCharsets.UTF_8)) val unverifiedVaultConfig = UnverifiedVaultConfig(vaultConfig, URI.create(String.format("%s:%s", CryptoConstants.MASTERKEY_SCHEME, CryptoConstants.MASTERKEY_FILE_NAME)), CryptoConstants.MAX_VAULT_VERSION) val result: Vault = inTest.unlock(unlockToken, Optional.of(unverifiedVaultConfig), "foo") { false } @@ -192,7 +192,7 @@ internal class MasterkeyCryptoCloudProviderTest { whenever(vault.path).thenReturn("/foo") whenever(vault.isUnlocked).thenReturn(true) - val unlockToken = UnlockTokenImpl(vault, masterkeyV7.toByteArray(StandardCharsets.UTF_8)) + val unlockToken = UnlockTokenImpl(vault, secureRandom, masterkeyV7.toByteArray(StandardCharsets.UTF_8)) val result = inTest.unlock(unlockToken, Optional.absent(), "foo", { false }) MatcherAssert.assertThat(result.isUnlocked, CoreMatchers.`is`(true)) @@ -206,7 +206,7 @@ internal class MasterkeyCryptoCloudProviderTest { @Test @DisplayName("unlockLegacyUsingNewVault(\"foo\")") fun testUnlockLegacyVaultUsingVaultFormat8() { - val unlockToken: UnlockToken = UnlockTokenImpl(vault, masterkeyV8.toByteArray(StandardCharsets.UTF_8)) + val unlockToken: UnlockToken = UnlockTokenImpl(vault, secureRandom, masterkeyV8.toByteArray(StandardCharsets.UTF_8)) Assertions.assertThrows(MissingVaultConfigFileException::class.java) { inTest.unlock(unlockToken, Optional.absent(), "foo", { false }) } } @@ -302,7 +302,7 @@ internal class MasterkeyCryptoCloudProviderTest { if (legacy) { MatcherAssert.assertThat(testVaultPasswordVault(masterkeyV7, Optional.absent(), password), CoreMatchers.`is`(true)) - val unlockToken = UnlockTokenImpl(vault, masterkeyV7.toByteArray(StandardCharsets.UTF_8)) + val unlockToken = UnlockTokenImpl(vault, secureRandom, masterkeyV7.toByteArray(StandardCharsets.UTF_8)) Mockito.verify(inTest).cryptorFor(unlockToken.getKeyFile(password), CryptorProvider.Scheme.SIV_CTRMAC) } else { @@ -310,7 +310,7 @@ internal class MasterkeyCryptoCloudProviderTest { MatcherAssert.assertThat(testVaultPasswordVault(masterkeyV8, Optional.of(unverifiedVaultConfig), password), CoreMatchers.`is`(true)) - val unlockToken = UnlockTokenImpl(vault, masterkeyV8.toByteArray(StandardCharsets.UTF_8)) + val unlockToken = UnlockTokenImpl(vault, secureRandom, masterkeyV8.toByteArray(StandardCharsets.UTF_8)) Mockito.verify(inTest).cryptorFor(unlockToken.getKeyFile(password), CryptorProvider.Scheme.SIV_GCM) } diff --git a/domain/src/main/java/org/cryptomator/domain/UnverifiedHubVaultConfig.kt b/domain/src/main/java/org/cryptomator/domain/UnverifiedHubVaultConfig.kt new file mode 100644 index 000000000..db23a0980 --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/UnverifiedHubVaultConfig.kt @@ -0,0 +1,20 @@ +package org.cryptomator.domain + +import java.net.URI + +class UnverifiedHubVaultConfig( + override val jwt: String, + override val keyId: URI, + override val vaultFormat: Int, + val clientId: String, + val authEndpoint: URI, + val tokenEndpoint: URI, + val apiBaseUrl: URI +) : UnverifiedVaultConfig(jwt, keyId, vaultFormat) { + + fun vaultId(): String { + assert(keyId.scheme.startsWith("hub+")) + val path = keyId.path + return path.substring(path.lastIndexOf('/') + 1) + } +} diff --git a/domain/src/main/java/org/cryptomator/domain/UnverifiedVaultConfig.kt b/domain/src/main/java/org/cryptomator/domain/UnverifiedVaultConfig.kt index 2bb8b14d5..6c65ebc61 100644 --- a/domain/src/main/java/org/cryptomator/domain/UnverifiedVaultConfig.kt +++ b/domain/src/main/java/org/cryptomator/domain/UnverifiedVaultConfig.kt @@ -3,4 +3,19 @@ package org.cryptomator.domain import java.io.Serializable import java.net.URI -class UnverifiedVaultConfig(val jwt: String, val keyId: URI, val vaultFormat: Int) : Serializable +open class UnverifiedVaultConfig(open val jwt: String, open val keyId: URI, open val vaultFormat: Int) : Serializable { + fun keyLoadingStrategy(): KeyLoadingStrategy = KeyLoadingStrategy.fromKeyId(keyId) +} + +enum class KeyLoadingStrategy(private val prefix: String) { + MASTERKEY("masterkeyfile"), + HUB("hub+http"); + + companion object { + fun fromKeyId(keyId: URI): KeyLoadingStrategy { + val keyIdStr = keyId.toString() + return entries.firstOrNull { keyIdStr.startsWith(it.prefix) } + ?: throw IllegalArgumentException("Unsupported keyId prefix: $keyId") + } + } +} diff --git a/domain/src/main/java/org/cryptomator/domain/exception/hub/HubAuthenticationFailedException.java b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubAuthenticationFailedException.java new file mode 100644 index 000000000..b4e18d3cf --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubAuthenticationFailedException.java @@ -0,0 +1,15 @@ +package org.cryptomator.domain.exception.hub; + +import org.cryptomator.domain.exception.BackendException; + +public class HubAuthenticationFailedException extends BackendException { + + public HubAuthenticationFailedException() { + super(); + } + + public HubAuthenticationFailedException(Exception e) { + super(e); + } + +} diff --git a/domain/src/main/java/org/cryptomator/domain/exception/hub/HubDeviceAlreadyRegisteredForOtherUserException.java b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubDeviceAlreadyRegisteredForOtherUserException.java new file mode 100644 index 000000000..0543217f1 --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubDeviceAlreadyRegisteredForOtherUserException.java @@ -0,0 +1,11 @@ +package org.cryptomator.domain.exception.hub; + +import org.cryptomator.domain.exception.BackendException; + +public class HubDeviceAlreadyRegisteredForOtherUserException extends BackendException { + + public HubDeviceAlreadyRegisteredForOtherUserException() { + super(); + } + +} diff --git a/domain/src/main/java/org/cryptomator/domain/exception/hub/HubDeviceSetupRequiredException.java b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubDeviceSetupRequiredException.java new file mode 100644 index 000000000..7081def2c --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubDeviceSetupRequiredException.java @@ -0,0 +1,11 @@ +package org.cryptomator.domain.exception.hub; + +import org.cryptomator.domain.exception.BackendException; + +public class HubDeviceSetupRequiredException extends BackendException { + + public HubDeviceSetupRequiredException() { + super(); + } + +} diff --git a/domain/src/main/java/org/cryptomator/domain/exception/hub/HubInvalidSetupCodeException.java b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubInvalidSetupCodeException.java new file mode 100644 index 000000000..350264c3b --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubInvalidSetupCodeException.java @@ -0,0 +1,11 @@ +package org.cryptomator.domain.exception.hub; + +import org.cryptomator.domain.exception.BackendException; + +public class HubInvalidSetupCodeException extends BackendException { + + public HubInvalidSetupCodeException(Throwable e) { + super(e); + } + +} diff --git a/domain/src/main/java/org/cryptomator/domain/exception/hub/HubInvalidVersionException.java b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubInvalidVersionException.java new file mode 100644 index 000000000..363aa7fb7 --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubInvalidVersionException.java @@ -0,0 +1,11 @@ +package org.cryptomator.domain.exception.hub; + +import org.cryptomator.domain.exception.BackendException; + +public class HubInvalidVersionException extends BackendException { + + public HubInvalidVersionException(String message) { + super(message); + } + +} diff --git a/domain/src/main/java/org/cryptomator/domain/exception/hub/HubLicenseUpgradeRequiredException.java b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubLicenseUpgradeRequiredException.java new file mode 100644 index 000000000..4da6c6e66 --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubLicenseUpgradeRequiredException.java @@ -0,0 +1,11 @@ +package org.cryptomator.domain.exception.hub; + +import org.cryptomator.domain.exception.BackendException; + +public class HubLicenseUpgradeRequiredException extends BackendException { + + public HubLicenseUpgradeRequiredException() { + super(); + } + +} diff --git a/domain/src/main/java/org/cryptomator/domain/exception/hub/HubUserSetupRequiredException.java b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubUserSetupRequiredException.java new file mode 100644 index 000000000..4659bd183 --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubUserSetupRequiredException.java @@ -0,0 +1,11 @@ +package org.cryptomator.domain.exception.hub; + +import org.cryptomator.domain.exception.BackendException; + +public class HubUserSetupRequiredException extends BackendException { + + public HubUserSetupRequiredException() { + super(); + } + +} diff --git a/domain/src/main/java/org/cryptomator/domain/exception/hub/HubVaultAccessForbiddenException.java b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubVaultAccessForbiddenException.java new file mode 100644 index 000000000..d2e0a1b94 --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubVaultAccessForbiddenException.java @@ -0,0 +1,11 @@ +package org.cryptomator.domain.exception.hub; + +import org.cryptomator.domain.exception.BackendException; + +public class HubVaultAccessForbiddenException extends BackendException { + + public HubVaultAccessForbiddenException() { + super(); + } + +} diff --git a/domain/src/main/java/org/cryptomator/domain/exception/hub/HubVaultIsArchivedException.java b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubVaultIsArchivedException.java new file mode 100644 index 000000000..3112dfa82 --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubVaultIsArchivedException.java @@ -0,0 +1,11 @@ +package org.cryptomator.domain.exception.hub; + +import org.cryptomator.domain.exception.BackendException; + +public class HubVaultIsArchivedException extends BackendException { + + public HubVaultIsArchivedException() { + super(); + } + +} diff --git a/domain/src/main/java/org/cryptomator/domain/exception/hub/HubVaultOperationNotSupportedException.java b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubVaultOperationNotSupportedException.java new file mode 100644 index 000000000..2db6e509d --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/exception/hub/HubVaultOperationNotSupportedException.java @@ -0,0 +1,11 @@ +package org.cryptomator.domain.exception.hub; + +import org.cryptomator.domain.exception.BackendException; + +public class HubVaultOperationNotSupportedException extends BackendException { + + public HubVaultOperationNotSupportedException() { + super(); + } + +} diff --git a/domain/src/main/java/org/cryptomator/domain/exception/vaultconfig/HubNotSupportedOnPreAndroid31Exception.java b/domain/src/main/java/org/cryptomator/domain/exception/vaultconfig/HubNotSupportedOnPreAndroid31Exception.java new file mode 100644 index 000000000..81de5fba3 --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/exception/vaultconfig/HubNotSupportedOnPreAndroid31Exception.java @@ -0,0 +1,11 @@ +package org.cryptomator.domain.exception.vaultconfig; + +import org.cryptomator.domain.exception.BackendException; + +public class HubNotSupportedOnPreAndroid31Exception extends BackendException { + + public HubNotSupportedOnPreAndroid31Exception() { + super(); + } + +} diff --git a/domain/src/main/java/org/cryptomator/domain/exception/vaultconfig/VaultConfigLoadException.java b/domain/src/main/java/org/cryptomator/domain/exception/vaultconfig/VaultConfigLoadException.java index 088bfa708..9334524ec 100644 --- a/domain/src/main/java/org/cryptomator/domain/exception/vaultconfig/VaultConfigLoadException.java +++ b/domain/src/main/java/org/cryptomator/domain/exception/vaultconfig/VaultConfigLoadException.java @@ -1,7 +1,5 @@ package org.cryptomator.domain.exception.vaultconfig; -import com.auth0.jwt.exceptions.JWTVerificationException; - import org.cryptomator.domain.exception.BackendException; public class VaultConfigLoadException extends BackendException { @@ -10,7 +8,7 @@ public VaultConfigLoadException(String message) { super(message); } - public VaultConfigLoadException(String message, JWTVerificationException e) { + public VaultConfigLoadException(String message, Throwable e) { super(message, e); } diff --git a/domain/src/main/java/org/cryptomator/domain/repository/CloudRepository.java b/domain/src/main/java/org/cryptomator/domain/repository/CloudRepository.java index e3147f931..a16a75cfa 100644 --- a/domain/src/main/java/org/cryptomator/domain/repository/CloudRepository.java +++ b/domain/src/main/java/org/cryptomator/domain/repository/CloudRepository.java @@ -41,4 +41,6 @@ public interface CloudRepository { Cloud unlock(Vault vault, Optional vaultFile, CharSequence password, Flag cancelledFlag) throws BackendException; + Cloud unlock(Vault vault, UnverifiedVaultConfig unverifiedVaultConfig, String vaultKeyJwe, String userKeyJwe, Flag cancelledFlag) throws BackendException; + } diff --git a/domain/src/main/java/org/cryptomator/domain/repository/HubRepository.kt b/domain/src/main/java/org/cryptomator/domain/repository/HubRepository.kt new file mode 100644 index 000000000..02db0d8ed --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/repository/HubRepository.kt @@ -0,0 +1,29 @@ +package org.cryptomator.domain.repository + +import org.cryptomator.domain.UnverifiedHubVaultConfig +import org.cryptomator.domain.exception.BackendException + +interface HubRepository { + + @Throws(BackendException::class) + fun getVaultKeyJwe(unverifiedHubVaultConfig: UnverifiedHubVaultConfig, accessToken: String): String + + @Throws(BackendException::class) + fun getUser(unverifiedHubVaultConfig: UnverifiedHubVaultConfig, accessToken: String): UserDto + + @Throws(BackendException::class) + fun getDevice(unverifiedHubVaultConfig: UnverifiedHubVaultConfig, accessToken: String): DeviceDto + + @Throws(BackendException::class) + fun createDevice(unverifiedHubVaultConfig: UnverifiedHubVaultConfig, accessToken: String, deviceName: String, setupCode: String, userPrivateKey: String) + + @Throws(BackendException::class) + fun getConfig(unverifiedHubVaultConfig: UnverifiedHubVaultConfig, accessToken: String): ConfigDto + + data class DeviceDto(val userPrivateKey: String) + + data class ConfigDto(val apiLevel: Int) + + data class UserDto(val id: String, val name: String, val publicKey: String, val privateKey: String, val setupCode: String) + +} diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/vault/CreateHubDevice.java b/domain/src/main/java/org/cryptomator/domain/usecases/vault/CreateHubDevice.java new file mode 100644 index 000000000..2241dc019 --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/usecases/vault/CreateHubDevice.java @@ -0,0 +1,32 @@ +package org.cryptomator.domain.usecases.vault; + +import org.cryptomator.domain.UnverifiedHubVaultConfig; +import org.cryptomator.domain.exception.BackendException; +import org.cryptomator.domain.repository.HubRepository; +import org.cryptomator.generator.Parameter; +import org.cryptomator.generator.UseCase; + + +@UseCase +class CreateHubDevice { + + private final HubRepository hubRepository; + private final UnverifiedHubVaultConfig unverifiedVaultConfig; + private final String accessToken; + private final String deviceName; + private final String setupCode; + + public CreateHubDevice(HubRepository hubRepository, @Parameter UnverifiedHubVaultConfig unverifiedVaultConfig, @Parameter String accessToken, @Parameter String deviceName, @Parameter String setupCode) { + this.hubRepository = hubRepository; + this.unverifiedVaultConfig = unverifiedVaultConfig; + this.accessToken = accessToken; + this.deviceName = deviceName; + this.setupCode = setupCode; + } + + public void execute() throws BackendException { + HubRepository.UserDto user = hubRepository.getUser(unverifiedVaultConfig, accessToken); + hubRepository.createDevice(unverifiedVaultConfig, accessToken, deviceName, setupCode, user.getPrivateKey()); + } + +} diff --git a/domain/src/main/java/org/cryptomator/domain/usecases/vault/UnlockHubVault.java b/domain/src/main/java/org/cryptomator/domain/usecases/vault/UnlockHubVault.java new file mode 100644 index 000000000..b9744b24a --- /dev/null +++ b/domain/src/main/java/org/cryptomator/domain/usecases/vault/UnlockHubVault.java @@ -0,0 +1,53 @@ +package org.cryptomator.domain.usecases.vault; + +import org.cryptomator.domain.Cloud; +import org.cryptomator.domain.UnverifiedHubVaultConfig; +import org.cryptomator.domain.Vault; +import org.cryptomator.domain.exception.BackendException; +import org.cryptomator.domain.exception.hub.HubInvalidVersionException; +import org.cryptomator.domain.repository.CloudRepository; +import org.cryptomator.domain.repository.HubRepository; +import org.cryptomator.domain.usecases.cloud.Flag; +import org.cryptomator.generator.Parameter; +import org.cryptomator.generator.UseCase; + +@UseCase +class UnlockHubVault { + + private final int HUB_MINIMUM_VERSION = 1; + private final CloudRepository cloudRepository; + private final Vault vault; + private final HubRepository hubRepository; + private final UnverifiedHubVaultConfig unverifiedVaultConfig; + private final String accessToken; + private volatile boolean cancelled; + private final Flag cancelledFlag = new Flag() { + @Override + public boolean get() { + return cancelled; + } + }; + + public UnlockHubVault(CloudRepository cloudRepository, HubRepository hubRepository, @Parameter Vault vault, @Parameter UnverifiedHubVaultConfig unverifiedVaultConfig, @Parameter String accessToken) { + this.cloudRepository = cloudRepository; + this.vault = vault; + this.hubRepository = hubRepository; + this.unverifiedVaultConfig = unverifiedVaultConfig; + this.accessToken = accessToken; + } + + public void onCancel() { + cancelled = true; + } + + public Cloud execute() throws BackendException { + HubRepository.ConfigDto config = hubRepository.getConfig(unverifiedVaultConfig, accessToken); + if (config.getApiLevel() < HUB_MINIMUM_VERSION) { + throw new HubInvalidVersionException("Version is " + config.getApiLevel() + " but minimum is " + HUB_MINIMUM_VERSION); + } + String vaultKeyJwe = hubRepository.getVaultKeyJwe(unverifiedVaultConfig, accessToken); + HubRepository.DeviceDto device = hubRepository.getDevice(unverifiedVaultConfig, accessToken); + return cloudRepository.unlock(vault, unverifiedVaultConfig, vaultKeyJwe, device.getUserPrivateKey(), cancelledFlag); + } + +} diff --git a/fastlane/izzyscript/result_apkstore.json b/fastlane/izzyscript/result_apkstore.json index 7ee076158..9c591b5e0 100644 --- a/fastlane/izzyscript/result_apkstore.json +++ b/fastlane/izzyscript/result_apkstore.json @@ -1 +1 @@ -{"applicationId":"org.cryptomator","emoji":[],"labels":["scanner-warning"],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\nOffending libs:
\n
    \n
  • Azure SDK for Java (/com/azure): NonFreeNet
  • \n
  • Dropbox Core SDK for Java (/com/dropbox/core): NonFreeNet
  • \n
  • Google Mobile Services (/com/google/android/gms): NonFreeComp
  • \n
  • Google API Client Libraries (/com/google/api/client): NonFreeNet
  • \n
  • Google Drive API (/com/google/api/services/drive): NonFreeDep,NonFreeNet
  • \n
  • Google Java API Client Services (/com/google/api/services): NonFreeNet
  • \n
  • Microsoft Authentication Library (/com/microsoft/identity): NonFreeNet
  • \n
  • pCloud Java SDK (/com/pcloud/sdk): NonFreeNet
  • \n
\n8 offender(s). Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Asynclayoutinflater/androidx/asynclayoutinflaterUI ComponentApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Browser/androidx/browserUtilityApache-2.0
Cardview/androidx/cardviewUI ComponentApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Concurrent/androidx/concurrentUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Coordinatorlayout/androidx/coordinatorlayoutUI ComponentApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Drawerlayout/androidx/drawerlayoutUI ComponentApache-2.0
Dynamicanimation/androidx/dynamicanimationUI ComponentApache-2.0
Android Emoji2 Compat/androidx/emoji2UI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
AndroidX Fragment/androidx/fragmentUI ComponentApache-2.0
Interpolator/androidx/interpolatorUI ComponentApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Android Multi Dex Library/androidx/multidexUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
ResourceInspection/androidx/resourceinspectionDevelopment AidApache-2.0
Recyclerview/androidx/recyclerviewUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Slidingpanelayout/androidx/slidingpanelayoutUI ComponentApache-2.0
Startup/androidx/startupUtilityApache-2.0
Swiperefreshlayout/androidx/swiperefreshlayoutUI ComponentApache-2.0
AndroidX Test/androidx/testDevelopment FrameworkApache-2.0
Tracing/androidx/tracingUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
Viewpager/androidx/viewpagerUI ComponentApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Jetpack WindowManager Library/androidx/windowUtilityApache-2.0
java-jwt/com/auth0/jwtUtilityMIT
Azure SDK for Java/com/azureDevelopment FrameworkMITNonFreeNet
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Woodstox/com/ctc/wstxUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
Dropbox Core SDK for Java/com/dropbox/coreUtilityMITNonFreeNet
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Mobile Services/com/google/android/gmsDevelopment FrameworkProprietaryNonFreeComp
Google Material Design/com/google/android/materialUtilityApache-2.0
Google API Client Libraries/com/google/api/clientDevelopment FrameworkApache-2.0NonFreeNet
Google Drive API/com/google/api/services/driveUtilityApache-2.0NonFreeDep,NonFreeNet
Google Java API Client Services/com/google/api/servicesUtilityApache-2.0NonFreeNet
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
J2ObjC/com/google/j2objcUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
Microsoft Azure Active Directory Authentication Library/com/microsoft/aad/adalUtilityMIT
Surface Duo SDK/com/microsoft/device/dualscreenUtilityMIT
Microsoft Graph-SDK/com/microsoft/graphDevelopment FrameworkMIT
Microsoft Authentication Library/com/microsoft/identityUtilityMITNonFreeNet
Nimbus JOSE+JWT/com/nimbusds/joseUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
pCloud Java SDK/com/pcloud/sdkUtilityApache-2.0NonFreeNet
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
Wutka DTD/com/wutka/dtdDevelopment Aidnone
Yubico Mobile Android SDK/com/yubico/yubikitUtilityApache-2.0
HttpClient Android repackaged/cz/msebera/android/httpclientUtilityApache-2.0
Dagger/daggerUtilityApache-2.0
FindBugs/edu/umd/cs/findbugsUtilityLGPL-3.0-or-later
MinIO Client SDK for Java/io/minioUtilityApache-2.0
RxJava/io/reactivexUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Javax XML/javax/xmlUtilityGPL-2.0
Junit/junitUtilityEPL-1.0
Kotlin/kotlinUtilityApache-2.0
Kotlin Android Extensions Runtime/kotlinx/android/extensions-runtimeUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
kotlin-parcelize/kotlinx/parcelizeUtilityApache-2.0
JCIP Annotations/net/jcip/annotationsUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Apache Http/org/apache/httpUtilityApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
Stax2 API/org/codehaus/stax2UtilityBSD
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
Java Hamcrest/org/hamcrestUtilityBSD-3-Clause
IntelliJ IDEA/org/intellijUtilityApache-2.0
jUnit Java Unit Test/org/junitUtilityEPL-2.0
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Reactor Core/reactor/coreUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/asynclayoutinflater","name":"Asynclayoutinflater","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/asynclayoutinflater","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/browser","name":"Browser","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/browser","license":"Apache-2.0"},{"id":"/androidx/cardview","name":"Cardview","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/cardview/","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/concurrent","name":"Concurrent","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/concurrent","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/coordinatorlayout","name":"Coordinatorlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/coordinatorlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/drawerlayout","name":"Drawerlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/drawerlayout","license":"Apache-2.0"},{"id":"/androidx/dynamicanimation","name":"Dynamicanimation","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/dynamicanimation","license":"Apache-2.0"},{"id":"/androidx/emoji2","name":"Android Emoji2 Compat","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/emoji2/","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment","name":"AndroidX Fragment","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/interpolator","name":"Interpolator","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/interpolator","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/multidex","name":"Android Multi Dex Library","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/multidex","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/resourceinspection","name":"ResourceInspection","typ":"Development Aid","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/resourceinspection","license":"Apache-2.0"},{"id":"/androidx/recyclerview","name":"Recyclerview","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/recyclerview","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/slidingpanelayout","name":"Slidingpanelayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/slidingpanelayout","license":"Apache-2.0"},{"id":"/androidx/startup","name":"Startup","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/startup","license":"Apache-2.0"},{"id":"/androidx/swiperefreshlayout","name":"Swiperefreshlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/swiperefreshlayout","license":"Apache-2.0"},{"id":"/androidx/test","name":"AndroidX Test","typ":"Development Framework","anti":"","url":"https://github.com/android/android-test","license":"Apache-2.0"},{"id":"/androidx/tracing","name":"Tracing","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/tracing","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager","name":"Viewpager","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/viewpager","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/androidx/window","name":"Jetpack WindowManager Library","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/window/","license":"Apache-2.0"},{"id":"/com/auth0/jwt","name":"java-jwt","typ":"Utility","anti":"","url":"https://github.com/auth0/java-jwt","license":"MIT"},{"id":"/com/azure","name":"Azure SDK for Java","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/Azure/azure-sdk-for-java","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/ctc/wstx","name":"Woodstox","typ":"Utility","anti":"","url":"https://github.com/FasterXML/woodstox","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/dropbox/core","name":"Dropbox Core SDK for Java","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/dropbox/dropbox-sdk-java","license":"MIT"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/gms","name":"Google Mobile Services","typ":"Development Framework","anti":"NonFreeComp","url":"https://developers.google.com/android/reference/com/google/android/gms/package-summary","license":"Proprietary"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/api/client","name":"Google API Client Libraries","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client","license":"Apache-2.0"},{"id":"/com/google/api/services/drive","name":"Google Drive API","typ":"Utility","anti":"NonFreeDep,NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services/tree/main/clients/google-api-services-drive","license":"Apache-2.0"},{"id":"/com/google/api/services","name":"Google Java API Client Services","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/google/j2objc","name":"J2ObjC","typ":"Utility","anti":"","url":"https://github.com/google/j2objc","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/microsoft/aad/adal","name":"Microsoft Azure Active Directory Authentication Library","typ":"Utility","anti":"","url":"https://github.com/AzureAD/azure-activedirectory-library-for-android","license":"MIT"},{"id":"/com/microsoft/device/dualscreen","name":"Surface Duo SDK","typ":"Utility","anti":"","url":"https://github.com/microsoft/surface-duo-sdk","license":"MIT"},{"id":"/com/microsoft/graph","name":"Microsoft Graph-SDK","typ":"Development Framework","anti":"","url":"https://github.com/microsoftgraph/msgraph-sdk-java","license":"MIT"},{"id":"/com/microsoft/identity","name":"Microsoft Authentication Library","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/AzureAD/microsoft-authentication-library-for-android","license":"MIT"},{"id":"/com/nimbusds/jose","name":"Nimbus JOSE+JWT","typ":"Utility","anti":"","url":"https://github.com/gesellix/Nimbus-JOSE-JWT","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/pcloud/sdk","name":"pCloud Java SDK","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/pCloud/pcloud-sdk-java","license":"Apache-2.0"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/com/wutka/dtd","name":"Wutka DTD","typ":"Development Aid","anti":"","url":"https://mvnrepository.com/artifact/com.liferay/com.wutka.dtd","license":""},{"id":"/com/yubico/yubikit","name":"Yubico Mobile Android SDK","typ":"Utility","anti":"","url":"https://github.com/Yubico/yubikit-android","license":"Apache-2.0"},{"id":"/cz/msebera/android/httpclient","name":"HttpClient Android repackaged","typ":"Utility","anti":"","url":"https://github.com/smarek/httpclient-android","license":"Apache-2.0"},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/edu/umd/cs/findbugs","name":"FindBugs","typ":"Utility","anti":"","url":"http://findbugs.sourceforge.net/","license":"LGPL-3.0-or-later"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/javax/xml","name":"Javax XML","typ":"Utility","anti":"","url":"https://docs.oracle.com/en/java/javase/17/docs/api/java.xml/javax/xml/package-summary.html","license":"GPL-2.0"},{"id":"/junit","name":"Junit","typ":"Utility","anti":"","url":"https://junit.org/junit4/","license":"EPL-1.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/android/extensions-runtime","name":"Kotlin Android Extensions Runtime","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/master/plugins/android-extensions/android-extensions-runtime","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/kotlinx/parcelize","name":"kotlin-parcelize","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/cdbfa7fbbc6f31dbcb6264f456bfedee1a85c40b/plugins/parcelize","license":"Apache-2.0"},{"id":"/net/jcip/annotations","name":"JCIP Annotations","typ":"Utility","anti":"","url":"https://github.com/stephenc/jcip-annotations","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/apache/http","name":"Apache Http","typ":"Utility","anti":"","url":"https://hc.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/codehaus/stax2","name":"Stax2 API","typ":"Utility","anti":"","url":"https://github.com/FasterXML/stax2-api","license":"BSD"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/hamcrest","name":"Java Hamcrest","typ":"Utility","anti":"","url":"https://github.com/hamcrest/JavaHamcrest","license":"BSD-3-Clause"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/junit","name":"jUnit Java Unit Test","typ":"Utility","anti":"","url":"http://junit.org/","license":"EPL-2.0"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/reactor/core","name":"Reactor Core","typ":"Utility","anti":"","url":"https://github.com/reactor/reactor-core","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 3853 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 80668 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 103 libraries, 8 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file +{"applicationId":"org.cryptomator","emoji":[],"labels":["scanner-warning"],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\nOffending libs:
\n
    \n
  • Azure SDK for Java (/com/azure): NonFreeNet
  • \n
  • Dropbox Core SDK for Java (/com/dropbox/core): NonFreeNet
  • \n
  • Google Mobile Services (/com/google/android/gms): NonFreeComp
  • \n
  • Google API Client Libraries (/com/google/api/client): NonFreeNet
  • \n
  • Google Drive API (/com/google/api/services/drive): NonFreeDep,NonFreeNet
  • \n
  • Google Java API Client Services (/com/google/api/services): NonFreeNet
  • \n
  • Microsoft Authentication Library (/com/microsoft/identity): NonFreeNet
  • \n
  • pCloud Java SDK (/com/pcloud/sdk): NonFreeNet
  • \n
\n8 offender(s). Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Browser/androidx/browserUtilityApache-2.0
Cardview/androidx/cardviewUI ComponentApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Concurrent/androidx/concurrentUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Coordinatorlayout/androidx/coordinatorlayoutUI ComponentApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Drawerlayout/androidx/drawerlayoutUI ComponentApache-2.0
Dynamicanimation/androidx/dynamicanimationUI ComponentApache-2.0
Android Emoji2 Compat/androidx/emoji2UI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
AndroidX Fragment/androidx/fragmentUI ComponentApache-2.0
Interpolator/androidx/interpolatorUI ComponentApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Android Multi Dex Library/androidx/multidexUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
ResourceInspection/androidx/resourceinspectionDevelopment AidApache-2.0
Recyclerview/androidx/recyclerviewUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Slidingpanelayout/androidx/slidingpanelayoutUI ComponentApache-2.0
Startup/androidx/startupUtilityApache-2.0
Swiperefreshlayout/androidx/swiperefreshlayoutUI ComponentApache-2.0
AndroidX Test/androidx/testDevelopment FrameworkApache-2.0
Tracing/androidx/tracingUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
Viewpager/androidx/viewpagerUI ComponentApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Jetpack WindowManager Library/androidx/windowUtilityApache-2.0
java-jwt/com/auth0/jwtUtilityMIT
Azure SDK for Java/com/azureDevelopment FrameworkMITNonFreeNet
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Woodstox/com/ctc/wstxUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
Dropbox Core SDK for Java/com/dropbox/coreUtilityMITNonFreeNet
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Mobile Services/com/google/android/gmsDevelopment FrameworkProprietaryNonFreeComp
Google Material Design/com/google/android/materialUtilityApache-2.0
Google API Client Libraries/com/google/api/clientDevelopment FrameworkApache-2.0NonFreeNet
Google Drive API/com/google/api/services/driveUtilityApache-2.0NonFreeDep,NonFreeNet
Google Java API Client Services/com/google/api/servicesUtilityApache-2.0NonFreeNet
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
J2ObjC/com/google/j2objcUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
Microsoft Azure Active Directory Authentication Library/com/microsoft/aad/adalUtilityMIT
Surface Duo SDK/com/microsoft/device/dualscreenUtilityMIT
Microsoft Graph-SDK/com/microsoft/graphDevelopment FrameworkMIT
Microsoft Authentication Library/com/microsoft/identityUtilityMITNonFreeNet
Nimbus JOSE+JWT/com/nimbusds/joseUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
pCloud Java SDK/com/pcloud/sdkUtilityApache-2.0NonFreeNet
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
Wutka DTD/com/wutka/dtdDevelopment Aidnone
Yubico Mobile Android SDK/com/yubico/yubikitUtilityApache-2.0
HttpClient Android repackaged/cz/msebera/android/httpclientUtilityApache-2.0
Dagger/daggerUtilityApache-2.0
FindBugs/edu/umd/cs/findbugsUtilityLGPL-3.0-or-later
MinIO Client SDK for Java/io/minioUtilityApache-2.0
RxJava/io/reactivexUtilityApache-2.0
Jakarta Dependency Injection/jakarta/injectUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Javax XML/javax/xmlUtilityGPL-2.0
Junit/junitUtilityEPL-1.0
Kotlin/kotlinUtilityApache-2.0
Kotlin Android Extensions Runtime/kotlinx/android/extensions-runtimeUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
kotlin-parcelize/kotlinx/parcelizeUtilityApache-2.0
AppAuth for Android/net/openid/appauthUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Apache Http/org/apache/httpUtilityApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
Stax2 API/org/codehaus/stax2UtilityBSD
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
Java Hamcrest/org/hamcrestUtilityBSD-3-Clause
IntelliJ IDEA/org/intellijUtilityApache-2.0
JSpecify/org/jspecifyDevelopment AidApache-2.0
jUnit Java Unit Test/org/junitUtilityEPL-2.0
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Reactor Core/reactor/coreUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/browser","name":"Browser","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/browser","license":"Apache-2.0"},{"id":"/androidx/cardview","name":"Cardview","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/cardview/","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/concurrent","name":"Concurrent","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/concurrent","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/coordinatorlayout","name":"Coordinatorlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/coordinatorlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/drawerlayout","name":"Drawerlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/drawerlayout","license":"Apache-2.0"},{"id":"/androidx/dynamicanimation","name":"Dynamicanimation","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/dynamicanimation","license":"Apache-2.0"},{"id":"/androidx/emoji2","name":"Android Emoji2 Compat","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/emoji2/","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment","name":"AndroidX Fragment","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/interpolator","name":"Interpolator","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/interpolator","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/multidex","name":"Android Multi Dex Library","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/multidex","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/resourceinspection","name":"ResourceInspection","typ":"Development Aid","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/resourceinspection","license":"Apache-2.0"},{"id":"/androidx/recyclerview","name":"Recyclerview","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/recyclerview","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/slidingpanelayout","name":"Slidingpanelayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/slidingpanelayout","license":"Apache-2.0"},{"id":"/androidx/startup","name":"Startup","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/startup","license":"Apache-2.0"},{"id":"/androidx/swiperefreshlayout","name":"Swiperefreshlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/swiperefreshlayout","license":"Apache-2.0"},{"id":"/androidx/test","name":"AndroidX Test","typ":"Development Framework","anti":"","url":"https://github.com/android/android-test","license":"Apache-2.0"},{"id":"/androidx/tracing","name":"Tracing","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/tracing","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager","name":"Viewpager","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/viewpager","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/androidx/window","name":"Jetpack WindowManager Library","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/window/","license":"Apache-2.0"},{"id":"/com/auth0/jwt","name":"java-jwt","typ":"Utility","anti":"","url":"https://github.com/auth0/java-jwt","license":"MIT"},{"id":"/com/azure","name":"Azure SDK for Java","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/Azure/azure-sdk-for-java","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/ctc/wstx","name":"Woodstox","typ":"Utility","anti":"","url":"https://github.com/FasterXML/woodstox","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/dropbox/core","name":"Dropbox Core SDK for Java","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/dropbox/dropbox-sdk-java","license":"MIT"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/gms","name":"Google Mobile Services","typ":"Development Framework","anti":"NonFreeComp","url":"https://developers.google.com/android/reference/com/google/android/gms/package-summary","license":"Proprietary"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/api/client","name":"Google API Client Libraries","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client","license":"Apache-2.0"},{"id":"/com/google/api/services/drive","name":"Google Drive API","typ":"Utility","anti":"NonFreeDep,NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services/tree/main/clients/google-api-services-drive","license":"Apache-2.0"},{"id":"/com/google/api/services","name":"Google Java API Client Services","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/google/j2objc","name":"J2ObjC","typ":"Utility","anti":"","url":"https://github.com/google/j2objc","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/microsoft/aad/adal","name":"Microsoft Azure Active Directory Authentication Library","typ":"Utility","anti":"","url":"https://github.com/AzureAD/azure-activedirectory-library-for-android","license":"MIT"},{"id":"/com/microsoft/device/dualscreen","name":"Surface Duo SDK","typ":"Utility","anti":"","url":"https://github.com/microsoft/surface-duo-sdk","license":"MIT"},{"id":"/com/microsoft/graph","name":"Microsoft Graph-SDK","typ":"Development Framework","anti":"","url":"https://github.com/microsoftgraph/msgraph-sdk-java","license":"MIT"},{"id":"/com/microsoft/identity","name":"Microsoft Authentication Library","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/AzureAD/microsoft-authentication-library-for-android","license":"MIT"},{"id":"/com/nimbusds/jose","name":"Nimbus JOSE+JWT","typ":"Utility","anti":"","url":"https://github.com/gesellix/Nimbus-JOSE-JWT","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/pcloud/sdk","name":"pCloud Java SDK","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/pCloud/pcloud-sdk-java","license":"Apache-2.0"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/com/wutka/dtd","name":"Wutka DTD","typ":"Development Aid","anti":"","url":"https://mvnrepository.com/artifact/com.liferay/com.wutka.dtd","license":""},{"id":"/com/yubico/yubikit","name":"Yubico Mobile Android SDK","typ":"Utility","anti":"","url":"https://github.com/Yubico/yubikit-android","license":"Apache-2.0"},{"id":"/cz/msebera/android/httpclient","name":"HttpClient Android repackaged","typ":"Utility","anti":"","url":"https://github.com/smarek/httpclient-android","license":"Apache-2.0"},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/edu/umd/cs/findbugs","name":"FindBugs","typ":"Utility","anti":"","url":"http://findbugs.sourceforge.net/","license":"LGPL-3.0-or-later"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/jakarta/inject","name":"Jakarta Dependency Injection","typ":"Utility","anti":"","url":"https://github.com/jakartaee/inject","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/javax/xml","name":"Javax XML","typ":"Utility","anti":"","url":"https://docs.oracle.com/en/java/javase/17/docs/api/java.xml/javax/xml/package-summary.html","license":"GPL-2.0"},{"id":"/junit","name":"Junit","typ":"Utility","anti":"","url":"https://junit.org/junit4/","license":"EPL-1.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/android/extensions-runtime","name":"Kotlin Android Extensions Runtime","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/master/plugins/android-extensions/android-extensions-runtime","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/kotlinx/parcelize","name":"kotlin-parcelize","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/cdbfa7fbbc6f31dbcb6264f456bfedee1a85c40b/plugins/parcelize","license":"Apache-2.0"},{"id":"/net/openid/appauth","name":"AppAuth for Android","typ":"Utility","anti":"","url":"https://github.com/openid/AppAuth-Android","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/apache/http","name":"Apache Http","typ":"Utility","anti":"","url":"https://hc.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/codehaus/stax2","name":"Stax2 API","typ":"Utility","anti":"","url":"https://github.com/FasterXML/stax2-api","license":"BSD"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/hamcrest","name":"Java Hamcrest","typ":"Utility","anti":"","url":"https://github.com/hamcrest/JavaHamcrest","license":"BSD-3-Clause"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/jspecify","name":"JSpecify","typ":"Development Aid","anti":"","url":"https://github.com/jspecify/jspecify","license":"Apache-2.0"},{"id":"/org/junit","name":"jUnit Java Unit Test","typ":"Utility","anti":"","url":"http://junit.org/","license":"EPL-2.0"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/reactor/core","name":"Reactor Core","typ":"Utility","anti":"","url":"https://github.com/reactor/reactor-core","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 3938 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 95638 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 104 libraries, 8 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file diff --git a/fastlane/izzyscript/result_fdroid.json b/fastlane/izzyscript/result_fdroid.json index beee3e676..3c4c993d9 100644 --- a/fastlane/izzyscript/result_fdroid.json +++ b/fastlane/izzyscript/result_fdroid.json @@ -1 +1 @@ -{"applicationId":"org.cryptomator","emoji":[],"labels":["scanner-warning"],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\nOffending libs:
\n
    \n
  • Azure SDK for Java (/com/azure): NonFreeNet
  • \n
  • Dropbox Core SDK for Java (/com/dropbox/core): NonFreeNet
  • \n
  • Microsoft Authentication Library (/com/microsoft/identity): NonFreeNet
  • \n
  • pCloud Java SDK (/com/pcloud/sdk): NonFreeNet
  • \n
\n4 offender(s). Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Asynclayoutinflater/androidx/asynclayoutinflaterUI ComponentApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Browser/androidx/browserUtilityApache-2.0
Cardview/androidx/cardviewUI ComponentApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Concurrent/androidx/concurrentUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Coordinatorlayout/androidx/coordinatorlayoutUI ComponentApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Drawerlayout/androidx/drawerlayoutUI ComponentApache-2.0
Dynamicanimation/androidx/dynamicanimationUI ComponentApache-2.0
Android Emoji2 Compat/androidx/emoji2UI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
AndroidX Fragment/androidx/fragmentUI ComponentApache-2.0
Interpolator/androidx/interpolatorUI ComponentApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Android Multi Dex Library/androidx/multidexUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
ResourceInspection/androidx/resourceinspectionDevelopment AidApache-2.0
Recyclerview/androidx/recyclerviewUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Slidingpanelayout/androidx/slidingpanelayoutUI ComponentApache-2.0
Startup/androidx/startupUtilityApache-2.0
Swiperefreshlayout/androidx/swiperefreshlayoutUI ComponentApache-2.0
AndroidX Test/androidx/testDevelopment FrameworkApache-2.0
Tracing/androidx/tracingUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
Viewpager/androidx/viewpagerUI ComponentApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Jetpack WindowManager Library/androidx/windowUtilityApache-2.0
java-jwt/com/auth0/jwtUtilityMIT
Azure SDK for Java/com/azureDevelopment FrameworkMITNonFreeNet
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Woodstox/com/ctc/wstxUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
Dropbox Core SDK for Java/com/dropbox/coreUtilityMITNonFreeNet
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Material Design/com/google/android/materialUtilityApache-2.0
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
Microsoft Azure Active Directory Authentication Library/com/microsoft/aad/adalUtilityMIT
Surface Duo SDK/com/microsoft/device/dualscreenUtilityMIT
Microsoft Graph-SDK/com/microsoft/graphDevelopment FrameworkMIT
Microsoft Authentication Library/com/microsoft/identityUtilityMITNonFreeNet
Nimbus JOSE+JWT/com/nimbusds/joseUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
pCloud Java SDK/com/pcloud/sdkUtilityApache-2.0NonFreeNet
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
Wutka DTD/com/wutka/dtdDevelopment Aidnone
Yubico Mobile Android SDK/com/yubico/yubikitUtilityApache-2.0
HttpClient Android repackaged/cz/msebera/android/httpclientUtilityApache-2.0
Dagger/daggerUtilityApache-2.0
FindBugs/edu/umd/cs/findbugsUtilityLGPL-3.0-or-later
MinIO Client SDK for Java/io/minioUtilityApache-2.0
RxJava/io/reactivexUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Javax XML/javax/xmlUtilityGPL-2.0
Junit/junitUtilityEPL-1.0
Kotlin/kotlinUtilityApache-2.0
Kotlin Android Extensions Runtime/kotlinx/android/extensions-runtimeUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
kotlin-parcelize/kotlinx/parcelizeUtilityApache-2.0
JCIP Annotations/net/jcip/annotationsUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
Stax2 API/org/codehaus/stax2UtilityBSD
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
Java Hamcrest/org/hamcrestUtilityBSD-3-Clause
IntelliJ IDEA/org/intellijUtilityApache-2.0
jUnit Java Unit Test/org/junitUtilityEPL-2.0
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Reactor Core/reactor/coreUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/asynclayoutinflater","name":"Asynclayoutinflater","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/asynclayoutinflater","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/browser","name":"Browser","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/browser","license":"Apache-2.0"},{"id":"/androidx/cardview","name":"Cardview","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/cardview/","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/concurrent","name":"Concurrent","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/concurrent","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/coordinatorlayout","name":"Coordinatorlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/coordinatorlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/drawerlayout","name":"Drawerlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/drawerlayout","license":"Apache-2.0"},{"id":"/androidx/dynamicanimation","name":"Dynamicanimation","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/dynamicanimation","license":"Apache-2.0"},{"id":"/androidx/emoji2","name":"Android Emoji2 Compat","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/emoji2/","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment","name":"AndroidX Fragment","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/interpolator","name":"Interpolator","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/interpolator","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/multidex","name":"Android Multi Dex Library","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/multidex","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/resourceinspection","name":"ResourceInspection","typ":"Development Aid","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/resourceinspection","license":"Apache-2.0"},{"id":"/androidx/recyclerview","name":"Recyclerview","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/recyclerview","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/slidingpanelayout","name":"Slidingpanelayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/slidingpanelayout","license":"Apache-2.0"},{"id":"/androidx/startup","name":"Startup","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/startup","license":"Apache-2.0"},{"id":"/androidx/swiperefreshlayout","name":"Swiperefreshlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/swiperefreshlayout","license":"Apache-2.0"},{"id":"/androidx/test","name":"AndroidX Test","typ":"Development Framework","anti":"","url":"https://github.com/android/android-test","license":"Apache-2.0"},{"id":"/androidx/tracing","name":"Tracing","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/tracing","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager","name":"Viewpager","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/viewpager","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/androidx/window","name":"Jetpack WindowManager Library","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/window/","license":"Apache-2.0"},{"id":"/com/auth0/jwt","name":"java-jwt","typ":"Utility","anti":"","url":"https://github.com/auth0/java-jwt","license":"MIT"},{"id":"/com/azure","name":"Azure SDK for Java","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/Azure/azure-sdk-for-java","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/ctc/wstx","name":"Woodstox","typ":"Utility","anti":"","url":"https://github.com/FasterXML/woodstox","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/dropbox/core","name":"Dropbox Core SDK for Java","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/dropbox/dropbox-sdk-java","license":"MIT"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/microsoft/aad/adal","name":"Microsoft Azure Active Directory Authentication Library","typ":"Utility","anti":"","url":"https://github.com/AzureAD/azure-activedirectory-library-for-android","license":"MIT"},{"id":"/com/microsoft/device/dualscreen","name":"Surface Duo SDK","typ":"Utility","anti":"","url":"https://github.com/microsoft/surface-duo-sdk","license":"MIT"},{"id":"/com/microsoft/graph","name":"Microsoft Graph-SDK","typ":"Development Framework","anti":"","url":"https://github.com/microsoftgraph/msgraph-sdk-java","license":"MIT"},{"id":"/com/microsoft/identity","name":"Microsoft Authentication Library","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/AzureAD/microsoft-authentication-library-for-android","license":"MIT"},{"id":"/com/nimbusds/jose","name":"Nimbus JOSE+JWT","typ":"Utility","anti":"","url":"https://github.com/gesellix/Nimbus-JOSE-JWT","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/pcloud/sdk","name":"pCloud Java SDK","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/pCloud/pcloud-sdk-java","license":"Apache-2.0"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/com/wutka/dtd","name":"Wutka DTD","typ":"Development Aid","anti":"","url":"https://mvnrepository.com/artifact/com.liferay/com.wutka.dtd","license":""},{"id":"/com/yubico/yubikit","name":"Yubico Mobile Android SDK","typ":"Utility","anti":"","url":"https://github.com/Yubico/yubikit-android","license":"Apache-2.0"},{"id":"/cz/msebera/android/httpclient","name":"HttpClient Android repackaged","typ":"Utility","anti":"","url":"https://github.com/smarek/httpclient-android","license":"Apache-2.0"},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/edu/umd/cs/findbugs","name":"FindBugs","typ":"Utility","anti":"","url":"http://findbugs.sourceforge.net/","license":"LGPL-3.0-or-later"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/javax/xml","name":"Javax XML","typ":"Utility","anti":"","url":"https://docs.oracle.com/en/java/javase/17/docs/api/java.xml/javax/xml/package-summary.html","license":"GPL-2.0"},{"id":"/junit","name":"Junit","typ":"Utility","anti":"","url":"https://junit.org/junit4/","license":"EPL-1.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/android/extensions-runtime","name":"Kotlin Android Extensions Runtime","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/master/plugins/android-extensions/android-extensions-runtime","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/kotlinx/parcelize","name":"kotlin-parcelize","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/cdbfa7fbbc6f31dbcb6264f456bfedee1a85c40b/plugins/parcelize","license":"Apache-2.0"},{"id":"/net/jcip/annotations","name":"JCIP Annotations","typ":"Utility","anti":"","url":"https://github.com/stephenc/jcip-annotations","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/codehaus/stax2","name":"Stax2 API","typ":"Utility","anti":"","url":"https://github.com/FasterXML/stax2-api","license":"BSD"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/hamcrest","name":"Java Hamcrest","typ":"Utility","anti":"","url":"https://github.com/hamcrest/JavaHamcrest","license":"BSD-3-Clause"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/junit","name":"jUnit Java Unit Test","typ":"Utility","anti":"","url":"http://junit.org/","license":"EPL-2.0"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/reactor/core","name":"Reactor Core","typ":"Utility","anti":"","url":"https://github.com/reactor/reactor-core","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 3853 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 72528 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 97 libraries, 4 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file +{"applicationId":"org.cryptomator","emoji":[],"labels":["scanner-warning"],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\nOffending libs:
\n
    \n
  • Azure SDK for Java (/com/azure): NonFreeNet
  • \n
  • Dropbox Core SDK for Java (/com/dropbox/core): NonFreeNet
  • \n
  • Microsoft Authentication Library (/com/microsoft/identity): NonFreeNet
  • \n
  • pCloud Java SDK (/com/pcloud/sdk): NonFreeNet
  • \n
\n4 offender(s). Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Browser/androidx/browserUtilityApache-2.0
Cardview/androidx/cardviewUI ComponentApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Concurrent/androidx/concurrentUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Coordinatorlayout/androidx/coordinatorlayoutUI ComponentApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Drawerlayout/androidx/drawerlayoutUI ComponentApache-2.0
Dynamicanimation/androidx/dynamicanimationUI ComponentApache-2.0
Android Emoji2 Compat/androidx/emoji2UI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
AndroidX Fragment/androidx/fragmentUI ComponentApache-2.0
Interpolator/androidx/interpolatorUI ComponentApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Android Multi Dex Library/androidx/multidexUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
ResourceInspection/androidx/resourceinspectionDevelopment AidApache-2.0
Recyclerview/androidx/recyclerviewUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Slidingpanelayout/androidx/slidingpanelayoutUI ComponentApache-2.0
Startup/androidx/startupUtilityApache-2.0
Swiperefreshlayout/androidx/swiperefreshlayoutUI ComponentApache-2.0
AndroidX Test/androidx/testDevelopment FrameworkApache-2.0
Tracing/androidx/tracingUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
Viewpager/androidx/viewpagerUI ComponentApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Jetpack WindowManager Library/androidx/windowUtilityApache-2.0
java-jwt/com/auth0/jwtUtilityMIT
Azure SDK for Java/com/azureDevelopment FrameworkMITNonFreeNet
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Woodstox/com/ctc/wstxUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
Dropbox Core SDK for Java/com/dropbox/coreUtilityMITNonFreeNet
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Material Design/com/google/android/materialUtilityApache-2.0
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
J2ObjC/com/google/j2objcUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
Microsoft Azure Active Directory Authentication Library/com/microsoft/aad/adalUtilityMIT
Surface Duo SDK/com/microsoft/device/dualscreenUtilityMIT
Microsoft Graph-SDK/com/microsoft/graphDevelopment FrameworkMIT
Microsoft Authentication Library/com/microsoft/identityUtilityMITNonFreeNet
Nimbus JOSE+JWT/com/nimbusds/joseUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
pCloud Java SDK/com/pcloud/sdkUtilityApache-2.0NonFreeNet
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
Wutka DTD/com/wutka/dtdDevelopment Aidnone
Yubico Mobile Android SDK/com/yubico/yubikitUtilityApache-2.0
HttpClient Android repackaged/cz/msebera/android/httpclientUtilityApache-2.0
Dagger/daggerUtilityApache-2.0
FindBugs/edu/umd/cs/findbugsUtilityLGPL-3.0-or-later
MinIO Client SDK for Java/io/minioUtilityApache-2.0
RxJava/io/reactivexUtilityApache-2.0
Jakarta Dependency Injection/jakarta/injectUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Javax XML/javax/xmlUtilityGPL-2.0
Junit/junitUtilityEPL-1.0
Kotlin/kotlinUtilityApache-2.0
Kotlin Android Extensions Runtime/kotlinx/android/extensions-runtimeUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
kotlin-parcelize/kotlinx/parcelizeUtilityApache-2.0
AppAuth for Android/net/openid/appauthUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
Stax2 API/org/codehaus/stax2UtilityBSD
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
Java Hamcrest/org/hamcrestUtilityBSD-3-Clause
IntelliJ IDEA/org/intellijUtilityApache-2.0
JSpecify/org/jspecifyDevelopment AidApache-2.0
jUnit Java Unit Test/org/junitUtilityEPL-2.0
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Reactor Core/reactor/coreUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/browser","name":"Browser","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/browser","license":"Apache-2.0"},{"id":"/androidx/cardview","name":"Cardview","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/cardview/","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/concurrent","name":"Concurrent","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/concurrent","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/coordinatorlayout","name":"Coordinatorlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/coordinatorlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/drawerlayout","name":"Drawerlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/drawerlayout","license":"Apache-2.0"},{"id":"/androidx/dynamicanimation","name":"Dynamicanimation","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/dynamicanimation","license":"Apache-2.0"},{"id":"/androidx/emoji2","name":"Android Emoji2 Compat","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/emoji2/","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment","name":"AndroidX Fragment","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/interpolator","name":"Interpolator","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/interpolator","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/multidex","name":"Android Multi Dex Library","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/multidex","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/resourceinspection","name":"ResourceInspection","typ":"Development Aid","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/resourceinspection","license":"Apache-2.0"},{"id":"/androidx/recyclerview","name":"Recyclerview","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/recyclerview","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/slidingpanelayout","name":"Slidingpanelayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/slidingpanelayout","license":"Apache-2.0"},{"id":"/androidx/startup","name":"Startup","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/startup","license":"Apache-2.0"},{"id":"/androidx/swiperefreshlayout","name":"Swiperefreshlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/swiperefreshlayout","license":"Apache-2.0"},{"id":"/androidx/test","name":"AndroidX Test","typ":"Development Framework","anti":"","url":"https://github.com/android/android-test","license":"Apache-2.0"},{"id":"/androidx/tracing","name":"Tracing","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/tracing","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager","name":"Viewpager","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/viewpager","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/androidx/window","name":"Jetpack WindowManager Library","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/window/","license":"Apache-2.0"},{"id":"/com/auth0/jwt","name":"java-jwt","typ":"Utility","anti":"","url":"https://github.com/auth0/java-jwt","license":"MIT"},{"id":"/com/azure","name":"Azure SDK for Java","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/Azure/azure-sdk-for-java","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/ctc/wstx","name":"Woodstox","typ":"Utility","anti":"","url":"https://github.com/FasterXML/woodstox","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/dropbox/core","name":"Dropbox Core SDK for Java","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/dropbox/dropbox-sdk-java","license":"MIT"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/google/j2objc","name":"J2ObjC","typ":"Utility","anti":"","url":"https://github.com/google/j2objc","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/microsoft/aad/adal","name":"Microsoft Azure Active Directory Authentication Library","typ":"Utility","anti":"","url":"https://github.com/AzureAD/azure-activedirectory-library-for-android","license":"MIT"},{"id":"/com/microsoft/device/dualscreen","name":"Surface Duo SDK","typ":"Utility","anti":"","url":"https://github.com/microsoft/surface-duo-sdk","license":"MIT"},{"id":"/com/microsoft/graph","name":"Microsoft Graph-SDK","typ":"Development Framework","anti":"","url":"https://github.com/microsoftgraph/msgraph-sdk-java","license":"MIT"},{"id":"/com/microsoft/identity","name":"Microsoft Authentication Library","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/AzureAD/microsoft-authentication-library-for-android","license":"MIT"},{"id":"/com/nimbusds/jose","name":"Nimbus JOSE+JWT","typ":"Utility","anti":"","url":"https://github.com/gesellix/Nimbus-JOSE-JWT","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/pcloud/sdk","name":"pCloud Java SDK","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/pCloud/pcloud-sdk-java","license":"Apache-2.0"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/com/wutka/dtd","name":"Wutka DTD","typ":"Development Aid","anti":"","url":"https://mvnrepository.com/artifact/com.liferay/com.wutka.dtd","license":""},{"id":"/com/yubico/yubikit","name":"Yubico Mobile Android SDK","typ":"Utility","anti":"","url":"https://github.com/Yubico/yubikit-android","license":"Apache-2.0"},{"id":"/cz/msebera/android/httpclient","name":"HttpClient Android repackaged","typ":"Utility","anti":"","url":"https://github.com/smarek/httpclient-android","license":"Apache-2.0"},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/edu/umd/cs/findbugs","name":"FindBugs","typ":"Utility","anti":"","url":"http://findbugs.sourceforge.net/","license":"LGPL-3.0-or-later"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/jakarta/inject","name":"Jakarta Dependency Injection","typ":"Utility","anti":"","url":"https://github.com/jakartaee/inject","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/javax/xml","name":"Javax XML","typ":"Utility","anti":"","url":"https://docs.oracle.com/en/java/javase/17/docs/api/java.xml/javax/xml/package-summary.html","license":"GPL-2.0"},{"id":"/junit","name":"Junit","typ":"Utility","anti":"","url":"https://junit.org/junit4/","license":"EPL-1.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/android/extensions-runtime","name":"Kotlin Android Extensions Runtime","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/master/plugins/android-extensions/android-extensions-runtime","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/kotlinx/parcelize","name":"kotlin-parcelize","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/cdbfa7fbbc6f31dbcb6264f456bfedee1a85c40b/plugins/parcelize","license":"Apache-2.0"},{"id":"/net/openid/appauth","name":"AppAuth for Android","typ":"Utility","anti":"","url":"https://github.com/openid/AppAuth-Android","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/codehaus/stax2","name":"Stax2 API","typ":"Utility","anti":"","url":"https://github.com/FasterXML/stax2-api","license":"BSD"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/hamcrest","name":"Java Hamcrest","typ":"Utility","anti":"","url":"https://github.com/hamcrest/JavaHamcrest","license":"BSD-3-Clause"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/jspecify","name":"JSpecify","typ":"Development Aid","anti":"","url":"https://github.com/jspecify/jspecify","license":"Apache-2.0"},{"id":"/org/junit","name":"jUnit Java Unit Test","typ":"Utility","anti":"","url":"http://junit.org/","license":"EPL-2.0"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/reactor/core","name":"Reactor Core","typ":"Utility","anti":"","url":"https://github.com/reactor/reactor-core","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 3938 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 87567 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 99 libraries, 4 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file diff --git a/fastlane/izzyscript/result_lite.json b/fastlane/izzyscript/result_lite.json index 704d9aa43..072702969 100644 --- a/fastlane/izzyscript/result_lite.json +++ b/fastlane/izzyscript/result_lite.json @@ -1 +1 @@ -{"applicationId":"org.cryptomator","emoji":[],"labels":[],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\n
  • Library definitions checked against: 3853
  • Libraries matched in this APK: 80
\nNo offending libs found. Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Cardview/androidx/cardviewUI ComponentApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Concurrent/androidx/concurrentUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Coordinatorlayout/androidx/coordinatorlayoutUI ComponentApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Drawerlayout/androidx/drawerlayoutUI ComponentApache-2.0
Dynamicanimation/androidx/dynamicanimationUI ComponentApache-2.0
Android Emoji2 Compat/androidx/emoji2UI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
AndroidX Fragment/androidx/fragmentUI ComponentApache-2.0
Interpolator/androidx/interpolatorUI ComponentApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Android Multi Dex Library/androidx/multidexUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
ResourceInspection/androidx/resourceinspectionDevelopment AidApache-2.0
Recyclerview/androidx/recyclerviewUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Slidingpanelayout/androidx/slidingpanelayoutUI ComponentApache-2.0
Startup/androidx/startupUtilityApache-2.0
Swiperefreshlayout/androidx/swiperefreshlayoutUI ComponentApache-2.0
AndroidX Test/androidx/testDevelopment FrameworkApache-2.0
Tracing/androidx/tracingUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
Viewpager/androidx/viewpagerUI ComponentApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Jetpack WindowManager Library/androidx/windowUtilityApache-2.0
java-jwt/com/auth0/jwtUtilityMIT
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Material Design/com/google/android/materialUtilityApache-2.0
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
Wutka DTD/com/wutka/dtdDevelopment Aidnone
Dagger/daggerUtilityApache-2.0
MinIO Client SDK for Java/io/minioUtilityApache-2.0
RxJava/io/reactivexUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Javax XML/javax/xmlUtilityGPL-2.0
Junit/junitUtilityEPL-1.0
Kotlin/kotlinUtilityApache-2.0
Kotlin Android Extensions Runtime/kotlinx/android/extensions-runtimeUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
kotlin-parcelize/kotlinx/parcelizeUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
Java Hamcrest/org/hamcrestUtilityBSD-3-Clause
IntelliJ IDEA/org/intellijUtilityApache-2.0
jUnit Java Unit Test/org/junitUtilityEPL-2.0
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/cardview","name":"Cardview","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/cardview/","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/concurrent","name":"Concurrent","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/concurrent","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/coordinatorlayout","name":"Coordinatorlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/coordinatorlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/drawerlayout","name":"Drawerlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/drawerlayout","license":"Apache-2.0"},{"id":"/androidx/dynamicanimation","name":"Dynamicanimation","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/dynamicanimation","license":"Apache-2.0"},{"id":"/androidx/emoji2","name":"Android Emoji2 Compat","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/emoji2/","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment","name":"AndroidX Fragment","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/interpolator","name":"Interpolator","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/interpolator","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/multidex","name":"Android Multi Dex Library","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/multidex","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/resourceinspection","name":"ResourceInspection","typ":"Development Aid","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/resourceinspection","license":"Apache-2.0"},{"id":"/androidx/recyclerview","name":"Recyclerview","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/recyclerview","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/slidingpanelayout","name":"Slidingpanelayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/slidingpanelayout","license":"Apache-2.0"},{"id":"/androidx/startup","name":"Startup","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/startup","license":"Apache-2.0"},{"id":"/androidx/swiperefreshlayout","name":"Swiperefreshlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/swiperefreshlayout","license":"Apache-2.0"},{"id":"/androidx/test","name":"AndroidX Test","typ":"Development Framework","anti":"","url":"https://github.com/android/android-test","license":"Apache-2.0"},{"id":"/androidx/tracing","name":"Tracing","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/tracing","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager","name":"Viewpager","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/viewpager","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/androidx/window","name":"Jetpack WindowManager Library","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/window/","license":"Apache-2.0"},{"id":"/com/auth0/jwt","name":"java-jwt","typ":"Utility","anti":"","url":"https://github.com/auth0/java-jwt","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/com/wutka/dtd","name":"Wutka DTD","typ":"Development Aid","anti":"","url":"https://mvnrepository.com/artifact/com.liferay/com.wutka.dtd","license":""},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/javax/xml","name":"Javax XML","typ":"Utility","anti":"","url":"https://docs.oracle.com/en/java/javase/17/docs/api/java.xml/javax/xml/package-summary.html","license":"GPL-2.0"},{"id":"/junit","name":"Junit","typ":"Utility","anti":"","url":"https://junit.org/junit4/","license":"EPL-1.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/android/extensions-runtime","name":"Kotlin Android Extensions Runtime","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/master/plugins/android-extensions/android-extensions-runtime","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/kotlinx/parcelize","name":"kotlin-parcelize","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/cdbfa7fbbc6f31dbcb6264f456bfedee1a85c40b/plugins/parcelize","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/hamcrest","name":"Java Hamcrest","typ":"Utility","anti":"","url":"https://github.com/hamcrest/JavaHamcrest","license":"BSD-3-Clause"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/junit","name":"jUnit Java Unit Test","typ":"Utility","anti":"","url":"http://junit.org/","license":"EPL-2.0"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 3853 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 49250 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 80 libraries, 0 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file +{"applicationId":"org.cryptomator","emoji":[],"labels":[],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\n
  • Library definitions checked against: 3938
  • Libraries matched in this APK: 86
\nNo offending libs found. Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Browser/androidx/browserUtilityApache-2.0
Cardview/androidx/cardviewUI ComponentApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Concurrent/androidx/concurrentUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Coordinatorlayout/androidx/coordinatorlayoutUI ComponentApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Drawerlayout/androidx/drawerlayoutUI ComponentApache-2.0
Dynamicanimation/androidx/dynamicanimationUI ComponentApache-2.0
Android Emoji2 Compat/androidx/emoji2UI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
AndroidX Fragment/androidx/fragmentUI ComponentApache-2.0
Interpolator/androidx/interpolatorUI ComponentApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Android Multi Dex Library/androidx/multidexUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
ResourceInspection/androidx/resourceinspectionDevelopment AidApache-2.0
Recyclerview/androidx/recyclerviewUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Slidingpanelayout/androidx/slidingpanelayoutUI ComponentApache-2.0
Startup/androidx/startupUtilityApache-2.0
Swiperefreshlayout/androidx/swiperefreshlayoutUI ComponentApache-2.0
AndroidX Test/androidx/testDevelopment FrameworkApache-2.0
Tracing/androidx/tracingUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
Viewpager/androidx/viewpagerUI ComponentApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Jetpack WindowManager Library/androidx/windowUtilityApache-2.0
java-jwt/com/auth0/jwtUtilityMIT
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Material Design/com/google/android/materialUtilityApache-2.0
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
J2ObjC/com/google/j2objcUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
Nimbus JOSE+JWT/com/nimbusds/joseUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
Wutka DTD/com/wutka/dtdDevelopment Aidnone
Dagger/daggerUtilityApache-2.0
MinIO Client SDK for Java/io/minioUtilityApache-2.0
RxJava/io/reactivexUtilityApache-2.0
Jakarta Dependency Injection/jakarta/injectUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Javax XML/javax/xmlUtilityGPL-2.0
Junit/junitUtilityEPL-1.0
Kotlin/kotlinUtilityApache-2.0
Kotlin Android Extensions Runtime/kotlinx/android/extensions-runtimeUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
kotlin-parcelize/kotlinx/parcelizeUtilityApache-2.0
AppAuth for Android/net/openid/appauthUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
Java Hamcrest/org/hamcrestUtilityBSD-3-Clause
IntelliJ IDEA/org/intellijUtilityApache-2.0
JSpecify/org/jspecifyDevelopment AidApache-2.0
jUnit Java Unit Test/org/junitUtilityEPL-2.0
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/browser","name":"Browser","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/browser","license":"Apache-2.0"},{"id":"/androidx/cardview","name":"Cardview","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/cardview/","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/concurrent","name":"Concurrent","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/concurrent","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/coordinatorlayout","name":"Coordinatorlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/coordinatorlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/drawerlayout","name":"Drawerlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/drawerlayout","license":"Apache-2.0"},{"id":"/androidx/dynamicanimation","name":"Dynamicanimation","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/dynamicanimation","license":"Apache-2.0"},{"id":"/androidx/emoji2","name":"Android Emoji2 Compat","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/emoji2/","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment","name":"AndroidX Fragment","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/interpolator","name":"Interpolator","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/interpolator","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/multidex","name":"Android Multi Dex Library","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/multidex","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/resourceinspection","name":"ResourceInspection","typ":"Development Aid","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/resourceinspection","license":"Apache-2.0"},{"id":"/androidx/recyclerview","name":"Recyclerview","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/recyclerview","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/slidingpanelayout","name":"Slidingpanelayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/slidingpanelayout","license":"Apache-2.0"},{"id":"/androidx/startup","name":"Startup","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/startup","license":"Apache-2.0"},{"id":"/androidx/swiperefreshlayout","name":"Swiperefreshlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/swiperefreshlayout","license":"Apache-2.0"},{"id":"/androidx/test","name":"AndroidX Test","typ":"Development Framework","anti":"","url":"https://github.com/android/android-test","license":"Apache-2.0"},{"id":"/androidx/tracing","name":"Tracing","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/tracing","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager","name":"Viewpager","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/viewpager","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/androidx/window","name":"Jetpack WindowManager Library","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/window/","license":"Apache-2.0"},{"id":"/com/auth0/jwt","name":"java-jwt","typ":"Utility","anti":"","url":"https://github.com/auth0/java-jwt","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/google/j2objc","name":"J2ObjC","typ":"Utility","anti":"","url":"https://github.com/google/j2objc","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/nimbusds/jose","name":"Nimbus JOSE+JWT","typ":"Utility","anti":"","url":"https://github.com/gesellix/Nimbus-JOSE-JWT","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/com/wutka/dtd","name":"Wutka DTD","typ":"Development Aid","anti":"","url":"https://mvnrepository.com/artifact/com.liferay/com.wutka.dtd","license":""},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/jakarta/inject","name":"Jakarta Dependency Injection","typ":"Utility","anti":"","url":"https://github.com/jakartaee/inject","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/javax/xml","name":"Javax XML","typ":"Utility","anti":"","url":"https://docs.oracle.com/en/java/javase/17/docs/api/java.xml/javax/xml/package-summary.html","license":"GPL-2.0"},{"id":"/junit","name":"Junit","typ":"Utility","anti":"","url":"https://junit.org/junit4/","license":"EPL-1.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/android/extensions-runtime","name":"Kotlin Android Extensions Runtime","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/master/plugins/android-extensions/android-extensions-runtime","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/kotlinx/parcelize","name":"kotlin-parcelize","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/cdbfa7fbbc6f31dbcb6264f456bfedee1a85c40b/plugins/parcelize","license":"Apache-2.0"},{"id":"/net/openid/appauth","name":"AppAuth for Android","typ":"Utility","anti":"","url":"https://github.com/openid/AppAuth-Android","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/hamcrest","name":"Java Hamcrest","typ":"Utility","anti":"","url":"https://github.com/hamcrest/JavaHamcrest","license":"BSD-3-Clause"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/jspecify","name":"JSpecify","typ":"Development Aid","anti":"","url":"https://github.com/jspecify/jspecify","license":"Apache-2.0"},{"id":"/org/junit","name":"jUnit Java Unit Test","typ":"Utility","anti":"","url":"http://junit.org/","license":"EPL-2.0"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 3938 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 65920 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 86 libraries, 0 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file diff --git a/fastlane/izzyscript/result_playstore.json b/fastlane/izzyscript/result_playstore.json index 7ee076158..9c591b5e0 100644 --- a/fastlane/izzyscript/result_playstore.json +++ b/fastlane/izzyscript/result_playstore.json @@ -1 +1 @@ -{"applicationId":"org.cryptomator","emoji":[],"labels":["scanner-warning"],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\nOffending libs:
\n
    \n
  • Azure SDK for Java (/com/azure): NonFreeNet
  • \n
  • Dropbox Core SDK for Java (/com/dropbox/core): NonFreeNet
  • \n
  • Google Mobile Services (/com/google/android/gms): NonFreeComp
  • \n
  • Google API Client Libraries (/com/google/api/client): NonFreeNet
  • \n
  • Google Drive API (/com/google/api/services/drive): NonFreeDep,NonFreeNet
  • \n
  • Google Java API Client Services (/com/google/api/services): NonFreeNet
  • \n
  • Microsoft Authentication Library (/com/microsoft/identity): NonFreeNet
  • \n
  • pCloud Java SDK (/com/pcloud/sdk): NonFreeNet
  • \n
\n8 offender(s). Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Asynclayoutinflater/androidx/asynclayoutinflaterUI ComponentApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Browser/androidx/browserUtilityApache-2.0
Cardview/androidx/cardviewUI ComponentApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Concurrent/androidx/concurrentUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Coordinatorlayout/androidx/coordinatorlayoutUI ComponentApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Drawerlayout/androidx/drawerlayoutUI ComponentApache-2.0
Dynamicanimation/androidx/dynamicanimationUI ComponentApache-2.0
Android Emoji2 Compat/androidx/emoji2UI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
AndroidX Fragment/androidx/fragmentUI ComponentApache-2.0
Interpolator/androidx/interpolatorUI ComponentApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Android Multi Dex Library/androidx/multidexUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
ResourceInspection/androidx/resourceinspectionDevelopment AidApache-2.0
Recyclerview/androidx/recyclerviewUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Slidingpanelayout/androidx/slidingpanelayoutUI ComponentApache-2.0
Startup/androidx/startupUtilityApache-2.0
Swiperefreshlayout/androidx/swiperefreshlayoutUI ComponentApache-2.0
AndroidX Test/androidx/testDevelopment FrameworkApache-2.0
Tracing/androidx/tracingUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
Viewpager/androidx/viewpagerUI ComponentApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Jetpack WindowManager Library/androidx/windowUtilityApache-2.0
java-jwt/com/auth0/jwtUtilityMIT
Azure SDK for Java/com/azureDevelopment FrameworkMITNonFreeNet
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Woodstox/com/ctc/wstxUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
Dropbox Core SDK for Java/com/dropbox/coreUtilityMITNonFreeNet
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Mobile Services/com/google/android/gmsDevelopment FrameworkProprietaryNonFreeComp
Google Material Design/com/google/android/materialUtilityApache-2.0
Google API Client Libraries/com/google/api/clientDevelopment FrameworkApache-2.0NonFreeNet
Google Drive API/com/google/api/services/driveUtilityApache-2.0NonFreeDep,NonFreeNet
Google Java API Client Services/com/google/api/servicesUtilityApache-2.0NonFreeNet
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
J2ObjC/com/google/j2objcUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
Microsoft Azure Active Directory Authentication Library/com/microsoft/aad/adalUtilityMIT
Surface Duo SDK/com/microsoft/device/dualscreenUtilityMIT
Microsoft Graph-SDK/com/microsoft/graphDevelopment FrameworkMIT
Microsoft Authentication Library/com/microsoft/identityUtilityMITNonFreeNet
Nimbus JOSE+JWT/com/nimbusds/joseUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
pCloud Java SDK/com/pcloud/sdkUtilityApache-2.0NonFreeNet
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
Wutka DTD/com/wutka/dtdDevelopment Aidnone
Yubico Mobile Android SDK/com/yubico/yubikitUtilityApache-2.0
HttpClient Android repackaged/cz/msebera/android/httpclientUtilityApache-2.0
Dagger/daggerUtilityApache-2.0
FindBugs/edu/umd/cs/findbugsUtilityLGPL-3.0-or-later
MinIO Client SDK for Java/io/minioUtilityApache-2.0
RxJava/io/reactivexUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Javax XML/javax/xmlUtilityGPL-2.0
Junit/junitUtilityEPL-1.0
Kotlin/kotlinUtilityApache-2.0
Kotlin Android Extensions Runtime/kotlinx/android/extensions-runtimeUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
kotlin-parcelize/kotlinx/parcelizeUtilityApache-2.0
JCIP Annotations/net/jcip/annotationsUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Apache Http/org/apache/httpUtilityApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
Stax2 API/org/codehaus/stax2UtilityBSD
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
Java Hamcrest/org/hamcrestUtilityBSD-3-Clause
IntelliJ IDEA/org/intellijUtilityApache-2.0
jUnit Java Unit Test/org/junitUtilityEPL-2.0
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Reactor Core/reactor/coreUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/asynclayoutinflater","name":"Asynclayoutinflater","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/asynclayoutinflater","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/browser","name":"Browser","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/browser","license":"Apache-2.0"},{"id":"/androidx/cardview","name":"Cardview","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/cardview/","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/concurrent","name":"Concurrent","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/concurrent","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/coordinatorlayout","name":"Coordinatorlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/coordinatorlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/drawerlayout","name":"Drawerlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/drawerlayout","license":"Apache-2.0"},{"id":"/androidx/dynamicanimation","name":"Dynamicanimation","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/dynamicanimation","license":"Apache-2.0"},{"id":"/androidx/emoji2","name":"Android Emoji2 Compat","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/emoji2/","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment","name":"AndroidX Fragment","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/interpolator","name":"Interpolator","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/interpolator","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/multidex","name":"Android Multi Dex Library","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/multidex","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/resourceinspection","name":"ResourceInspection","typ":"Development Aid","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/resourceinspection","license":"Apache-2.0"},{"id":"/androidx/recyclerview","name":"Recyclerview","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/recyclerview","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/slidingpanelayout","name":"Slidingpanelayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/slidingpanelayout","license":"Apache-2.0"},{"id":"/androidx/startup","name":"Startup","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/startup","license":"Apache-2.0"},{"id":"/androidx/swiperefreshlayout","name":"Swiperefreshlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/swiperefreshlayout","license":"Apache-2.0"},{"id":"/androidx/test","name":"AndroidX Test","typ":"Development Framework","anti":"","url":"https://github.com/android/android-test","license":"Apache-2.0"},{"id":"/androidx/tracing","name":"Tracing","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/tracing","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager","name":"Viewpager","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/viewpager","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/androidx/window","name":"Jetpack WindowManager Library","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/window/","license":"Apache-2.0"},{"id":"/com/auth0/jwt","name":"java-jwt","typ":"Utility","anti":"","url":"https://github.com/auth0/java-jwt","license":"MIT"},{"id":"/com/azure","name":"Azure SDK for Java","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/Azure/azure-sdk-for-java","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/ctc/wstx","name":"Woodstox","typ":"Utility","anti":"","url":"https://github.com/FasterXML/woodstox","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/dropbox/core","name":"Dropbox Core SDK for Java","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/dropbox/dropbox-sdk-java","license":"MIT"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/gms","name":"Google Mobile Services","typ":"Development Framework","anti":"NonFreeComp","url":"https://developers.google.com/android/reference/com/google/android/gms/package-summary","license":"Proprietary"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/api/client","name":"Google API Client Libraries","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client","license":"Apache-2.0"},{"id":"/com/google/api/services/drive","name":"Google Drive API","typ":"Utility","anti":"NonFreeDep,NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services/tree/main/clients/google-api-services-drive","license":"Apache-2.0"},{"id":"/com/google/api/services","name":"Google Java API Client Services","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/google/j2objc","name":"J2ObjC","typ":"Utility","anti":"","url":"https://github.com/google/j2objc","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/microsoft/aad/adal","name":"Microsoft Azure Active Directory Authentication Library","typ":"Utility","anti":"","url":"https://github.com/AzureAD/azure-activedirectory-library-for-android","license":"MIT"},{"id":"/com/microsoft/device/dualscreen","name":"Surface Duo SDK","typ":"Utility","anti":"","url":"https://github.com/microsoft/surface-duo-sdk","license":"MIT"},{"id":"/com/microsoft/graph","name":"Microsoft Graph-SDK","typ":"Development Framework","anti":"","url":"https://github.com/microsoftgraph/msgraph-sdk-java","license":"MIT"},{"id":"/com/microsoft/identity","name":"Microsoft Authentication Library","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/AzureAD/microsoft-authentication-library-for-android","license":"MIT"},{"id":"/com/nimbusds/jose","name":"Nimbus JOSE+JWT","typ":"Utility","anti":"","url":"https://github.com/gesellix/Nimbus-JOSE-JWT","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/pcloud/sdk","name":"pCloud Java SDK","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/pCloud/pcloud-sdk-java","license":"Apache-2.0"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/com/wutka/dtd","name":"Wutka DTD","typ":"Development Aid","anti":"","url":"https://mvnrepository.com/artifact/com.liferay/com.wutka.dtd","license":""},{"id":"/com/yubico/yubikit","name":"Yubico Mobile Android SDK","typ":"Utility","anti":"","url":"https://github.com/Yubico/yubikit-android","license":"Apache-2.0"},{"id":"/cz/msebera/android/httpclient","name":"HttpClient Android repackaged","typ":"Utility","anti":"","url":"https://github.com/smarek/httpclient-android","license":"Apache-2.0"},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/edu/umd/cs/findbugs","name":"FindBugs","typ":"Utility","anti":"","url":"http://findbugs.sourceforge.net/","license":"LGPL-3.0-or-later"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/javax/xml","name":"Javax XML","typ":"Utility","anti":"","url":"https://docs.oracle.com/en/java/javase/17/docs/api/java.xml/javax/xml/package-summary.html","license":"GPL-2.0"},{"id":"/junit","name":"Junit","typ":"Utility","anti":"","url":"https://junit.org/junit4/","license":"EPL-1.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/android/extensions-runtime","name":"Kotlin Android Extensions Runtime","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/master/plugins/android-extensions/android-extensions-runtime","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/kotlinx/parcelize","name":"kotlin-parcelize","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/cdbfa7fbbc6f31dbcb6264f456bfedee1a85c40b/plugins/parcelize","license":"Apache-2.0"},{"id":"/net/jcip/annotations","name":"JCIP Annotations","typ":"Utility","anti":"","url":"https://github.com/stephenc/jcip-annotations","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/apache/http","name":"Apache Http","typ":"Utility","anti":"","url":"https://hc.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/codehaus/stax2","name":"Stax2 API","typ":"Utility","anti":"","url":"https://github.com/FasterXML/stax2-api","license":"BSD"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/hamcrest","name":"Java Hamcrest","typ":"Utility","anti":"","url":"https://github.com/hamcrest/JavaHamcrest","license":"BSD-3-Clause"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/junit","name":"jUnit Java Unit Test","typ":"Utility","anti":"","url":"http://junit.org/","license":"EPL-2.0"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/reactor/core","name":"Reactor Core","typ":"Utility","anti":"","url":"https://github.com/reactor/reactor-core","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 3853 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 80668 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 103 libraries, 8 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file +{"applicationId":"org.cryptomator","emoji":[],"labels":["scanner-warning"],"report":"

APK library scanner

\nunsigned/org.cryptomator_fdroid.apk\nOffending libs:
\n
    \n
  • Azure SDK for Java (/com/azure): NonFreeNet
  • \n
  • Dropbox Core SDK for Java (/com/dropbox/core): NonFreeNet
  • \n
  • Google Mobile Services (/com/google/android/gms): NonFreeComp
  • \n
  • Google API Client Libraries (/com/google/api/client): NonFreeNet
  • \n
  • Google Drive API (/com/google/api/services/drive): NonFreeDep,NonFreeNet
  • \n
  • Google Java API Client Services (/com/google/api/services): NonFreeNet
  • \n
  • Microsoft Authentication Library (/com/microsoft/identity): NonFreeNet
  • \n
  • pCloud Java SDK (/com/pcloud/sdk): NonFreeNet
  • \n
\n8 offender(s). Full report available here.\n
Full list of libraries detected:\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
LibraryIdTypeLicenseAntiFeatures
Android Support v4/android/support/v4Development FrameworkApache-2.0
AndroidX Activity/androidx/activityUtilityApache-2.0
Android Jetpack Annotations/androidx/annotationUtilityApache-2.0
Arch/androidx/archUtilityApache-2.0
AppCompat/androidx/appcompatUtilityApache-2.0
Biometric/androidx/biometricUtilityApache-2.0
Browser/androidx/browserUtilityApache-2.0
Cardview/androidx/cardviewUI ComponentApache-2.0
Android Support Library collections/androidx/collectionUtilityApache-2.0
Concurrent/androidx/concurrentUtilityApache-2.0
Constraint Layout Library/androidx/constraintlayoutUtilityApache-2.0
Coordinatorlayout/androidx/coordinatorlayoutUI ComponentApache-2.0
Androidx Core/androidx/coreUtilityApache-2.0
AndroidX Cursor Adapter/androidx/cursoradapterUtilityApache-2.0
Android Support Library Custom View/androidx/customviewUI ComponentApache-2.0
Documentfile/androidx/documentfileUI ComponentApache-2.0
Drawerlayout/androidx/drawerlayoutUI ComponentApache-2.0
Dynamicanimation/androidx/dynamicanimationUI ComponentApache-2.0
Android Emoji2 Compat/androidx/emoji2UI ComponentApache-2.0
Exifinterface/androidx/exifinterfaceUtilityApache-2.0
AndroidX Fragment/androidx/fragmentUI ComponentApache-2.0
Interpolator/androidx/interpolatorUI ComponentApache-2.0
androidx.legacy/androidx/legacyUtilityApache-2.0
Lifecycle/androidx/lifecycleUtilityApache-2.0
Loader/androidx/loaderUtilityApache-2.0
AndroidX Local Broadcast Manager/androidx/localbroadcastmanagerUtilityApache-2.0
Android Multi Dex Library/androidx/multidexUtilityApache-2.0
Preference/androidx/preferenceUtilityApache-2.0
Print/androidx/printUtilityApache-2.0
ResourceInspection/androidx/resourceinspectionDevelopment AidApache-2.0
Recyclerview/androidx/recyclerviewUtilityApache-2.0
Android Activity Saved State/androidx/savedstateUtilityApache-2.0
Slidingpanelayout/androidx/slidingpanelayoutUI ComponentApache-2.0
Startup/androidx/startupUtilityApache-2.0
Swiperefreshlayout/androidx/swiperefreshlayoutUI ComponentApache-2.0
AndroidX Test/androidx/testDevelopment FrameworkApache-2.0
Tracing/androidx/tracingUtilityApache-2.0
Transition/androidx/transitionUI ComponentApache-2.0
Vectordrawable/androidx/vectordrawableUI ComponentApache-2.0
Android Jetpack VersionedParcelable/androidx/versionedparcelableUtilityApache-2.0
Viewpager/androidx/viewpagerUI ComponentApache-2.0
AndroidX Widget ViewPager2/androidx/viewpager2UI ComponentApache-2.0
Jetpack WindowManager Library/androidx/windowUtilityApache-2.0
java-jwt/com/auth0/jwtUtilityMIT
Azure SDK for Java/com/azureDevelopment FrameworkMITNonFreeNet
okhttp-digest/com/burgstaller/okhttpUtilityApache-2.0
Woodstox/com/ctc/wstxUtilityApache-2.0
Subsampling Scale Image View/com/davemorrissey/labs/subscaleviewUI ComponentApache-2.0
Dropbox Core SDK for Java/com/dropbox/coreUtilityMITNonFreeNet
FasterXML Jackson/com/fasterxml/jacksonUtilityApache-2.0
Google Mobile Services/com/google/android/gmsDevelopment FrameworkProprietaryNonFreeComp
Google Material Design/com/google/android/materialUtilityApache-2.0
Google API Client Libraries/com/google/api/clientDevelopment FrameworkApache-2.0NonFreeNet
Google Drive API/com/google/api/services/driveUtilityApache-2.0NonFreeDep,NonFreeNet
Google Java API Client Services/com/google/api/servicesUtilityApache-2.0NonFreeNet
Google Core Libraries for Java 6+/com/google/commonUtilityApache-2.0
Error Prone/com/google/errorproneUtilityApache-2.0
Google Gson/com/google/gsonUtilityApache-2.0
J2ObjC/com/google/j2objcUtilityApache-2.0
RxBinding/com/jakewharton/rxbindingUtilityApache-2.0
Microsoft Azure Active Directory Authentication Library/com/microsoft/aad/adalUtilityMIT
Surface Duo SDK/com/microsoft/device/dualscreenUtilityMIT
Microsoft Graph-SDK/com/microsoft/graphDevelopment FrameworkMIT
Microsoft Authentication Library/com/microsoft/identityUtilityMITNonFreeNet
Nimbus JOSE+JWT/com/nimbusds/joseUtilityApache-2.0
zxcvbn4j/com/nulabinc/zxcvbnUtilityMIT
pCloud Java SDK/com/pcloud/sdkUtilityApache-2.0NonFreeNet
RecyclerView-FastScroll/com/simplecityapps/recyclerview_fastscrollUI ComponentApache-2.0
OkHttp/com/squareup/okhttpUtilityApache-2.0
Disk LRU Cache/com/tomclaw/cacheUtilityMIT
Wutka DTD/com/wutka/dtdDevelopment Aidnone
Yubico Mobile Android SDK/com/yubico/yubikitUtilityApache-2.0
HttpClient Android repackaged/cz/msebera/android/httpclientUtilityApache-2.0
Dagger/daggerUtilityApache-2.0
FindBugs/edu/umd/cs/findbugsUtilityLGPL-3.0-or-later
MinIO Client SDK for Java/io/minioUtilityApache-2.0
RxJava/io/reactivexUtilityApache-2.0
Jakarta Dependency Injection/jakarta/injectUtilityApache-2.0
JavaX Annotation API/javax/annotationUtilityBSD-3-Clause
JavaX Dependency Injection/javax/injectUtilityApache-2.0
Javax XML/javax/xmlUtilityGPL-2.0
Junit/junitUtilityEPL-1.0
Kotlin/kotlinUtilityApache-2.0
Kotlin Android Extensions Runtime/kotlinx/android/extensions-runtimeUtilityApache-2.0
kotlinx.coroutines/kotlinx/coroutinesUtilityApache-2.0
kotlin-parcelize/kotlinx/parcelizeUtilityApache-2.0
AppAuth for Android/net/openid/appauthUtilityApache-2.0
OkHttp okio Framework/okioUtilityApache-2.0
Apache Commons/org/apache/commonsDevelopment FrameworkApache-2.0
Apache Http/org/apache/httpUtilityApache-2.0
Bouncy Castle/org/bouncycastleUtilityMIT
Checker Framework/org/checkerframeworkUtilityGPL-2.0-only
Stax2 API/org/codehaus/stax2UtilityBSD
greenDAO/org/greenrobot/greendaoUtilityApache-2.0
Java Hamcrest/org/hamcrestUtilityBSD-3-Clause
IntelliJ IDEA/org/intellijUtilityApache-2.0
JSpecify/org/jspecifyDevelopment AidApache-2.0
jUnit Java Unit Test/org/junitUtilityEPL-2.0
Reactive Streams/org/reactivestreamsUtilityMIT
Simple/org/simpleframework/xmlUtilityLGPL-2.1-only
Simple Logging Facade for Java/org/slf4jUtilityMIT
snappy-java/org/xerial/snappyUtilityApache-2.0
Reactor Core/reactor/coreUtilityApache-2.0
Timber/timber/logUtilityApache-2.0

\n\n
\n","reportData":{"unsigned/org.cryptomator_fdroid.apk":[{"id":"/android/support/v4","name":"Android Support v4","typ":"Development Framework","anti":"","url":"https://developer.android.com/reference/android/support/v4/app/package-summary.html","license":"Apache-2.0"},{"id":"/androidx/activity","name":"AndroidX Activity","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/annotation","name":"Android Jetpack Annotations","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/annotation","license":"Apache-2.0"},{"id":"/androidx/arch","name":"Arch","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/arch","license":"Apache-2.0"},{"id":"/androidx/appcompat","name":"AppCompat","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/appcompat","license":"Apache-2.0"},{"id":"/androidx/biometric","name":"Biometric","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/biometric","license":"Apache-2.0"},{"id":"/androidx/browser","name":"Browser","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/browser","license":"Apache-2.0"},{"id":"/androidx/cardview","name":"Cardview","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/cardview/","license":"Apache-2.0"},{"id":"/androidx/collection","name":"Android Support Library collections","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/concurrent","name":"Concurrent","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/concurrent","license":"Apache-2.0"},{"id":"/androidx/constraintlayout","name":"Constraint Layout Library","typ":"Utility","anti":"","url":"https://github.com/androidx/constraintlayout","license":"Apache-2.0"},{"id":"/androidx/coordinatorlayout","name":"Coordinatorlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/coordinatorlayout","license":"Apache-2.0"},{"id":"/androidx/core","name":"Androidx Core","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/core","license":"Apache-2.0"},{"id":"/androidx/cursoradapter","name":"AndroidX Cursor Adapter","typ":"Utility","anti":"","url":"https://developer.android.com/tools/extras/support-library.html","license":"Apache-2.0"},{"id":"/androidx/customview","name":"Android Support Library Custom View","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/customview/","license":"Apache-2.0"},{"id":"/androidx/documentfile","name":"Documentfile","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/documentfile","license":"Apache-2.0"},{"id":"/androidx/drawerlayout","name":"Drawerlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/drawerlayout","license":"Apache-2.0"},{"id":"/androidx/dynamicanimation","name":"Dynamicanimation","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/dynamicanimation","license":"Apache-2.0"},{"id":"/androidx/emoji2","name":"Android Emoji2 Compat","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/emoji2/","license":"Apache-2.0"},{"id":"/androidx/exifinterface","name":"Exifinterface","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/exifinterface","license":"Apache-2.0"},{"id":"/androidx/fragment","name":"AndroidX Fragment","typ":"UI Component","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/fragment/","license":"Apache-2.0"},{"id":"/androidx/interpolator","name":"Interpolator","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/interpolator","license":"Apache-2.0"},{"id":"/androidx/legacy","name":"androidx.legacy","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/legacy","license":"Apache-2.0"},{"id":"/androidx/lifecycle","name":"Lifecycle","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/lifecycle","license":"Apache-2.0"},{"id":"/androidx/loader","name":"Loader","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/loader","license":"Apache-2.0"},{"id":"/androidx/localbroadcastmanager","name":"AndroidX Local Broadcast Manager","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-localbroadcastmanager-release/localbroadcastmanager/","license":"Apache-2.0"},{"id":"/androidx/multidex","name":"Android Multi Dex Library","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/multidex","license":"Apache-2.0"},{"id":"/androidx/preference","name":"Preference","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/preference","license":"Apache-2.0"},{"id":"/androidx/print","name":"Print","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/print","license":"Apache-2.0"},{"id":"/androidx/resourceinspection","name":"ResourceInspection","typ":"Development Aid","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/resourceinspection","license":"Apache-2.0"},{"id":"/androidx/recyclerview","name":"Recyclerview","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/recyclerview","license":"Apache-2.0"},{"id":"/androidx/savedstate","name":"Android Activity Saved State","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx","license":"Apache-2.0"},{"id":"/androidx/slidingpanelayout","name":"Slidingpanelayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/slidingpanelayout","license":"Apache-2.0"},{"id":"/androidx/startup","name":"Startup","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/startup","license":"Apache-2.0"},{"id":"/androidx/swiperefreshlayout","name":"Swiperefreshlayout","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/swiperefreshlayout","license":"Apache-2.0"},{"id":"/androidx/test","name":"AndroidX Test","typ":"Development Framework","anti":"","url":"https://github.com/android/android-test","license":"Apache-2.0"},{"id":"/androidx/tracing","name":"Tracing","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/tracing","license":"Apache-2.0"},{"id":"/androidx/transition","name":"Transition","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/transition","license":"Apache-2.0"},{"id":"/androidx/vectordrawable","name":"Vectordrawable","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/vectordrawable","license":"Apache-2.0"},{"id":"/androidx/versionedparcelable","name":"Android Jetpack VersionedParcelable","typ":"Utility","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/versionedparcelable","license":"Apache-2.0"},{"id":"/androidx/viewpager","name":"Viewpager","typ":"UI Component","anti":"","url":"https://developer.android.com/jetpack/androidx/releases/viewpager","license":"Apache-2.0"},{"id":"/androidx/viewpager2","name":"AndroidX Widget ViewPager2","typ":"UI Component","anti":"","url":"https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2","license":"Apache-2.0"},{"id":"/androidx/window","name":"Jetpack WindowManager Library","typ":"Utility","anti":"","url":"https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/window/","license":"Apache-2.0"},{"id":"/com/auth0/jwt","name":"java-jwt","typ":"Utility","anti":"","url":"https://github.com/auth0/java-jwt","license":"MIT"},{"id":"/com/azure","name":"Azure SDK for Java","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/Azure/azure-sdk-for-java","license":"MIT"},{"id":"/com/burgstaller/okhttp","name":"okhttp-digest","typ":"Utility","anti":"","url":"https://github.com/rburgst/okhttp-digest","license":"Apache-2.0"},{"id":"/com/ctc/wstx","name":"Woodstox","typ":"Utility","anti":"","url":"https://github.com/FasterXML/woodstox","license":"Apache-2.0"},{"id":"/com/davemorrissey/labs/subscaleview","name":"Subsampling Scale Image View","typ":"UI Component","anti":"","url":"https://github.com/davemorrissey/subsampling-scale-image-view","license":"Apache-2.0"},{"id":"/com/dropbox/core","name":"Dropbox Core SDK for Java","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/dropbox/dropbox-sdk-java","license":"MIT"},{"id":"/com/fasterxml/jackson","name":"FasterXML Jackson","typ":"Utility","anti":"","url":"https://github.com/FasterXML/jackson-core","license":"Apache-2.0"},{"id":"/com/google/android/gms","name":"Google Mobile Services","typ":"Development Framework","anti":"NonFreeComp","url":"https://developers.google.com/android/reference/com/google/android/gms/package-summary","license":"Proprietary"},{"id":"/com/google/android/material","name":"Google Material Design","typ":"Utility","anti":"","url":"https://github.com/material-components/material-components-android","license":"Apache-2.0"},{"id":"/com/google/api/client","name":"Google API Client Libraries","typ":"Development Framework","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client","license":"Apache-2.0"},{"id":"/com/google/api/services/drive","name":"Google Drive API","typ":"Utility","anti":"NonFreeDep,NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services/tree/main/clients/google-api-services-drive","license":"Apache-2.0"},{"id":"/com/google/api/services","name":"Google Java API Client Services","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/googleapis/google-api-java-client-services","license":"Apache-2.0"},{"id":"/com/google/common","name":"Google Core Libraries for Java 6+","typ":"Utility","anti":"","url":"https://github.com/google/guava","license":"Apache-2.0"},{"id":"/com/google/errorprone","name":"Error Prone","typ":"Utility","anti":"","url":"https://github.com/google/error-prone","license":"Apache-2.0"},{"id":"/com/google/gson","name":"Google Gson","typ":"Utility","anti":"","url":"https://github.com/google/gson","license":"Apache-2.0"},{"id":"/com/google/j2objc","name":"J2ObjC","typ":"Utility","anti":"","url":"https://github.com/google/j2objc","license":"Apache-2.0"},{"id":"/com/jakewharton/rxbinding","name":"RxBinding","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/RxBinding","license":"Apache-2.0"},{"id":"/com/microsoft/aad/adal","name":"Microsoft Azure Active Directory Authentication Library","typ":"Utility","anti":"","url":"https://github.com/AzureAD/azure-activedirectory-library-for-android","license":"MIT"},{"id":"/com/microsoft/device/dualscreen","name":"Surface Duo SDK","typ":"Utility","anti":"","url":"https://github.com/microsoft/surface-duo-sdk","license":"MIT"},{"id":"/com/microsoft/graph","name":"Microsoft Graph-SDK","typ":"Development Framework","anti":"","url":"https://github.com/microsoftgraph/msgraph-sdk-java","license":"MIT"},{"id":"/com/microsoft/identity","name":"Microsoft Authentication Library","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/AzureAD/microsoft-authentication-library-for-android","license":"MIT"},{"id":"/com/nimbusds/jose","name":"Nimbus JOSE+JWT","typ":"Utility","anti":"","url":"https://github.com/gesellix/Nimbus-JOSE-JWT","license":"Apache-2.0"},{"id":"/com/nulabinc/zxcvbn","name":"zxcvbn4j","typ":"Utility","anti":"","url":"https://github.com/nulab/zxcvbn4j","license":"MIT"},{"id":"/com/pcloud/sdk","name":"pCloud Java SDK","typ":"Utility","anti":"NonFreeNet","url":"https://github.com/pCloud/pcloud-sdk-java","license":"Apache-2.0"},{"id":"/com/simplecityapps/recyclerview_fastscroll","name":"RecyclerView-FastScroll","typ":"UI Component","anti":"","url":"https://github.com/timusus/RecyclerView-FastScroll","license":"Apache-2.0"},{"id":"/com/squareup/okhttp","name":"OkHttp","typ":"Utility","anti":"","url":"https://github.com/square/okhttp","license":"Apache-2.0"},{"id":"/com/tomclaw/cache","name":"Disk LRU Cache","typ":"Utility","anti":"","url":"https://github.com/solkin/disk-lru-cache","license":"MIT"},{"id":"/com/wutka/dtd","name":"Wutka DTD","typ":"Development Aid","anti":"","url":"https://mvnrepository.com/artifact/com.liferay/com.wutka.dtd","license":""},{"id":"/com/yubico/yubikit","name":"Yubico Mobile Android SDK","typ":"Utility","anti":"","url":"https://github.com/Yubico/yubikit-android","license":"Apache-2.0"},{"id":"/cz/msebera/android/httpclient","name":"HttpClient Android repackaged","typ":"Utility","anti":"","url":"https://github.com/smarek/httpclient-android","license":"Apache-2.0"},{"id":"/dagger","name":"Dagger","typ":"Utility","anti":"","url":"https://github.com/google/dagger","license":"Apache-2.0"},{"id":"/edu/umd/cs/findbugs","name":"FindBugs","typ":"Utility","anti":"","url":"http://findbugs.sourceforge.net/","license":"LGPL-3.0-or-later"},{"id":"/io/minio","name":"MinIO Client SDK for Java","typ":"Utility","anti":"","url":"https://github.com/minio/minio-java","license":"Apache-2.0"},{"id":"/io/reactivex","name":"RxJava","typ":"Utility","anti":"","url":"https://github.com/ReactiveX/RxJava","license":"Apache-2.0"},{"id":"/jakarta/inject","name":"Jakarta Dependency Injection","typ":"Utility","anti":"","url":"https://github.com/jakartaee/inject","license":"Apache-2.0"},{"id":"/javax/annotation","name":"JavaX Annotation API","typ":"Utility","anti":"","url":"https://github.com/amaembo/jsr-305/tree/master/ri","license":"BSD-3-Clause"},{"id":"/javax/inject","name":"JavaX Dependency Injection","typ":"Utility","anti":"","url":"https://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html","license":"Apache-2.0"},{"id":"/javax/xml","name":"Javax XML","typ":"Utility","anti":"","url":"https://docs.oracle.com/en/java/javase/17/docs/api/java.xml/javax/xml/package-summary.html","license":"GPL-2.0"},{"id":"/junit","name":"Junit","typ":"Utility","anti":"","url":"https://junit.org/junit4/","license":"EPL-1.0"},{"id":"/kotlin","name":"Kotlin","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin","license":"Apache-2.0"},{"id":"/kotlinx/android/extensions-runtime","name":"Kotlin Android Extensions Runtime","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/master/plugins/android-extensions/android-extensions-runtime","license":"Apache-2.0"},{"id":"/kotlinx/coroutines","name":"kotlinx.coroutines","typ":"Utility","anti":"","url":"https://github.com/Kotlin/kotlinx.coroutines","license":"Apache-2.0"},{"id":"/kotlinx/parcelize","name":"kotlin-parcelize","typ":"Utility","anti":"","url":"https://github.com/JetBrains/kotlin/tree/cdbfa7fbbc6f31dbcb6264f456bfedee1a85c40b/plugins/parcelize","license":"Apache-2.0"},{"id":"/net/openid/appauth","name":"AppAuth for Android","typ":"Utility","anti":"","url":"https://github.com/openid/AppAuth-Android","license":"Apache-2.0"},{"id":"/okio","name":"OkHttp okio Framework","typ":"Utility","anti":"","url":"https://github.com/square/okio","license":"Apache-2.0"},{"id":"/org/apache/commons","name":"Apache Commons","typ":"Development Framework","anti":"","url":"https://commons.apache.org/","license":"Apache-2.0"},{"id":"/org/apache/http","name":"Apache Http","typ":"Utility","anti":"","url":"https://hc.apache.org/","license":"Apache-2.0"},{"id":"/org/bouncycastle","name":"Bouncy Castle","typ":"Utility","anti":"","url":"http://www.bouncycastle.org/java.html","license":"MIT"},{"id":"/org/checkerframework","name":"Checker Framework","typ":"Utility","anti":"","url":"https://checkerframework.org/","license":"GPL-2.0-only"},{"id":"/org/codehaus/stax2","name":"Stax2 API","typ":"Utility","anti":"","url":"https://github.com/FasterXML/stax2-api","license":"BSD"},{"id":"/org/greenrobot/greendao","name":"greenDAO","typ":"Utility","anti":"","url":"https://github.com/greenrobot/greenDAO","license":"Apache-2.0"},{"id":"/org/hamcrest","name":"Java Hamcrest","typ":"Utility","anti":"","url":"https://github.com/hamcrest/JavaHamcrest","license":"BSD-3-Clause"},{"id":"/org/intellij","name":"IntelliJ IDEA","typ":"Utility","anti":"","url":"https://github.com/JetBrains/intellij-community","license":"Apache-2.0"},{"id":"/org/jspecify","name":"JSpecify","typ":"Development Aid","anti":"","url":"https://github.com/jspecify/jspecify","license":"Apache-2.0"},{"id":"/org/junit","name":"jUnit Java Unit Test","typ":"Utility","anti":"","url":"http://junit.org/","license":"EPL-2.0"},{"id":"/org/reactivestreams","name":"Reactive Streams","typ":"Utility","anti":"","url":"http://www.reactive-streams.org/","license":"MIT"},{"id":"/org/simpleframework/xml","name":"Simple","typ":"Utility","anti":"","url":"https://sourceforge.net/projects/simple/","license":"LGPL-2.1-only"},{"id":"/org/slf4j","name":"Simple Logging Facade for Java","typ":"Utility","anti":"","url":"https://www.slf4j.org/","license":"MIT"},{"id":"/org/xerial/snappy","name":"snappy-java","typ":"Utility","anti":"","url":"https://github.com/xerial/snappy-java","license":"Apache-2.0"},{"id":"/reactor/core","name":"Reactor Core","typ":"Utility","anti":"","url":"https://github.com/reactor/reactor-core","license":"Apache-2.0"},{"id":"/timber/log","name":"Timber","typ":"Utility","anti":"","url":"https://github.com/JakeWharton/timber","license":"Apache-2.0"}],"log":["Fetching library definitions from https://gitlab.com/IzzyOnDroid/repo/-/raw/master/lib","Loaded 3938 library definitions","Analyzing 'unsigned/org.cryptomator_fdroid.apk'...","Apktool returned: 0","Read 95638 bytes of smali path names from 'org.cryptomator_fdroid.dirlist'","Identified 104 libraries, 8 offenders.","Done analyzing 'unsigned/org.cryptomator_fdroid.apk'"],"self_url":"/artifacts/public/issuebot///iod-scan-apk.php.json"}} \ No newline at end of file diff --git a/fastlane/release-notes-de.txt b/fastlane/release-notes-de.txt index be2ad06ed..926c5be64 100644 --- a/fastlane/release-notes-de.txt +++ b/fastlane/release-notes-de.txt @@ -1 +1 @@ -- Migration von Cloud-Zugangs-Tokens und Tresor-Passwörtern zu AES 256bit GCM +- Hub-Unterstützung hinzugefügt diff --git a/fastlane/release-notes-en.txt b/fastlane/release-notes-en.txt index 837a30de8..d72028770 100644 --- a/fastlane/release-notes-en.txt +++ b/fastlane/release-notes-en.txt @@ -1 +1 @@ -- Migrate cloud access tokens and vault passwords to AES 256bit GCM +- Add Hub support diff --git a/fastlane/release-notes.html b/fastlane/release-notes.html index 3f02b0171..96a0c891a 100644 --- a/fastlane/release-notes.html +++ b/fastlane/release-notes.html @@ -1,3 +1,3 @@
    -
  • Migrate cloud access tokens and vault passwords to AES 256bit GCM
  • +
  • Add Hub support
diff --git a/presentation/build.gradle b/presentation/build.gradle index 39e5fcf06..fa4ccded7 100644 --- a/presentation/build.gradle +++ b/presentation/build.gradle @@ -48,6 +48,10 @@ android { viewBinding true } + defaultConfig.manifestPlaceholders = [ + 'appAuthRedirectScheme': 'org.cryptomator.android' + ] + buildTypes { release { crunchPngs false @@ -122,7 +126,7 @@ android { packagingOptions { resources { - excludes += ['META-INF/jersey-module-version', 'META-INF/NOTICE.md', 'META-INF/DEPENDENCIES', 'META-INF/INDEX.LIST'] + excludes += ['META-INF/jersey-module-version', 'META-INF/NOTICE.md', 'META-INF/DEPENDENCIES', 'META-INF/INDEX.LIST', 'META-INF/**/MANIFEST.MF'] } } @@ -171,6 +175,8 @@ dependencies { implementation dependencies.androidxPreference implementation dependencies.androidxBiometric + implementation dependencies.appauth + // cloud playstoreImplementation dependencies.dropboxCore playstoreImplementation dependencies.dropboxAndroid diff --git a/presentation/src/main/java/org/cryptomator/presentation/di/component/ApplicationComponent.java b/presentation/src/main/java/org/cryptomator/presentation/di/component/ApplicationComponent.java index 19b3c96c9..ca0232028 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/di/component/ApplicationComponent.java +++ b/presentation/src/main/java/org/cryptomator/presentation/di/component/ApplicationComponent.java @@ -9,6 +9,7 @@ import org.cryptomator.domain.executor.ThreadExecutor; import org.cryptomator.domain.repository.CloudContentRepository; import org.cryptomator.domain.repository.CloudRepository; +import org.cryptomator.domain.repository.HubRepository; import org.cryptomator.domain.repository.UpdateCheckRepository; import org.cryptomator.domain.repository.VaultRepository; import org.cryptomator.presentation.di.module.ApplicationModule; @@ -36,6 +37,8 @@ public interface ApplicationComponent { CloudRepository cloudRepository(); + HubRepository hubRepository(); + UpdateCheckRepository updateCheckRepository(); FileUtil fileUtil(); diff --git a/presentation/src/main/java/org/cryptomator/presentation/exception/ExceptionHandlers.kt b/presentation/src/main/java/org/cryptomator/presentation/exception/ExceptionHandlers.kt index a6d26333f..f71a4ca2c 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/exception/ExceptionHandlers.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/exception/ExceptionHandlers.kt @@ -12,11 +12,17 @@ import org.cryptomator.domain.exception.NoSuchCloudFileException import org.cryptomator.domain.exception.UnableToDecryptWebdavPasswordException import org.cryptomator.domain.exception.VaultAlreadyExistException import org.cryptomator.domain.exception.authentication.AuthenticationException +import org.cryptomator.domain.exception.hub.HubAuthenticationFailedException +import org.cryptomator.domain.exception.hub.HubDeviceAlreadyRegisteredForOtherUserException +import org.cryptomator.domain.exception.hub.HubInvalidSetupCodeException +import org.cryptomator.domain.exception.hub.HubInvalidVersionException +import org.cryptomator.domain.exception.hub.HubVaultOperationNotSupportedException import org.cryptomator.domain.exception.license.DesktopSupporterCertificateException import org.cryptomator.domain.exception.license.LicenseNotValidException import org.cryptomator.domain.exception.license.NoLicenseAvailableException import org.cryptomator.domain.exception.update.GeneralUpdateErrorException import org.cryptomator.domain.exception.update.HashMismatchUpdateCheckException +import org.cryptomator.domain.exception.vaultconfig.HubNotSupportedOnPreAndroid31Exception import org.cryptomator.domain.exception.vaultconfig.MissingVaultConfigFileException import org.cryptomator.domain.exception.vaultconfig.UnsupportedMasterkeyLocationException import org.cryptomator.domain.exception.vaultconfig.VaultConfigLoadException @@ -50,6 +56,7 @@ class ExceptionHandlers @Inject constructor(private val context: Context, defaul staticHandler(LicenseNotValidException::class.java, R.string.dialog_enter_license_not_valid_content) staticHandler(NoLicenseAvailableException::class.java, R.string.dialog_enter_license_no_content) staticHandler(HashMismatchUpdateCheckException::class.java, R.string.error_hash_mismatch_update) + staticHandler(HubNotSupportedOnPreAndroid31Exception::class.java, R.string.error_hub_unlock_pre_31) staticHandler(GeneralUpdateErrorException::class.java, R.string.error_general_update) staticHandler( MissingVaultConfigFileException::class.java, String.format( @@ -74,6 +81,11 @@ class ExceptionHandlers @Inject constructor(private val context: Context, defaul staticHandler(VaultConfigLoadException::class.java, R.string.error_vault_config_loading) staticHandler(UnsupportedMasterkeyLocationException::class.java, R.string.error_masterkey_location_not_supported) staticHandler(NoSuchBucketException::class.java, R.string.error_no_such_bucket) + staticHandler(HubVaultOperationNotSupportedException::class.java, R.string.error_hub_vault_operation_not_supported) + staticHandler(HubAuthenticationFailedException::class.java, R.string.error_hub_authentication_failed) + staticHandler(HubDeviceAlreadyRegisteredForOtherUserException::class.java, R.string.error_hub_device_already_register_for_other_user) + staticHandler(HubInvalidSetupCodeException::class.java, R.string.error_hub_invalid_setup_code) + staticHandler(HubInvalidVersionException::class.java, R.string.error_hub_invalid_version) exceptionHandlers.add(MissingCryptorExceptionHandler()) exceptionHandlers.add(CancellationExceptionHandler()) exceptionHandlers.add(NoSuchVaultExceptionHandler()) diff --git a/presentation/src/main/java/org/cryptomator/presentation/model/ProgressStateModel.kt b/presentation/src/main/java/org/cryptomator/presentation/model/ProgressStateModel.kt index 93acd60ca..d11d0b1fc 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/model/ProgressStateModel.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/model/ProgressStateModel.kt @@ -47,6 +47,7 @@ open class ProgressStateModel private constructor(private val name: String, imag val UNLOCKING_VAULT = ProgressStateModel("VAULT", text(R.string.dialog_progress_unlocking_vault)) val CHANGING_PASSWORD = ProgressStateModel("PASSWORD", text(R.string.dialog_progress_change_password)) val CREATING_VAULT = ProgressStateModel("VAULT", text(R.string.dialog_progress_creating_vault)) + val CREATING_HUB_DEVICE = ProgressStateModel("HUB_DEVICE", text(R.string.dialog_progress_creating_hub_device_setup)) val UNKNOWN = ProgressStateModel("UNKNOWN_MIMETYPE", text(R.string.dialog_progress_please_wait)) val COMPLETED = ProgressStateModel("COMPLETED") diff --git a/presentation/src/main/java/org/cryptomator/presentation/presenter/UnlockVaultPresenter.kt b/presentation/src/main/java/org/cryptomator/presentation/presenter/UnlockVaultPresenter.kt index 3d57504c4..6b729c46c 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/presenter/UnlockVaultPresenter.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/presenter/UnlockVaultPresenter.kt @@ -1,22 +1,41 @@ package org.cryptomator.presentation.presenter +import android.content.Intent +import android.net.Uri import android.os.Handler import androidx.biometric.BiometricManager import com.google.common.base.Optional +import net.openid.appauth.AuthorizationException +import net.openid.appauth.AuthorizationRequest +import net.openid.appauth.AuthorizationResponse +import net.openid.appauth.AuthorizationService +import net.openid.appauth.AuthorizationServiceConfiguration +import net.openid.appauth.ResponseTypeValues import org.cryptomator.data.cloud.crypto.CryptoConstants import org.cryptomator.domain.Cloud +import org.cryptomator.domain.KeyLoadingStrategy +import org.cryptomator.domain.UnverifiedHubVaultConfig import org.cryptomator.domain.UnverifiedVaultConfig import org.cryptomator.domain.Vault import org.cryptomator.domain.di.PerView import org.cryptomator.domain.exception.NetworkConnectionException import org.cryptomator.domain.exception.authentication.AuthenticationException +import org.cryptomator.domain.exception.hub.HubAuthenticationFailedException +import org.cryptomator.domain.exception.hub.HubDeviceSetupRequiredException +import org.cryptomator.domain.exception.hub.HubLicenseUpgradeRequiredException +import org.cryptomator.domain.exception.hub.HubUserSetupRequiredException +import org.cryptomator.domain.exception.hub.HubVaultAccessForbiddenException +import org.cryptomator.domain.exception.hub.HubVaultIsArchivedException +import org.cryptomator.domain.exception.hub.HubVaultOperationNotSupportedException import org.cryptomator.domain.usecases.vault.ChangePasswordUseCase +import org.cryptomator.domain.usecases.vault.CreateHubDeviceUseCase import org.cryptomator.domain.usecases.vault.DeleteVaultUseCase import org.cryptomator.domain.usecases.vault.GetUnverifiedVaultConfigUseCase import org.cryptomator.domain.usecases.vault.LockVaultUseCase import org.cryptomator.domain.usecases.vault.PrepareUnlockUseCase import org.cryptomator.domain.usecases.vault.RemoveStoredVaultPasswordsAndDisableBiometricAuthUseCase import org.cryptomator.domain.usecases.vault.SaveVaultUseCase +import org.cryptomator.domain.usecases.vault.UnlockHubVaultUseCase import org.cryptomator.domain.usecases.vault.UnlockToken import org.cryptomator.domain.usecases.vault.UnlockVaultUsingMasterkeyUseCase import org.cryptomator.domain.usecases.vault.VaultOrUnlockToken @@ -47,6 +66,8 @@ class UnlockVaultPresenter @Inject constructor( private val lockVaultUseCase: LockVaultUseCase, private val unlockVaultUsingMasterkeyUseCase: UnlockVaultUsingMasterkeyUseCase, private val prepareUnlockUseCase: PrepareUnlockUseCase, + private val unlockHubVaultUseCase: UnlockHubVaultUseCase, + private val createHubDeviceUseCase: CreateHubDeviceUseCase, private val removeStoredVaultPasswordsAndDisableBiometricAuthUseCase: RemoveStoredVaultPasswordsAndDisableBiometricAuthUseCase, private val saveVaultUseCase: SaveVaultUseCase, private val authenticationExceptionHandler: AuthenticationExceptionHandler, @@ -57,6 +78,7 @@ class UnlockVaultPresenter @Inject constructor( private var startedUsingPrepareUnlock = false private var retryUnlockHandler: Handler? = null private var pendingUnlock: PendingUnlock? = null + private var hubAuthService: AuthorizationService? = null @InjectIntent lateinit var intent: UnlockVaultIntent @@ -70,6 +92,7 @@ class UnlockVaultPresenter @Inject constructor( running = false retryUnlockHandler?.removeCallbacksAndMessages(null) } + hubAuthService?.dispose() } fun setup() { @@ -83,7 +106,7 @@ class UnlockVaultPresenter @Inject constructor( .withVault(vault) .run(object : DefaultResultHandler>() { override fun onSuccess(unverifiedVaultConfig: Optional) { - onUnverifiedVaultConfigRetrieved(unverifiedVaultConfig) + onUnverifiedVaultConfigRetrieved(unverifiedVaultConfig, vault) } override fun onError(e: Throwable) { @@ -103,7 +126,7 @@ class UnlockVaultPresenter @Inject constructor( .withVault(Vault.aCopyOf(vault).withCloud(cloud).build()) .run(object : DefaultResultHandler>() { override fun onSuccess(unverifiedVaultConfig: Optional) { - onUnverifiedVaultConfigRetrieved(unverifiedVaultConfig) + onUnverifiedVaultConfigRetrieved(unverifiedVaultConfig, vault) } override fun onError(e: Throwable) { @@ -119,8 +142,8 @@ class UnlockVaultPresenter @Inject constructor( } } - private fun onUnverifiedVaultConfigRetrieved(unverifiedVaultConfig: Optional) { - if (!unverifiedVaultConfig.isPresent || unverifiedVaultConfig.get().keyId.scheme == CryptoConstants.MASTERKEY_SCHEME) { + private fun onUnverifiedVaultConfigRetrieved(unverifiedVaultConfig: Optional, vault: Vault) { + if (!unverifiedVaultConfig.isPresent || unverifiedVaultConfig.get().keyLoadingStrategy() == KeyLoadingStrategy.MASTERKEY) { when (intent.vaultAction()) { UnlockVaultIntent.VaultAction.UNLOCK, UnlockVaultIntent.VaultAction.UNLOCK_FOR_BIOMETRIC_AUTH -> { startedUsingPrepareUnlock = sharedPreferencesHandler.backgroundUnlockPreparation() @@ -130,6 +153,121 @@ class UnlockVaultPresenter @Inject constructor( UnlockVaultIntent.VaultAction.CHANGE_PASSWORD -> view?.showChangePasswordDialog(intent.vaultModel(), unverifiedVaultConfig.orNull()) else -> {} } + } else if (unverifiedVaultConfig.isPresent && unverifiedVaultConfig.get().keyLoadingStrategy() == KeyLoadingStrategy.HUB) { + when (intent.vaultAction()) { + UnlockVaultIntent.VaultAction.UNLOCK -> { + val unverifiedHubVaultConfig = unverifiedVaultConfig.get() as UnverifiedHubVaultConfig + if (hubAuthService == null) { + hubAuthService = AuthorizationService(context()) + } + view?.showProgress(ProgressModel.GENERIC) + unlockHubVault(unverifiedHubVaultConfig, vault) + } + UnlockVaultIntent.VaultAction.UNLOCK_FOR_BIOMETRIC_AUTH -> showErrorAndFinish(HubVaultOperationNotSupportedException()) + UnlockVaultIntent.VaultAction.CHANGE_PASSWORD -> showErrorAndFinish(HubVaultOperationNotSupportedException()) + UnlockVaultIntent.VaultAction.ENCRYPT_PASSWORD -> showErrorAndFinish(HubVaultOperationNotSupportedException()) + } + } + } + + private fun showErrorAndFinish(e: Throwable) { + showError(e) + finishWithResult(null) + } + + private fun unlockHubVault(unverifiedVaultConfig: UnverifiedHubVaultConfig, vault: Vault) { + val authIntent = buildHubAuthIntent(unverifiedVaultConfig) + requestActivityResult(ActivityResultCallbacks.hubAuthenticationUnlock(vault, unverifiedVaultConfig), authIntent) + } + + private fun buildHubAuthIntent(unverifiedVaultConfig: UnverifiedHubVaultConfig): Intent? { + val serviceConfig = AuthorizationServiceConfiguration(Uri.parse(unverifiedVaultConfig.authEndpoint.toString()), Uri.parse(unverifiedVaultConfig.tokenEndpoint.toString())) + val authRequestBuilder = AuthorizationRequest.Builder( + serviceConfig, + unverifiedVaultConfig.clientId, + ResponseTypeValues.CODE, + Uri.parse(CryptoConstants.HUB_REDIRECT_URL) + ) + return hubAuthService?.getAuthorizationRequestIntent(authRequestBuilder.build()) + } + + @Callback(dispatchResultOkOnly = false) + fun hubAuthenticationUnlock(result: ActivityResult, vault: Vault, unverifiedHubVaultConfig: UnverifiedHubVaultConfig) { + if (result.isResultOk) { + val resp = AuthorizationResponse.fromIntent(result.intent()) + if (resp != null) { + hubAuthService?.performTokenRequest(resp.createTokenExchangeRequest()) { token, ex -> + token?.accessToken?.let { + unlockHubVault(vault, unverifiedHubVaultConfig, it) + } ?: showErrorAndFinish(HubAuthenticationFailedException(ex)) + } + } else { + val ex = AuthorizationException.fromIntent(result.intent()) + showErrorAndFinish(HubAuthenticationFailedException(ex)) + } + } else { + showErrorAndFinish(HubAuthenticationFailedException()) + } + } + + private fun unlockHubVault(vault: Vault, unverifiedHubVaultConfig: UnverifiedHubVaultConfig, accessToken: String) { + unlockHubVaultUseCase + .withVault(vault) + .andUnverifiedVaultConfig(unverifiedHubVaultConfig) + .andAccessToken(accessToken) + .run(object : DefaultResultHandler() { + override fun onSuccess(cloud: Cloud) { + finishWithResult(cloud) + } + + override fun onError(e: Throwable) { + when (e) { + is HubDeviceSetupRequiredException -> view?.showCreateHubDeviceDialog(VaultModel(vault), unverifiedHubVaultConfig) + is HubUserSetupRequiredException -> view?.showHubUserSetupRequiredDialog(unverifiedHubVaultConfig) + is HubLicenseUpgradeRequiredException -> view?.showHubLicenseUpgradeRequiredDialog() + is HubVaultAccessForbiddenException -> view?.showHubVaultAccessForbiddenDialog() + is HubVaultIsArchivedException -> view?.showHubVaultIsArchivedDialog() + else -> { + super.onError(e) + finishWithResult(null) + } + } + } + }) + } + + fun onCreateHubDeviceClick(vaultModel: VaultModel, unverifiedVaultConfig: UnverifiedHubVaultConfig, deviceName: String, setupCode: String) { + view?.showProgress(ProgressModel.GENERIC) + val authIntent = buildHubAuthIntent(unverifiedVaultConfig) + requestActivityResult(ActivityResultCallbacks.hubAuthenticationCreateDevice(vaultModel, unverifiedVaultConfig, deviceName, setupCode), authIntent) + } + + @Callback(dispatchResultOkOnly = false) + fun hubAuthenticationCreateDevice(result: ActivityResult, vault: VaultModel, unverifiedHubVaultConfig: UnverifiedHubVaultConfig, deviceName: String, setupCode: String) { + if (result.isResultOk) { + val resp = AuthorizationResponse.fromIntent(result.intent()) + if (resp != null) { + hubAuthService?.performTokenRequest(resp.createTokenExchangeRequest()) { token, ex -> + token?.accessToken?.let { + createHubDeviceUseCase + .withAccessToken(it) + .andUnverifiedVaultConfig(unverifiedHubVaultConfig) + .andDeviceName(deviceName) + .andSetupCode(setupCode) + .run(object : DefaultResultHandler() { + override fun onSuccess(void: Void?) { + view?.showProgress(ProgressModel.COMPLETED) + unlockHubVault(unverifiedHubVaultConfig, vault.toVault()) + } + }) + } ?: showErrorAndFinish(HubAuthenticationFailedException(ex)) + } + } else { + val ex = AuthorizationException.fromIntent(result.intent()) + showErrorAndFinish(HubAuthenticationFailedException(ex)) + } + } else { + showErrorAndFinish(HubAuthenticationFailedException()) } } @@ -375,11 +513,18 @@ class UnlockVaultPresenter @Inject constructor( }) } - @Callback + @Callback(dispatchResultOkOnly = false) fun changePasswordAfterAuthentication(result: ActivityResult, vault: Vault, unverifiedVaultConfig: UnverifiedVaultConfig, oldPassword: String, newPassword: String) { - val cloud = result.getSingleResult(CloudModel::class.java).toCloud() - val vaultWithUpdatedCloud = Vault.aCopyOf(vault).withCloud(cloud).build() - onChangePasswordClick(VaultModel(vaultWithUpdatedCloud), unverifiedVaultConfig, oldPassword, newPassword) + if(result.isResultOk) { + val cloud = result.getSingleResult(CloudModel::class.java).toCloud() + val vaultWithUpdatedCloud = Vault.aCopyOf(vault).withCloud(cloud).build() + onChangePasswordClick(VaultModel(vaultWithUpdatedCloud), unverifiedVaultConfig, oldPassword, newPassword) + } else { + view?.closeDialog() + val error = result.getSingleResult(Throwable::class.java) + error?.let { showError(it) } + finishWithResult(null) + } } fun saveVaultAfterChangePasswordButFailedBiometricAuth(vault: Vault) { @@ -411,6 +556,17 @@ class UnlockVaultPresenter @Inject constructor( finishWithResult(null) } + fun onGoToHubProfileClicked(unverifiedVaultConfig: UnverifiedHubVaultConfig) { + val intent = Intent(Intent.ACTION_VIEW) + intent.data = Uri.parse(unverifiedVaultConfig.apiBaseUrl.resolve("../app/profile").toString()) + requestActivityResult(ActivityResultCallbacks.onGoToHubProfileFinished(), intent) + } + + @Callback(dispatchResultOkOnly = false) + fun onGoToHubProfileFinished(result: ActivityResult) { + finishWithResult(null) + } + private open class PendingUnlock(private val vault: Vault?) : Serializable { private var unlockToken: UnlockToken? = null @@ -458,7 +614,9 @@ class UnlockVaultPresenter @Inject constructor( getUnverifiedVaultConfigUseCase, // lockVaultUseCase, // unlockVaultUsingMasterkeyUseCase, // + unlockHubVaultUseCase, // prepareUnlockUseCase, // + createHubDeviceUseCase, // removeStoredVaultPasswordsAndDisableBiometricAuthUseCase, // saveVaultUseCase ) diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/UnlockVaultActivity.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/UnlockVaultActivity.kt index 8014d7c87..ed72ddc53 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/UnlockVaultActivity.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/UnlockVaultActivity.kt @@ -2,6 +2,7 @@ package org.cryptomator.presentation.ui.activity import android.os.Build import androidx.annotation.RequiresApi +import org.cryptomator.domain.UnverifiedHubVaultConfig import org.cryptomator.domain.UnverifiedVaultConfig import org.cryptomator.domain.Vault import org.cryptomator.generator.Activity @@ -14,7 +15,12 @@ import org.cryptomator.presentation.presenter.UnlockVaultPresenter import org.cryptomator.presentation.ui.activity.view.UnlockVaultView import org.cryptomator.presentation.ui.dialog.BiometricAuthKeyInvalidatedDialog import org.cryptomator.presentation.ui.dialog.ChangePasswordDialog +import org.cryptomator.presentation.ui.dialog.CreateHubDeviceDialog import org.cryptomator.presentation.ui.dialog.EnterPasswordDialog +import org.cryptomator.presentation.ui.dialog.HubLicenseUpgradeRequiredDialog +import org.cryptomator.presentation.ui.dialog.HubUserSetupRequiredDialog +import org.cryptomator.presentation.ui.dialog.HubVaultAccessForbiddenDialog +import org.cryptomator.presentation.ui.dialog.HubVaultArchivedDialog import org.cryptomator.presentation.ui.dialog.VaultNotFoundDialog import org.cryptomator.presentation.ui.fragment.UnlockVaultFragment import org.cryptomator.presentation.util.BiometricAuthentication @@ -23,9 +29,16 @@ import javax.inject.Inject @Activity class UnlockVaultActivity : BaseActivity(ActivityUnlockVaultBinding::inflate), // UnlockVaultView, // + EnterPasswordDialog.Callback, // BiometricAuthentication.Callback, // + BiometricAuthKeyInvalidatedDialog.Callback, // ChangePasswordDialog.Callback, // - VaultNotFoundDialog.Callback { + VaultNotFoundDialog.Callback, // + CreateHubDeviceDialog.Callback, // + HubUserSetupRequiredDialog.Callback, // + HubVaultArchivedDialog.Callback, // + HubLicenseUpgradeRequiredDialog.Callback, // + HubVaultAccessForbiddenDialog.Callback { @Inject lateinit var presenter: UnlockVaultPresenter @@ -107,6 +120,26 @@ class UnlockVaultActivity : BaseActivity(ActivityUnl showDialog(ChangePasswordDialog.newInstance(vaultModel, unverifiedVaultConfig)) } + override fun showCreateHubDeviceDialog(vaultModel: VaultModel, unverifiedVaultConfig: UnverifiedHubVaultConfig) { + showDialog(CreateHubDeviceDialog.newInstance(vaultModel, unverifiedVaultConfig)) + } + + override fun showHubUserSetupRequiredDialog(unverifiedHubVaultConfig: UnverifiedHubVaultConfig) { + showDialog(HubUserSetupRequiredDialog.newInstance(unverifiedHubVaultConfig)) + } + + override fun showHubLicenseUpgradeRequiredDialog() { + showDialog(HubLicenseUpgradeRequiredDialog.newInstance()) + } + + override fun showHubVaultAccessForbiddenDialog() { + showDialog(HubVaultAccessForbiddenDialog.newInstance()) + } + + override fun showHubVaultIsArchivedDialog() { + showDialog(HubVaultArchivedDialog.newInstance()) + } + override fun onChangePasswordClick(vaultModel: VaultModel, unverifiedVaultConfig: UnverifiedVaultConfig?, oldPassword: String, newPassword: String) { presenter.onChangePasswordClick(vaultModel, unverifiedVaultConfig, oldPassword, newPassword) } @@ -123,4 +156,36 @@ class UnlockVaultActivity : BaseActivity(ActivityUnl presenter.onCancelMissingVaultClicked(vault) } + override fun onCreateHubDeviceClicked(vaultModel: VaultModel, unverifiedVaultConfig: UnverifiedHubVaultConfig, deviceName: String, setupCode: String) { + presenter.onCreateHubDeviceClick(vaultModel, unverifiedVaultConfig, deviceName, setupCode) + } + + override fun onCreateHubDeviceCanceled() { + finish() + } + + override fun onGoToHubProfileClicked(unverifiedVaultConfig: UnverifiedHubVaultConfig) { + presenter.onGoToHubProfileClicked(unverifiedVaultConfig) + } + + override fun onCancelHubUserSetupClicked() { + finish() + } + + override fun onHubVaultArchivedDialogFinished() { + finish() + } + + override fun onHubLicenseUpgradeRequiredDialogFinished() { + finish() + } + + override fun onVaultAccessForbiddenDialogFinished() { + finish() + } + + override fun onBiometricAuthKeyInvalidatedDialogFinished() { + finish() + } + } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/view/UnlockVaultView.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/view/UnlockVaultView.kt index ae777241a..d920e777b 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/activity/view/UnlockVaultView.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/activity/view/UnlockVaultView.kt @@ -1,5 +1,6 @@ package org.cryptomator.presentation.ui.activity.view +import org.cryptomator.domain.UnverifiedHubVaultConfig import org.cryptomator.domain.UnverifiedVaultConfig import org.cryptomator.presentation.model.VaultModel import org.cryptomator.presentation.ui.dialog.EnterPasswordDialog @@ -13,5 +14,10 @@ interface UnlockVaultView : View, EnterPasswordDialog.Callback { fun cancelBasicAuthIfRunning() fun stoppedBiometricAuthDuringCloudAuthentication(): Boolean fun showChangePasswordDialog(vaultModel: VaultModel, unverifiedVaultConfig: UnverifiedVaultConfig?) + fun showCreateHubDeviceDialog(vaultModel: VaultModel, unverifiedVaultConfig: UnverifiedHubVaultConfig) + fun showHubUserSetupRequiredDialog(unverifiedHubVaultConfig: UnverifiedHubVaultConfig) + fun showHubLicenseUpgradeRequiredDialog() + fun showHubVaultAccessForbiddenDialog() + fun showHubVaultIsArchivedDialog() } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/BiometricAuthKeyInvalidatedDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/BiometricAuthKeyInvalidatedDialog.kt index 8b7213e65..817e7b3ae 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/BiometricAuthKeyInvalidatedDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/BiometricAuthKeyInvalidatedDialog.kt @@ -1,21 +1,43 @@ package org.cryptomator.presentation.ui.dialog import android.content.DialogInterface +import android.view.KeyEvent import androidx.appcompat.app.AlertDialog import org.cryptomator.generator.Dialog import org.cryptomator.presentation.R import org.cryptomator.presentation.databinding.DialogBiometricAuthKeyInvalidatedBinding @Dialog -class BiometricAuthKeyInvalidatedDialog : BaseDialog(DialogBiometricAuthKeyInvalidatedBinding::inflate) { +class BiometricAuthKeyInvalidatedDialog : BaseDialog(DialogBiometricAuthKeyInvalidatedBinding::inflate) { + + interface Callback { + + fun onBiometricAuthKeyInvalidatedDialogFinished() + + } public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { builder // .setTitle(R.string.dialog_biometric_auth_key_invalidated_title) // .setNegativeButton(getString(R.string.dialog_biometric_auth_key_invalidated_neutral_button)) { _: DialogInterface, _: Int -> } + .setOnKeyListener { _, keyCode, _ -> + if (keyCode == KeyEvent.KEYCODE_BACK) { + dialog?.dismiss() + callback?.onBiometricAuthKeyInvalidatedDialogFinished() + true + } else { + false + } + } return builder.create() } + override fun onStart() { + super.onStart() + val dialog = dialog as AlertDialog? + dialog?.setCanceledOnTouchOutside(false) + } + public override fun setupView() { // empty } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ChangePasswordDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ChangePasswordDialog.kt index 616a8e3b4..6dea116d3 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ChangePasswordDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/ChangePasswordDialog.kt @@ -2,6 +2,7 @@ package org.cryptomator.presentation.ui.dialog import android.content.DialogInterface import android.os.Bundle +import android.view.KeyEvent import android.view.View import android.widget.Button import android.widget.LinearLayout @@ -53,6 +54,15 @@ class ChangePasswordDialog : BaseProgressErrorDialog + if (keyCode == KeyEvent.KEYCODE_BACK) { + dialog.dismiss() + callback?.onChangePasswordCanceled() + true + } else { + false + } + } binding.etOldPassword.requestFocus() binding.etOldPassword.nextFocusForwardId = binding.etNewPassword.id binding.etNewPassword.nextFocusForwardId = binding.etNewRetypePassword.id diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/CreateHubDeviceDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/CreateHubDeviceDialog.kt new file mode 100644 index 000000000..b0be92b98 --- /dev/null +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/CreateHubDeviceDialog.kt @@ -0,0 +1,115 @@ +package org.cryptomator.presentation.ui.dialog + +import android.content.DialogInterface +import android.os.Bundle +import android.view.KeyEvent +import android.view.View +import android.widget.LinearLayout +import android.widget.TextView +import androidx.appcompat.app.AlertDialog +import org.cryptomator.domain.UnverifiedHubVaultConfig +import org.cryptomator.generator.Dialog +import org.cryptomator.presentation.R +import org.cryptomator.presentation.databinding.DialogCreateHubDeviceBinding +import org.cryptomator.presentation.databinding.ViewDialogErrorBinding +import org.cryptomator.presentation.model.ProgressModel +import org.cryptomator.presentation.model.ProgressStateModel +import org.cryptomator.presentation.model.VaultModel + +@Dialog +class CreateHubDeviceDialog : BaseProgressErrorDialog(DialogCreateHubDeviceBinding::inflate) { + + interface Callback { + + fun onCreateHubDeviceClicked(vaultModel: VaultModel, unverifiedVaultConfig: UnverifiedHubVaultConfig, deviceName: String, setupCode: String) + fun onCreateHubDeviceCanceled() + } + + override fun onStart() { + super.onStart() + val dialog = dialog as AlertDialog? + dialog?.let { + val createDeviceButton = dialog.getButton(android.app.Dialog.BUTTON_POSITIVE) + createDeviceButton?.setOnClickListener { + val vaultModel = requireArguments().getSerializable(VAULT_ARG) as VaultModel + val unverifiedVaultConfig = requireArguments().getSerializable(VAULT_CONFIG_ARG) as UnverifiedHubVaultConfig + if (valid(binding.etDeviceName.text.toString(), binding.etSetupCode.text.toString())) { + showProgress(ProgressModel(ProgressStateModel.CREATING_HUB_DEVICE)) + callback?.onCreateHubDeviceClicked(vaultModel, unverifiedVaultConfig, binding.etDeviceName.text.toString(), binding.etSetupCode.text.toString()) + onWaitForResponse(binding.etDeviceName) + } + } + dialog.setCanceledOnTouchOutside(false) + dialog.setOnKeyListener { _, keyCode, _ -> + if (keyCode == KeyEvent.KEYCODE_BACK) { + dialog.dismiss() + callback?.onCreateHubDeviceCanceled() + true + } else { + false + } + } + binding.etDeviceName.requestFocus() + binding.etDeviceName.nextFocusForwardId = binding.etSetupCode.id + createDeviceButton?.let { + binding.etSetupCode.nextFocusForwardId = it.id + registerOnEditorDoneActionAndPerformButtonClick(binding.etSetupCode) { it } + } + } + } + + private fun valid(name: String, setupCode: String): Boolean { + return when { + name.isEmpty() -> { + showError(R.string.dialog_create_hub_device_name_empty) + false + } + setupCode.isEmpty() -> { + showError(R.string.dialog_create_hub_device_setup_code_empty) + false + } + else -> true + } + } + + override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { + return builder.setTitle(requireContext().getString(R.string.dialog_create_hub_device_title)) + .setPositiveButton(requireContext().getString(R.string.dialog_create_hub_device_positive_button)) { _: DialogInterface, _: Int -> } + .setNegativeButton(requireContext().getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int -> callback?.onCreateHubDeviceCanceled() } + .create() + } + + override fun setupView() { + } + + override fun dialogProgressLayout(): LinearLayout { + return binding.llDialogProgress.llProgress + } + + override fun dialogProgressTextView(): TextView { + return binding.llDialogProgress.tvProgress + } + + override fun dialogErrorBinding(): ViewDialogErrorBinding { + return binding.llDialogError + } + + override fun enableViewAfterError(): View { + return binding.etDeviceName + } + + companion object { + + private const val VAULT_ARG = "vault" + private const val VAULT_CONFIG_ARG = "vaultConfig" + fun newInstance(vaultModel: VaultModel, unverifiedVaultConfig: UnverifiedHubVaultConfig): CreateHubDeviceDialog { + val args = Bundle() + args.putSerializable(VAULT_ARG, vaultModel) + args.putSerializable(VAULT_CONFIG_ARG, unverifiedVaultConfig) + val fragment = CreateHubDeviceDialog() + fragment.arguments = args + return fragment + } + } + +} diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/EnterPasswordDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/EnterPasswordDialog.kt index c7d43f322..b8a8f9699 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/EnterPasswordDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/EnterPasswordDialog.kt @@ -4,6 +4,7 @@ import android.content.DialogInterface import android.os.Bundle import android.text.Editable import android.text.TextWatcher +import android.view.KeyEvent import android.view.View import android.widget.Button import android.widget.LinearLayout @@ -17,7 +18,6 @@ import org.cryptomator.presentation.model.ProgressModel import org.cryptomator.presentation.model.ProgressStateModel import org.cryptomator.presentation.model.VaultModel - @Dialog(secure = true) class EnterPasswordDialog : BaseProgressErrorDialog(DialogEnterPasswordBinding::inflate) { @@ -47,7 +47,17 @@ class EnterPasswordDialog : BaseProgressErrorDialog binding.etPassword.nextFocusForwardId = button.id } - it.setCanceledOnTouchOutside(false) + dialog.setCanceledOnTouchOutside(false) + dialog.setOnKeyListener { _, keyCode, _ -> + if (keyCode == KeyEvent.KEYCODE_BACK) { + dialog.dismiss() + callback?.onUnlockCanceled() + callback?.closeDialog() + true + } else { + false + } + } binding.etPassword.requestFocus() } } diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/HubLicenseUpgradeRequiredDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/HubLicenseUpgradeRequiredDialog.kt new file mode 100644 index 000000000..c2a82becf --- /dev/null +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/HubLicenseUpgradeRequiredDialog.kt @@ -0,0 +1,43 @@ +package org.cryptomator.presentation.ui.dialog + +import android.content.DialogInterface +import android.view.KeyEvent +import androidx.appcompat.app.AlertDialog +import org.cryptomator.generator.Dialog +import org.cryptomator.presentation.R +import org.cryptomator.presentation.databinding.DialogHubLicenseUpgradeRequiredBinding + +@Dialog +class HubLicenseUpgradeRequiredDialog : BaseDialog(DialogHubLicenseUpgradeRequiredBinding::inflate) { + + interface Callback { + + fun onHubLicenseUpgradeRequiredDialogFinished() + } + + public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { + builder // + .setTitle(R.string.dialog_hub_license_upgrade_required_title) // + .setNeutralButton(getString(R.string.dialog_hub_license_upgrade_required_neutral_button)) { _: DialogInterface, _: Int -> callback?.onHubLicenseUpgradeRequiredDialogFinished() } + .setOnKeyListener { _, keyCode, _ -> + if (keyCode == KeyEvent.KEYCODE_BACK) { + dialog?.dismiss() + callback?.onHubLicenseUpgradeRequiredDialogFinished() + true + } else { + false + } + } + return builder.create() + } + + public override fun setupView() { + } + + companion object { + + fun newInstance(): HubLicenseUpgradeRequiredDialog { + return HubLicenseUpgradeRequiredDialog() + } + } +} diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/HubUserSetupRequiredDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/HubUserSetupRequiredDialog.kt new file mode 100644 index 000000000..9ee48962d --- /dev/null +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/HubUserSetupRequiredDialog.kt @@ -0,0 +1,65 @@ +package org.cryptomator.presentation.ui.dialog + +import android.content.DialogInterface +import android.os.Bundle +import android.view.KeyEvent +import androidx.appcompat.app.AlertDialog +import org.cryptomator.domain.UnverifiedHubVaultConfig +import org.cryptomator.generator.Dialog +import org.cryptomator.presentation.R +import org.cryptomator.presentation.databinding.DialogHubUserSetupRequiredBinding + +@Dialog +class HubUserSetupRequiredDialog : BaseDialog(DialogHubUserSetupRequiredBinding::inflate) { + + interface Callback { + + fun onGoToHubProfileClicked(unverifiedVaultConfig: UnverifiedHubVaultConfig) + fun onCancelHubUserSetupClicked() + + } + + public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { + builder // + .setTitle(R.string.dialog_hub_user_setup_required_title) // + .setPositiveButton(getString(R.string.dialog_hub_user_setup_required_neutral_button)) { _: DialogInterface, _: Int -> } // + .setNegativeButton(getString(R.string.dialog_hub_user_setup_required_negative_button)) { _: DialogInterface, _: Int -> callback?.onCancelHubUserSetupClicked() } // + .setOnKeyListener { _, keyCode, _ -> + if (keyCode == KeyEvent.KEYCODE_BACK) { + dialog?.dismiss() + callback?.onCancelHubUserSetupClicked() + true + } else { + false + } + } + return builder.create() + } + + override fun onStart() { + super.onStart() + val dialog = dialog as AlertDialog? + val goToProfileButton = dialog?.getButton(android.app.Dialog.BUTTON_POSITIVE) + goToProfileButton?.setOnClickListener { + val unverifiedVaultConfig = requireArguments().getSerializable(VAULT_CONFIG_ARG) as UnverifiedHubVaultConfig + callback?.onGoToHubProfileClicked(unverifiedVaultConfig) + } + dialog?.setCanceledOnTouchOutside(false) + } + + override fun setupView() { + // empty + } + + companion object { + + private const val VAULT_CONFIG_ARG = "vaultConfig" + fun newInstance(unverifiedVaultConfig: UnverifiedHubVaultConfig): HubUserSetupRequiredDialog { + val args = Bundle() + args.putSerializable(VAULT_CONFIG_ARG, unverifiedVaultConfig) + val fragment = HubUserSetupRequiredDialog() + fragment.arguments = args + return fragment + } + } +} diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/HubVaultAccessForbiddenDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/HubVaultAccessForbiddenDialog.kt new file mode 100644 index 000000000..72b49585a --- /dev/null +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/HubVaultAccessForbiddenDialog.kt @@ -0,0 +1,43 @@ +package org.cryptomator.presentation.ui.dialog + +import android.content.DialogInterface +import android.view.KeyEvent +import androidx.appcompat.app.AlertDialog +import org.cryptomator.generator.Dialog +import org.cryptomator.presentation.R +import org.cryptomator.presentation.databinding.DialogHubVaultAccessForbiddenBinding + +@Dialog +class HubVaultAccessForbiddenDialog : BaseDialog(DialogHubVaultAccessForbiddenBinding::inflate) { + + interface Callback { + + fun onVaultAccessForbiddenDialogFinished() + } + + public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { + builder // + .setTitle(R.string.dialog_hub_vault_access_forbidden_title) // + .setNeutralButton(getString(R.string.dialog_hub_vault_access_forbidden_neutral_button)) { _: DialogInterface, _: Int -> callback?.onVaultAccessForbiddenDialogFinished() } // + .setOnKeyListener { _, keyCode, _ -> + if (keyCode == KeyEvent.KEYCODE_BACK) { + dialog?.dismiss() + callback?.onVaultAccessForbiddenDialogFinished() + true + } else { + false + } + } + return builder.create() + } + + public override fun setupView() { + } + + companion object { + + fun newInstance(): HubVaultAccessForbiddenDialog { + return HubVaultAccessForbiddenDialog() + } + } +} diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/HubVaultArchivedDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/HubVaultArchivedDialog.kt new file mode 100644 index 000000000..30923ee82 --- /dev/null +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/HubVaultArchivedDialog.kt @@ -0,0 +1,46 @@ +package org.cryptomator.presentation.ui.dialog + +import android.content.DialogInterface +import android.view.KeyEvent +import androidx.appcompat.app.AlertDialog +import org.cryptomator.generator.Dialog +import org.cryptomator.presentation.R +import org.cryptomator.presentation.databinding.DialogHubVaultArchivedBinding + +@Dialog +class HubVaultArchivedDialog : BaseDialog(DialogHubVaultArchivedBinding::inflate) { + + interface Callback { + + fun onHubVaultArchivedDialogFinished() + } + + public override fun setupDialog(builder: AlertDialog.Builder): android.app.Dialog { + builder // + .setTitle(R.string.dialog_hub_vault_archived_title) // + .setNeutralButton(getString(R.string.dialog_hub_vault_archived_positive_button)) { _: DialogInterface, _: Int -> callback?.onHubVaultArchivedDialogFinished() } + .setOnKeyListener { _, keyCode, _ -> + if (keyCode == KeyEvent.KEYCODE_BACK) { + dialog?.dismiss() + callback?.onHubVaultArchivedDialogFinished() + true + } else { + false + } + } + return builder.create() + } + + public override fun setupView() { + super.onStart() + val dialog = dialog as AlertDialog? + dialog?.setCanceledOnTouchOutside(false) + } + + companion object { + + fun newInstance(): HubVaultArchivedDialog { + return HubVaultArchivedDialog() + } + } +} diff --git a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/VaultNotFoundDialog.kt b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/VaultNotFoundDialog.kt index 3731a8d5b..d26f9c294 100644 --- a/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/VaultNotFoundDialog.kt +++ b/presentation/src/main/java/org/cryptomator/presentation/ui/dialog/VaultNotFoundDialog.kt @@ -2,6 +2,7 @@ package org.cryptomator.presentation.ui.dialog import android.content.Context import android.content.DialogInterface +import android.view.KeyEvent import androidx.appcompat.app.AlertDialog import org.cryptomator.domain.Vault import org.cryptomator.presentation.R @@ -25,12 +26,21 @@ class VaultNotFoundDialog private constructor(private val context: Context) { .setPositiveButton(ResourceHelper.getString(R.string.dialog_vault_not_found_positive_button_text)) { _: DialogInterface, _: Int -> callback.onDeleteMissingVaultClicked(vault) } // .setNegativeButton(ResourceHelper.getString(R.string.dialog_button_cancel)) { _: DialogInterface, _: Int -> callback.onCancelMissingVaultClicked(vault) } // .setOnCancelListener { callback.onCancelMissingVaultClicked(vault) } - .create().show() + .setOnKeyListener { _, keyCode, _ -> + if (keyCode == KeyEvent.KEYCODE_BACK) { + callback.onCancelMissingVaultClicked(vault) + true + } else { + false + } + } + .create() + .show() } companion object { - @kotlin.jvm.JvmStatic + @JvmStatic fun withContext(context: Context): VaultNotFoundDialog { return VaultNotFoundDialog(context) } diff --git a/presentation/src/main/res/layout/dialog_create_hub_device.xml b/presentation/src/main/res/layout/dialog_create_hub_device.xml new file mode 100644 index 000000000..c68a71f5e --- /dev/null +++ b/presentation/src/main/res/layout/dialog_create_hub_device.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/presentation/src/main/res/layout/dialog_hub_license_upgrade_required.xml b/presentation/src/main/res/layout/dialog_hub_license_upgrade_required.xml new file mode 100644 index 000000000..40461f58b --- /dev/null +++ b/presentation/src/main/res/layout/dialog_hub_license_upgrade_required.xml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/presentation/src/main/res/layout/dialog_hub_user_setup_required.xml b/presentation/src/main/res/layout/dialog_hub_user_setup_required.xml new file mode 100644 index 000000000..8b0473436 --- /dev/null +++ b/presentation/src/main/res/layout/dialog_hub_user_setup_required.xml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/presentation/src/main/res/layout/dialog_hub_vault_access_forbidden.xml b/presentation/src/main/res/layout/dialog_hub_vault_access_forbidden.xml new file mode 100644 index 000000000..f01563b46 --- /dev/null +++ b/presentation/src/main/res/layout/dialog_hub_vault_access_forbidden.xml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/presentation/src/main/res/layout/dialog_hub_vault_archived.xml b/presentation/src/main/res/layout/dialog_hub_vault_archived.xml new file mode 100644 index 000000000..cd69e775b --- /dev/null +++ b/presentation/src/main/res/layout/dialog_hub_vault_archived.xml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/presentation/src/main/res/values-af-rZA/strings.xml b/presentation/src/main/res/values-af-rZA/strings.xml new file mode 100644 index 000000000..02ca5ecd2 --- /dev/null +++ b/presentation/src/main/res/values-af-rZA/strings.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/presentation/src/main/res/values-ar-rSA/strings.xml b/presentation/src/main/res/values-ar-rSA/strings.xml index 9149b8461..37ab5ac12 100644 --- a/presentation/src/main/res/values-ar-rSA/strings.xml +++ b/presentation/src/main/res/values-ar-rSA/strings.xml @@ -35,6 +35,7 @@ لا يوجد مخزن بهذه المعلومات في S3 موقع المفتاح الرئيسي غير مدعوم بعد فشل في التواصل مع تطبيق F-Droid. غير مثبت؟ + هذا الجهاز مسجل لمستخدم مختلف بالفعل. حاول تغيير حساب المستخدم أو استخدام جهاز مختلف. ذاكرة التخزين المحلية @@ -67,7 +68,6 @@ تم تغيير كلمة المرور بنجاح الخزينة - اختر مِلَفَ المفتاحِ الرئيسِ ضع هنا اسم المخزن: %1$s @@ -351,6 +351,11 @@ لا مزيد من الصور للعرض… تم تحديث وثائق تفويض \'%1$s\' إذا كنت ترغب في إضافة حساب pCloud جديد، انقر على هذا الرابط www.pcloud. om، ثم قم بتسجيل الخروج من الحساب الحالي و بعدها انقر مرة أخرى على \'+\' في هذا التطبيق لإنشاء اتصال سحابي جديد. + يبدو أن هذا هو الوصول الأول إلى Hub من هذا الجهاز. لتحديده لأغراض تفويض الوصول، تحتاج إلى تسمية هذا الجهاز. + مفتاح الحساب الخاص بك مطلوب لتسجيل الدخول من تطبيقات أو متصفحات جديدة. يمكن العثور عليه في ملفك الشخصي. + تم رفض الوصول + للمتابعة، يرجى إكمال الخطوات المطلوبة في ملف المستخدم الخاص بك في Hub. + اذهب إلى الملف الشخصي Cryptomator يحتاج صلاحية الوصول إلي التخزين ليستطيع استعمال الخزائن المحلية Cryptomator يحتاج صلاحية الوصول إلي التخزين ليستطيع تحميل الصور تلقائيا Cryptomator يحتاج إلى صَلاحِيَة إظهار الإشعارات لعرض حالة المخزن على سبيل المثال diff --git a/presentation/src/main/res/values-ba-rRU/strings.xml b/presentation/src/main/res/values-ba-rRU/strings.xml index b0c3e1f24..2c5f20185 100644 --- a/presentation/src/main/res/values-ba-rRU/strings.xml +++ b/presentation/src/main/res/values-ba-rRU/strings.xml @@ -67,7 +67,6 @@ Серһүҙ уңышлы үҙгәртелде Һаҡлағыс - Masterkey файлын һайлағыҙ Бында ҡуйығыҙ Һаҡлағыс исеме: %1$s @@ -345,6 +344,11 @@ Күрһәтерлек һүрәттәр юҡ… \'%1$s\' иҫәп яҙыуы мәғлүмәттәре яңыртылды Әгәр ҙә һеҙ яңы pCloud иҫәп яҙмаһы өҫтәргә ниәтләһәгеҙ, ошо url www.pcloud.com аша күсегеҙ, ағымдағы иҫәп яҙмаһынан сығығыҙ һәм яңы болот бәйләнеше булдырыу өсөн был ҡушымталағы \'+\' төймәһенә баҫығыҙ. + Был, күрәһең, был ҡоролманан Хабҡа тәү инеү ваҡыты. Инеүҙе рөхсәт итеү өсөн йыһазды асыҡлаусы исем атарға кәрәк. + Яңы ҡушымталар йәки браузерҙарҙан инеү өсөн Һеҙҙең иҫәп-хисап асҡысы кәрәк. Уны профилегеҙҙә табырға мөмкин. + Инеү кире ҡағылды + Артабан барыр өсөн, Hub ҡулланыусылар профилендә кәрәкле аҙымдарҙы тамамлағыҙ. + Профилгә күс Урындағы һаҡлағыстарҙы ҡулланыу өсөн Cryptomator-ға һаҡлағысҡа инеү рәхсәте кәрәк Автоматик фото тейәү өсөн Cryptomator-ға һаҡлағысҡа инеү рәхсәте кәрәк Cryptomator-ға белдереү ебәреү хоҡуҡтары кәрәк. Мәҫәлән, һаҡлағыс торошо тураһында. diff --git a/presentation/src/main/res/values-be-rBY/strings.xml b/presentation/src/main/res/values-be-rBY/strings.xml index 0f6a51758..7f37d54e8 100644 --- a/presentation/src/main/res/values-be-rBY/strings.xml +++ b/presentation/src/main/res/values-be-rBY/strings.xml @@ -47,7 +47,6 @@ Пароль паспяхова зменены Скарбніца - Абяры файл masterkey Размясціць тут Імя скрабніцы: %1$s Перамясціць @@ -149,6 +148,7 @@ Замкнуць Зачыніць Назад + Адмова ў доступе diff --git a/presentation/src/main/res/values-bg-rBG/strings.xml b/presentation/src/main/res/values-bg-rBG/strings.xml index 4d9d552e9..43ff62089 100644 --- a/presentation/src/main/res/values-bg-rBG/strings.xml +++ b/presentation/src/main/res/values-bg-rBG/strings.xml @@ -67,7 +67,6 @@ Паролата е сменена Хранилище - Изберете файл на главен ключ Постави тук Име на хранилище: %1$s @@ -236,6 +235,11 @@ Поради дефект в приложенията на Microsoft, файлът, който трябва да бъде редактиран, трябва да бъде споделен с тези приложения в публична папка на вашето устройство. След възобновяване на работата на Cryptomator, публично достъпният файл се изтрива отново, но Cryptomator не може да повлияе на случващото се с файла междувременно. Преди да включите тук се уверете, че сте наясно с това поведение. Това ще се прилага само за файлове на Microsoft.\n\nСлед включване Cryptomator ще се рестартира. Затваряне Назад + Изглежда, че това е първи достъп до Hub от това устройство. За да го разпознаете при разрешаване на достъпа, трябва да му дадете име. + Вашият ключ за профила е необходим при вход от нови приложения или мрежови четци. Може да бъде намерен в профила. + Отказан достъп + За да продължите завършете необходимите стъпки в потребителския профил в Hub. + Към профила diff --git a/presentation/src/main/res/values-bn-rBD/strings.xml b/presentation/src/main/res/values-bn-rBD/strings.xml index c3c5fcd6b..aff7e5f38 100644 --- a/presentation/src/main/res/values-bn-rBD/strings.xml +++ b/presentation/src/main/res/values-bn-rBD/strings.xml @@ -67,7 +67,6 @@ পাসওয়ার্ড সফলভাবে পরিবর্তিত হয়েছে ভোল্ট - মাস্টার কী ফাইলটি নির্বাচন করুন এখানে রাখুন ভোল্টের নাম: %1$s diff --git a/presentation/src/main/res/values-bs-rBA/strings.xml b/presentation/src/main/res/values-bs-rBA/strings.xml index cc0903462..51b28571f 100644 --- a/presentation/src/main/res/values-bs-rBA/strings.xml +++ b/presentation/src/main/res/values-bs-rBA/strings.xml @@ -5,6 +5,8 @@ Došlo je do greške Provjera autentičnosti nije uspjela + Account Key je nevažeći. + Nepodržana Hub verzija. @@ -16,6 +18,7 @@ Ukloni Sef + Odaberite masterkey ili vault fajl Odaberi Izmjeni @@ -49,6 +52,12 @@ Zaključaj Zatvori Nazad + Ime ne može biti prazno. + Kreiranje uređaja… + Pristup zabranjen + Vault je arhiviran + Potrebno je korisničko podešavanje + Idite na Profil diff --git a/presentation/src/main/res/values-ca-rES/strings.xml b/presentation/src/main/res/values-ca-rES/strings.xml index dad4733db..529c3e6fb 100644 --- a/presentation/src/main/res/values-ca-rES/strings.xml +++ b/presentation/src/main/res/values-ca-rES/strings.xml @@ -35,6 +35,7 @@ No existeix el cubell Encara no es permet la ubicació personalitzada de la clau mestra Error en la comunicació amb l\'aplicació F-Droid. Està instal·lada? + El dispositiu ja ha estat registrat per un altre usuari. Mireu de canviar el compte d\'usuari o feu servir un dispositiu diferent. Emmagatzematge local @@ -67,7 +68,6 @@ La contrasenya s\'han canviat correctament Caixa forta - Seleccioneu el fitxer de clau mestra Col·locar aquí Nom de la caixa forta: %1$s @@ -347,6 +347,11 @@ Credencials de \'%1$s\' actualitzades Si teníeu la intenció d\'afegir un compte de pCloud nou, toqueu aquest URL www.pcloud.com, tanqueu la sessió del compte actual i torneu a tocar el \"+\" d\'aquesta aplicació per crear una nova connexió al núvol. Migra + Sembla que és el primer accés al Hub des d\'aquest dispositiu. Per identificar-lo i poder autoritzar l\'accés heu de posar nom a aquest dispositiu. + Cal la vostra Account Key per a iniciar sessió des d\'una aplicació o navegador nous. La trobareu al vostre perfil. + Accés denegat + Per a continuar, si us plau, seguiu els passos necessaris en el vostre perfil d\'usuari de Hub. + Vés al perfil Cryptomator necessita accés a l\'emmagatzematge per a fer servir caixes fortes locals Cryptomator necessita accés a l\'emmagatzematge per a la pujada de fotos automàtica Cryptomator necessita permís de notificacions per poder informar del seu estat, per exemple diff --git a/presentation/src/main/res/values-cs-rCZ/strings.xml b/presentation/src/main/res/values-cs-rCZ/strings.xml index 27c5b0085..29c26c55b 100644 --- a/presentation/src/main/res/values-cs-rCZ/strings.xml +++ b/presentation/src/main/res/values-cs-rCZ/strings.xml @@ -35,6 +35,7 @@ Bucket neexistuje Vlastní umístění hlavního klíče ještě není podporováno Nepodařilo se komunikovat s aplikací F-Droid. Možná není nainstalována? + Toto zařízení je již registrováno pro jiného uživatele. Zkuste změnit uživatelský účet nebo použijte jiné zařízení. Místní úložiště @@ -67,7 +68,6 @@ Heslo bylo úspěšně změněno Trezor - Vyberte soubor s hlavním klíčem Umístit zde Název trezoru: %1$s @@ -348,6 +348,10 @@ Žádné další obrázky k zobrazení… Údaje o \'%1$s\' byly aktualizovány Pokud máte v úmyslu přidat nový účet na pCloud, klepněte na tuto url www.pcloud. om, odhlas jste se z aktuálního účtu a znovu klepněte na \'+\' v této aplikaci pro vytvoření nového cloudového připojení. + Váš Account Key je vyžadován k přihlášení z nových aplikací nebo prohlížečů. Naleznete jej ve vašem profilu. + Přístup odepřen + Chcete-li pokračovat, dokončete prosím požadované kroky ve vašem uživatelském profilu Hubu. + Jít na profil Cryptomator potřebuje přístup k úložišti, aby mohl používat místní trezory Cryptomator potřebuje přístup k úložišti pro automatické nahrávání fotek Cryptomator potřebuje oprávnění k oznámení. Například: zobrazení stavu trezoru diff --git a/presentation/src/main/res/values-da-rDK/strings.xml b/presentation/src/main/res/values-da-rDK/strings.xml index babaf1fba..1d346f97a 100644 --- a/presentation/src/main/res/values-da-rDK/strings.xml +++ b/presentation/src/main/res/values-da-rDK/strings.xml @@ -35,6 +35,7 @@ Bucket findes ikke Brugerdefineret hovednøgle-placering understøttes ikke endnu Kunne ikke kommunikere med F-Droid appen. Er den ikke installeret? + Denne enhed er allerede registreret af en anden bruger. Prøv at ændre brugerkontoen eller brug en anden enhed. Lokalt lager @@ -67,7 +68,6 @@ Adgangskoden blev ændret Boks - Vælg hovednøgle-fil Placér her Boks-navn: %1$s @@ -346,6 +346,11 @@ Ikke flere billeder at vise… Login for \'%1$s\' opdateret Hvis du har til hensigt at tilføje en ny pCloud-konto, skal du trykke på denne Url www.pcloud.com, logge ud af den aktuelle konto og tryk igen på \'+\' i denne app for at oprette en ny cloud-forbindelse. + Det ser ud til at dette er første gang denne enhed tilgår Hub. For at kunne identificere den for adgangstilladelse, skal du navngive denne enhed. + Din kontonøgle er påkrævet til at logge ind fra nye apps eller browsere. Den kan findes i din profil. + Adgang nægtet + For at fortsætte, skal du fuldføre de nødvendige trin i din Hub brugerprofil. + Gå til Profil Cryptomator skal bruge lageradgang for at tilgå lokale bokse Cryptomator har brug for lageradgang for at kunne uploade fotos automatisk Cryptomator har brug for notifikationstilladelser for at vise f.eks. boksstatus diff --git a/presentation/src/main/res/values-de-rDE/strings.xml b/presentation/src/main/res/values-de-rDE/strings.xml index d9e6ccb5e..31e6c7878 100644 --- a/presentation/src/main/res/values-de-rDE/strings.xml +++ b/presentation/src/main/res/values-de-rDE/strings.xml @@ -35,6 +35,7 @@ Bucket existiert nicht Benutzerdefinierter Ort der Masterkey-Datei wird noch nicht unterstützt Fehler bei der Kommunikation mit der F-Droid-App. Nicht installiert? + Dieses Gerät ist bereits für einen anderen Benutzer registriert. Ändere das Benutzerkonto oder verwende ein anderes Gerät. Lokaler Speicher @@ -67,7 +68,6 @@ Passwort wurde erfolgreich geändert Tresor - Masterkey-Datei auswählen Hier ablegen Tresorname: %1$s @@ -352,6 +352,11 @@ Tresor Passwort-Migration erforderlich Aufgrund von Sicherheitsverbesserungen wirst du zweimal nach deiner biometrischen Authentifizierung für jeden Tresor gefragt, um deine Tresorpasswörter neu zu verschlüsseln. Dies ist notwendig, um deine Tresorpasswörter weiterhin mit der neuesten Technologie zu schützen. Wenn du dies nicht möchtest, werden die gespeicherten Passwörter entfernt. Migrieren + Dies scheint der erste Hub-Zugriff von diesem Gerät zu sein. Um es für die Zugriffsberechtigung zu identifizieren, musst du diesem Gerät einen Namen geben. + Um sich von neuen Apps oder Browsern aus anzumelden, ist dein Account Key erforderlich. Er befindet sich in deinem Profil. + Zugriff verweigert + Schließe bitte die erforderlichen Schritte in deinem Hub-Benutzerprofil ab, um fortzufahren. + Zum Profil Cryptomator benötigt Speicherzugriff, um lokale Tresore nutzen zu können Cryptomator benötigt Zugriff auf den Speicher um den automatischen Foto-Upload zu nutzen Cryptomator benötigt die Berechtigung zur Anzeige von Benachrichtigungen, um beispielsweise den Status des Tresors anzeigen zu können diff --git a/presentation/src/main/res/values-el-rGR/strings.xml b/presentation/src/main/res/values-el-rGR/strings.xml index ba9c8f18f..2403d2ee8 100644 --- a/presentation/src/main/res/values-el-rGR/strings.xml +++ b/presentation/src/main/res/values-el-rGR/strings.xml @@ -35,6 +35,11 @@ Δεν υπάρχει τέτοιος κάδος Η προσαρμοσμένη τοποθεσία Masterkey δεν υποστηρίζεται ακόμα Αποτυχία επικοινωνίας με την εφαρμογή F-Droid. Δεν έχει εγκατασταθεί; + Η λειτουργία Κρύπτης δεν υποστηρίζεται για το Hub + Η ταυτοποίηση στο Hub απέτυχε + Αυτή η συσκευή είναι ήδη εγγεγραμμένη για διαφορετικό χρήστη. Προσπαθήστε να αλλάξετε τον λογαριασμό χρήστη ή να χρησιμοποιήσετε διαφορετική συσκευή. + Το Κλειδί Λογαριασμού δεν είναι έγκυρο. + Μη υποστηριζόμενη έκδοση Hub. Τοπικός αποθηκευτικός χώρος @@ -67,7 +72,7 @@ Ο κωδικός πρόσβασης άλλαξε επιτυχώς Κρύπτη - Επιλέξτε masterkey αρχείο + Επιλέξτε masterkey ή αρχείο κρύπτης Τοποθέτησε εδώ Όνομα κρύπτης: %1$s @@ -352,6 +357,23 @@ Απαιτείται κωδικός πρόσβασης μετεγκατάστασης κρύπτης Λόγω βελτιώσεων ασφαλείας, θα σας ζητηθεί η βιομετρική ταυτοποίησή σας δύο φορές για κάθε κρύπτη για να επανκρυπτογραφήσετε τους κωδικούς πρόσβασης της κρύπτης σας. Αυτό είναι απαραίτητο για να συνεχίσετε να προστατεύετε τους κωδικούς πρόσβασης της κρύπτης σας με την τελευταία τεχνολογία. Αν δεν επιθυμείτε να συμβεί αυτό, οι αποθηκευμένοι κωδικοί πρόσβασης θα αφαιρεθούν. Μετεγκατάσταση + Εγγραφή συσκευής Hub + Όνομα + Αυτή φαίνεται να είναι η πρώτη πρόσβαση στο Hub από αυτήν τη συσκευή. Για να την αναγνωρίσετε για εξουσιοδότηση πρόσβασης, πρέπει να ονομάσετε αυτήν τη συσκευή. + Το όνομα δεν μπορεί να είναι κενό. + Κλειδί Λογαριασμού + Το Κλειδί Λογαριασμού σας απαιτείται για να συνδεθείτε από νέες εφαρμογές ή προγράμματα περιήγησης. Μπορείτε να το βρείτε στο προφίλ σας. + Το Κλειδί Λογαριασμού δεν μπορεί να είναι κενό. + Δημιουργία συσκευής… + Δεν επιτρέπεται η πρόσβαση + Ο χρήστης σας δεν έχει ακόμη εξουσιοδοτηθεί να έχει πρόσβαση σε αυτή την κρύπτη. Ζητήστε από τον ιδιοκτήτη της κρύπτης να το εξουσιοδοτήσει.\" + Έλεγχος άδειας Hub + Η συνεδρία σας στο Cryptomator Hub έχει μη έγκυρη άδεια χρήσης. Ενημερώστε έναν διαχειριστή του Hub για να αναβαθμίσει ή να ανανεώσει την άδεια χρήσης.\" + Η Κρύπτη αρχειοθετήθηκε + Αυτό η κρύπτη είναι αρχειοθετημένη και δεν μπορεί να ξεκλειδωθεί. Για να την ξεκλειδώσετε, ο κάτοχος της κρύπτης πρέπει να την επαναφέρει. + Απαιτείται ρύθμιση χρήστη + Για να συνεχίσετε, παρακαλούμε συμπληρώστε τα βήματα που απαιτούνται στο προφίλ χρήστη Hub σας. + Πηγαίνετε στο Προφίλ Το Cryptomator χρειάζεται πρόσβαση στον αποθηκευτικό χώρο για τη χρήση τοπικών κρυπτών Το Cryptomator χρειάζεται πρόσβαση στον αποθηκευτικό χώρο για να χρησιμοποιηθεί η αυτόματη μεταφόρτωση φωτογραφιών Το Cryptomator χρειάζεται δικαιώματα ειδοποίησης για να εμφανίσει για παράδειγμα την κατάσταση κρύπτης diff --git a/presentation/src/main/res/values-en-rUS/strings.xml b/presentation/src/main/res/values-en-rUS/strings.xml new file mode 100644 index 000000000..4324ea161 --- /dev/null +++ b/presentation/src/main/res/values-en-rUS/strings.xml @@ -0,0 +1,48 @@ + + + + + + + + + Next + + + + + + + + + + + + Done + Weak + Fair + Strong + + General + + + + + + Cancel + Unlock + + Lock + Close + Back + + + + + + + + + + + diff --git a/presentation/src/main/res/values-es-rES/strings.xml b/presentation/src/main/res/values-es-rES/strings.xml index ca3803abf..0039731ca 100644 --- a/presentation/src/main/res/values-es-rES/strings.xml +++ b/presentation/src/main/res/values-es-rES/strings.xml @@ -35,6 +35,12 @@ El bucket no existe Ubicación personalizada Masterkey aún no soportada Error al comunicarse con la aplicación F-Droid. ¿No está instalada? + Operación de bóveda no soportada para Hub + Ha fallado la autenticación de Hub + Este dispositivo ya se ha registrado para otro usuario. Intente cambiar la cuenta de usuario o utilice un dispositivo diferente. + La Account Key no es válida. + Versión de Hub no soportada. + Hub solo es compatible con Android 12 o superior. Almacenamiento local @@ -67,7 +73,7 @@ Contraseña cambiada con éxito Bóveda - Seleccionar archivo masterkey + Seleccionar archivo masterkey o bóveda Dejar aquí Nombre de la bóveda: %1$s @@ -352,6 +358,23 @@ Migración de contraseña de bóveda requerida Debido a las mejoras de seguridad, se le pedirá la autenticación biométrica dos veces por cada bóveda para volver a cifrar sus contraseñas de bóveda. Esto es necesario para continuar protegiendo sus contraseñas de bóveda con la última tecnología. Si no desea que esto suceda, se eliminarán las contraseñas almacenadas. Migrar + Registrar dispositivo Hub + Nombre + Este parece ser el primer acceso al Hub desde este dispositivo. Para identificarlo y autorizar el acceso, necesita nombrar este dispositivo. + El nombre no puede estar vacío. + Account Key + Se requiere su clave de cuenta para iniciar sesión desde nuevas aplicaciones o navegadores. Puede encontrarse en su perfil. + La Account Key no puede estar vacía. + Creando dispositivo… + Acceso denegado + Su usuario aún no ha sido autorizado para acceder a esta bóveda. Pídale al propietario de la bóveda que lo autorice.\" + Comprobar licencia de Hub + Su instancia de Cryptomator Hub tiene una licencia inválida. Informe a un administrador del Hub para actualizar o renovar la licencia.\" + Bóveda archivada + Esta bóveda está archivada y no puede ser desbloqueada. Para desbloquearla, el propietario de la bóveda debe desarchivarla. + Configuración de usuario requerida + Para continuar, complete los pasos necesarios en su perfil de usuario de Hub. + Ir al Perfil Cryptomator necesita acceso de almacenamiento para usar bóvedas locales Cryptomator necesita acceso de almacenamiento para cargar fotos automáticamente Cryptomator necesita permisos de notificación para mostrar el estado de la bóveda por ejemplo diff --git a/presentation/src/main/res/values-fa-rIR/strings.xml b/presentation/src/main/res/values-fa-rIR/strings.xml index 7883eeed2..f8ab8447f 100644 --- a/presentation/src/main/res/values-fa-rIR/strings.xml +++ b/presentation/src/main/res/values-fa-rIR/strings.xml @@ -67,7 +67,6 @@ رمز عبور با موفقیت تغییر یافت مخزن - فایل کلید اصلی را انتخاب کنید اینجا قرار دهید نام مخزن: %1$s diff --git a/presentation/src/main/res/values-fi-rFI/strings.xml b/presentation/src/main/res/values-fi-rFI/strings.xml index 5771d79cd..ae9aef5f7 100644 --- a/presentation/src/main/res/values-fi-rFI/strings.xml +++ b/presentation/src/main/res/values-fi-rFI/strings.xml @@ -1,26 +1,97 @@ + Salaa + Tapahtui virhe + Tunnistautuminen epäonnistui + Tunnistautuminen epäonnistui, kirjaudu sisään käyttäen %1$s + Ei internet-yhteyttä + Väärä salasana + Tiedosto tai kansio on jo olemassa. + Holvin versiota %1$s ei tueta. Tämä holvi on luotu Cryptomatorin vanhemmalla tai uudemmalla versiolla. + %1$s tiedosto puuttuu holvikansiostasi. Varmista, että tämä tiedosto on olemassa holvikansiossa pilvessä. + Holvi on jo olemassa. + Tiedostoa ei ole olemassa. + Holvi on lukittu. + Pilvi on jo olemassa. + Lataa sovellus, joka voi avata tämän tiedoston. + Palvelinta ei löytynyt. + Avaa laitteesi asetukset ja aseta näytön lukitus manuaalisesti + Vienti epäonnistui. Yritä poistaa erikoismerkit tiedostojen nimistä ja yritä vientiä uudelleen. + Ei saa sisältää erikoismerkkejä. + Tiedostonimet eivät saa sisältää erikoismerkkejä. + Holvin nimi ei saa sisältää erikoismerkkejä. + Päivityksen tarkistus epäonnistui. Tapahtui virhe. + Päivityksen tarkistus epäonnistui. Laskettu tiiviste ei täsmää ladattuun tiedostoon + Päivityksen tarkistus epäonnistui. Ei internet-yhteyttä. + Google Play -palveluita ei ole asennettu + Biometrinen tunnistautuminen keskeytetty + %1$s versio poikkeaa %2$s versiosta + %1$s ei täsmää %2$s kanssa + Holvin asetuksia ladatessa tapahtui virhe + Tiedosto ei ole enää saatavilla Cryptomatoriin palaamisen jälkeen. Mahdollisia muutoksia ei voida siirtää pilveen. + Tämä laite on jo rekisteröity toiselle käyttäjälle. Yritä vaihtaa käyttäjätiliä tai käytää toista laitetta. Seuraava + Järjestä + A - Ö + Ö - A + Uusin ensin + Vanhin ensin + Suurin ensin + Pienin ensin + Lue lisää + Pilvi ei ole luettelossa? + Lisää Cryptomatoriin + Luo uusi holvi + Lisää olemassa oleva holvi + Poista + Napauta tätä luodaksesi uuden holvin + Salasanan vaihto onnistui - Vault + Holvi + Holvin nimi: %1$s + + Siirrä %1$s + Siirrä %2$d tiedostoa + + Siirrä + Tyhjää kansio + muokattu %1$s sitten + Valitse + Ei jaettavaa + Lisää kansioon %1$s + Luo kansio + Luo tekstitiedosto + Lataa tiedostoja + Tiedostot + Tiedosto viety + Tiedostot viety + Ei mitään vietävää + Latauskansion luonti epäonnistui + Jaa + Nimeä uudelleen + Salasana Valmis + Heikko + Kohtalainen + Vahva + Yleiset @@ -29,13 +100,16 @@ Peruuta Avaa + Poista Lukitse Sulje Takaisin + Pääsy estetty + minuuttia diff --git a/presentation/src/main/res/values-fil-rPH/strings.xml b/presentation/src/main/res/values-fil-rPH/strings.xml index c88034b7d..c90debd5f 100644 --- a/presentation/src/main/res/values-fil-rPH/strings.xml +++ b/presentation/src/main/res/values-fil-rPH/strings.xml @@ -35,6 +35,7 @@ Hindi matagpuan ang bucket na ito Hindi pa suportado ang custom Masterkey location Nabigong makipag-ugnayan sa F-Droid app. Hindi naka-install? + Ang device na ito ay registrado na sa ibang user. Subukang palitan ang user account o gumamit ng ibang device. Local storage @@ -67,7 +68,6 @@ Matagumpay na napalitan ang password Vault - Piliin ang masterkey file Ilagay dito Pangalan ng vault: %1$s @@ -352,6 +352,11 @@ Kinakailangan ang paglipat ng password ng Vault Dahil sa mga pagpapahusay sa seguridad, hihilingin sa iyo ang iyong biometric na pagpapatotoo nang dalawang beses para sa bawat vault upang muling i-encrypt ang iyong mga password sa vault. Ito ay kinakailangan upang patuloy na maprotektahan ang iyong mga password sa vault gamit ang pinakabagong teknolohiya. Kung hindi mo gustong mangyari ito, aalisin ang mga nakaimbak na password. Mag-migrate + Mukhang ito ang unang access sa Hub mula sa device na ito. Upang matukoy ito para sa awtorisasyon sa pag-access, kailangan mong pangalanan ang device na ito. + Ang iyong Account Key ay kailangan para mag login galing sa bagong apps o browser. Mahahanap mo ito sa iyong profile. + Walang pahintulot + Upang magpatuloy, mangyaring kumpletuhin ang mga hakbang na kinakailangan sa iyong Hub user profile. + Pumunta sa Profile Kailangan ng Cryptomator ng access sa storage para magamit ang mga lokal na vault Kailangan ng Cryptomator ng access sa storage upang magamit ang awtomatikong pag-upload ng larawan Ang Cryptomator ay nangangailangan ng mga pahintulot sa abiso upang ipakita ang status ng vault halimbawa diff --git a/presentation/src/main/res/values-fr-rFR/strings.xml b/presentation/src/main/res/values-fr-rFR/strings.xml index 88c092594..f4dc963c3 100644 --- a/presentation/src/main/res/values-fr-rFR/strings.xml +++ b/presentation/src/main/res/values-fr-rFR/strings.xml @@ -35,6 +35,11 @@ Aucun bucket correspondant Localisation personnalisée de la Masterkey n\'est pas encore prise en charge Impossible de communiquer avec l\'application F-Droid. Est-elle installée ? + Opération du coffre non prise en charge pour le Hub + L’authentification sur Hub a échoué + Cet appareil est déjà enregistré pour un autre utilisateur. Essayez de changer de compte ou utilisez un autre appareil. + La clé de compte est invalide. + Version Hub non prise en charge . Stockage local @@ -67,7 +72,7 @@ Mot de passe modifié avec succès Coffre - Sélectionné le fichier de clé principal + Sélectionner le fichier de clé principal ou le coffre Placé ici Nom du coffre-fort: %1$s @@ -352,6 +357,23 @@ Migration du mot de passe du coffre requise En raison des améliorations apportées à la sécurité, votre authentification biométrique vous sera demandée deux fois pour chaque coffre-fort afin de re-chiffrer vos mots de passe. Ceci est nécessaire pour continuer à protéger vos mots de passe de coffres-forts à l\'aide des technologies les plus récentes. Si vous ne souhaitez pas vous réauthentifier, les mots de passe stockés seront supprimés. Migrer + Enregistrer l’appareil Hub + Nom + Il semble que ce soit le premier accès au Hub à partir de cet appareil. Afin de l\'identifier pour l\'autorisation d\'accès, vous devez nommer cet appareil. + Le nom ne peut pas être vide. + Clé de compte + Votre clé de compte est requise pour vous connecter depuis de nouvelles applications ou de nouveaux navigateurs. Elle se trouve dans votre profil. + La clé de compte ne peut pas être vide. + Création de l’appareil… + Accès refusé + Votre utilisateur n’a pas encore été autorisé à accéder à ce coffre-fort. Demandez au propriétaire du coffre-fort de l’autoriser.\" + Vérifier la licence Hub + Votre instance Cryptomator Hub a une licence invalide. Veuillez informer un administrateur Hub pour mettre à niveau ou renouveler la licence.\" + Coffre archivé + Ce coffre est archivé et ne peut pas être déverrouillé. Pour le déverrouiller, un propriétaire du coffre doit le désarchiver. + Configuration de l’utilisateur requise + Pour continuer, veuillez compléter les étapes requises dans votre profil d\'utilisateur Hub. + Aller au profil Cryptomator a besoin de l\'accès au stockage pour utiliser les coffres locaux Cryptomator a besoin de l\'accès au stockage pour effectuer le téléversement automatique de photos Cryptomator requiert des permissions de notification pour afficher le statut du coffre, par exemple diff --git a/presentation/src/main/res/values-gl-rES/strings.xml b/presentation/src/main/res/values-gl-rES/strings.xml index 44ec5f82b..e9a15473c 100644 --- a/presentation/src/main/res/values-gl-rES/strings.xml +++ b/presentation/src/main/res/values-gl-rES/strings.xml @@ -61,7 +61,6 @@ O contrasinal cambiouse correctamente Caixa forte - Seleccione o ficheiro da chave mestra Colocar aquí Nome da caixa forte: %1$s diff --git a/presentation/src/main/res/values-hi-rIN/strings.xml b/presentation/src/main/res/values-hi-rIN/strings.xml index ab8376dc1..bd8fe926c 100644 --- a/presentation/src/main/res/values-hi-rIN/strings.xml +++ b/presentation/src/main/res/values-hi-rIN/strings.xml @@ -67,9 +67,12 @@ पासवर्ड सफलतापूर्वक बदला गया। गुप्त तिजोरी - मास्टरकी फ़ाइल का चयन करें | यहाँ रखें वॉल्ट का नाम: %1$s + + फ़ाइल को %1$s यहां ले जाएं + %2$d दस्तावेज को यहां ले जाएं | + मूव करें खाली फ़ोल्डर %1$s पहले बदला गया @@ -285,6 +288,7 @@ डाउनलोड चल रहा है। क्रिप्टोमेटर का नवीनतम संस्करण डाउनलोड हो रहा है। पीछे जाएं + प्रवेश अस्वीकृत diff --git a/presentation/src/main/res/values-hr-rHR/strings.xml b/presentation/src/main/res/values-hr-rHR/strings.xml index f9a480f19..33ae2b109 100644 --- a/presentation/src/main/res/values-hr-rHR/strings.xml +++ b/presentation/src/main/res/values-hr-rHR/strings.xml @@ -67,7 +67,6 @@ Lozinka je uspješno promijenjena Trezor - Odaberi datoteku glavnog ključa Postavi ovdje Ime trezora: %1$s diff --git a/presentation/src/main/res/values-hu-rHU/strings.xml b/presentation/src/main/res/values-hu-rHU/strings.xml index c97cf8990..fccaebf75 100644 --- a/presentation/src/main/res/values-hu-rHU/strings.xml +++ b/presentation/src/main/res/values-hu-rHU/strings.xml @@ -35,6 +35,11 @@ Nem található ilyen adat Az egyéni Masterkey hely választása még nem támogatott Nem sikerült kommunikálni az F-Droid alkalmazással. Nincs telepítve? + A széf művelet nem támogatott a Hub számára + A Hub felé történő hitelesítés sikertelen + Ez az eszköz már egy másik felhasználóhoz van regisztrálva. Próbáljon meg felhasználói fiókot váltani, vagy használjon egy másik eszközt. + Az Account Key érvénytelen. + Nem támogatott Hub verzió. Helyi tároló @@ -67,7 +72,7 @@ Jelszó sikeresen megváltoztatva Széf - Válassza ki a Masterkey fájlt + Válassza ki a mesterkulcs vagy széf fájlt Helyezze ide Trezor neve: %1$s @@ -307,14 +312,25 @@ Figyelem Engedélyezés A Microsoft-alkalmazások egy hibája miatt a szerkesztendő fájlt meg kell osztani ezekkel az alkalmazásokkal az eszközön lévő nyilvános médiamappában. Miután a Cryptomator végzett, a nyilvánosan elérhető fájl ismét törlődik, de a Cryptomatornak nincs befolyása arra, hogy mi történik időközben ezzel a fájlal. Győződj meg róla, hogy tisztában vagy ezzel a viselkedéssel, amikor bekapcsolod ezt az opciót. Ez csak a Microsoft fájltípusokra vonatkozik.\n\nAz bekapcsolás után a Cryptomator újraindul. + Ez a beállítás egy biztonsági funkció, amely megakadályozza, hogy más alkalmazások megtévesszék a felhasználókat, és olyan dolgokat tegyenek, amelyeket nem akarnak.\n\nA letiltással megerősíti, hogy tisztában van a kockázatokkal. Figyelem Letiltás Az app el van takarva + Egy másik alkalmazás jelenít meg valamit a Cryptomator fölött (pl. egy kékfényszűrő vagy éjszakai mód alkalmazás). Biztonsági okokból a Cryptomator le van tiltva.\n\nHogyan engedélyezze a Cryptomator-t Bezár + Kérem, adja hozzá újra a széfeket a(z) %1s felhőhöz + Az alkalmazás ezen verziójára történő frissítés során el kell távolítanunk a következő széfeket az alkalmazásból:\n%2s \n\nEzek a széfek nem kerülnek eltávolításra a felhőből, csak az alkalmazásból. Elnézést a kellemetlenségért, és kérem, adja hozzá újra ezeket a széfeket, hogy folytathassa a munkát velük. + A széf a felhőkapcsolat gyökérmappája + Hozzon létre egy új felhőkapcsolatot, ahol legalább a széf mappájának szülőmappáját választja gyökérkönyvtárként a széf hozzáadásához. + Ez a beállítás egy biztonsági funkció, amely megakadályozza, hogy más alkalmazások megtévesszék a felhasználókat, és olyan dolgokat tegyenek, amelyeket nem akarnak.\n\nA letiltással megerősíti, hogy tisztában van a kockázatokkal. + Biztosan törli ezt a felhőkapcsolatot? + Ez a művelet eltávolítja a felhőkapcsolatot és az összes széfet ebből a felhőből. Töröl %1$d elemet? Biztosan törölni akarja ezeket az elemeket? Biztosan törli ezt a fájlt? Ezzel a mappa teljes tartalma törlődik. Biztos, hogy törölni szeretné ezt a mappát? + A biometrikus hitelesítési funkció inaktiválva + Mivel a kulcs érvénytelenítve lett, a biometrikus hitelesítési funkció inaktiválva lett. Az újbóli engedélyezéshez nyissa meg a Cryptomator beállításait. Adjon meg egy érvényes licencet Úgy érzékeltük, hogy a Cryptomatort a Google Play áruházon kívül telepítette. Adjon meg egy érvényes licencet, amit meg tud vásárolni itt: https://cryptomator.org/android/ A megadott licenc nem érvényes. Győződjön meg arról, hogy jól írta be. @@ -324,16 +340,32 @@ Licenc megerősítése Köszönöm %1$s, hogy megadta érvényes licencét. Frissítés elérhető + Frissítse a Cryptomator-t a legújabb verzióra. Az OK gomb megnyomásával a háttérben letöltjük az alkalmazást, és kérni fogjuk, hogy telepítse. Frissítés most Ugrás a Letöltési oldalra Később Letöltés folyamatban + A Cryptomator legújabb verziójának letöltése folyamatban A mappa egy szimbolikus link + Nem tud navigálni erre a szimbolikus linkre Vissza Nem lehet betölteni a könyvtár tartalmát + A(z) \'%1$s\' felhőmappának nincs érvényes könyvtárfájlja. Lehetséges, hogy a mappát egy másik eszközön hozták létre, és még nem szinkronizálódott teljesen a felhőbe. Kérem, ellenőrizze a felhőben, hogy a következő fájl létezik-e, és nem üres-e:\n%2$s + Nincs több megjeleníthető kép… + A(z) „%1$s” hitelesítő adatai frissítve Ha új pCloud fiókot szeretne hozzáadni, koppintson erre az url-re: www.pcloud.com, jelentkezzen ki a jelenlegi fiókból és koppintson újra a \'+\' gombra az appban, hogy új felhő kapcsolatot létesítsen. + Széf jelszó migráció szükséges + A biztonsági fejlesztések miatt minden széf esetében kétszer kérjük a biometrikus hitelesítést a széf jelszavainak újratitkosításához. Ez szükséges ahhoz, hogy a széf jelszavait a legújabb technológiával védjük továbbra is. Ha nem kívánja ezt végrehajtani, a tárolt jelszavak eltávolításra kerülnek. + Migráció + Hub eszköz regisztrálása + Név + Úgy tűnik, ez az első Hub-hozzáférés erről az eszközről. A hozzáférési jogosultság azonosításához el kell neveznie ezt az eszközt. + A név nem lehet üres. + Account Key + Hozzáférés megtagadva A Cryptomatornak tárhely-hozzáférésre van szüksége a trezorok használatához A Cryptomatornak tárhely-hozzáférésre van szüksége az automatikus fotófeltöltés használatához + A Cryptomatornak értesítési engedélyekre van szüksége például a széf állapotának megjelenítéséhez diff --git a/presentation/src/main/res/values-in-rID/strings.xml b/presentation/src/main/res/values-in-rID/strings.xml index 7368b5705..1287ae95f 100644 --- a/presentation/src/main/res/values-in-rID/strings.xml +++ b/presentation/src/main/res/values-in-rID/strings.xml @@ -4,7 +4,7 @@ Enkripsi Kesalahan terjadi - Autentikasi gagal + Pengesahan gagal Autentikasi gagal, mohon masuk menggunakan %1$s Tidak ada koneksi jaringan Kata sandi salah @@ -27,14 +27,19 @@ Pemeriksaan pembaruan gagal. Tidak ada koneksi internet. Gagal mendekripsi kata sandi WebDAV, harap tambahkan kembali di pengaturan Google Play Services belum terpasang - Autentikasi biometrik dibatalkan + Pengesahan biometrik dibatalkan Versi yang ditentukan di %1$s berbeda dengan %2$s %1$s tidak cocok dengan %2$s ini Terjadi kesalahan saat memuat konfigurasi vault File lokal sudah tidak tersedia setelah beralih kembali ke Cryptomator. Perubahan yang ada tidak dapat disimpan kembali ke cloud. Bucket tidak ada - Lokasi Masterkey khusus belum didukung + Lokasi Kunci utama belum didukung Gagal berkomunikasi dengan aplikasi F-Droid. Belum dipasang? + Operasi berkas tidak didukung Hub + Otentikasi ke Hub gagal + Perangkat ini sudah terdaftar untuk pengguna lain. Cobalah menggunakan akun pengguna atau perangkat yang berbeda. + Kunci Akun tidak sah. + Versi Hub tidak didukung. Penyimpanan lokal @@ -48,13 +53,13 @@ Cari Sebelumnya Lanjut - Urutkan + Sortir A - Z Z - A - Terbaru dulu - Terlama dulu - Terbesar dulu - Terkecil dulu + Diurutkan mulai dari yang terbaru + Diurutkan mulai dari yang terlama + Diurutkan mulai dari yang terbesar + Diurutkan mulai dari yang terkecil Baca lebih lanjut Cloud tidak ada di dalam daftar? @@ -67,7 +72,7 @@ Kasa Sandi berhasil diubah Vault - Pilih file Masterkey + Pilih file Masterkey atau berkas brangkas Tempatkan disini Nama vault: %1$s @@ -306,14 +311,17 @@ Perhatian Aktifkan Karena adanya bug pada aplikasi Microsoft, berkas yang akan diedit harus dibagikan dengan aplikasi ini di folder media publik di perangkat Anda. Setelah Cryptomator dilanjutkan, berkas yang dapat diakses publik akan dihapus lagi, namun Cryptomator tidak dapat memengaruhi apa yang terjadi pada berkas ini untuk sementara. Pastikan Anda mengetahui perilaku ini saat mengaktifkan opsi ini. Ini hanya berlaku untuk jenis berkas Microsoft.\n\nCryptomator akan dimulai ulang setelah aktivasi. + Pengaturan ini adalah fitur keamanan untuk mencegah aplikasi lain mengelabui pengguna melakukan hal-hal yang tidak ingin mereka lakukan.\n\nDengan menonaktifkan, Anda mengonfirmasi bahwa telah menyadari akan bahaya tersebut. Perhatian Matikan Aplikasi terhalang + Aplikasi lain menampilkan sesuatu di atas tampilan Cryptomator (misal, Filter cahaya biru atau aplikasi mode malam). Untuk alasan keamanan, Cryptomator dinonaktifkan.\n\nCara mengaktifkan Cryptomator Tutup Harap tambahkan kembali vault untuk cloud %1s Saat bermigrasi ke versi aplikasi ini, kita perlu menghapus vault berikut dari aplikasi:\n%2s \n\nVault tersebut tidak dihapus dari cloud, tetapi hanya dari aplikasi ini. Maaf atas ketidaknyamanan ini dan harap tambahkan kembali vault ini untuk terus bekerja dengannya. Vault adalah folder induk dari koneksi cloud Buat koneksi cloud baru di mana Anda memilih setidaknya folder induk dari folder vault ini sebagai direktori induk untuk menambahkan vault ini. + Pengaturan ini adalah fitur keamanan untuk mencegah aplikasi lain mengelabui pengguna melakukan hal-hal yang tidak ingin mereka lakukan.\n\nDengan menonaktifkan, Anda mengonfirmasi bahwa telah menyadari akan bahaya tersebut. Anda yakin ingin menghapus koneksi cloud ini? Tindakan ini akan menghapus koneksi cloud dan semua vault pada cloud ini. Hapus %1$d item? @@ -345,6 +353,26 @@ Tidak ada lagi gambar untuk ditampilkan… Kredensial \'%1$s\' diperbarui Jika Anda ingin menambahkan akun pCloud baru, ketuk url berikut www.pcloud.com, keluar dari akun saat ini kemudian ketuk tombol \'+\' lagi di aplikasi ini untuk membuat koneksi cloud baru. + Diperlukan migrasi kata sandi vault + Untuk peningkatan keamanan, Anda akan diminta melakukan autentikasi biometrik dua kali untuk tiap brangkas guna mengenkripsi ulang kata sandi brangkas Anda. Hal ini diperlukan guna melindungi kata sandi brangkas Anda dengan teknologi terkini. Jika Anda tidak ingin hal ini terjadi, kata sandi yang tersimpan akan dihapus. + Migrasi + Mendaftarkan perangkat Hub + Nama + Tampaknya ini adalah akses Hub pertama dari perangkat ini. Untuk mengidentifikasi otorisasi akses ini, Anda perlu memberi nama untuk perangkat ini. + Nama harus diisi. + Kunci Akun + Kunci Akun Anda diperlukan untuk masuk dari aplikasi atau browser baru. Kunci dapat ditemukan di profil Anda. + Kunci akun harus diisi. + Membuat perangkat… + Akses ditolak + Perangkat Anda belum diizinkan mengakses brangkas ini. Minta pemilik brangkas untuk mengizinkannya.\" + Periksa lisensi Hub + Instans Cryptomator Hub Anda memiliki lisensi yang tidak sah. Mintalah kepada administrator Hub untuk meningkatkan atau memperbarui lisensi.\" + Brangkas diarsipkan + Brangkas ini telah diarsipkan dan tidak bisa dibuka. Untuk membukanya, pemilik brangkas harus mengeluarkannya dari arsip. + Diperlukan pengaturan dari pengguna + Untuk melanjutkan, silakan lengkapi langkah-langkah yang diperlukan di profil pengguna Hub Anda. + Buka Profil Cryptomator membutuhkan akses penyimpanan untuk menggunakan vault lokal Cryptomator membutuhkan akses penyimpanan untuk menggunakan unggahan foto otomatis Cryptomator perlu izin pemberitahuan untuk menampilkan status brankas, misalnya diff --git a/presentation/src/main/res/values-it-rIT/strings.xml b/presentation/src/main/res/values-it-rIT/strings.xml index f628d2a27..c98c03330 100644 --- a/presentation/src/main/res/values-it-rIT/strings.xml +++ b/presentation/src/main/res/values-it-rIT/strings.xml @@ -35,6 +35,12 @@ Nessun bucket di questo tipo Posizione personalizzata della Chiave Principale non ancora supportata Impossibile comunicare con l\'app F-Droid. Forse non è installata? + Hub non supporta l\'operazione sulla cassaforte + Autenticazione su Hub non riuscita + Questo dispositivo è già registrato per un utente diverso. Prova a cambiare l\'account utente o usa un altro dispositivo. + Chiave account non valida. + Versione Hub non supportata. + Hub è supportato solo su Android 12 o superiore. Archivio locale @@ -67,7 +73,7 @@ Password modificata con successo Cassaforte - Seleziona il file della chiave principale + Seleziona la chiave principale o il file della cassaforte Posiziona qui Nome cassaforte: %1$s @@ -352,6 +358,23 @@ Richiesta migrazione password della cassaforte A causa di miglioramenti di sicurezza, ti verrà chiesta l\'autenticazione biometrica due volte per ogni cassaforte per ri-crittografare la password della tua cassaforte. Questo è necessario per continuare a proteggere le password della tua cassaforte con la tecnologia più recente. Se non si desidera che ciò accada, le password memorizzate verranno rimosse. Migra + Registra dispositivo Hub + Nome + Sembra che questo sia il primo accesso alle Centrali delle Casseforti da questo dispositivo. Per poterlo identificare ai fini dell\'autorizzazione all\'accesso è necessario dare un nome a questo dispositivo. + Il nome non può essere vuoto. + Chiave dell\'account + La chiave del tuo account è richiesta per accedere da nuove applicazioni o browser. Può essere trovata nel tuo profilo. + La chiave dell\'account non può essere vuota. + Creazione dispositivo… + Accesso negato + Il tuo utente non è ancora stato autorizzato ad accedere a questa cassaforte. Chiedi al proprietario della cassaforte di autorizzarti.\" + Controlla la licenza Hub + La tua istanza Cryptomator Hub ha una licenza non valida. Si prega di informare un amministratore Hub per aggiornare o rinnovare la licenza.\" + Cassaforte archiviata + Questa cassaforte è archiviata e non può essere sbloccata. Per sbloccarla, il proprietario della cassaforte deve ripristinarla dall\'archivio. + Richiesta configurazione dell\'utente + Per procedere, completa i passaggi richiesti nel tuo profilo dell\'Hub. + Vai al profilo Cryptomator ha bisogno dell\'accesso all\'archivio per utilizzare le cassaforti locali Cryptomator ha bisogno di accesso all\'archivio per utilizzare il caricamento automatico delle foto Cryptomator necessita dei permessi di notifica per visualizzare lo stato della cassaforte ad esempio diff --git a/presentation/src/main/res/values-iw-rIL/strings.xml b/presentation/src/main/res/values-iw-rIL/strings.xml index cb3c9cd14..44a7b41cb 100644 --- a/presentation/src/main/res/values-iw-rIL/strings.xml +++ b/presentation/src/main/res/values-iw-rIL/strings.xml @@ -67,7 +67,6 @@ הסיסמא שונתה בהצלחה כספת - בחר קובץ masterkey מקם כאן שם הכספת: %1$s @@ -345,6 +344,7 @@ אין עוד תמונות להציג… פרטי ההתחברות של \'%1$s\' עודכנו אם ברצונך להוסיף חשבון pCloud חדש, לחץ על הקישור www.pcloud.com, התנתק מהחשבון הנוכחי ולחץ על ה \'+\' בישום זה ליצירת חיבור ענן חדש. + הגישה נדחתה Cryptomator זקוק להרשאת גישה לזיכרון המכשיר כדי להשתמש בכספת מקומית Cryptomator זקוק להרשאת גישה לזיכרון המכשיר כדי לבצע העלאה אוטומטית של תמונות Cryptomator צריך הרשאה לשליחת התראות על מנת, לדוגמה, להציג לכם את מצב הכספת diff --git a/presentation/src/main/res/values-ja-rJP/strings.xml b/presentation/src/main/res/values-ja-rJP/strings.xml index 9c634ee58..620fff361 100644 --- a/presentation/src/main/res/values-ja-rJP/strings.xml +++ b/presentation/src/main/res/values-ja-rJP/strings.xml @@ -35,6 +35,11 @@ バケットがありません 好きな場所に Masterkey を置くことはまだできません F-Droidアプリと通信ができません。インストールしてありませんか? + ハブではサポートされていない金庫の操作です + ハブに対する認証に失敗しました + このデバイスは既に別のユーザーに登録されています。ユーザーアカウントを変更するか、別のデバイスを使用してください。 + アカウントキーが無効です。 + サポートされていないハブのバージョンです。 ローカルストレージ @@ -67,7 +72,7 @@ パスワードが正常に変更されました 金庫 - Masterkey ファイルを選択 + マスターキーまたは金庫のファイルを選択 ここにおく 金庫の名前: %1$s @@ -351,6 +356,23 @@ 金庫のパスワード移行が必要です セキュリティ強化のため、金庫ごとに生体認証を2回ずつ要求されます。これは最新技術で金庫のパスワードを保護し続けるために必要です。これを行いたくない場合は保存されたパスワードが削除されます。 移行 + ハブデバイスを登録 + 名前 + + 名前を空にすることはできません。 + アカウントキー + アカウントキーは新しいアプリやブラウザからログインするために必要です。プロフィール中に記載されています。 + アカウントキーは空にできません。 + デバイスを作成中… + アクセスが拒否されました + あなたのユーザーはこの金庫にアクセスする権限がありません。金庫の所有者に権限を認可してもらってください。 + ハブライセンスを確認 + Cryptomator Hub インスタンスのライセンスが無効です。ライセンスをアップグレードまたは更新するには、Hub の管理者にご連絡ください。 + 金庫をアーカイブしました + この金庫はアーカイブされており解錠できません。解錠するには金庫の所有者がアーカイブを取り消す必要があります。 + ユーザー設定が必要です + 続行するにはHubユーザープロフィールで必要な手順を完了してください。 + プロフィールへ移動 ローカルの金庫を使用するには、Cryptomator がストレージにアクセスする許可が必要です 自動的に画像をアップロードするには、Cryptomator がストレージにアクセスする許可が必要です 金庫の状態などを表示するには、Cryptomator に通知権限が必要です。 diff --git a/presentation/src/main/res/values-ko-rKR/strings.xml b/presentation/src/main/res/values-ko-rKR/strings.xml index 4ae63ed71..ced5ce625 100644 --- a/presentation/src/main/res/values-ko-rKR/strings.xml +++ b/presentation/src/main/res/values-ko-rKR/strings.xml @@ -67,7 +67,6 @@ 비밀번호 변경 성공 Vault - 마스터키 파일 선택 여기에 만들기 Vault 이름: %1$s @@ -345,6 +344,7 @@ 더 띄울 사진들이 없습니다. \'%1$s\' 자격증명 업데이트됨 새 pCloud 계정을 추가하려면 이 링크 www.pcloud.com를 누르고, 현재 계정에서 로그아웃한 뒤 여기에서 \'+\'를 다시 눌러서 추가해주세요. + 액세스 거부 Cryptomator에서 로컬 Vault에 접근하기 위해 저장소 접근 권한이 필요합니다. Cryptomator에서 자동으로 사진을 업로드하기 위해 저장소 접근 권한이 필요합니다. Cryptomator는 vault 상태 표시등의 이유로 알림 귄한이 필요합니다 diff --git a/presentation/src/main/res/values-lv-rLV/strings.xml b/presentation/src/main/res/values-lv-rLV/strings.xml index 2543ef4f2..c625c4023 100644 --- a/presentation/src/main/res/values-lv-rLV/strings.xml +++ b/presentation/src/main/res/values-lv-rLV/strings.xml @@ -1,14 +1,42 @@ + Šifrēt + Radās kļūda + Autentifikācija neizdevās + Autentifikācija neizdevās, lūdzu autentificējies izmantojot %1$s + Nav tīkla savienojuma + Nepareiza parole + Fails vai mape jau pastāv. + Krātuves versija %1$s nav atbalstīta. Šī krātuve ir izveidota jaunākā vai vecākā Cryptomator versijā. + Krātuve jau pastāv. + Fails neeksistē. + Krātuve ir slēgta. + Lūdzu, lejupielādē aplikāciju, kas var atvērt šo failu. + Serveris nav atrasts. + Google Play Pakalpojumi nav instalēti + Biometriskā autentifikācija pārtraukta + Lokālā krātuve + Iestatījumi + Meklēt + Atpakaļ Tālāk + Kārtot + A - Z + Z - A + Jaunākie vispirms + Vecākie vispirms + Lielākie vispirms + Mazākie vispirms + Rādīt vairāk + Pievienot Cryptomator Glabātava @@ -26,6 +54,7 @@ Stipra Vispārēji + Meklēt diff --git a/presentation/src/main/res/values-nb-rNO/strings.xml b/presentation/src/main/res/values-nb-rNO/strings.xml index 68c5e59fc..6f730036e 100644 --- a/presentation/src/main/res/values-nb-rNO/strings.xml +++ b/presentation/src/main/res/values-nb-rNO/strings.xml @@ -35,6 +35,7 @@ Ingen slik bøtte Egendefinert lokasjon for Hovednøkkel er foreløpig ikke støttet Mislyktes i å kommunisere med F-Droid-app\'en. Ikke installert? + Denne enheten er allerede registrert for en annen bruker. Prøv å endre brukerkontoen eller bruk en annen enhet. Lokal lagring @@ -67,7 +68,6 @@ Passordet er endret Hvelv - Velg hovednøkkelfil Plasser her Navn på hvelvet: %1$s @@ -346,6 +346,12 @@ Ingen flere bilder å vise… Legitimasjonen til \'%1$s\' er oppdatert Dersom du akter å legge til en ny pCloud-konto, trykk på denne URL-en www.pcloud.com, logg ut fra den nåværende kontoen og trykk på «+» i denne app\'en for å opprette en ny nettskyforbindelse. + Navn + Dette ser ut til å være den første Hub-tilgangen fra denne enheten. For å kunne identifisere den for tilgangsautorisasjon, må du å navngi denne enheten. + Din kontonøkkel kreves for å logge inn fra nye apper eller nettlesere. Den finner du i profilen din. + Ingen tilgang + For å fortsette, fullfør trinnene som kreves i din Hub-brukerprofil. + Gå til profil Cryptomator trenger lagringstilgang for å bruke lokale hvelv Cryptomator trenger lagringstilgang for å bruke automatisk bildeopplasting Cryptomator trenger varseltillatelser for å for eksempel vise hvelvets status diff --git a/presentation/src/main/res/values-nl-rNL/strings.xml b/presentation/src/main/res/values-nl-rNL/strings.xml index 7858d39fb..0fc83bd17 100644 --- a/presentation/src/main/res/values-nl-rNL/strings.xml +++ b/presentation/src/main/res/values-nl-rNL/strings.xml @@ -35,6 +35,11 @@ Deze bucket is niet gevonden Aangepaste Masterkey locatie nog niet ondersteund Kan niet communiceren met de F-Droid app. Niet geïnstalleerd? + Kluis bewerking wordt niet ondersteund voor Hub + Verificatie van Hub is mislukt + Dit apparaat is al geregistreerd voor een andere gebruiker. Probeer de account te wijzigen of gebruik een ander apparaat. + De accountsleutel is ongeldig. + Niet-ondersteunde Hub versie. Lokale opslag @@ -67,7 +72,7 @@ Wachtwoord succesvol gewijzigd Kluis - Selecteer het Masterkey-bestand + Selecteer de hoofdsleutel of het kluisbestand Plaats hier Kluis naam: %1$s @@ -352,6 +357,23 @@ Migratie van kluis wachtwoord is vereist Als gevolg van verbeteringen in veiligheid vragen we u per kluis tweemaal om uw biometrische authenticatie om deze te versleutelen. Dit is nodig om je wachtwoorden met de nieuwste technologie te blijven beschermen. Indien je dit niet wilt, worden de opgeslagen wachtwoorden verwijderd. Migreren + Registreer Hub apparaat + Naam + Dit lijkt de eerste Hub toegang te zijn vanaf dit toestel. Om dit toestel te autoriseren voor toegang, moet u dit toestel benoemen. + Het naamveld kan niet leeg zijn. + Account sleutel + Uw accountsleutel is vereist om in te loggen vanuit nieuwe apps of browsers. Deze kan worden gevonden in uw profiel. + Accountsleutelveld kan niet leeg zijn. + Aanmaken van apparaat… + Toegang geweigerd + Uw gebruiker is nog niet geautoriseerd om toegang te krijgen tot deze kluis. Vraag de eigenaar van de kluis om toestemming te geven.\" + Controleer de Hub-licentie + Uw Cryptomator Hub-exemplaar heeft een ongeldige licentie. Informeer een Hub-beheerder om de licentie te upgraden of te verlengen.\" + Kluis gearchiveerd + Deze kluis is gearchiveerd en kan niet worden ontgrendeld. Om het te ontgrendelen, moet een kluiseigenaar het archief uit het archief halen. + Instellen van gebruiker vereist + Om verder te gaan, gelieve de stappen te voltooien in uw Hub-gebruikersprofiel. + Ga naar Profiel Cryptomator heeft toegang tot opslag nodig om lokale kluizen te kunnen gebruiken Cryptomator heeft toegang tot opslag nodig om automatisch uploaden van foto\'s te kunnen gebruiken Cryptomator heeft notificatie toegang nodig om een voorbeeld van de kluis status weer te geven diff --git a/presentation/src/main/res/values-no-rNO/strings.xml b/presentation/src/main/res/values-no-rNO/strings.xml new file mode 100644 index 000000000..02ca5ecd2 --- /dev/null +++ b/presentation/src/main/res/values-no-rNO/strings.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/presentation/src/main/res/values-pa-rIN/strings.xml b/presentation/src/main/res/values-pa-rIN/strings.xml index 8d658bcfd..18676e46f 100644 --- a/presentation/src/main/res/values-pa-rIN/strings.xml +++ b/presentation/src/main/res/values-pa-rIN/strings.xml @@ -5,60 +5,319 @@ ਇੱਕ ਤਰੁੱਟੀ ਆਈ ਹੈ ਪ੍ਰਮਾਣਿਕਤਾ ਅਸਫਲ + ਪਰਮਾਣੀਕਰਨ ਅਸਫ਼ਲ ਹੈ, %1$s ਵਰਤ ਕੇ ਲਾਗਇਨ ਹੋਵੋ ਕੋਈ ਨੈੱਟਵਰਕ ਕਨੈਕਸ਼ਨ ਨਹੀਂ ਗ਼ਲਤ ਪਾਸਵਰਡ + ਫਾਇਲ ਜਾਂ ਫੋਲਡਰ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ। \"%@\" ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ। + ਫਾਇਲ ਮੌਜੂਦ ਨਹੀਂ ਹੈ। + ਵਾਲਟ ਨੂੰ ਲਾਕ ਕੀਤਾ ਗਿਆ ਹੈ। + ਕਲਾਉਡ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ। + ਸਰਵਰ ਨਹੀਂ ਲੱਭਿਆ। + ਖਾਸ ਅੱਖਰ ਨਹੀਂ ਹੋ ਸਕਦੇ ਹਨ। + ਫਾਇਲ ਦੇ ਨਾਂ ਵਿੱਚ ਖਾਸ ਅੱਖਰ ਨਹੀਂ ਹੋ ਸਕਦੇ ਹਨ। + ਵਾਲਟ ਦੇ ਨਾਂ ਵਿੱਚ ਖਾਸ ਅੱਖਰ ਨਹੀਂ ਹੋ ਸਕਦੇ ਹਨ। + ਅੱਪਡੇਟ ਜਾਂਚ ਲਈ ਅਸਫ਼ਲ ਹੈ। ਕੋਈ ਇੰਟਰਨੈੱਟ ਕਨੈਕਸ਼ਨ ਨਹੀਂ ਹੈ। + Google Play ਸੇਵਾਵਾਂ ਇੰਸਟਾਲ ਨਹੀਂ ਹਨ + ਲੋਕਲ ਸਟੋਰੇਜ਼ ਸੈਟਿੰਗਾਂ + ਖੋਜੋ ਪਿਛਲਾ ਅੱਗੇ + ਲੜੀਬੱਧ \? + Z - A ਨਵੇਂ ਪਹਿਲਾਂ ਪੁਰਾਣੇ ਪਹਿਲਾਂ + ਸਭ ਤੋਂ ਵੱਡੀ ਪਹਿਲਾਂ + ਸਭ ਤੋਂ ਛੋਟੇ ਪਹਿਲਾਂ + ਹੋਰ ਪੜ੍ਹੋ + Cryptomator ਵਿੱਚ ਜੋੜੋ + ਨਵਾਂ ਵਾਲਟ ਬਣਾਓ + ਮੌਜੂਦਾ ਵਾਲਟ ਨੂੰ ਜੋੜੋ + ਹਟਾਓ + ਨਵਾਂ ਵਾਲਟ ਬਣਾਉਣ ਲਈ ਇੱਥੇ ਛੂਹੋ + ਪਾਸਵਰਡ ਨੂੰ ਕਾਮਯਾਬੀ ਨਾਲ ਬਦਲਿਆ ਵਾਲਟ + ਇੱਥੇ ਰੱਖੋ + ਵਾਲਟ ਦਾ ਨਾਂ: %1$s + ਭੇਜੋ + ਖਾਲੀ ਫ਼ੋਲਡਰ + %1$s ਪਹਿਲਾਂ ਸੋਧ ਕੀਤੀ + ਇਸ ਨਾਲ ਸਾਂਝਾ + ਟਿਕਾਣੇ ਨੂੰ ਚੁਣੋ ਚੁਣੋ + ਸਾਂਝਾ ਕਰਨ ਲਈ ਕੁਝ ਨਹੀਂ ਹੈ + %1$s ਵਿੱਚ ਜੋੜੋ + ਫੋਲਡਰ ਨੂੰ ਬਣਾਓ + ਲਿਖਤ ਫਾਇਲ ਨੂੰ ਬਣਾਓ + ਫਾਇਲਾਂ ਨੂੰ ਅੱਪਲੋਡ ਕਰੋ + ਫਾਇਲਾਂ + ਫਾਇਲ ਐਕਸਪੋਰਟ ਕੀਤੀ + ਫਾਇਲਾਂ ਨੂੰ ਐਕਸਪੋਰਟ ਕੀਤਾ + ਐਕਸਪੋਰਟ ਕਰਨ ਲਈ ਕੁਝ ਨਹੀਂ ਹੈ + ਡਾਊਨਲੋਡ ਡਾਇਰੈਕਟਰੀ ਬਣਾਉਣ ਲਈ ਅਸਫ਼ਲ ਹੈ + ਸਾਂਝਾ ਕਰੋ + ਨਾਂ ਬਦਲੋ + ਸੋਧੋ + ਐਕਸਪੋਰਟ + ਹਟਾਓ + ਇਸ ਨਾਲ ਖੋਲ੍ਹੋ… + ਆਈਟਮਾਂ ਨੂੰ ਚੁਣੋ + %1$d ਨੂੰ ਚੁਣਿਆ + ਚੁਣੋ + ਸਭ ਨੂੰ ਚੁਣੋ + ਤਾਜ਼ਾ ਕਰੋ + ਕੋਈ ਕਨੈਕਸ਼ਨ ਨਹੀਂ + ਮੁੜ-ਕੋਸ਼ਿਸ਼ + ਕਾਮਯਾਬੀ ਨਾਲ ਸੰਭਾਲਿਆ + %1$s ਨੂੰ ਇੱਥੇ ਸੰਭਾਲੋ… + ਲਿਖਤ + ਫਾਇਲ + ਫਾਇਲਾਂ + ਫਾਇਲ ਦਾ ਨਾਂ ਵਿਲੱਖਣ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ, ਡੁਪਲੀਕੇਟ ਦੇ ਨਾਂ ਨੂੰ ਬਦਲੋ। + ਸੰਭਾਲਣ ਦੀ ਥਾਂ + ਸੰਭਾਲੋ + ਇੰਕ੍ਰਿਪਸ਼ਨ ਪੂਰੀ ਹੋਈ + ਕਲਾਉਡ ਸੇਵਾ + ਟਿਕਾਣੇ ਨੂੰ ਚੁਣੋ + ਟਿਕਾਣੇ ਨੂੰ ਜੋੜਨ ਲਈ ਇੱਥੇ ਛੂਹੋ + URL + ਵਰਤੋਂਕਾਰ ਨਾਂ ਪਾਸਵਰਡ + ਕਨੈਕਟ + URL ਖਾਲੀ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ। + URL ਗ਼ੈਰ-ਵਾਜਬ ਹੈ। + ਵਰਤੋਂਕਾਰ ਨਾਂ ਖਾਲੀ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ। + ਪਾਸਵਰਡ ਖਾਲੀ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ। + ਦਿਖਾਉਣ ਲਈ ਨਾਂ + ਪਹੁੰਚ ਕੁੰਜੀ + ਗੁਪਤ ਕੁੰਜੀ + ਐਂਡ-ਪੁਆਇੰਟ + ਖੇਤਰ + ਦਿਖਾਉਣ ਵਾਲਾ ਨਾਂ ਖਾਲੀ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ + ਐਕਸੈਸ ਕੁੰਜੀ ਖਾਲੀ ਨਹੀਂ ਹੋ ਸਕਦੀ ਹੈ + ਗੁਪਤ ਕੁੰਜੀ ਖਾਲੀ ਨਹੀਂ ਹੋ ਸਕਦੀ ਹੈ + ਬਕਟ ਕੁੰਜੀ ਖਾਲੀ ਨਹੀਂ ਹੋ ਸਕਦੀ ਹੈ + ਐਂਡ-ਪੁਆਇੰਟ ਜਾਂ ਸਰਵਰ ਖਾਲੀ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ + ਵਾਲਟ ਨਾਂ ਖਾਲੀ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ। + ਵਾਲਟ ਦਾ ਨਾਂ + ਬਣਾਓ + ਪਾਸਵਰਡ ਸੈੱਟ ਕਰੋ ਮੁਕੰਮਲ + ਜ਼ਰੂਰੀ: ਜੇ ਤੁਸੀਂ ਆਪਣਾ ਪਾਸਵਰਡ ਭੁੱਲ ਗਏ ਤਾਂ ਤੁਹਾਡੇ ਡਾਟੇ ਨੂੰ ਬਹਾਲ ਕਰਨ ਦਾ ਕੋਈ ਵੀ ਢੰਗ ਨਹੀਂ ਹੈ। + ਪਾਸਵਰਡ ਨੂੰ ਮੁੜ ਲਿਖੋ + ਵਾਲਟ ਬਣਾਉਣ ਲਈ ਬਹੁਤ ਕਮਜ਼ੋਰ ਹੈ ਕਮਜ਼ੋਰ ਠੀਕ-ਠਾਕ ਮਜ਼ਬੂਤ + ਬਹੁਤ ਮਜ਼ਬੂਤ ਆਮ + ਕਲਾਉਡ ਸੇਵਾਵਾਂ + ਬਾਇਓ-ਮੈਟਰਿਕ ਪਰਮਾਣੀਕਰਨ + ਸਕਰੀਨਸ਼ਾਟ ਲੈਣ ਉੱਤੇ ਪਾਬੰਦੀ ਲਾਓ + ਖੋਜੋ + ਆਪਣੇ-ਆਪ ਲਾਕ ਕਰੋ + ਇਸ ਦੇ ਬਾਅਦ ਲਾਕ + ਜਦੋਂ ਸਕਰੀਨ ਅਸਮਰੱਥ ਹੁੰਦੀ ਹੈ + ਆਪਣੇ-ਆਪ ਫੋਟੋ ਨੂੰ ਅਪੱਲੋਡ ਕਰੋ + ਅੱਪਲੋਡ ਕਰਨ ਲਈ ਵਾਲਟ ਨੂੰ ਚੁਣੋ + ਸਰਗਰਮ + ਫ਼ੌਰਨ ਅੱਪਲੋਡ ਕਰੋ + ਜਦੋਂ ਵੀ ਵਾਲਟ ਅਣ-ਲਾਕ ਹੋਵੇ ਤਾਂ ਸਿੱਧਾ ਅੱਪਲੋਡ ਕਰੋ + ਸਿਰਫ਼ WIFI ਵਰਤ ਕੇ ਅੱਪਲੋਡ ਕਰੋ + ਵੀਡੀਓ ਨੂੰ ਅੱਪਲੋਡ ਕਰੋ + Cryptomator ਦੀ ਵੈੱਬਸਾਈਟ + ਟਵਿੱਟਰ ਉੱਤੇ ਸਾਨੂੰ ਫ਼ਾਲੋ ਕਰੋ + ਫੇਸਬੁੱਕ ਉੱਤੇ ਸਾਨੂੰ ਪਸੰਦ ਕਰੋ + ਕਨੂੰਨੀ + ਲਸੰਸ + ਲਸੰਸ ਦੀਆਂ ਸ਼ਰਤਾਂ + ਸਹਿਯੋਗ + ਮਦਦ ਲਈ ਬੇਨਤੀ + ਡੀਬੱਗ ਮੋਡ + ਲਾਗ ਫਾਇਲ ਨੂੰ ਭੇਜੋ + ਭੇਜਣਾ ਅਸਫ਼ਲ ਹੈ + ਸੁਰੱਖਿਆ ਇਸ਼ਾਰੇ + ਵਰਜ਼ਨ + ਤਕਨੀਕੀ ਸੈਟਿੰਗਾਂ + ਅਣ-ਲਾਕ ਰੱਖਿਆ + OneDrive ਕਨੈਕਸ਼ਨ + WebDAV ਕਨੈਕਸ਼ਨ + S3 ਕਨੈਕਸ਼ਨ + ਲੋਕਲ ਸਟੋਰੇਜ਼ ਟਿਕਾਣੇ + ਇਸ ਵਿੱਚ ਲਾਗਇਨ + ਇਸ ਤੋਂ ਸਾਈਨ ਆਉਟ + ਇੰਸਟਾਲ ਕਰੋ + ਜੋੜੋ + ਵੈੱਬਸਾਈਟ ਰੱਦ ਕਰੋ ਅਣ-ਲਾਕ ਕਰੋ + ਪੁਰਾਣਾ ਪਾਸਵਰਡ + ਨਵਾਂ ਪਾਸਵਰਡ + ਪਾਸਵਰਡ ਨੂੰ ਬਦਲੋ + ਪੁਰਾਣਾ ਪਾਸਵਰਡ ਖਾਲੀ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ। + ਨਵਾਂ ਪਾਸਵਰਡ ਖਾਲੀ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ। + %1$s ਵਾਲਟ ਨਹੀਂ ਲੱਭਿਆ + ਹਟਾਓ + ਫਾਇਲ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ + ਬਦਲੋ + \'%1$s\' ਨਾਂ ਨਾਲ ਫਾਇਲ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ। + ਸਭ ਨੂੰ ਬਦਲੋ + ਮੌਜੂਦਾ ਨੂੰ ਬਦਲੋ + ਬਦਲੋ + \'%1$s\' ਨਾਂ ਨਾਲ ਫਾਇਲ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ। ਕੀ ਤੁਸੀਂ ਇਸ ਨੂੰ ਬਦਲਣਾ ਚਾਹੁੰਦੇ ਹੋ? + ਸਭ ਫਾਇਲਾਂ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹਨ। ਕੀ ਤੁਸੀਂ ਉਹਨਾਂ ਨੂੰ ਬਦਲਣਾ ਚਾਹੁੰਦੇ ਹੋ? + %1$d ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹਨ। ਕੀ ਤੁਸੀਂ ਉਹਨਾਂ ਨੂੰ ਬਦਲਣਾ ਚਾਹੁੰਦੇ ਹੋ? + ਫਾਇਲ ਨੂੰ ਬਦਲਣਾ ਹੈ? + ਫਾਇਲਾਂ ਨੂੰ ਬਦਲਣਾ ਹੈ? + ਫਾਇਲਾਂ ਸਾਂਝੀਆਂ ਕਰਨ ਲਈ ਅਸਮਰੱਥ ਹੈ + ਠੀਕ ਹੈ + ਵਾਲਟ ਨੂੰ ਬਣਾਓ + %1$s ਨੂੰ ਖੋਲ੍ਹਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ + ਵਾਲਟ ਦਾ ਨਾਂ ਬਦਲੋ + ਫੋਲਡਰ ਦਾ ਨਾਂ ਬਦਲੋ + ਫਾਇਲ ਦਾ ਨਾਂ ਬਦਲੋ + ਤੁਹਾਡੇ ਕੋਲ ਨਾ-ਸੰਭਾਲੀਆਂ ਤਬਦੀਲੀਆਂ ਹਨ + ਕੀ ਤੁਸੀਂ ਬਿਨਾਂ ਸੰਭਾਲੇ ਹੀ ਬੰਦ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? + ਖ਼ਾਰਜ ਕਰੋ + ਫਾਇਲ ਦਾ ਨਾਂ + text.txt + ਕੀ ਤੁਸੀਂ ਇਸ ਵਾਲਟ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? + ਇਹ ਕਾਰਵਾਈ ਸਿਰਫ਼ ਇਸ ਸੂਚੀ ਵਿੱਚੋਂ ਹੀ ਵਾਲਟ ਨੂੰ ਹਟਾਏਗੀ, ਪਰ ਅਸਲ ਥਾਂ ਉੱਤੇ ਮੌਜੂਦ ਰਹੇਗਾ। + ਅੱਪਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ… + %2$d ਵਿੱਚੋਂ %1$d ਫਾਇਲ + ਐਕਸਪੋਰਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ(%1$d/%2$d) + ਉਡੀਕੋ… + ਫੋਲਡਰ ਬਣਾਇਆ ਜਾ ਰਿਹਾ ਹੈ… + ਲਿਖਤ ਫਾਇਲ ਬਣਾਈ ਜਾ ਰਹੀ ਹੈ… + ਪਰਮਾਣੀਕਰਨ… + ਨਾਂ ਬਦਲਿਆ ਜਾ ਰਿਹਾ ਹੈ… + ਹਟਾਇਆ ਜਾ ਰਿਹਾ ਹੈ… + ਵਾਲਟ ਅਣ-ਲਾਕ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ… + ਪਾਸਵਰਡ ਬਦਲਿਆ ਜਾ ਰਿਹਾ ਹੈ… + ਵਾਲਟ ਬਣਾਇਆ ਜਾ ਰਿਹਾ ਹੈ… + ਅੱਪਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ… + ਡਾਊਨਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ… + ਇੰਕ੍ਰਿਪਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ… + ਡਿ-ਕ੍ਰਿਪਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ… + ਭੇਜਿਆ ਜਾ ਰਿਹਾ ਹੈ… ਲਾਕ ਕਰੋ + ਵੇਰਵੇ + ਇਹ ਸੁਰੱਖਿਆ ਖ਼ਤਰਾ ਹੋ ਸਕਦਾ ਹੈ। ਮੈਨੂੰ ਪਤਾ ਹੈ ਮੈਂ ਕੀ ਕਰ ਰਿਹਾ/ਰਹੀ ਹਾਂ। + ਬੈਟਰੀ ਅਨੁਕੂਲਣ ਨੂੰ ਅਸਮਰੱਥ ਕਰੋ + ਮੁੜ ਨਹੀਂ ਪੁੱਛਣਾ ਹੈ? + ਸਕਰੀਨ ਲਾਕ ਸੈੱਟ ਕਰਨਾ ਹੈ? + ਸਕਰੀਨ ਲਾਕ ਸੈੱਟ ਕਰੋ + ਧਿਆਨ ਦਿਓ + ਸਮਰੱਥ + ਧਿਆਨ ਦਿਓ + ਅਸਮਰੱਥ ਬੰਦ ਕਰੋ + ਕੀ ਤੁਸੀਂ ਇਸ ਕਲਾਉਡ ਕਨੈਕਸ਼ਨ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? + ਇਹ ਕਾਰਵਾਈ ਕਲਾਉਡ ਕਨੈਕਸ਼ਨ ਅਤੇ ਇਸ ਕਲਾਉਡ ਵਿਚਲੇ ਸਭ ਵਾਲਟਾਂ ਨੂੰ ਹਟਾਏਗੀ। + %1$d ਆਈਟਮਾਂ ਨੂੰ ਹਟਾਉਣਾ ਹੈ? + ਕੀ ਤੁਸੀਂ ਇਹ ਆਈਟਮਾਂ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? + ਕੀ ਤੁਸੀਂ ਇਸ ਫਾਇਲ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? + ਇਸ ਨਾਲ ਫੋਲਡਰ ਵਿਚਲੀ ਸਾਰੀ ਸਮੱਗਰੀ ਨੂੰ ਵੀ ਹਟਾਇਆ ਜਾਵੇਗਾ। ਕੀ ਤੁਸੀਂ ਇਸ ਫੋਲਡਰ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? + ਬਾਹਰ + ਲਸੰਸ ਦੀ ਤਸਦੀਕ + ਆਪਣਾ ਵਾਜਬ ਲਸੰਸ ਦੇਣ ਲਈ %1$s ਦਾ ਧੰਨਵਾਦ ਹੈ। + ਅੱਪਡੇਟ ਮੌਜੂਦ ਹੈ + ਹੁਣੇ ਅੱਪਡੇਟ ਕਰੋ + ਡਾਊਨਲੋਡ ਸਾਈਟ ਉੱਤੇ ਜਾਓ + ਬਾਅਦ ਵਿੱਚ + ਡਾਊਨਲੋਡ ਚੱਲ ਰਿਹਾ ਹੈ ਪਿੱਛੇ + ਡਾਇਰੈਕਟਰੀ ਦੀ ਸਮੱਗਰੀ ਨੂੰ ਲੋਡ ਕਰਨ ਲਈ ਅਸਮਰੱਥ ਹੈ + ਵਾਲਟ ਦੇ ਪਾਸਵਰਡ ਨੂੰ ਮਾਈਗਰੇਟ ਕਰਨ ਦੀ ਲੋੜ ਹੈ + ਤੁਹਾਡੀ Account Key ਨਵੀਆਂ ਐਪਾਂ ਜਾਂ ਬਰਾਊਜ਼ਰਾਂ ਵਿੱਚ ਲਾਗਇਨ ਕਰਨ ਸਮੇਂ ਚਾਹੀਦੀ ਹੈ। ਇਸ ਨੂੰ ਤੁਹਾਡੇ ਪਰੋਫਾਇਲ ਵਿੱਚ ਲੱਭਿਆ ਜਾ ਸਕਦਾ ਹੈ। + ਪਹੁੰਚ ਤੋਂ ਇਨਾਕਰ + ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣੇ Hub ਵਰਤੋਂਕਾਰ ਪਰੋਫਾਇਲ ਵਿੱਚ ਲੋੜੀਂਦੇ ਪੜਾਅ ਪੂਰੇ ਕਰੋ। + ਪ੍ਰੋਫ਼ਾਈਲ ਤੇ ਜਾਓ + ਸਿਫ਼ਰ kB + ਬਾਈਟ + kB + MB + GB + TB + ਸਕਿੰਟ + ਸਕਿੰਟ + ਮਿੰਟ + ਮਿੰਟ + ਘੰਟਾ + ਘੰਟੇ + ਦਿਨ + ਦਿਨ + ਹਫ਼ਤਾ + ਹਫ਼ਤੇ + ਮਹੀਨਾ + ਮਹੀਨੇ + ਸਾਲ + ਸਾਲ + ਬਾਇਓਮੈਟਰਿਕ ਲਾਗਇਨ + ਵਾਲਟ ਦੇ ਪਾਸਵਰਡ ਨੂੰ ਵਰਤੋਂ + ਫਾਇਲਾਂ ਨੂੰ ਆਪਣੇ-ਆਪ ਅੱਪਲੋਡ ਕਰਨ ਲਈ ਅਸਮਰੱਥ + ਵਾਲਟ ਅਣ-ਲਾਕ ਹੈ: %1$d + %1$s ਵਿੱਚ ਆਪਣੇ-ਆਪ ਲਾਕ ਕਰੋ + ਸਭ ਲਾਕ ਹਨ + ਅੱਪਲੋਡ ਨੂੰ ਰੱਦ ਕਰੋ + %1d/%2d ਨੂੰ ਅੱਪਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ + ਕੈਸ਼ + ਕੁੱਲ ਕੈਸ਼ ਆਕਾਰ + ਕੈਸ਼ ਨੂੰ ਮਿਟਾਓ + ਇਸ ਲਈ ਰਜਿਸਟਰ ਹੈ + %1$s + ਅੱਪਡੇਟ ਚੈਕ ਕਰਨ ਦਾ ਅੰਤਰਾਲ + ਅੱਪਡੇਟ ਲਈ ਜਾਂਚ ਕਰੋ + %1$s ਨੂੰ ਆਖਰੀ ਵਾਰ ਚਲਾਇਆ + ਫ਼ੌਰਨ + 1 ਮਿੰਟ + 2 ਮਿੰਟ + 5 ਮਿੰਟ + 10 ਮਿੰਟ + ਕਦੇ ਨਹੀਂ + 50 MB + 100 MB + 250 MB + 500 MB + 1 GB + 5 GB + ਸਟਾਈਲ + ਆਟੋਮੈਟਿਕ (ਸਿਸਟਮ ਮੁਤਾਬਕ) ਹਲਕਾ ਗੂੜ੍ਹਾ + ਦਿਨ \'ਚ ਇੱਕ ਵਾਰ diff --git a/presentation/src/main/res/values-pl-rPL/strings.xml b/presentation/src/main/res/values-pl-rPL/strings.xml index a6365a047..875f95543 100644 --- a/presentation/src/main/res/values-pl-rPL/strings.xml +++ b/presentation/src/main/res/values-pl-rPL/strings.xml @@ -35,6 +35,11 @@ Nie ma takiego bucketu Niestandardowa lokalizacja klucza głównego jest jeszcze nieobsługiwana Nie udało się połączyć z aplikacją F-Droid. Nie ma aplikacji? + Operacja sejfu nie jest obsługiwana dla Huba + Uwierzytelnianie w Hubie nie powiodło się + To urządzenie jest już zarejestrowane dla innego użytkownika. Spróbuj zmienić konto użytkownika lub użyć innego urządzenia. + Klucz konta jest nieprawidłowy. + Nieobsługiwana wersja Hubu. Pamięć wewnętrzna @@ -67,7 +72,7 @@ Hasło zostało pomyślnie zmienione Sejf - Wybierz plik klucza głównego + Wybierz klucz główny lub plik sejfu Umieść tutaj Nazwa sejfu: %1$s @@ -354,6 +359,23 @@ Wymagana migracja hasła sejfu Z powodu ulepszenia zabezpieczeń, dla każdego sejfu zostaniesz dwukrotnie poproszony o weryfikację biometryczną celem ponownego zaszyfrowania haseł. Jest to konieczne, aby nadal chronić hasła za pomocą najnowszej technologii. Jeśli sobie tego nie życzysz, przechowywane hasła zostaną usunięte. Migruj + Zarejestruj urządzenie Hub + Nazwa + Wygląda że jest to pierwszy dostęp do Huba z tego urządzenia. Aby zidentyfikować go w celu autoryzacji dostępu, musisz nazwać to urządzenie. + Nazwa nie może być pusta. + Klucz konta + Twój Klucz Konta jest wymagany do zalogowania się z nowych aplikacji lub przeglądarek. Można go znaleźć w twoim profilu. + Klucz konta nie może być pusty. + Tworzenie urządzenia… + Brak dostępu + Twoje urządzenie nie zostało jeszcze upoważnione do dostępu do tego sejfu. Poproś właściciela sejfu o autoryzację.\" + Sprawdź licencję Huba + Twoja instancja Cryptomator Hub ma nieprawidłową licencję. Poinformuj administratora Huba o uaktualnieniu lub odnowieniu licencji.\" + Zarchiwizowano sejf + Ten sejf jest zarchiwizowany i nie może być odblokowany. Aby go odblokować, właściciel sejfu musi go odarchiwizować. + Wymagana konfiguracja użytkownika + Aby kontynuować, wykonaj kroki wymagane w profilu użytkownika Hub. + Przejdź do profilu Cryptomator potrzebuje dostępu do pamięci lokalnej, aby uzyskać dostęp do sejfu Cryptomator potrzebuje dostępu do pamięci lokalnej, aby automatycznie przesyłać zdjęcia Cryptomator potrzebuje uprawnień do powiadomień, aby wyświetlić np. status sejfu diff --git a/presentation/src/main/res/values-pt-rBR/strings.xml b/presentation/src/main/res/values-pt-rBR/strings.xml index 88c54cb89..74a9329dc 100644 --- a/presentation/src/main/res/values-pt-rBR/strings.xml +++ b/presentation/src/main/res/values-pt-rBR/strings.xml @@ -35,6 +35,11 @@ Bucket não encontrado Localização de Masterkey personalizada ainda não é suportada Falha na comunicação com o aplicativo F-Droid. Ele está instalado? + Operação de cofre não suportada para Hub + A autenticação para o Hub falhou + Este dispositivo já está registrado para um usuário diferente. Tente alterar a conta de usuário ou use um dispositivo diferente. + A Chave da Conta é inválida. + Versão do Hub não suportada. Armazenamento Local @@ -67,7 +72,7 @@ Senha alterada com sucesso Cofre - Selecionar arquivo masterkey + Selecione o arquivo masterkey ou vault Coloque aqui Nome do Cofre: %1$s @@ -352,6 +357,23 @@ Migração da senha do cofre necessária Devido a aprimoramentos de segurança, você será solicitado pela sua autenticação biométrica duas vezes para cada cofre para recriptografar as senhas do seu cofre. Isto é necessário para continuar a proteger as senhas do seu cofre com a tecnologia mais recente. Se você não deseja que isso aconteça, as senhas armazenadas serão removidas. Migrar + Registrar o dispositivo do Hub + Nome + Parece ser o primeiro acesso do Hub a partir deste dispositivo. Para identificá-lo para autorização de acesso, você precisa nomear este dispositivo. + Nome não pode estar vazio. + Chave da Conta + Sua Chave de Conta é necessária para acessar a partir de novos aplicativos ou navegadores. Ela pode ser encontrada no seu perfil. + Chave da Conta não pode estar vazia. + Criando dispositivo… + Acesso negado + Seu dispositivo ainda não foi autorizado a acessar este cofre. Peça ao proprietário do cofre para autorizá-lo.\" + Verifique a licença do Hub + Sua instância do Cryptomator Hub possui uma licença inválida. Por favor, informe a um administrador do Hub que atualize ou renove a licença.\" + Cofre arquivado + Este cofre está arquivado e não pode ser desbloqueado. Para desbloqueá-lo, o proprietário do cofre deve desarquivá-lo. + Configuração de usuário necessária + Para prosseguir, por favor preencha as etapas necessárias no seu perfil de usuário do Hub. + Ir para o Perfil Cryptomator precisa de permissão de acesso ao armazenamento para fazer upload de arquivos Cryptomator precisa de permissão de acesso ao armazenamento para fazer upload de arquivos O Cryptomator precisa de permissões para notificar o estado dos cofres, por exemplo. diff --git a/presentation/src/main/res/values-pt-rPT/strings.xml b/presentation/src/main/res/values-pt-rPT/strings.xml index 69a576c5d..31d8818af 100644 --- a/presentation/src/main/res/values-pt-rPT/strings.xml +++ b/presentation/src/main/res/values-pt-rPT/strings.xml @@ -35,6 +35,12 @@ Bucket inexistente A localização de Chave-Mestra personalizada ainda não é suportada Falha em comunicar-se com a aplicação F-Droid. Não está instalado? + Operação do cofre não suportada pelo Hub + Falha na autenticação do Hub + Este dispositivo já está registado por um utilizador diferente. Tente alterar a conta de utilizador ou use um dispositivo diferente. + A chave da conta é inválida. + Versão do Hub não suportada. + Hub só é suportado no Android 12 ou superior. Armazenamento local @@ -67,7 +73,7 @@ Palavra-passe alterada com sucesso Cofre - Selecionar ficheiro MasterKey + Selecionar ficheiro chave-mestra ou o ficheiro do cofre Colocar aqui Nome do cofre: %1$s @@ -352,6 +358,23 @@ É necessária a migração da palavra-passe do cofre Devido a melhorias de segurança, ser-lhe-á pedida a sua autenticação biométrica duas vezes para cada cofre, para voltar a encriptar as suas palavras-passe dos cofres. Isto é necessário para continuar a proteção das palavras-passe dos cofres com a última tecnologia. Se preferir que isso não aconteça, as palavras-passe serão removidas. Migrar + Registar o dispositivo Hub + Nome + Este parece ser o primeiro acesso ao Hub a partir deste dispositivo. De maneira a identificá-lo para autorizar o acesso, é necessário dar um nome a este dispositivo. + Nome não pode estar vazio. + Chave da Conta + A sua chave de conta é necessária para iniciar sessão em novos aplicativos ou navegadores. Ela pode ser encontrada no seu perfil. + A chave da conta não pode estar vazia. + Criando dispositivo… + Acesso negado + O seu utilizador ainda não foi autorizado a aceder este cofre. Peça ao proprietário do cofre para autorizá-lo.\" + Verificar a licença do Hub + A sua instância do Cryptomator Hub possui uma licença inválida. Por favor, informe o administrador do Hub para atualizar ou renovar a sua licença.\" + Cofre arquivado + Este cofre está arquivado e não pode ser desbloqueado. Para desbloqueá-lo, o proprietário do cofre deve desarquivá-lo. + Configuração do utilizador necessária + Para continuar, por favor conclua as etapas exigidas no seu perfil de utilizador no Hub. + Vá para o Perfil Cryptomator precisa de acesso ao armazenamento para usar cofres locais Cryptomator precisa de acesso ao armazenamento para usar o envio automático de fotos O Cryptomator precisa de permissões de notificação para exibir, como exemplo, o estado do cofre diff --git a/presentation/src/main/res/values-ro-rRO/strings.xml b/presentation/src/main/res/values-ro-rRO/strings.xml index 2b69129a0..4e37f4b59 100644 --- a/presentation/src/main/res/values-ro-rRO/strings.xml +++ b/presentation/src/main/res/values-ro-rRO/strings.xml @@ -7,7 +7,7 @@ Autentificare eșuată Autentificare eșuată, vă rugăm să vă conectați din nou prin %1$s Nu există conexiune la rețea - Parolă greşită + Parolă greșită Un fișier sau dosar există deja. Seiful cu versiunea %1$s nu este suportată. Acest seif a fost creat cu o versiune mai veche sau mai nouă de Cryptomator. Lipsește fișierul %1$s din dosarul seif. Asigurați-vă că acest fișier există în folderul seif din cloud. @@ -35,6 +35,7 @@ Nu există așa găleată Nu este suportată încă utilizarea locației personalizate pentru cheia master Nu s-a putut comunicat cu aplicația F-Droid. Este posibil ca aplicația sa nu fie instalata? + Acest dispozitiv este deja înregistrat pentru un alt utilizator. Încercați să schimbați contul de utilizator sau folosiți un alt dispozitiv. Stocare locală @@ -67,7 +68,6 @@ Parola a fost modificată cu succes Seif - Selectaţi fişierul Masterkey Plasează aici Numele seifului: %1$s @@ -318,6 +318,7 @@ În timp ce migrăm la această versiune de aplicație, trebuie să eliminăm următoarele seifuri din aplicație:\n%2s \n\nAceste seifuri nu sunt eliminate din cloud, ci doar din această aplicație. Ne cerem scuze pentru inconveniența creata şi vă rugăm să adăugați din nou aceste seifuri pentru a continua să le folosiți. Seiful este dosarul principal al conexiunii cloud Creați o nouă conexiune cloud unde selectați dosarul părinte al acestui seif ca dosarul de baza pentru adăugarea acestui seif. + setare Sunteţi sigur că doriţi să eliminaţi această conexiune cloud? Această acțiune va elimina conexiunea în cloud și toate seifurile acestui cloud. Ștergeți %1$d elemente? @@ -349,6 +350,18 @@ Nu mai sunt imagini de afișat… Acreditări ale \'%1$s\' au fost actualizate Dacă doriți să adăugaţi un cont nou de tip pCloud, faceţi clic pe acest link www.pcloud. om, deconectați-vă de la contul curent, și faceți clic din nou pe \'+\' din această aplicație pentru a crea o nouă conexiune cloud. + Este necesară migrarea parolei seifului + Din cauza actualizărilor de securitate, ți se va cere autentificarea biometrică de două ori pentru fiecare seif ca să re-criptați parolele seifului. Acest lucru este necesar pentru a continua să îți protejezi parolele seifului cu ajutorul tehnologiei de ultimă oră. Dacă nu doriţi să se întâmple acest lucru, parolele stocate vor fi eliminate. + Migrează + Nume + Se pare că este prima data când accesați Hub-ul de pe acest dispozitiv. Trebuie sa denumiți acest dispozitiv pentru autorizarea accesului. + Cheia contului dvs. este necesară pentru a vă conecta din aplicații sau browsere noi. Aceasta poate fi găsită în profilul dvs. + Acces respins + Verifica licență Hub-ului + Seif arhivat + Acest seif este arhivat și nu poate fi deblocat. Pentru deblocare proprietarul seifului trebuie să îl dezarhiveze. + Pentru a continua, vă rugăm să finalizaţi paşii necesari în profilul dumneavoastra din Hub. + Mergi la profil Cryptomator are nevoie de acces la stocare pentru a utiliza seifuri locale Cryptomator are nevoie de acces la stocare pentru a folosi încărcarea automată a fotografiilor Cryptomator are nevoie de permisiuni de notificare pentru a afișa starea seifului de exemplu diff --git a/presentation/src/main/res/values-ru-rRU/strings.xml b/presentation/src/main/res/values-ru-rRU/strings.xml index ce9db3e06..daaa130cf 100644 --- a/presentation/src/main/res/values-ru-rRU/strings.xml +++ b/presentation/src/main/res/values-ru-rRU/strings.xml @@ -35,6 +35,12 @@ Нет такого бакета Произвольное расположение Masterkey пока не поддерживается Не удалось связаться с приложением F-Droid. Не установлено? + Операция с хранилищем не поддерживается для хаба + Ошибка аутентификации через хаб + Это устройство уже зарегистрировано другим пользователем. Попробуйте изменить учётную запись или используйте другое устройство. + Неверный ключ учётной записи. + Неподдерживаемая версия хаба. + Хаб поддерживается только на Android 12 и новее. Локальное хранилище @@ -67,7 +73,7 @@ Пароль успешно изменён Хранилище - Выберите файл Masterkey + Выберите файл Masterkey или хранилище Поместить сюда Имя хранилища: %1$s @@ -354,6 +360,23 @@ Требуется миграция пароля В связи с повышением безопасности вам будет предложено дважды использовать биометрическую аутентификацию для каждого хранилища для повторного шифрования паролей. Это необходимо, чтобы продолжать защищать ваши пароли с помощью новейших технологий. Если вы не хотите, чтобы это произошло, сохранённые пароли будут удалены. Миграция + Зарегистрировать хаб-устройство + Имя + Похоже, это первый доступ к Hub с данного устройства. Чтобы идентифицировать его для предоставления доступа, нужно дать устройству имя. + Имя не может быть пустым. + Ключ учётной записи + Для входа в систему из новых приложений или браузеров требуется ключ вашего аккаунта. Он находится в вашем профиле. + Ключ учётной записи не может быть пустым. + Создание устройства… + Нет доступа + Ваш пользователь еще не авторизован для доступа к этому хранилищу. Попросите владельца хранилища об авторизации. + Проверить лицензию на хаб + У хаба Cryptomator неверная лицензия. Попросите администратора хаба обновить или продлить лицензию. + Хранилище архивировано + Это хранилище архивировано и не может быть разблокировано. Чтобы разблокировать, владелец хранилища должен его разархивировать. + Требуется настройка пользователя + Для продолжения выполните необходимые шаги в вашем профиле пользователя Hub. + Перейти в профиль Для использования локальных хранилищ необходим доступ к месту хранения Для автозагрузки фото у Cryptomator должен быть доступ к месту хранения Для отображения состояния хранилища Cryptomator требуется разрешение на уведомление diff --git a/presentation/src/main/res/values-sk-rSK/strings.xml b/presentation/src/main/res/values-sk-rSK/strings.xml index ec7bfbeda..fde4e85f3 100644 --- a/presentation/src/main/res/values-sk-rSK/strings.xml +++ b/presentation/src/main/res/values-sk-rSK/strings.xml @@ -67,7 +67,6 @@ Heslo úspešne zmenené Trezor - Zvoľte hlavný kľúčový súbor Umiestniť sem Meno trezoru: %1$s @@ -309,14 +308,17 @@ Upozornenie Povoliť Kvôli chybe v aplikáciách spoločnosti Microsoft musí byť upravovaný súbor zdieľaný s týmito aplikáciami vo verejnom priečinku médií vo vašom zariadení. Po obnovení programu Cryptomator sa verejne prístupný súbor opäť odstráni, ale program Cryptomator nemôže ovplyvniť, čo sa s týmto súborom medzitým stalo. Pri aktivácii tejto možnosti sa uistite, že ste si vedomí tohto správania. Toto sa vzťahuje len na typy súborov spoločnosti Microsoft.\n\nCryptomator sa po aktivácii znovu spustí. + Toto nastavenie je bezpečnostná vlastnosť a zabraňuje ostatným aplikáciám klamať užívateľov robiť veci čo nechcú robiť.\n\nVypnutím súhlasíte s tým žeste si vedomí rizika. Upozornenie Zakázať Aplikácia je zatmavená + Ďalšia aplikácia zobrazuje niečo na vrchu Cryptomator-a (ako napr. modré svetlo alebo nočný režim). Z bezpečnostných dôvodov je Cryptomator zakázaný.\n\nAko povoliť Cryptomator Zavrieť Prosím zadajte znovu trezory pre %1s cloud Počas migrácie na túto verziu aplikácie potrebujeme odstrániť nasledujúce trezory z aplikácie:\n%2s \n\n Tieto trezory nebudú odstránené z cloudu, ale len z tejto aplikácie. Prepáčte za nepohodlie a prosím znovu zadajte trezory pre pokračovanie ich používania. Trezor je koreňovým adresárom cloudového spojenia Vytvorte nové cloudové pripojenie kde vyberiete minimálne nadradený adresár tohto trezora ako koreňový adresár pre pridanie tohot trezora. + Toto nastavenie je bezpečnostná vlastnosť a chráni ostatné aplikácie pred klamaním užívateľov robiť veci, ktoré nechcú obiť.\n\nVypnutím súhlasíte, že <a href="https://docs.cryptomator.org/en/latest/android/settings/#screen-security">ste si vedomí rizika. Ste si istý že chcete odstrániť toto cloudové pripojenie? Táto akcia odstráni pripojenie cloudu a všetky trezory tohto cloudu. Odstrániť %1$d položky? @@ -348,6 +350,18 @@ Niet už viac obrázkov k zobrazeniu… Prístupy k %1$s aktualizované Ak zamýšľate pridať nový pCloud účet, kliknite na tento link www.pcloud.com, odhláste sa zo súčasného účtu a opätovne kliknite na \'+\' v tejto aplikácii pre vytvorenie nového cloudového pripojenia. + Pre migráciu peňaženky je požadované heslo + Migrovať + Meno + Zdá sa, že ide o prvý prístup k Hub-u z tohto zariadenia. Z dôvodu identifikácie prístupovej autorizácie, je potrebné pomenovať toto zariadenie. + Názov nemôže byť prázdny. + Kľúč účtu + Váš kľúč účtu je vyžadovaný pre prihlásenie z nových aplikácii alebo prehliadačov. Môžete ho nájsť vo vašom profile. + Prístup zamietnutý + Trezor archivovaný + Vyžaduje sa nastavenie užívateľom + Pre pokračovanie, prosím splňte kroky požadované vo Vašom užívateľskom Hub profile. + Prejsť na profil Cryptomator potrebuje prístup k úložisku pre prácu s lokálnymi trezormy Cryptomator potrebuje prístup k úložisku pre automatické nahrávanie fotografii Cryptomator potrebuje povolenie notifikácií, napríklad na zobrazenie stavu trezoru diff --git a/presentation/src/main/res/values-sl-rSI/strings.xml b/presentation/src/main/res/values-sl-rSI/strings.xml index 8fa5e57b8..2f23ffc02 100644 --- a/presentation/src/main/res/values-sl-rSI/strings.xml +++ b/presentation/src/main/res/values-sl-rSI/strings.xml @@ -67,7 +67,6 @@ Geslo je bilo uspešno spremenjeno Trezor - Izberite datoteko z glavnim ključem Shrani tu Ime trezorja: %1$s Premakni @@ -294,6 +293,10 @@ Posodobi zdaj Pozneje Nazaj + Zdi se, da prvič dostopate do Hub-a s te naprave. Napravo morate poimenovati, da jo lahko identificirate za avtorizacijo za dostop. + Vaš Account Key je zahtevan za prijavo z novih aplikacij ali brskalnikov. Najdete ga lahko v svojem profilu. + Za nadaljevanje, prosimo zaključite zahtevane korake v svojem Hub uporabniškem profilu. + Pojdi v profil diff --git a/presentation/src/main/res/values-sv-rSE/strings.xml b/presentation/src/main/res/values-sv-rSE/strings.xml index b4c7576c6..c5a4dafad 100644 --- a/presentation/src/main/res/values-sv-rSE/strings.xml +++ b/presentation/src/main/res/values-sv-rSE/strings.xml @@ -35,6 +35,11 @@ Ingen sådan bucket Anpassad Masterkey-plats stöds inte ännu Det gick inte att kommunicera med F-Droid-appen. Inte installerad? + Valvoperation stöds inte för Hub + Autentisering mot Hub misslyckades + Denna enhet är redan registrerad för en annan användare. Försök att ändra användarkontot eller använda en annan enhet. + Kontonyckeln är ogiltig. + Hub-versionen stöds inte. Lokal lagring @@ -67,7 +72,7 @@ Lösenordet har ändrats Valv - Välj Masterkey-fil + Välj masterkey eller valvfil Placera här Valvets namn: %1$s @@ -352,6 +357,23 @@ Lösenorden behöver överföras till nya valvet På grund av säkerhetsförbättringar kommer du att bli ombedd att använda din biometriska autentisering två gånger för varje valv för att omkryptera dina valvlösenord. Detta är nödvändigt för att fortsätta att skydda ditt valv lösenord med den senaste tekniken. Om du inte vill att detta ska ske kommer de sparade lösenorden att tas bort. Migrera + Registrera navenhet + Namn + Detta verkar vara den första Hub-åtkomsten från den här enheten. För att identifiera den för åtkomstbehörighet, måste du namnge den här enheten. + Namnet kan inte vara tomt. + Konto nyckel + Din kontonyckel krävs för att logga in från nya appar eller webbläsare. Den finns i din profil. + Kontonyckeln kan inte vara tom. + Skapar enhet… + Åtkomst nekad + Din användare har ännu inte behörighet att komma åt detta valv. Be valvägaren att auktorisera det.\" + Kontrollera navlicens + Din Cryptomator Hub-instans har en ogiltig licens. Vänligen informera en Hub administratör för att uppgradera eller förnya licensen.\" + Valvet arkiverades + Detta valv är arkiverat och kan inte låsas upp. För att låsa upp det måste valvägaren avarkivera det. + Användarkonfiguration krävs + För att fortsätta, vänligen fyll i de steg som krävs i din Hub-användarprofil. + Gå till profil Cryptomator behöver åtkomst till lagringsutrymmet för att använda lokala valv Cryptomator behöver åtkomst till lagringsutrymmet för att kunna använda automatisk uppladdning av foton Cryptomator behöver aviseringsbehörigheter för att till exempel visa valvstatus diff --git a/presentation/src/main/res/values-sw-rTZ/strings.xml b/presentation/src/main/res/values-sw-rTZ/strings.xml index c6d4f4751..e9b5c7b2f 100644 --- a/presentation/src/main/res/values-sw-rTZ/strings.xml +++ b/presentation/src/main/res/values-sw-rTZ/strings.xml @@ -67,7 +67,6 @@ Neno la siri limebadilishwa kwa ufanisi Kuba - Teua faili ya masterkey Weka hapa Jina la kuba: %1$s Hamisha @@ -339,6 +338,7 @@ Hakuna picha zaidi za kuonyesha… Hati za utambulisho za \'%1$s\' zimesasishwa Ikiwa ulitaka kuongeza akaunti mpya ya pCloud, gusa url hii www.pcloud.com, ondoka kwenye akaunti ya sasa na uguse tena \'+\' katika programu hii ili kuunda muunganisho mpya wa wingu. + Ufikiaji umekataliwa Cryptomator inahitaji ufikiaji wa kuhifadhi ili kutumia kuba za ndani Cryptomator inahitaji ufikiaji wa kuhifadhi ili kutumia upakiaji wa picha kiotomatiki Cryptomator inahitaji ruhusa za taarifa ili kuonyesha hali ya kuba kwa mfano diff --git a/presentation/src/main/res/values-ta-rIN/strings.xml b/presentation/src/main/res/values-ta-rIN/strings.xml index 7be6154a0..9d61f9d2e 100644 --- a/presentation/src/main/res/values-ta-rIN/strings.xml +++ b/presentation/src/main/res/values-ta-rIN/strings.xml @@ -56,7 +56,6 @@ கடவுச்சொல் வெற்றிகரமாக மாற்றப்பட்டது பெட்டகம் - தலைமைவிசை கோப்பை தேர்ந்தெடுக்கவும் இங்கே வைக்கவும் பெட்டகத்தின் பெயர்: %1$s @@ -110,15 +109,20 @@ புனைப்பெயர் பகுதி + ரகசிய குறியீடு குறிப்பிடவில்லை முடிந்தது + மீண்டும் கடவுச்சொல்லை பதிவிடவும் + பெட்டகத்தை உண்டாக்குயம் அளவிற்க்கு வலிமையாக இல்லை பலவீனமானது சுமார் வலுவான + மிகவும் கடினமான மேகக்கணி சேவைகள் உயிரியளவுகள் உறுதிசெய்தல் + தேடு நேரடி தேடல் இதன்பிறகு செயலியை பூட்டு diff --git a/presentation/src/main/res/values-th-rTH/strings.xml b/presentation/src/main/res/values-th-rTH/strings.xml index 62b7d62e6..d2cd8920a 100644 --- a/presentation/src/main/res/values-th-rTH/strings.xml +++ b/presentation/src/main/res/values-th-rTH/strings.xml @@ -8,6 +8,7 @@ Vault ถูกล็อก ไม่พบเซิฟเวอร์ การยืนยันตัวตนด้วยไบโอเมตริกซ์ถูกยกเลิก + อุปกรณ์นี้ลงทะเบียนไว้แล้วสำหรับผู้ใชอื่น โปรดลองเปลี่ยนบัญชีผู้ใช้หรือลงทะเบียนอุปกรณ์อื่น @@ -190,6 +191,8 @@ ย้อนกลับ เนื่องจากการปรับปรุงด้านความปลอดภัย คุณจะถูกขอให้ตรวจสอบไบโอเมตริกซ์สองครั้งสำหรับแต่ละ vault เพื่อทำการเข้ารหัสรหัสผ่านของคุณใหม่ นี่เป็นสิ่งจำเป็นเพื่อรักษาความปลอดภัยรหัสผ่านของคุณด้วยเทคโนโลยีล่าสุด หากคุณไม่ต้องการ รหัสผ่านที่เก็บไว้จะถูกลบ โอนย้าย + การเข้าถึงถูกปฏิเสธ + ไปยังโปร์ไฟล์ diff --git a/presentation/src/main/res/values-tr-rTR/strings.xml b/presentation/src/main/res/values-tr-rTR/strings.xml index 49dd19eab..ac86b854c 100644 --- a/presentation/src/main/res/values-tr-rTR/strings.xml +++ b/presentation/src/main/res/values-tr-rTR/strings.xml @@ -7,12 +7,12 @@ Kimlik doğrulama başarısız Kimlik doğrulama başarısız, lütfen %1$s kullanarak giriş yapınız Ağ bağlantısı yok - Şifre hatalı + Hatalı parola Dosya veya klasör zaten var. %1$s kasa sürümü desteklenmiyor. Bu kasa, Cryptomator\'ın daha eski veya daha yeni bir sürümüyle oluşturuldu. Kasa klasörünüzde %1$s dosyası eksik. Bu dosyanın buluttaki kasa klasörünüzde bulunduğundan emin olun. Kasa zaten var. - Dosya mevcut değil. + Dosya bulunmuyor. Kasa kilitlendi. Bulut zaten var. Lütfen bu dosyayı açabilen bir uygulama edinin. @@ -23,18 +23,23 @@ Dosya adları özel karakterler içeremez. Kasa adı özel karakterler içeremez. Genel bir hata oluştu ve güncelleme kontrolü başarısız oldu. - Güncelleme kontrolü başarısız. Hesaplanan hash değeri ile yüklenen dosyanın ki eşleşmiyor + Güncelleme kontrolü başarısız. Hesaplanan sağlama özeti, yüklenen dosyanınkiyle ile eşleşmiyor Güncelleme kontrolü başarısız oldu. İnternet bağlantısı yok. WebDAV parolasının şifresi çözülemedi, lütfen ayarlarda yeniden ekleyin Google Play Hizmetleri yüklenmedi Biyometrik kimlik doğrulama iptal edildi %1$s içinde belirtilen sürüm %2$s\'den farklı %1$s, bu %2$s ile eşleşmiyor - Cüzdan ayarlarını yüklerken genel hata - Cryptomator geri döndükten sonra, lokal dosya artık mevcut olmaz. Muhtemel değişiklikler bulutta tekrar oluşturulamaz. + Kasa yapılandırması yüklenirken genel hata + Cryptomator\'a geri döndükten sonra yerel dosya artık mevcut değil. Olası değişiklikler buluta geri aktarılamaz. Böyle bir kova yok Özel ana anahtar konumu henüz desteklenmiyor F-Droid uygulamasıyla iletişim kurulamadı. Yüklü değil mi? + Kasa işlemi Hub için desteklenmiyor + Hub\'a karşı kimlik doğrulama başarısız oldu + Bu cihaz zaten farklı bir kullanıcı için kayıtlı. Kullanıcı hesabını değiştirmeyi veya farklı bir cihaz kullanmayı deneyin. + Hesap Anahtarı geçersiz. + Desteklenmeyen Hub sürümü. Yerel depolama @@ -51,10 +56,10 @@ Sırala A - Z Z - A - Yeniden eskiye - Eskiden yeniye - Büyükten küçüğe - Küçükten büyüğe + Önce en yenisi + Önce en eskisi + Önce en büyüğü + Önce en küçüğü Daha fazlasını oku Bulut listede yok mu? @@ -63,21 +68,21 @@ Yeni kasa oluştur Mevcut kasayı ekle Kaldır - Yeni bir kasa oluşturmak için buraya dokunun - Şifre başarıyla değiştirildi + Yeni kasa oluşturmak için buraya dokunun + Parola başarıyla değiştirildi Kasa - Ana anahtar dosyasını seçin - Buraya kaydet + Ana anahtar veya kasa dosyasını seç + Buraya yerleştir Kasa adı: %1$s %1$s öğesini şuraya taşı %2$d öğeyi şuraya taşı Taşı - Boş + Klasör boş %1$s önce değiştirildi - İle paylaş + Şununla paylaş Bir varış noktası seçin Seç Paylaşacak bir şey yok @@ -86,14 +91,14 @@ Metin dosyası oluştur Dosya yükle Dosyalar - Dosya başarıyla dışa aktarıldı - Dosyalar başarıyla dışa aktarıldı + Dosya dışa aktarıldı + Dosyalar dışa aktarıldı Dışa aktarılacak bir şey yok İndirme dizini oluşturulamadı Paylaş - Yeniden adlandır + Yeniden Adlandır Düzenle - Dışa aktar + Dışa Aktar Sil Bununla aç… Öğeleri seç @@ -107,11 +112,11 @@ Başarıyla kaydedildi %1$s kaydet… - Metin - Dosya - Dosyalar + metin + dosya + dosyalar Dosya adları benzersiz olmalıdır, lütfen mükerrer olanları yeniden adlandırın. - Konumu kaydet + Kaydetme konumu Kaydet Şifreleme tamamlandı @@ -120,7 +125,7 @@ Bir yer seçin Konum eklemek için buraya dokunun Sunucu WebDAV uyumlu görünmüyor - Dizinlerin açılmasını destekleyen dosya yöneticisi bulunamadı + Dizin açmayı destekleyen dosya yöneticisi bulunamadı URL Kullanıcı adı @@ -134,7 +139,7 @@ Görünen Ad Erişim Anahtarı Gizli Anahtar - Mevcut kova + Mevcut Kova Uç nokta Bölge Görünen ad boş olamaz @@ -147,19 +152,19 @@ Kasa adı Oluştur - Şifreyi belirle + Parola belirle Parola, yeniden yazılan parolayla eşleşmiyor. Bitti ÖNEMLİ UYARI: Parolanızı unutursanız, verilerinizi kurtarmanın herhangi bir yolu yoktur. - Yeni şifreyi tekrar yazın - Cüzdan oluşturmak için çok zayıf - Güçsüz + Yeni parolayı tekrar yazın + Kasa oluşturmak için çok zayıf + Zayıf Makul - Kuvvetli + Güçlü Çok güçlü Genel - Kaydetme konumları + Bulut servisleri Biyometrik kimlik doğrulama Biyometrik kimlik doğrulamayı etkinleştir Yüz tanıma kilidini (varsa) onaylayın @@ -172,10 +177,10 @@ Sorgulama yaparken, arama sonuçlarını güncelle Glob kalıbı kullanarak ara Glob kalıbı kullan. alice.*.jpg gibi - Otomatik Kilitleme + Otomatik kilitleme Kilitleme zamanı Ekran devre dışı bırakıldığında - Otomatik Fotoğraf Yükleme + Otomatik fotoğraf yükleme Yükleme için kasa seçin Etkinleştir Arka planda görüntüleri yakalayın ve seçilen kasanın kilidi açıldığında yüklemeye başlayın @@ -210,7 +215,7 @@ pCloud bağlantıları S3 bağlantıları Yerel depolama konumları - Giriş + Giriş yap Oturumunu kapat @@ -232,11 +237,11 @@ İptal Kilidi Aç - Eski şifre - Yeni şifre - Şifreyi değiştir - Eski şifre boş olamaz. - Yeni şifre boş olamaz. + Eski Parola + Yeni Parola + Parolayı değiştir + Eski parola boş olamaz. + Yeni parola boş olamaz. Yeni parola, parola tekrarı ile eşleşmiyor. %1$s kasası bulunamadı @@ -261,7 +266,7 @@ %1$s açılamıyor Lütfen bu dosyayı açabilecek bir uygulama indirin veya cihazınıza kaydetmek ister misiniz? Kasayı yeniden adlandır - Dosyayı yeniden adlandır + Klasörü yeniden adlandır Dosyayı yeniden adlandır Kaydedilmemiş değişiklikleriniz mevcut Kaydetmeden çıkmak istiyor musunuz? @@ -271,7 +276,7 @@ Bu kasayı kaldırmak istediğinizden emin misiniz? Bu işlem kasayı yalnızca bu listeden kaldıracak ve fiziksel olarak silmeyecektir. Yükleniyor… - %1$d / %2$d dosyası + Dosya %1$d / %2$d Dışa aktarılıyor (%1$d/%2$d) Lütfen bekleyin… Klasör oluşturuluyor… @@ -280,7 +285,7 @@ Yeniden adlandırılıyor… Siliniyor… Kasanın kilidi açılıyor… - Şifre değiştiriliyor… + Parola değiştiriliyor… Kasa oluşturuluyor… Yükleniyor… İndiriliyor… @@ -294,16 +299,16 @@ Bu bir güvenlik riski olabilir! Ne yaptığımı biliyorum. Pil optimizasyonlarını devre dışı bırak Arka planda çalışmadan yeni resimler ve videoları almak için pil optimizasyonlarını devre dışı bırakmanız gerekiyor. Ancak endişelenmeyin, %1$s fazla enerji tüketmez.\n\nUygulamak için \'Optimize edilmedi\'yi \'Tüm uygulamalar\' olarak değiştirin, %1$s\'yi seçin ve bu iletişim kutusunda \'%2$s\' tıkladıktan sonra \'Optimize etme\'ye dokunun. - Bir daha sorma? + Tekrar sorma HTTP\'nin kullanımı güvensizdir. Bunun yerine HTTPS kullanmanızı öneririz. Riskleri biliyorsanız, HTTP ile devam edebilirsiniz. HTTPS\'ye geç HTTPS kullanılsın mı? - Ekran kilidi ayarlanmadı. Kimlik bilgilerinizi güvenli bir şekilde saklamak için, Tamam ile bir kalıp veya şifre ayarlayınız. + Ekran kilidi ayarlanmadı. Kimlik bilgilerinizi güvenli bir şekilde saklamak için, Tamam ile bir desen veya parola ayarlayınız. Ekran kilidi ayarlansın mı? Ekran kilidini ayarla Sistemde temel kimlik doğrulama kurulumu yok Bu hizmeti kullanmak için en az bir parmağınızı/yüzünüzü kaydedin. - Bu modda, hassas veriler cihazınızdaki bir günlük dosyasına (örn. Dosya adları ve yolları) yazılabilir. Şifreler, tanımlama vb. bilgiler hariç tutulmuştur.\n\nHata ayıklama modunu mümkün olan en kısa sürede devre dışı bırakmayı unutmayın. + Bu modda, hassas veriler cihazınızdaki bir günlük dosyasına (örn. dosya adları ve yolları) yazılabilir. Parolalar, tanımlama vb. bilgiler hariç tutulmuştur.\n\nHata ayıklama modunu mümkün olan en kısa sürede devre dışı bırakmayı unutmayın. Dikkat Etkinleştir Microsoft uygulamalarındaki bir hata nedeniyle, düzenlenecek dosyanın cihazınızdaki herkese açık bir medya klasöründe bu uygulamalarla paylaşılması gerekir. Cryptomator yeniden başlatıldıktan sonra, herkese açık dosya tekrar silinir, ancak Cryptomator bu arada bu dosyaya ne olduğunu etkileyemez. Bu seçeneği etkinleştirirken bu davranışın farkında olduğunuzdan emin olun. Bu sadece Microsoft dosya türleri için geçerli olacaktır.\n\nCryptomator aktivasyondan sonra yeniden başlayacaktır. @@ -315,7 +320,7 @@ Kapat Lütfen %1s bulutu için kasaları yeniden ekleyin Bu uygulama sürümüne geçiş yaparken aşağıdaki kasaları uygulamadan kaldırmamız gerekiyor:\n%2s \n\nBu kasalar buluttan değil, yalnızca bu uygulamadan kaldırılır. Rahatsızlık için özür dileriz ve onlarla çalışmaya devam etmek için lütfen bu kasaları yeniden ekleyin. - Vault, bulut bağlantısının kök klasörüdür + Kasa, bulut bağlantısının kök klasörüdür Bu kasayı eklemek için kök dizin olarak bu kasa klasörünün en azından üst klasörünü seçtiğiniz yeni bir bulut bağlantısı oluşturun. Bu ayar bir güvenlik özelliğidir ve diğer uygulamaların kullanıcıları yapmak istemedikleri şeyleri yapmaları için kandırmasını önler.\n\nDevre dışı bırakarak risklerin farkında olduğunuzu onaylamış olursunuz. Bu bulut bağlantısını kaldırmak istediğinizden emin misiniz? @@ -327,20 +332,20 @@ Biyometrik kimlik doğrulama özelliği devre dışı bırakıldı Anahtar geçersiz olduğu için biyometrik kimlik doğrulama özelliği devre dışı bırakıldı. Yeniden etkinleştirmek için Cryptomator ayarlarını açın. Geçerli bir lisans sağlayın - Cryptomator\'u Google Play Store kullanmadan yüklediğinizi tespit ettik. https://cryptomator.org/android/ adresinden satın alınabilecek geçerli bir lisans edinin lütfen. + Cryptomator\'ı Google Play Store kullanmadan yüklediğinizi tespit ettik. https://cryptomator.org/android/ adresinden satın alınabilecek geçerli bir lisans edinin. Sağlanan lisans geçerli değil. Doğru girdiğinizden emin olun. Sağlanan anahtar, bir masaüstü destek sertifikasıdır. Lütfen geçerli bir lisans girin. Lisans verilmemiştir. Lütfen geçerli bir lisans girin. Çıkış Lisans onayı Geçerli lisansınızı sağladığınız için teşekkür ederiz %1$s. - Güncelleme uygun + Güncelleme mevcut Cryptomator\'ı en son sürüme güncellemek için Tamam\'a dokunun lütfen. Uygulamayı arka planda indireceğiz ve sizden yüklemenizi isteyeceğiz. Şimdi güncelle İndirme sitesine git Sonra - Çalışmayı indir - Cryptomator\'ın son sürümünü indir + İndirme sürüyor + Cryptomator\'ın son sürümünü indiriliyor Klasör sembolik bir bağlantıdır Bu sembolik bağlantıya gidemezsin Geri @@ -349,11 +354,28 @@ … göstermek için daha fazla resim yok %1$s kimlik bilgileri güncellendi Yeni bir pCloud hesabı eklemeyi düşünüyorsanız, bu url www.pcloud.com dokunun, mevcut hesaptan çıkın ve yeni bir bulut bağlantısı oluşturmak için \'+\'. tekrar dokunun. - Kasa şifre geçişi gerekli - Güvenlik geliştirmeleri nedeniyle, kasa şifrelerinizi yeniden şifrelemek için her kasa için iki kez biyometrik kimlik doğrulamanız istenecektir. Bu, kasa şifrelerinizi en son teknoloji ile korumaya devam etmek için gereklidir. Bunun olmasını istemezseniz, saklanan şifreler kaldırılacaktır. + Kasa parolası geçişi gerekli + Güvenlik geliştirmeleri nedeniyle, kasa parolalarınızı yeniden şifrelemek için her kasa için iki kez biyometrik kimlik doğrulamanız istenecektir. Bu, kasa parolalarınızı en son teknoloji ile korumaya devam etmek için gereklidir. Bunun olmasını istemezseniz, saklanan parolalar kaldırılacaktır. Taşı - Cryptomator\'un yerel kasaları kullanmak için depolama erişimine ihtiyacı var - Cryptomator\'un otomatik fotoğraf yüklemesi için depolama erişimine ihtiyacı var + Hub cihazını kaydet + Ad + Bu cihazdan ilk Hub erişimi gibi görünüyor. Erişim yetkilendirmesini tanımlamak için bu cihazı isimlendirmeniz gerekir. + İsim boş olamaz. + Hesap Anahtarı + Yeni uygulamalardan veya tarayıcılardan giriş yapmak için Hesap Anahtarınız gereklidir. Profilinizde bulunabilir. + Hesap Anahtarı boş olamaz. + Cihaz oluşturuluyor… + Erişim engellendi + Kullanıcınız henüz bu kasaya erişim için yetkilendirilmedi. Kasa sahibinden yetki vermesini isteyin.” + Hub lisansını kontrol et + Cryptomator Hub örneğinizin geçersiz bir lisansı var. Lütfen lisansı yükseltmek veya yenilemek için bir Hub yöneticisini bilgilendirin.” + Kasa arşivlendi + Bu kasa arşivlenmiştir ve kilidi açılamaz. Kilidi açmak için kasa sahibinin arşivi açması gerekir. + Kullanıcı kurulumu gerekli + Devam etmek için lütfen Hub kullanıcı profilinizde gerekli adımları tamamlayın. + Profile Git + Cryptomator\'ın yerel kasaları kullanmak için depolama erişimine ihtiyacı var + Cryptomator\'ın otomatik fotoğraf yüklemesi için depolama erişimine ihtiyacı var Cryptomator, örneğin kasa durumunu görüntülemek için bildirim izinlerine ihtiyaç duyar @@ -382,10 +404,10 @@ Biyometrik giriş Biyometrik kimlik bilgilerinizi kullanarak giriş yapın - Kasa şifresini kullan + Kasa parolasını kullan Dosyaları otomatik olarak yükleyemiyor - Kasaların Kilidi Açıldı: %1$d + Kilidi açık kasalar: %1$d %1$s içinde otomatik kilitlenecek Tümünü kilitle Yüklemeyi iptal et @@ -395,7 +417,7 @@ Kasaya %1$d görüntü yüklendi Otomatik fotoğraf yükleme başarısız oldu Yükleme sırasında genel hata oluştu. - Yükleme için seçilen klasör artık mevcut değil! Ayarlara gidin ve yeni bir tane seçin + Yükleme için seçilen klasör artık mevcut değil. Ayarlara gidin ve yeni bir tane seçin Kasa yükleme sırasında kilitlendi, devam etmek için lütfen kasayı yeniden açın Otomatik yükleme için belirtilen kasa artık mevcut değil. Kimlik doğrulama işlemini yenilemek için dokun. @@ -404,13 +426,13 @@ En son sürüm yüklendi Doğrulanıyor… Önbellek - Yeniden açıldıklarında daha sonra yeniden kullanılmak üzere, cihazda yerel olarak şifrelenmiş yakın zamanda erişilen dosyaları önbelleğe alın + Yeniden açıldıklarında daha sonra yeniden kullanılmak üzere cihazda yerel olarak şifrelenmiş yakın zamanda erişilen dosyaları önbelleğe alın Toplam önbellek boyutu Önbelleği temizle Değişiklikler, uygulama yeniden başlatıldığında uygulanacak Kayıtlı %1$s - Kontrol aralığını güncelle + Güncelleme kontrol aralığı Güncellemeleri kontrol et Son çalıştırma %1$s Bulut başına önbellek boyutu @@ -420,7 +442,7 @@ 2 dakika 5 dakika 10 dakika - Hiçbir zaman + Asla 50 MB 100 MB @@ -429,8 +451,8 @@ 1 GB 5 GB - Görünüm modu - Otomatik + Stil + Otomatik (sisteme göre) Aydınlık Karanlık diff --git a/presentation/src/main/res/values-ug-rCN/strings.xml b/presentation/src/main/res/values-ug-rCN/strings.xml new file mode 100644 index 000000000..19891687e --- /dev/null +++ b/presentation/src/main/res/values-ug-rCN/strings.xml @@ -0,0 +1,64 @@ + + + + پاروللاش + + خاتالىق كۆرۈلدى + دەلىللەش مەغلۇپ بولدى + دەلىللەش مەغلۇپ بولدى، %1$s نى ئىشلىتىپ كىرىڭ + تور يوق + پارول خاتا + ئوخشاش نامدىكى ھۆججەت ياكى قىسقۇچ بار. + ئامبار %1$s نەشىرىنى قوللىمايدۇ. بۇ ئامبار Cryptomator نىڭ كونا ياكى يېڭى نەشرى بىلەن ياسالغان. + ھۆججەت ئامبىرىڭىزدا %1$s تېپىلمىدى. بۇ ھۆججەتنىڭ بۇلۇت سۇپىسىدىكى ئامبىرىڭىزدا بارلىقىغا كاپالەتلىك قىلىڭ. + ئوخشاش ئامبار با. + ھۆججەت تېپىلمىدى. + بۇ ئۈسكۈنە ئاللىقاچان باشقا بىر ئىشلەتكۈچى ئۈچۈن تىزىملانغان. ئىشلەتكۈچى ھېساباتىنى ئۆزگەرتىشكە ئۇرۇنۇڭ ياكى باشقا بىر ئۈسكۈنە ئىشلىتىڭ. + + + + + كېيىنكى + + + + ئامبار + + + + + + پارول + + + + تامام + ئاجىز + ئوتتۇرا + بىخەتەر + + ئومۇمىي + + + + + + بىكار قىل + قۇلۇپنى ئاچ + + قۇلۇپلا + ياپ + قايت + كىرىش رەت قىلىندى + + + + + مىنۇتتا + + + + + + + diff --git a/presentation/src/main/res/values-uk-rUA/strings.xml b/presentation/src/main/res/values-uk-rUA/strings.xml index f8695960f..5304fec14 100644 --- a/presentation/src/main/res/values-uk-rUA/strings.xml +++ b/presentation/src/main/res/values-uk-rUA/strings.xml @@ -35,6 +35,11 @@ Немає такого кошика (сховища) Користувацьке розташування універсального ключа ще не підтримується Не вдалося зв\'язатися із застосунком F-Droid. Його встановлено? + Операція зі сховищем не підтримується для Hub + Автентифікація через Hub не вдалася + Цей пристрій вже зареєстровано для іншого користувача. Спробуйте змінити обліковий запис користувача або скористайтеся іншим пристроєм. + Ключ облікового запису недійсний. + Непідтримувана версія Hub. Локальне сховище @@ -67,7 +72,7 @@ Пароль успішно змінено Сховище - Виберіть файл майстер-ключа + Виберіть файл masterkey або сховища Розмістити тут Назва сховища: %1$s @@ -354,6 +359,23 @@ Необхідна міграція пароля сховища У зв\'язку з покращеннями безпеки, вам буде запропоновано двічі пройти біометричну автентифікацію для кожного сховища, щоб повторно зашифрувати паролі сховища. Це необхідно для продовження захисту паролів вашого сховища з використанням найновішої технології. Якщо ви не хочете, щоб це сталося, збережені паролі будуть видалені. Мігрувати + Зареєструвати пристрій Hub + Назва + Схоже, це перша спроба доступу до Hub з цього пристрою. Для того, щоб ідентифікувати його для надання доступу, вам потрібно назвати цей пристрій. + Назва не може бути пуста. + Ключ облікового запису + Ваш ключ облікового запису необхідний для входу в систему з нових програм. Його можна знайти у своєму профілі. + Ключ облікового запису не може бути порожнім. + Створення текстового файлу… + У доступі відмовлено + Ваш користувач ще не авторизований для доступу до цього сховища. Попросіть власника сховища авторизувати вас.\" + Перевірити ліцензію Hub + У вашій інстанції Cryptomator Hub недійсна ліцензія. Будь ласка, повідомте адміністратору Hub про необхідність оновлення або поновлення ліцензії.\" + Сховище заархівовано + Це сховище заархівовано і не може бути розблоковано. Для розблокування його власник сховища повинен розархівувати його. + Необхідна настройка користувача + Щоб продовжити, будь ласка, завершіть обов\'язкові кроки у вашому профілі користувача Hub. + Перейти до профілю Для використання локальних сховищ необхідно надати Cryptomator доступ до місця зберігання Для автоматичного завантаження фото необхідно надати Cryptomator доступ до місця зберігання Для відображення статусу сховища необхідно надати Cryptomator дозвіл на сповіщення diff --git a/presentation/src/main/res/values-vi-rVN/strings.xml b/presentation/src/main/res/values-vi-rVN/strings.xml index 93bef3170..c52158b0e 100644 --- a/presentation/src/main/res/values-vi-rVN/strings.xml +++ b/presentation/src/main/res/values-vi-rVN/strings.xml @@ -67,7 +67,6 @@ Thay đổi mật khẩu thành công Vault - Chọn tệp khoá chính Đặt ở đây Tên vault: %1$s @@ -345,6 +344,8 @@ Không còn hình ảnh để hiển thị… Đã cập nhật thông tin xác thực của \'%1$s\' Nếu bạn định thêm tài khoản pCloud mới, hãy nhấn vào url này www.pcloud.com, đăng xuất khỏi tài khoản hiện tại và nhấn lại vào \'+\' trong ứng dụng này để tạo kết nối đám mây mới. + Truy cập bị từ chối + Xem hồ sơ Cryptomator cần quyền truy cập bộ nhớ để sử dụng vault cục bộ Cryptomator cần quyền truy cập bộ nhớ để sử dụng tính năng tự động tải ảnh lên Cryptomator cần quyền thông báo để hiển thị trạng thái vault chẳng hạn diff --git a/presentation/src/main/res/values-zh-rCN/strings.xml b/presentation/src/main/res/values-zh-rCN/strings.xml index 250998e6b..63047d9d5 100644 --- a/presentation/src/main/res/values-zh-rCN/strings.xml +++ b/presentation/src/main/res/values-zh-rCN/strings.xml @@ -35,6 +35,12 @@ 没有这样的 bucket 尚不支持自定义 Masterkey 路径 无法找到 F-Droid 应用程序。可能未安装? + Hub 不支持保险库操作 + Hub 身份验证失败 + 此设备已被注册给另一位用户。请尝试更改用户帐户或使用别的设备。 + 账户密钥无效 + 不支持的 Hub 版本 + Hub 仅支持 Android 12 及以上版本。 本地存储 @@ -67,7 +73,7 @@ 密码修改成功 保险库 - 请选择 Masterkey 文件 + 选择 Masterkey 或保险库文件 在此添加 保险库名称:%1$s @@ -351,6 +357,23 @@ 需要迁移保险库密码 由于安全性能增强,每个保险库都会要求您进行两次生物识别验证,以重新加密您的保险库密码。这是继续使用最新技术保护您的保险库密码所必需的。如果您不希望这样做,存储的密码将被删除。 迁移 + 注册 Hub 设备 + 名称 + 这似乎是设备的首次 Hub 访问。为了识别它以进行访问授权,您需要命名此设备 + 名称不能为空 + 账户密钥 + 从新应用或浏览器登录需要您的账户密钥,您可以在个人中心找到它 + 账户密钥不能为空 + 正在创建设备… + 拒绝访问 + 您的用户尚未授权访问此保险库,请联系保险库所有者 + 检查 Hub 许可证 + 此 Cryptomator Hub 实例许可证无效,请联系 Hub 管理员升级或者续订许可证 + 私密库已存档 + 此保险库已存档且无法解锁。要想解锁,必须由其所有者取消存档 + 需要用户设置 + 要继续,请完成 Hub 用户中心所需的步骤 + 前往个人中心 Cryptomator 需要存储权限以使用本地保险库 Cryptomator 需要存储权限以自动上传图片 Cryptomator 需要通知权限以显示保险库状态等 diff --git a/presentation/src/main/res/values-zh-rHK/strings.xml b/presentation/src/main/res/values-zh-rHK/strings.xml index a05a889e3..717760efc 100644 --- a/presentation/src/main/res/values-zh-rHK/strings.xml +++ b/presentation/src/main/res/values-zh-rHK/strings.xml @@ -35,6 +35,7 @@ 沒有指定的儲存槽(bucket) 尚未支援自訂主金鑰位置 無法連結到 F-Droid,是否未安裝 F-Droid? + 此裝置已註冊為其他使用者。請嘗試更改使用者帳戶或使用其他裝置。 本機儲存空間 @@ -67,7 +68,6 @@ 密碼已成功更改 加密庫 - 選擇主金鑰檔案 存放在此 加密庫名稱:%1$s @@ -345,6 +345,7 @@ 無更多圖片可供顯示… 「%1$s 」的帳戶資訊已更新 如果您想要新增一個 pCloud 帳戶,請在點擊此連結 www.pcloud.com 後登出目前的帳號,再點擊 App 中的「+」來建立新的雲端連結。 + 拒絕存取 Cryptomator 需要儲存權限以存取本機上的加密庫 Cryptomator 需要儲存權限以便開啟自動圖片上傳。 Cryptomator 需要通知權限以顯示加密檔案庫的狀態等。 diff --git a/presentation/src/main/res/values-zh-rTW/strings.xml b/presentation/src/main/res/values-zh-rTW/strings.xml index 5aa061bd8..2520121b9 100644 --- a/presentation/src/main/res/values-zh-rTW/strings.xml +++ b/presentation/src/main/res/values-zh-rTW/strings.xml @@ -35,6 +35,12 @@ 沒有該儲存貯體 尚未支援自訂主金鑰位置 無法找到F-Droid應用程式。可能未安裝? + Hub不支援的加密檔案庫操作 + Hub 驗證失敗 + 其他使用者已在此裝置上註冊。請切換至該使用者帳戶或使用其他裝置進行註冊。 + 帳戶金鑰無效。 + 不支援的 Hub 版本。 + Hub 僅支援 Android 12 及更高版本 本機儲存空間 @@ -67,7 +73,7 @@ 密碼變更成功 加密檔案庫 - 選擇主金鑰檔案 + 請選擇主金鑰或加密檔案庫。 放在此 加密檔案庫名稱:%1$s @@ -351,6 +357,23 @@ 必要的檔案庫密碼遷移 基於安全加強,每個檔案庫將會要求您進行兩次生物辨識驗證以重新加密您的檔案庫密碼。這是為了繼續使用最新技術來保護檔案庫密碼所需的必要動作。如果您不想這麼做,儲存的密碼將會被刪除。 遷移 + 註冊Hub裝置 + 名稱 + 似乎這是第一次 Hub 訪問此設備。為了辨識它以授權訪問,您需要命名此設備。 + 名稱不可以空白 + 帳戶金鑰 + 需要您的帳戶金鑰才能從新應用或瀏覽器登入。 可以在你的個人資料中找到它。 + 帳戶金鑰不能為空。 + 正在建立裝置… + 拒絕存取 + 您的使用者尚未被授權存取此加密檔案庫。請要求加密檔案庫的擁有者授權。 + 檢查 Hub 授權 + 您的Cryptomator Hub實例擁有無效的授權。請通知Hub管理員升級或續訂授權。 + 加密檔案庫已封存。 + 此加密檔案庫已被封存,無法解鎖。要解鎖,必須由加密檔案庫的擁有者取消封存。 + 需要設定使用者 + 請完成您使用者檔案中所需的步驟,以便繼續進行。 + 轉到個人資料 Cryptomator 需要存儲訪問權限用以使用本地加密檔案庫 Cryptomator 需要存儲權限以便開啟自動圖片上傳 Cryptomator 需要通知權限以顯示加密檔案庫的狀態等。 diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index 11c5702f5..d3e34cdce 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -44,6 +44,13 @@ Custom Masterkey location not supported yet Failed to communicate with the F-Droid app. Not installed? + Vault operation not supported for Hub + Authentication against Hub failed + This device is already registered for a different user. Try to change the user account or use a different device. + The Account Key is invalid. + Unsupported Hub version. + Hub is only supported on Android 12 and above. + @@ -98,7 +105,7 @@ Vault @string/screen_vault_list_action_add_existing_vault - Select masterkey file + Select masterkey or vault file @string/screen_vault_list_action_create_new_vault Place here Vault name: %1$s @@ -524,6 +531,33 @@ Migrate @string/screen_vault_list_vault_action_delete + Register Hub device + @string/screen_enter_vault_name_button_text + Name + This seems to be the first Hub access from this device. In order to identify it for access authorization, you need to name this device. + Name can\'t be empty. + Account Key + Your Account Key is required to login from new apps or browsers. It can be found in your profile. + Account Key can\'t be empty. + Creating device… + + Access denied + Your user has not yet been authorized to access this vault. Ask the vault owner to authorize it." + @string/dialog_unable_to_share_positive_button + + Check Hub license + Your Cryptomator Hub instance has an invalid license. Please inform a Hub administrator to upgrade or renew the license." + @string/dialog_unable_to_share_positive_button + + Vault archived + This vault is archived and cannot be unlocked. To unlock it, a vault owner must unarchive it. + @string/dialog_unable_to_share_positive_button + + User setup required + To proceed, please complete the steps required in your Hub user profile. + Go to Profile + @string/dialog_button_cancel + Cryptomator needs storage access to use local vaults Cryptomator needs storage access to use auto photo upload Cryptomator needs notification permissions to display vault status for example diff --git a/src/fdroid/fastlane/metadata/android/de-DE/changelogs/default.txt b/src/fdroid/fastlane/metadata/android/de-DE/changelogs/default.txt index be2ad06ed..926c5be64 100644 --- a/src/fdroid/fastlane/metadata/android/de-DE/changelogs/default.txt +++ b/src/fdroid/fastlane/metadata/android/de-DE/changelogs/default.txt @@ -1 +1 @@ -- Migration von Cloud-Zugangs-Tokens und Tresor-Passwörtern zu AES 256bit GCM +- Hub-Unterstützung hinzugefügt diff --git a/src/fdroid/fastlane/metadata/android/en-US/changelogs/default.txt b/src/fdroid/fastlane/metadata/android/en-US/changelogs/default.txt index 837a30de8..d72028770 100644 --- a/src/fdroid/fastlane/metadata/android/en-US/changelogs/default.txt +++ b/src/fdroid/fastlane/metadata/android/en-US/changelogs/default.txt @@ -1 +1 @@ -- Migrate cloud access tokens and vault passwords to AES 256bit GCM +- Add Hub support diff --git a/src/fdroid/fastlane/metadata/android/fr-FR/changelogs/default.txt b/src/fdroid/fastlane/metadata/android/fr-FR/changelogs/default.txt index 837a30de8..d72028770 100644 --- a/src/fdroid/fastlane/metadata/android/fr-FR/changelogs/default.txt +++ b/src/fdroid/fastlane/metadata/android/fr-FR/changelogs/default.txt @@ -1 +1 @@ -- Migrate cloud access tokens and vault passwords to AES 256bit GCM +- Add Hub support diff --git a/src/lite/fastlane/metadata/android/de-DE/changelogs/default.txt b/src/lite/fastlane/metadata/android/de-DE/changelogs/default.txt index be2ad06ed..926c5be64 100644 --- a/src/lite/fastlane/metadata/android/de-DE/changelogs/default.txt +++ b/src/lite/fastlane/metadata/android/de-DE/changelogs/default.txt @@ -1 +1 @@ -- Migration von Cloud-Zugangs-Tokens und Tresor-Passwörtern zu AES 256bit GCM +- Hub-Unterstützung hinzugefügt diff --git a/src/lite/fastlane/metadata/android/en-US/changelogs/default.txt b/src/lite/fastlane/metadata/android/en-US/changelogs/default.txt index 837a30de8..d72028770 100644 --- a/src/lite/fastlane/metadata/android/en-US/changelogs/default.txt +++ b/src/lite/fastlane/metadata/android/en-US/changelogs/default.txt @@ -1 +1 @@ -- Migrate cloud access tokens and vault passwords to AES 256bit GCM +- Add Hub support diff --git a/src/lite/fastlane/metadata/android/fr-FR/changelogs/default.txt b/src/lite/fastlane/metadata/android/fr-FR/changelogs/default.txt index 837a30de8..d72028770 100644 --- a/src/lite/fastlane/metadata/android/fr-FR/changelogs/default.txt +++ b/src/lite/fastlane/metadata/android/fr-FR/changelogs/default.txt @@ -1 +1 @@ -- Migrate cloud access tokens and vault passwords to AES 256bit GCM +- Add Hub support diff --git a/src/playstore/fastlane/metadata/android/de-DE/changelogs/default.txt b/src/playstore/fastlane/metadata/android/de-DE/changelogs/default.txt index be2ad06ed..926c5be64 100644 --- a/src/playstore/fastlane/metadata/android/de-DE/changelogs/default.txt +++ b/src/playstore/fastlane/metadata/android/de-DE/changelogs/default.txt @@ -1 +1 @@ -- Migration von Cloud-Zugangs-Tokens und Tresor-Passwörtern zu AES 256bit GCM +- Hub-Unterstützung hinzugefügt diff --git a/src/playstore/fastlane/metadata/android/en-US/changelogs/default.txt b/src/playstore/fastlane/metadata/android/en-US/changelogs/default.txt index 837a30de8..d72028770 100644 --- a/src/playstore/fastlane/metadata/android/en-US/changelogs/default.txt +++ b/src/playstore/fastlane/metadata/android/en-US/changelogs/default.txt @@ -1 +1 @@ -- Migrate cloud access tokens and vault passwords to AES 256bit GCM +- Add Hub support diff --git a/src/playstore/fastlane/metadata/android/fr-FR/changelogs/default.txt b/src/playstore/fastlane/metadata/android/fr-FR/changelogs/default.txt index 837a30de8..d72028770 100644 --- a/src/playstore/fastlane/metadata/android/fr-FR/changelogs/default.txt +++ b/src/playstore/fastlane/metadata/android/fr-FR/changelogs/default.txt @@ -1 +1 @@ -- Migrate cloud access tokens and vault passwords to AES 256bit GCM +- Add Hub support diff --git a/util/build.gradle b/util/build.gradle index 0fe3afade..0521c8092 100644 --- a/util/build.gradle +++ b/util/build.gradle @@ -53,7 +53,10 @@ dependencies { implementation dependencies.androidxPreference + implementation dependencies.joseJwt + // test + androidTestImplementation dependencies.junitParams androidTestImplementation dependencies.androidxTestCore androidTestImplementation(dependencies.runner) { exclude group: 'com.android.support', module: 'support-annotations' @@ -62,6 +65,7 @@ dependencies { androidTestImplementation(dependencies.rules) { exclude group: 'com.android.support', module: 'support-annotations' } + androidTestImplementation dependencies.mockitoAndroid testImplementation dependencies.junit testImplementation dependencies.junitApi diff --git a/util/src/androidTest/java/org/cryptomator/util/crypto/HubDeviceCryptorTest.java b/util/src/androidTest/java/org/cryptomator/util/crypto/HubDeviceCryptorTest.java new file mode 100644 index 000000000..485551d82 --- /dev/null +++ b/util/src/androidTest/java/org/cryptomator/util/crypto/HubDeviceCryptorTest.java @@ -0,0 +1,187 @@ +package org.cryptomator.util.crypto; + +import com.nimbusds.jose.JWEObject; + +import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException; +import org.cryptomator.cryptolib.common.P384KeyPair; +import org.junit.Before; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.mockito.Mockito; + +import java.io.IOException; +import java.security.KeyFactory; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.KeyStoreSpi; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.text.ParseException; +import java.util.Arrays; +import java.util.Base64; + +public class HubDeviceCryptorTest { + + // key pairs from frontend tests (crypto.spec.ts): + private static final String USER_PRIV_KEY = "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDDCi4K1Ts3DgTz/ufkLX7EGMHjGpJv+WJmFgyzLwwaDFSfLpDw0Kgf3FKK+LAsV8r+hZANiAARLOtFebIjxVYUmDV09Q1sVxz2Nm+NkR8fu6UojVSRcCW13tEZatx8XGrIY9zC7oBCEdRqDc68PMSvS5RA0Pg9cdBNc/kgMZ1iEmEv5YsqOcaNADDSs0bLlXb35pX7Kx5Y="; + private static final String USER_PUB_KEY = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAESzrRXmyI8VWFJg1dPUNbFcc9jZvjZEfH7ulKI1UkXAltd7RGWrcfFxqyGPcwu6AQhHUag3OvDzEr0uUQND4PXHQTXP5IDGdYhJhL+WLKjnGjQAw0rNGy5V29+aV+yseW"; + private static final String DEVICE_PRIV_KEY = "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDB2bmFCWy2p+EbAn8NWS5Om+GA7c5LHhRZb8g2pSMSf0fsd7k7dZDVrnyHFiLdd/YGhZANiAAR6bsjTEdXKWIuu1Bvj6Y8wySlIROy7YpmVZTY128ItovCD8pcR4PnFljvAIb2MshCdr1alX4g6cgDOqcTeREiObcSfucOU9Ry1pJ/GnX6KA0eSljrk6rxjSDos8aiZ6Mg="; + private static final String DEVICE_PUB_KEY = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEem7I0xHVyliLrtQb4+mPMMkpSETsu2KZlWU2NdvCLaLwg/KXEeD5xZY7wCG9jLIQna9WpV+IOnIAzqnE3kRIjm3En7nDlPUctaSfxp1+igNHkpY65Oq8Y0g6LPGomejI"; + + // used for JWE generation in frontend: (jwe.spec.ts): + private static final String PRIV_KEY = "ME8CAQAwEAYHKoZIzj0CAQYFK4EEACIEODA2AgEBBDEA6QybmBitf94veD5aCLr7nlkF5EZpaXHCfq1AXm57AKQyGOjTDAF9EQB28fMywTDQ"; + private static final String PUB_KEY = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAERxQR+NRN6Wga01370uBBzr2NHDbKIC56tPUEq2HX64RhITGhii8Zzbkb1HnRmdF0aq6uqmUy4jUhuxnKxsv59A6JeK7Unn+mpmm3pQAygjoGc9wrvoH4HWJSQYUlsXDu"; + + private KeyStore keystore; + private HubDeviceCryptor inTest; + + @Before + public void setup() throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException, UnrecoverableKeyException, InvalidKeySpecException { + var keyStoreSpiMock = Mockito.mock(KeyStoreSpi.class); + keystore = new KeyStore(keyStoreSpiMock, null, "test") { + }; + keystore.load(null); + + var mockCertificate = Mockito.mock(Certificate.class); + var publicKey = KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(DEVICE_PUB_KEY))); + var devicePrivateKey = KeyFactory.getInstance("EC").generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(DEVICE_PRIV_KEY))); + Mockito.when(mockCertificate.getPublicKey()).thenReturn(publicKey); + Mockito.when(keystore.getCertificate(HubDeviceCryptor.DEFAULT_KEY_ALIAS)).thenReturn(mockCertificate); + Mockito.when(keystore.getKey(HubDeviceCryptor.DEFAULT_KEY_ALIAS, null)).thenReturn(devicePrivateKey); + Mockito.when(keystore.containsAlias(HubDeviceCryptor.DEFAULT_KEY_ALIAS)).thenReturn(true); + + inTest = new HubDeviceCryptor(keystore); + } + + @Test + public void deviceId() { + String deviceId = inTest.getDeviceId(); + Assertions.assertEquals(deviceId, "F82D0F002724A2916C5695016A17A7E8A3092FE99E0BF65B44998630330C54CA"); + } + + @Test + public void testGetDevicePublicKey() throws Exception { + var expectedPublicKey = KeyFactory // + .getInstance("EC") // + .generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(DEVICE_PUB_KEY))); + var actualPublicKey = inTest.getDevicePublicKey(); + Assertions.assertEquals(expectedPublicKey, actualPublicKey); + } + + @Test + public void testDecryptMasterkeyUsingDeviceKey() throws ParseException { + var userKeyJwe = JWEObject.parse(""" + eyJhbGciOiJQQkVTMi1IUzUxMitBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIiwicDJzIjoiT3hMY0Q\ + xX1pCODc1c2hvUWY2Q1ZHQSIsInAyYyI6MTAwMCwiYXB1IjoiIiwiYXB2IjoiIn0.FD4fcrP4Pb\ + aKOQ9ZfXl0gpMM6Fa2rfqAvL0K5ZyYUiVeHCNV-A02Rg.urT1ShSv6qQxh8X7.gEqAiUWD98a2E\ + P7ITCPTw4DJo6-BpqrxA73D6gNIj9z4d1hN-EP99Q4mWBWLH97H8ugbG5rGsm8xsjsBqpWORQqF\ + mJZR2AhlPiwFaC7n_MDDBupSy_swDnCfj731Lal297IP5WbkFcmozKsyhmwdkctxjf_VHA.fJki\ + kDjUaxwUKqpvT7qaAQ + """); + var vaultKeyJwe = JWEObject.parse(""" + eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlA\ + tMzg0Iiwia2V5X29wcyI6W10sImV4dCI6dHJ1ZSwieCI6IllUcEY3bGtTc3JvZVVUVFdCb21LNzBTN0\ + FhVTJyc0ptMURpZ1ZzbjRMY2F5eUxFNFBabldkYmFVcE9jQVV5a1ciLCJ5IjoiLU5pS3loUktjSk52N\ + m02Z0ZJUWc4cy1Xd1VXUW9uT3A5dkQ4cHpoa2tUU3U2RzFlU2FUTVlhZGltQ2Q4V0ExMSJ9LCJhcHUi\ + OiIiLCJhcHYiOiIifQ..BECWGzd9UvhHcTJC.znt4TlS-qiNEjxiu2v-du_E1QOBnyBR6LCt865SHxD\ + -kwRc1JwX_Lq9XVoFj2GnK9-9CgxhCLGurg5Jt9g38qv2brGAzWL7eSVeY1fIqdO_kUhLpGslRTN6h2\ + U0NHJi2-iE.WDVI2kOk9Dy3PWHyIg8gKA"""); + + var userKey = inTest.reEncryptUserKey(userKeyJwe, "123456"); + var masterkey = inTest.decryptVaultKey(vaultKeyJwe, userKey); + + var expectedEncKey = new byte[32]; + var expectedMacKey = new byte[32]; + Arrays.fill(expectedEncKey, (byte) 0x55); + Arrays.fill(expectedMacKey, (byte) 0x77); + Assertions.assertArrayEquals(expectedEncKey, masterkey.getEncKey().getEncoded()); + Assertions.assertArrayEquals(expectedMacKey, masterkey.getMacKey().getEncoded()); + } + + @Test + public void testDecryptVaultKey() throws ParseException, InvalidKeySpecException { + var vaultKeyJwe = JWEObject.parse(""" + eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlA\ + tMzg0Iiwia2V5X29wcyI6W10sImV4dCI6dHJ1ZSwieCI6IllUcEY3bGtTc3JvZVVUVFdCb21LNzBTN0\ + FhVTJyc0ptMURpZ1ZzbjRMY2F5eUxFNFBabldkYmFVcE9jQVV5a1ciLCJ5IjoiLU5pS3loUktjSk52N\ + m02Z0ZJUWc4cy1Xd1VXUW9uT3A5dkQ4cHpoa2tUU3U2RzFlU2FUTVlhZGltQ2Q4V0ExMSJ9LCJhcHUi\ + OiIiLCJhcHYiOiIifQ..BECWGzd9UvhHcTJC.znt4TlS-qiNEjxiu2v-du_E1QOBnyBR6LCt865SHxD\ + -kwRc1JwX_Lq9XVoFj2GnK9-9CgxhCLGurg5Jt9g38qv2brGAzWL7eSVeY1fIqdO_kUhLpGslRTN6h2\ + U0NHJi2-iE.WDVI2kOk9Dy3PWHyIg8gKA"""); + + var privateKey = P384KeyPair.create(new X509EncodedKeySpec(Base64.getDecoder().decode(PUB_KEY)), new PKCS8EncodedKeySpec(Base64.getDecoder().decode(PRIV_KEY))).getPrivate(); + var masterkey = HubDeviceCryptor.decryptVaultKey(vaultKeyJwe, privateKey); + + var expectedEncKey = new byte[32]; + var expectedMacKey = new byte[32]; + Arrays.fill(expectedEncKey, (byte) 0x55); + Arrays.fill(expectedMacKey, (byte) 0x77); + Assertions.assertArrayEquals(expectedEncKey, masterkey.getEncKey().getEncoded()); + Assertions.assertArrayEquals(expectedMacKey, masterkey.getMacKey().getEncoded()); + } + + @Test + public void testEncryptUserKeyWrongSetupCode() throws ParseException { + var userKeyJwe = JWEObject.parse(""" + eyJhbGciOiJQQkVTMi1IUzUxMitBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIiwicDJzIjoiT3hMY0Q\ + xX1pCODc1c2hvUWY2Q1ZHQSIsInAyYyI6MTAwMCwiYXB1IjoiIiwiYXB2IjoiIn0.FD4fcrP4Pb\ + aKOQ9ZfXl0gpMM6Fa2rfqAvL0K5ZyYUiVeHCNV-A02Rg.urT1ShSv6qQxh8X7.gEqAiUWD98a2E\ + P7ITCPTw4DJo6-BpqrxA73D6gNIj9z4d1hN-EP99Q4mWBWLH97H8ugbG5rGsm8xsjsBqpWORQqF\ + mJZR2AhlPiwFaC7n_MDDBupSy_swDnCfj731Lal297IP5WbkFcmozKsyhmwdkctxjf_VHA.fJki\ + kDjUaxwUKqpvT7qaAQ + """); + Assertions.assertThrows(HubDeviceCryptor.InvalidJweKeyException.class, () -> HubDeviceCryptor.decryptUserKey(userKeyJwe, "WRONG_SETUP_CODE")); + } + + @Test + public void testDecryptInvalidVaultKey() throws ParseException, InvalidKeySpecException { + var wrongKey = JWEObject.parse("eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0Iiwia2V5X29wcyI6W10sImV4dCI6dHJ1ZSwieCI6ImdodGR3VnNoUU8wRGFBdjVBOXBiZ1NCTW0yYzZKWVF4dkloR3p6RVdQTncxczZZcEFYeTRQTjBXRFJUWExtQ2wiLCJ5IjoiN3Rncm1Gd016NGl0ZmVQNzBndkpLcjRSaGdjdENCMEJHZjZjWE9WZ2M0bjVXMWQ4dFgxZ1RQakdrczNVSm1zUiJ9LCJhcHUiOiIiLCJhcHYiOiIifQ..x6JWRGSojUJUJYpp.5BRuzcaV.lLIhGH7Wz0n_iTBAubDFZA"); + var payloadIsNotJson = JWEObject.parse("eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0Iiwia2V5X29wcyI6W10sImV4dCI6dHJ1ZSwieCI6IkM2bWhsNE5BTHhEdHMwUlFlNXlyZWxQVDQyOGhDVzJNeUNYS3EwdUI0TDFMdnpXRHhVaVk3YTdZcEhJakJXcVoiLCJ5IjoiakM2dWc1NE9tbmdpNE9jUk1hdkNrczJpcFpXQjdkUmotR3QzOFhPSDRwZ2tpQ0lybWNlUnFxTnU3Z0c3Qk1yOSJ9LCJhcHUiOiIiLCJhcHYiOiIifQ..HNJJghL-SvERFz2v.N0z8YwFg.rYw29iX4i8XujdM4P4KKWg"); + var payloadFieldKeyNotAstring = JWEObject.parse("eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0Iiwia2V5X29wcyI6W10sImV4dCI6dHJ1ZSwieCI6IkJyYm9UQkl5Y0NDUEdJQlBUekU2RjBnbTRzRjRCamZPN1I0a2x0aWlCaThKZkxxcVdXNVdUSVBLN01yMXV5QVUiLCJ5IjoiNUpGVUI0WVJiYjM2RUZpN2Y0TUxMcFFyZXd2UV9Tc3dKNHRVbFd1a2c1ZU04X1ZyM2pkeml2QXI2WThRczVYbSJ9LCJhcHUiOiIiLCJhcHYiOiIifQ..QEq4Z2m6iwBx2ioS.IBo8TbKJTS4pug.61Z-agIIXgP8bX10O_yEMA"); + var payloadFieldKeyInValidBase64Data = JWEObject.parse("eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0Iiwia2V5X29wcyI6W10sImV4dCI6dHJ1ZSwieCI6ImNZdlVFZm9LYkJjenZySE5zQjUxOGpycUxPMGJDOW5lZjR4NzFFMUQ5dk95MXRqd1piZzV3cFI0OE5nU1RQdHgiLCJ5IjoiaWRJekhCWERzSzR2NTZEeU9yczJOcDZsSG1zb29fMXV0VTlzX3JNdVVkbkxuVXIzUXdLZkhYMWdaVXREM1RKayJ9LCJhcHUiOiIiLCJhcHYiOiIifQ..0VZqu5ei9U3blGtq.eDvhU6drw7mIwvXu6Q.f05QnhI7JWG3IYHvexwdFQ"); + var privateKey = P384KeyPair.create(new X509EncodedKeySpec(Base64.getDecoder().decode(PUB_KEY)), new PKCS8EncodedKeySpec(Base64.getDecoder().decode(PRIV_KEY))).getPrivate(); + + Assertions.assertThrows(HubDeviceCryptor.InvalidJweKeyException.class, () -> HubDeviceCryptor.decryptVaultKey(wrongKey, privateKey)); + Assertions.assertThrows(MasterkeyLoadingFailedException.class, () -> HubDeviceCryptor.decryptVaultKey(payloadIsNotJson, privateKey)); + Assertions.assertThrows(MasterkeyLoadingFailedException.class, () -> HubDeviceCryptor.decryptVaultKey(payloadFieldKeyNotAstring, privateKey)); + Assertions.assertThrows(MasterkeyLoadingFailedException.class, () -> HubDeviceCryptor.decryptVaultKey(payloadFieldKeyInValidBase64Data, privateKey)); + } + + @Test + public void testDecryptUserKeyECDHESWrongKey() throws ParseException, InvalidKeySpecException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException { + var jwe = JWEObject.parse(""" + eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrZXlfb3BzIjpbXSwiZXh0Ijp\ + 0cnVlLCJrdHkiOiJFQyIsIngiOiJoeHpiSWh6SUJza3A5ZkZFUmJSQ2RfOU1fbWYxNElqaDZhcnNoVX\ + NkcEEyWno5ejZZNUs4NHpZR2I4b2FHemNUIiwieSI6ImJrMGRaNWhpelZ0TF9hN2hNejBjTUduNjhIR\ + jZFdWlyNHdlclNkTFV5QWd2NWUzVzNYSG5sdHJ2VlRyU3pzUWYiLCJjcnYiOiJQLTM4NCJ9LCJhcHUi\ + OiIiLCJhcHYiOiIifQ..pu3Q1nR_yvgRAapG.4zW0xm0JPxbcvZ66R-Mn3k841lHelDQfaUvsZZAtWs\ + L2w4FMi6H_uu6ArAWYLtNREa_zfcPuyuJsFferYPSNRUWt4OW6aWs-l_wfo7G1ceEVxztQXzQiwD30U\ + TA8OOdPcUuFfEq2-d9217jezrcyO6m6FjyssEZIrnRArUPWKzGdghXccGkkf0LTZcGJoHeKal-RtyP8\ + PfvEAWTjSOCpBlSdUJ-1JL3tyd97uVFNaVuH3i7vvcMoUP_bdr0XW3rvRgaeC6X4daPLUvR1hK5Msut\ + QMtM2vpFghS_zZxIQRqz3B2ECxa9Bjxhmn8kLX5heZ8fq3lH-bmJp1DxzZ4V1RkWk.yVwXG9yARa5Ih\ + q2koh2NbQ"""); + + var userKeyPair = P384KeyPair.create(new X509EncodedKeySpec(Base64.getDecoder().decode(USER_PUB_KEY)), new PKCS8EncodedKeySpec(Base64.getDecoder().decode(USER_PRIV_KEY))); + var incorrectDevicePrivateKey = userKeyPair.getPrivate(); + + Assertions.assertThrows(HubDeviceCryptor.InvalidJweKeyException.class, () -> HubDeviceCryptor.decryptUserKey(jwe, incorrectDevicePrivateKey)); + } + + @Test + public void testEncryptAndDecryptUserKey() { + var userKey = P384KeyPair.generate(); + var deviceKey = P384KeyPair.generate(); + + var encrypted = HubDeviceCryptor.encryptUserKey(userKey.getPrivate(), deviceKey.getPublic()); + var decrypted = HubDeviceCryptor.decryptUserKey(encrypted, deviceKey.getPrivate()); + + Assertions.assertArrayEquals(userKey.getPrivate().getEncoded(), decrypted.getEncoded()); + } + +} + diff --git a/util/src/main/java/org/cryptomator/util/crypto/HubDeviceCryptor.java b/util/src/main/java/org/cryptomator/util/crypto/HubDeviceCryptor.java new file mode 100644 index 000000000..a3f3e8294 --- /dev/null +++ b/util/src/main/java/org/cryptomator/util/crypto/HubDeviceCryptor.java @@ -0,0 +1,234 @@ +package org.cryptomator.util.crypto; + +import android.security.keystore.KeyGenParameterSpec; +import android.security.keystore.KeyProperties; + +import com.google.common.base.Preconditions; +import com.google.common.io.BaseEncoding; +import com.nimbusds.jose.EncryptionMethod; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JWEAlgorithm; +import com.nimbusds.jose.JWEHeader; +import com.nimbusds.jose.JWEObject; +import com.nimbusds.jose.Payload; +import com.nimbusds.jose.crypto.ECDHDecrypter; +import com.nimbusds.jose.crypto.ECDHEncrypter; +import com.nimbusds.jose.crypto.PasswordBasedDecrypter; +import com.nimbusds.jose.jwk.Curve; +import com.nimbusds.jose.jwk.gen.ECKeyGenerator; + +import org.cryptomator.cryptolib.api.CryptoException; +import org.cryptomator.cryptolib.api.Masterkey; +import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException; +import org.cryptomator.cryptolib.common.MessageDigestSupplier; + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; +import java.security.spec.ECGenParameterSpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Arrays; +import java.util.Base64; +import java.util.Map; +import java.util.function.Function; + +import timber.log.Timber; + +public class HubDeviceCryptor { + + static final String DEFAULT_KEYSTORE_NAME = "AndroidKeyStore"; + static final String DEFAULT_KEY_ALIAS = "hubDeviceKey"; + private static final String JWE_PAYLOAD_KEY_FIELD = "key"; + private static final String EC_ALG = "EC"; + private final KeyStore keyStore; + + HubDeviceCryptor(KeyStore keyStore) { + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.S) { + throw new IllegalStateException("Hub unlock is only supported for devices using Android >= 12"); + } + try { + this.keyStore = keyStore; + this.keyStore.load(null); + if (!this.keyStore.containsAlias(DEFAULT_KEY_ALIAS)) { + var keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, DEFAULT_KEYSTORE_NAME); + var parameterSpec = new KeyGenParameterSpec // + .Builder(DEFAULT_KEY_ALIAS, KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_AGREE_KEY) // + .setAlgorithmParameterSpec(new ECGenParameterSpec(Curve.P_384.getStdName())) // + .setDigests(KeyProperties.DIGEST_SHA256) // + .setUserAuthenticationRequired(false) // + .build(); + keyPairGenerator.initialize(parameterSpec); + keyPairGenerator.generateKeyPair(); + } + } catch (KeyStoreException | NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | CertificateException | IOException e) { + throw new RuntimeException(e); + } + } + + public static HubDeviceCryptor getInstance() { + try { + var keyStore = KeyStore.getInstance(DEFAULT_KEYSTORE_NAME); + return new HubDeviceCryptor(keyStore); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + } + + public static ECPrivateKey decryptUserKey(JWEObject jwe, String setupCode) throws InvalidJweKeyException { + try { + jwe.decrypt(new PasswordBasedDecrypter(setupCode)); + return readKey(jwe, JWE_PAYLOAD_KEY_FIELD, HubDeviceCryptor::decodeECPrivateKey); + } catch (JOSEException e) { + throw new InvalidJweKeyException(e); + } + } + + public static ECPrivateKey decryptUserKey(JWEObject jwe, PrivateKey deviceKey) { + try { + jwe.decrypt(new ECDHDecrypter(deviceKey, null, Curve.P_384)); + return readKey(jwe, JWE_PAYLOAD_KEY_FIELD, HubDeviceCryptor::decodeECPrivateKey); + } catch (JOSEException e) { + throw new InvalidJweKeyException(e); + } + } + + private static ECPrivateKey decodeECPrivateKey(byte[] encoded) throws KeyDecodeFailedException { + try { + var factory = KeyFactory.getInstance(EC_ALG); + var privateKey = factory.generatePrivate(new PKCS8EncodedKeySpec(encoded)); + if (privateKey instanceof ECPrivateKey ecPrivateKey) { + return ecPrivateKey; + } else { + throw new IllegalStateException(EC_ALG + " key factory not generating ECPrivateKeys"); + } + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException(EC_ALG + " not supported"); + } catch (InvalidKeySpecException e) { + throw new KeyDecodeFailedException(e); + } + } + + private static T readKey(JWEObject jwe, String keyField, Function rawKeyFactory) throws MasterkeyLoadingFailedException { + Preconditions.checkArgument(jwe.getState() == JWEObject.State.DECRYPTED); + var fields = jwe.getPayload().toJSONObject(); + if (fields == null) { + Timber.tag("HubDeviceCryptor").e("Expected JWE payload to be JSON: " + jwe.getPayload()); + throw new MasterkeyLoadingFailedException("Expected JWE payload to be JSON"); + } + var keyBytes = new byte[0]; + try { + if (fields.get(keyField) instanceof String key) { + keyBytes = Base64.getDecoder().decode(key); + return rawKeyFactory.apply(keyBytes); + } else { + throw new IllegalArgumentException("JWE payload doesn't contain field " + keyField); + } + } catch (IllegalArgumentException | KeyDecodeFailedException e) { + Timber.tag("HubDeviceCryptor").e("Unexpected JWE payload: " + jwe.getPayload()); + throw new MasterkeyLoadingFailedException("Unexpected JWE payload", e); + } finally { + Arrays.fill(keyBytes, (byte) 0x00); + } + } + + private static JWEObject encryptKey(Key key, ECPublicKey userKey) { + try { + var encodedKey = key.getEncoded(); + if (encodedKey == null) { + throw new RuntimeException("Encoded key is null"); + } + var encodedVaultKey = Base64.getEncoder().encodeToString(encodedKey); + var keyGen = new ECKeyGenerator(Curve.P_384); + var ephemeralKeyPair = keyGen.generate(); + var header = new JWEHeader.Builder(JWEAlgorithm.ECDH_ES, EncryptionMethod.A256GCM).ephemeralPublicKey(ephemeralKeyPair.toPublicJWK()).build(); + var payload = new Payload(Map.of(JWE_PAYLOAD_KEY_FIELD, encodedVaultKey)); + var jwe = new JWEObject(header, payload); + jwe.encrypt(new ECDHEncrypter(userKey)); + return jwe; + } catch (JOSEException e) { + throw new RuntimeException(e); + } + } + + public static JWEObject encryptUserKey(ECPrivateKey userKey, ECPublicKey deviceKey) { + return encryptKey(userKey, deviceKey); + } + + public static Masterkey decryptVaultKey(JWEObject jwe, ECPrivateKey privateKey) throws InvalidJweKeyException { + try { + jwe.decrypt(new ECDHDecrypter(privateKey)); + return readKey(jwe, JWE_PAYLOAD_KEY_FIELD, Masterkey::new); + } catch (JOSEException e) { + throw new InvalidJweKeyException(e); + } + } + + public JWEObject reEncryptUserKey(JWEObject userKey, String setupCode) { + var userPrivateKey = decryptUserKey(userKey, setupCode); + var devicePublicKey = getDevicePublicKey(); + return encryptUserKey(userPrivateKey, devicePublicKey); + } + + public Masterkey decryptVaultKey(JWEObject vaultKeyJwe, JWEObject userKeyJwe) { + try { + var privateKey = (PrivateKey) keyStore.getKey(DEFAULT_KEY_ALIAS, null); + var userKey = decryptUserKey(userKeyJwe, privateKey); + return decryptVaultKey(vaultKeyJwe, userKey); + } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException e) { + throw new RuntimeException(e); + } + } + + public ECPublicKey getDevicePublicKey() { + try { + var certificate = keyStore.getCertificate(DEFAULT_KEY_ALIAS); + return (ECPublicKey) certificate.getPublicKey(); + } catch (KeyStoreException e) { + throw new RuntimeException(e); + } + } + + public byte[] getDevicePublicKeyEncoded() { + var devicePublicKey = getDevicePublicKey().getEncoded(); + if (devicePublicKey == null) { + throw new RuntimeException("Encoded Hub device key is null"); + } + return devicePublicKey; + } + + public String getDeviceId() { + var devicePublicKey = getDevicePublicKeyEncoded(); + try (var instance = MessageDigestSupplier.SHA256.instance()) { + var hashedKey = instance.get().digest(devicePublicKey); + return BaseEncoding.base16().encode(hashedKey); + } + } + + public static class KeyDecodeFailedException extends CryptoException { + + public KeyDecodeFailedException(Throwable cause) { + super("Malformed key", cause); + } + } + + public static class InvalidJweKeyException extends CryptoException { + + public InvalidJweKeyException(Throwable cause) { + super("Invalid key", cause); + } + + } + +}