diff --git a/.crowdin/config.example.yml b/.crowdin/config.example.yml new file mode 100644 index 00000000..4ef788a3 --- /dev/null +++ b/.crowdin/config.example.yml @@ -0,0 +1,10 @@ +project_id: "372633" +api_token: "" +base_path: "../app/src/main" +base_url: "https://api.crowdin.com" +preserve_hierarchy: true + +files: +- source: "res/values/strings.xml" + dest: "strings.xml" + translation: "res/values-%android_code%/%original_file_name%" diff --git a/.github/workflows/build-app-workflow.yaml b/.github/workflows/build-app-workflow.yaml index ab511ab7..d3c55f8e 100644 --- a/.github/workflows/build-app-workflow.yaml +++ b/.github/workflows/build-app-workflow.yaml @@ -35,7 +35,7 @@ jobs: sudo udevadm control --reload-rules sudo udevadm trigger --name-match=kvm - name: Tests - uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d + uses: reactivecircus/android-emulator-runner@6b0df4b0efb23bb0ec63d881db79aefbc976e4b2 with: api-level: 31 arch: x86_64 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b575535b..d4570016 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -14,7 +14,6 @@ jobs: actions: read contents: read security-events: write - if: github.event_name != 'schedule' || github.repository == 'beemdevelopment/Aegis' steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/crowdin.yml b/.github/workflows/crowdin.yml index e7898362..e0fd559c 100644 --- a/.github/workflows/crowdin.yml +++ b/.github/workflows/crowdin.yml @@ -13,13 +13,19 @@ jobs: - uses: actions/checkout@v4 - name: Install crowdin-cli run: | - wget https://github.com/crowdin/crowdin-cli/releases/download/4.6.1/crowdin-cli.zip - echo "7afd70de3a747ac631a5bad7866008163ae1d50c4606b5773f0b90a5481ffde2 crowdin-cli.zip" | sha256sum -c + wget https://github.com/crowdin/crowdin-cli/releases/download/3.7.2/crowdin-cli.zip + echo "ee9f838b819ccedc33c9b2537055e5ba7d7934561b24df1e1a6274cbd6e27f2d crowdin-cli.zip" | sha256sum -c unzip crowdin-cli.zip -d crowdin-cli - name: Upload to Crowdin env: - CROWDIN_PERSONAL_TOKEN: "${{ secrets.CROWDIN_TOKEN }}" + CROWDIN_TOKEN: "${{ secrets.CROWDIN_TOKEN }}" run: | - java -jar ./crowdin-cli/4.6.1/crowdin-cli.jar upload sources \ + java -jar ./crowdin-cli/3.7.2/crowdin-cli.jar upload sources \ --no-progress \ + --token "$CROWDIN_TOKEN" \ + --project-id 372633 \ + --base-path app/src/main \ + --source res/values/strings.xml \ + --translation "res/values-%android_code%/%original_file_name%" \ + --dest strings.xml \ --branch master diff --git a/FAQ.md b/FAQ.md index 6d514574..815490aa 100644 --- a/FAQ.md +++ b/FAQ.md @@ -86,14 +86,6 @@ Another common setup is to configure Aegis to back up to a folder on local storage of your device and then have a separate app (like [Syncthing](https://syncthing.net/)) sync that folder anywhere you want. -## Encrypted Backups - -### Why do I not get prompted to enter an encryption password when exporting? - -Aegis uses the same password you have configured to encrypt your vault as the -password which is used when exporting and importing your vault; so when prompted, -you will enter that when importing your vault. - ## Importing ### When importing from Authenticator Plus, an error is shown claiming that Accounts.txt is missing diff --git a/README.md b/README.md index 195bd4ed..daf1b813 100644 --- a/README.md +++ b/README.md @@ -123,33 +123,24 @@ documentation](docs/iconpacks.md). Unofficial monochrome-styled 2FA icons. [aegis-icons preview](https://github.com/aegis-icons/aegis-icons) + src="https://raw.githubusercontent.com/aegis-icons/aegis-icons/master/showcase.png">](https://github.com/aegis-icons/aegis-icons) - [delta-aegis-icons](https://github.com/Delta-Icons/aegis-icons) Delta version of the unofficial monochrome-styled 2FA icon pack aegis-icons. - [delta-icons preview](https://github.com/Delta-Icons/aegis-icons) - -- [aegis-simple-icons](https://github.com/alexbakker/aegis-simple-icons) \* +- [aegis-simple-icons](https://github.com/alexbakker/aegis-simple-icons) * This project periodically generates an icon pack for Aegis based on [Simple Icons](https://simpleicons.org/). - [aegis-simple-icons preview](https://github.com/alexbakker/aegis-simple-icons) - -- [aegis-simple-icons-outlined](https://github.com/michaelschattgen/aegis-simple-icons-outlined) \* +- [aegis-simple-icons-outlined](https://github.com/michaelschattgen/aegis-simple-icons-outlined) * This is a variant on the aegis-simple-icons pack where the icons contain no solid background and just the outlines are being used. - - [aegis-simple-icons-outlined preview](https://github.com/michaelschattgen/aegis-simple-icons-outlined) - + \* The icons are automatically generated, so -not all of them are as high quality as the ones you'll find in -[aegis-icons](https://github.com/aegis-icons/aegis-icons). + not all of them are as high quality as the ones you'll find in + [aegis-icons](https://github.com/aegis-icons/aegis-icons). ## Contributing @@ -167,6 +158,5 @@ This project is licensed under the GNU General Public License v3.0. See the A couple of libraries vendored in Aegis' repository are licensed under a different license: - - [TextDrawable](app/src/main/java/com/amulyakhare/textdrawable) - [TrustedIntents](app/src/main/java/info/guardianproject/trustedintents) diff --git a/app/build.gradle b/app/build.gradle index 43512d69..a5d0d21c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,10 +26,10 @@ android { defaultConfig { applicationId "${packageName}" - minSdkVersion 23 + minSdkVersion 21 targetSdkVersion 35 - versionCode 79 - versionName "3.4" + versionCode 74 + versionName "3.3.1" multiDexEnabled true buildConfigField "String", "GIT_HASH", "\"${getGitHash()}\"" buildConfigField "String", "GIT_BRANCH", "\"${getGitBranch()}\"" @@ -93,27 +93,16 @@ android { } } - // Required to make the APK reproducible - aaptOptions { - cruncherEnabled = false - } - defaultConfig { - vectorDrawables.generatedDensities = [] - } - packagingOptions { // R8 doesn't remove these resources, so exclude them manually. This reduces APK size by 4MB. resources { - excludes += [ - '/org/bouncycastle/pqc/**/*.properties', - 'META-INF/versions/9/OSGI-INF/MANIFEST.MF' - ] + excludes += ['/org/bouncycastle/pqc/**/*.properties'] } } compileOptions { - targetCompatibility JavaVersion.VERSION_17 - sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility 1.8 + sourceCompatibility 1.8 coreLibraryDesugaringEnabled true } lint { @@ -152,13 +141,13 @@ aboutLibraries { } dependencies { - def cameraxVersion = '1.4.2' + def cameraxVersion = '1.4.0' def glideVersion = '4.16.0' - def guavaVersion = '33.4.8' - def hiltVersion = '2.56.2' + def guavaVersion = '33.3.1' + def hiltVersion = '2.52' def junitVersion = '4.13.2' def libsuVersion = '6.0.0' - def roomVersion = '2.7.1' + def roomVersion = "2.6.1" annotationProcessor 'androidx.annotation:annotation:1.9.1' annotationProcessor "androidx.room:room-compiler:$roomVersion" @@ -166,18 +155,18 @@ dependencies { annotationProcessor "com.github.bumptech.glide:compiler:${glideVersion}" implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'androidx.activity:activity:1.10.1' + implementation 'androidx.activity:activity:1.9.3' implementation 'androidx.appcompat:appcompat:1.7.0' implementation "androidx.biometric:biometric:1.1.0" implementation "androidx.camera:camera-camera2:$cameraxVersion" implementation "androidx.camera:camera-lifecycle:$cameraxVersion" implementation "androidx.camera:camera-view:$cameraxVersion" - implementation 'androidx.core:core:1.16.0' - implementation 'androidx.constraintlayout:constraintlayout:2.2.1' - implementation 'androidx.documentfile:documentfile:1.1.0' - implementation 'androidx.lifecycle:lifecycle-process:2.9.0' + implementation 'androidx.core:core:1.15.0' + implementation 'androidx.constraintlayout:constraintlayout:2.2.0' + implementation 'androidx.documentfile:documentfile:1.0.1' + implementation 'androidx.lifecycle:lifecycle-process:2.8.7' implementation "androidx.preference:preference:1.2.1" - implementation 'androidx.recyclerview:recyclerview:1.4.0' + implementation 'androidx.recyclerview:recyclerview:1.3.2' implementation "androidx.room:room-runtime:$roomVersion" implementation 'androidx.viewpager2:viewpager2:1.1.0' implementation 'com.caverock:androidsvg-aar:1.4' @@ -192,7 +181,7 @@ dependencies { implementation "com.github.topjohnwu.libsu:io:${libsuVersion}" implementation "com.google.guava:guava:${guavaVersion}-android" implementation 'com.google.android.material:material:1.12.0' - implementation 'com.google.protobuf:protobuf-javalite:4.31.0' + implementation 'com.google.protobuf:protobuf-javalite:4.28.3' implementation 'com.google.zxing:core:3.5.3' implementation('com.mikepenz:aboutlibraries:11.2.3') { exclude group: 'com.mikepenz', module: 'aboutlibraries-core' @@ -200,7 +189,7 @@ dependencies { implementation 'com.mikepenz:aboutlibraries-core-android:11.2.3' implementation 'com.nulab-inc:zxcvbn:1.9.0' implementation 'net.lingala.zip4j:zip4j:2.11.5' - implementation 'org.bouncycastle:bcprov-jdk18on:1.80' + implementation 'org.bouncycastle:bcprov-jdk18on:1.79' implementation 'org.simpleflatmapper:sfm-csv:8.2.3' androidTestAnnotationProcessor "com.google.dagger:hilt-android-compiler:$hiltVersion" @@ -218,8 +207,8 @@ dependencies { testImplementation 'androidx.test:core:1.6.1' testImplementation "com.google.guava:guava:${guavaVersion}-jre" testImplementation "junit:junit:${junitVersion}" - testImplementation 'org.json:json:20250517' - testImplementation 'org.robolectric:robolectric:4.14.1' + testImplementation 'org.json:json:20240303' + testImplementation 'org.robolectric:robolectric:4.14' - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.3' } diff --git a/app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java b/app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java index e0151395..9f15019b 100644 --- a/app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java +++ b/app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java @@ -61,20 +61,13 @@ import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import org.junit.runner.RunWith; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.List; -import java.util.Locale; import javax.crypto.Cipher; import javax.crypto.SecretKey; @@ -190,9 +183,7 @@ public class BackupExportTest extends AegisTest { onView(withText(R.string.export_format_html)).inRoot(RootMatchers.isPlatformPopup()).perform(click()); onView(withId(android.R.id.button1)).perform(click()); onView(withId(R.id.checkbox_accept)).perform(click()); - File file = doExport(); - - checkHtmlExport(file); + doExport(); } @Test @@ -205,9 +196,7 @@ public class BackupExportTest extends AegisTest { onView(withText(R.string.export_format_html)).inRoot(RootMatchers.isPlatformPopup()).perform(click()); onView(withId(android.R.id.button1)).perform(click()); onView(withId(R.id.checkbox_accept)).perform(click()); - File file = doExport(); - - checkHtmlExport(file); + doExport(); } @Test @@ -391,26 +380,6 @@ public class BackupExportTest extends AegisTest { checkReadEntries(entries); } - private void checkHtmlExport(File file) { - try (InputStream inStream = new FileInputStream(file)) { - Reader inReader = new InputStreamReader(inStream, StandardCharsets.UTF_8); - XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); - XmlPullParser parser = factory.newPullParser(); - parser.setInput(inReader); - while (parser.getEventType() != XmlPullParser.START_TAG) { - parser.next(); - } - if (!parser.getName().toLowerCase(Locale.ROOT).equals("html")) { - throw new RuntimeException("not an html document!"); - } - while (parser.getEventType() != XmlPullParser.END_DOCUMENT) { - parser.next(); - } - } catch (IOException | XmlPullParserException e) { - throw new RuntimeException("Unable to read html export file", e); - } - } - private void checkReadEntries(Collection entries) { List vectors = VaultEntries.get(); assertEquals(vectors.size(), entries.size()); diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 09337184..d3ea78bb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,7 +4,6 @@ - @android:color/transparent diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4fe617bd..2725c77f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -236,8 +236,6 @@ Please select an authentication method Encrypting the vault Exporting the vault - Optimizing icon - Optimizing icons %1$d/%2$d Reading file Requesting root access Analyzing QR code @@ -373,27 +371,8 @@ Note Clear - Duplicate entry - This entry has the same name and issuer as one or more existing entries. How would you like to proceed? - Overwrite existing entry/entries - Replace the existing entry or entries with the new one. This action cannot be undone - Add suffix - Add a suffix to the name of this new entry. The new name will be: %s - Cancel save - Allows you to edit the entry before attempting to save it again - - Are you sure you want to delete %d entry with the following name:\n\n%s - %s - Are you sure you want to delete %d entries with the following name:\n\n%s - %s - - - Confirm deletion - - Make your device vibrate when codes are refreshing - Haptic feedback Highlight tokens when tapped Make tokens easier to distinguish from each other by temporarily highlighting them when tapped - Multiselect groups - Allow the selection of multiple groups at the same time Minimize on copy Minimize the app after copying a token Copy tokens to the clipboard @@ -514,7 +493,6 @@ Unable to copy URI to clipboard URI copied to clipboard Scan this QR code with the authenticator app you would like to transfer this entry to - Tap the QR code to toggle full screen brightness Scan these QR codes with Aegis or Google Authenticator.\n\nDue to limitations of the Google Authenticator app, only TOTP & HOTP tokens that use SHA1 and produce 6-digit codes are included Very weak @@ -552,6 +530,7 @@ Supply a 2FAS Authenticator backup file. Supply an Aegis export/backup file. Supply an Authenticator Plus export file obtained through Settings -> Backup & Restore -> Export as Text and HTML. + Supply an Authenticator Pro export file obtained through Settings -> Back up -> Back up to encrypted file (recommended). Supply a copy of /data/data/com.authy.authy/shared_prefs/com.authy.storage.tokens.authenticator.xml, located in the internal storage directory of Authy. Supply an andOTP export/backup file. Supply a Bitwarden export/backup file. Encrypted files are not supported. @@ -566,7 +545,6 @@ Supply a copy of /data/data/com.azure.authenticator/databases/PhoneFactor, located in the internal storage directory of Microsoft Authenticator. Supply a plain text file with a Google Authenticator URI on each line. Steam v3.0 and newer are not supported. Supply a copy of /data/data/com.valvesoftware.android.steam.community/files/Steamguard-*.json, located in the internal storage directory of Steam. - Supply a Stratum export file obtained through Settings -> Back up -> Back up to encrypted file (recommended). Supply a TOTP Authenticator export file. Supply a WinAuth export file. Assign icons diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index f490f38b..7ae582e9 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -62,7 +62,6 @@ @color/aegis_theme_light_success @color/aegis_theme_light_onSurfaceDim ?attr/colorPrimary - ?attr/colorOutlineVariant ?attr/colorSurfaceVariant ?attr/colorOnSurfaceVariant @@ -133,7 +132,6 @@ @color/aegis_theme_dark_success @color/aegis_theme_dark_onSurfaceDim ?attr/colorPrimary - ?attr/colorOutlineVariant ?attr/colorSurfaceVariant ?attr/colorOnSurfaceVariant @@ -161,7 +159,6 @@ #000000 #000000 @android:color/white - #2F2F2F @android:color/white @@ -182,25 +179,16 @@ #000000 #000000 @android:color/white - #2F2F2F @android:color/white