Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bad2bafbe9 | ||
|
|
4f7b6e9f8e | ||
|
|
120fee358b | ||
|
|
85cc5d7d18 | ||
|
|
660b370d72 | ||
|
|
a23fd97f83 | ||
|
|
1f83456b2b | ||
|
|
28ea0d1b06 | ||
|
|
1584a23936 | ||
|
|
7fd0b8f407 | ||
|
|
bbe7525882 | ||
|
|
a9182577c0 | ||
|
|
7d6d3fe0f2 | ||
|
|
303cdc92e7 | ||
|
|
3b39a34045 | ||
|
|
2435c9ddef | ||
|
|
35bb9284d6 | ||
|
|
0c34cfcc5e | ||
|
|
a0c2db5315 | ||
|
|
b8f1f00d2f | ||
|
|
41c33003ac | ||
|
|
4103b776c4 | ||
|
|
ae1986d7d3 | ||
|
|
3b6648074a | ||
|
|
d5249d40cb | ||
|
|
a90f7e6abc | ||
|
|
55722dd818 | ||
|
|
7666c4e053 | ||
|
|
cb93a0658f | ||
|
|
97f665e8cf | ||
|
|
99516650fe | ||
|
|
3928ccc6b7 | ||
|
|
699f906843 | ||
|
|
ca809a0e0b | ||
|
|
d52e0ed04a | ||
|
|
c9936d68c1 | ||
|
|
59cfc88b4e | ||
|
|
39f9385c74 | ||
|
|
2017506b28 | ||
|
|
1497866597 | ||
|
|
78c12b5ee2 | ||
|
|
64159434d0 | ||
|
|
8bd1c1ec50 | ||
|
|
409e9c39ca | ||
|
|
73bd24da95 | ||
|
|
aeb2f46a4f | ||
|
|
cc9f8db288 | ||
|
|
83c70f0f6b | ||
|
|
91fffc8b04 | ||
|
|
50b583c2d7 | ||
|
|
0034da064f | ||
|
|
4fa61f0997 | ||
|
|
29bc7bb78f | ||
|
|
1df7d8de46 | ||
|
|
435fd6a1e7 | ||
|
|
c0f450d380 | ||
|
|
9f686d38ed | ||
|
|
8ade294d7a | ||
|
|
b5f3694805 | ||
|
|
1b1df0aa37 | ||
|
|
25dd92bdf0 | ||
|
|
e3ddc10a00 | ||
|
|
d0ae1ce566 | ||
|
|
b0eb0413f0 | ||
|
|
60a66efa79 | ||
|
|
e7c8437478 | ||
|
|
21ca31c1f3 | ||
|
|
0330982eb0 | ||
|
|
5fec321267 | ||
|
|
ca378d31d2 | ||
|
|
aedde8e447 | ||
|
|
1f090ce3af | ||
|
|
308cf250fd | ||
|
|
9ef9c3b9fd |
124
.github/workflows/ci.yml
vendored
124
.github/workflows/ci.yml
vendored
@@ -2,69 +2,85 @@ name: Flutter CI
|
||||
|
||||
# This workflow is triggered on pushes to the repository.
|
||||
on:
|
||||
workflow_dispatch:
|
||||
# Enable manual run
|
||||
push:
|
||||
# Sequence of patterns matched against refs/tags
|
||||
tags:
|
||||
- 'v*' # Push events to matching v*, i.e. v4.2.0
|
||||
workflow_dispatch:
|
||||
# Enable manual run
|
||||
push:
|
||||
# Sequence of patterns matched against refs/tags
|
||||
tags:
|
||||
- "v*" # Push events to matching v*, i.e. v4.2.0
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# This job will run on ubuntu virtual machine
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
build:
|
||||
# This job will run on ubuntu virtual machine
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Setup Java environment in order to build the Android app.
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: "adopt"
|
||||
java-version: "11"
|
||||
|
||||
# Setup Java environment in order to build the Android app.
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
# Setup the flutter environment.
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: "3.3.8"
|
||||
|
||||
# Setup the flutter environment.
|
||||
- uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version: '3.3.8'
|
||||
# Fetch sub modules
|
||||
- run: git submodule update --init --recursive
|
||||
|
||||
# Fetch sub modules
|
||||
- run: git submodule update --init --recursive
|
||||
# Get flutter dependencies.
|
||||
- run: flutter pub get
|
||||
|
||||
# Get flutter dependencies.
|
||||
- run: flutter pub get
|
||||
- name: Setup keys
|
||||
uses: timheuer/base64-to-file@v1
|
||||
with:
|
||||
fileName: "keystore/ente_auth_key.jks"
|
||||
encodedString: ${{ secrets.SIGNING_KEY }}
|
||||
|
||||
- name: Setup keys
|
||||
uses: timheuer/base64-to-file@v1
|
||||
with:
|
||||
fileName: 'keystore/ente_auth_key.jks'
|
||||
encodedString: ${{ secrets.SIGNING_KEY }}
|
||||
# Build independent apk.
|
||||
- name: Build
|
||||
run: flutter build apk --release --flavor independent && mv build/app/outputs/flutter-apk/app-independent-release.apk build/app/outputs/flutter-apk/ente-auth.apk
|
||||
env:
|
||||
SIGNING_KEY_PATH: "/home/runner/work/_temp/keystore/ente_auth_key.jks"
|
||||
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
|
||||
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
|
||||
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
|
||||
|
||||
# Build independent apk.
|
||||
- name: Build
|
||||
run: flutter build apk --release --flavor independent && mv build/app/outputs/flutter-apk/app-independent-release.apk build/app/outputs/flutter-apk/ente-auth.apk
|
||||
env:
|
||||
SIGNING_KEY_PATH: '/home/runner/work/_temp/keystore/ente_auth_key.jks'
|
||||
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
|
||||
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
|
||||
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
|
||||
# Build Play store aab.
|
||||
- name: Build
|
||||
run: flutter build appbundle --release --flavor playstore
|
||||
env:
|
||||
SIGNING_KEY_PATH: "/home/runner/work/_temp/keystore/ente_auth_key.jks"
|
||||
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
|
||||
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
|
||||
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
|
||||
|
||||
- name: Checksum
|
||||
run: sha256sum build/app/outputs/flutter-apk/ente-auth.apk > build/app/outputs/flutter-apk/sha256sum
|
||||
- name: Checksum
|
||||
run: sha256sum build/app/outputs/flutter-apk/ente-auth.apk > build/app/outputs/flutter-apk/sha256sum
|
||||
|
||||
# Upload generated apk to the artifacts.
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: release-apk
|
||||
path: build/app/outputs/flutter-apk/ente-auth.apk
|
||||
# Upload generated apk to the artifacts.
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: release-apk
|
||||
path: build/app/outputs/flutter-apk/ente-auth.apk
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: release-checksum
|
||||
path: build/app/outputs/flutter-apk/sha256sum
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: release-checksum
|
||||
path: build/app/outputs/flutter-apk/sha256sum
|
||||
|
||||
# Create a Github release
|
||||
- uses: ncipollo/release-action@v1
|
||||
with:
|
||||
artifacts: "build/app/outputs/flutter-apk/ente-auth.apk,build/app/outputs/flutter-apk/sha256sum"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Create a Github release
|
||||
- uses: ncipollo/release-action@v1
|
||||
with:
|
||||
artifacts: "build/app/outputs/flutter-apk/ente-auth.apk,build/app/outputs/flutter-apk/sha256sum"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Upload to Play store
|
||||
- uses: ente-io/upload-google-play@v1
|
||||
with:
|
||||
serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
|
||||
packageName: io.ente.auth
|
||||
releaseFiles: build/app/outputs/bundle/playstoreRelease/app-playstore-release.aab
|
||||
track: internal
|
||||
|
||||
2
.github/workflows/cla.yaml
vendored
2
.github/workflows/cla.yaml
vendored
@@ -7,6 +7,8 @@ on:
|
||||
|
||||
jobs:
|
||||
CLAAssistant:
|
||||
# This job only runs for pull request comments
|
||||
if: ${{ github.event.issue.pull_request }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "CLA Assistant"
|
||||
|
||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -2,3 +2,7 @@
|
||||
path = thirdparty/sentry-dart
|
||||
url = https://github.com/ente-io/sentry-dart.git
|
||||
branch = sentry_flutter_ente
|
||||
[submodule "flutter"]
|
||||
path = flutter
|
||||
url = https://github.com/flutter/flutter.git
|
||||
branch = stable
|
||||
|
||||
@@ -48,7 +48,7 @@ file, that adheres to the above format.
|
||||
### Android
|
||||
|
||||
This repository's [GitHub
|
||||
releases](https://github.com/ente-io/auth/releases/latest/download/ente-auth.apks)
|
||||
releases](https://github.com/ente-io/auth/releases/latest/download/ente-auth.apk)
|
||||
contains APKs, built straight from source. These builds keep themselves updated,
|
||||
without relying on third party stores.
|
||||
|
||||
@@ -88,13 +88,16 @@ tokens has been documented [here](architecture/README.md).
|
||||
4. For Android, run `flutter build apk --release --flavor independent`
|
||||
5. For iOS, run `flutter build ios`
|
||||
|
||||
For maintainers, there is [additional documentation](RELEASES.md) on
|
||||
automatically publishing the main branch to App store, Play store and GitHub
|
||||
releases.
|
||||
|
||||
## 🙋♂️ Support
|
||||
|
||||
If you need help, please reach out to support@ente.io, and a human will get in
|
||||
touch with you.
|
||||
|
||||
If you have feature requests, please create a [GitHub issue](./issues).
|
||||
If you have feature requests, please create a [GitHub issue](https://github.com/ente-io/auth/issues/).
|
||||
|
||||
If you wish to support us, please ⭐
|
||||
[star](https://github.com/ente-io/auth/stargazers) this project.
|
||||
|
||||
12
RELEASES.md
Normal file
12
RELEASES.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Releases
|
||||
|
||||
1. Create a PR to bump up the version number in `pubspec.yaml`.
|
||||
|
||||
2. Once that is merged, tag main. This'll trigger the
|
||||
[workflow](.github/workflows/ci.yml) to (a) create a new GitHub release with
|
||||
the independently distributed APK, and (b) build and upload a release to
|
||||
Google Play.
|
||||
|
||||
3. Xcode Cloud has already been configured and will automatically build and
|
||||
release to TestFlight when step 1 was merged to main (you can see logs under
|
||||
the PR checks).
|
||||
@@ -72,6 +72,9 @@ android {
|
||||
playstore {
|
||||
dimension "default"
|
||||
}
|
||||
fdroid {
|
||||
dimension "default"
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
||||
1
fastlane/metadata/android/en-US/changelogs/23.txt
Normal file
1
fastlane/metadata/android/en-US/changelogs/23.txt
Normal file
@@ -0,0 +1 @@
|
||||
- Hello, FDroid!
|
||||
35
fastlane/metadata/android/en-US/full_description.txt
Normal file
35
fastlane/metadata/android/en-US/full_description.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
ente authenticator provides end-to-end encrypted cloud backups so that you don't have to worry about losing your tokens. We use the same protocols [ente
|
||||
Photos](https://ente.io) uses to encrypt and preserve your data.
|
||||
|
||||
|
||||
Multi Device Synchronization
|
||||
|
||||
ente will automatically sync the 2FA tokens you add to your account, across all
|
||||
your devices. Every new device you sign into will have access to these tokens.
|
||||
|
||||
|
||||
Mode
|
||||
|
||||
ente generates 2FA tokens offline, so your network connectivity will not get in
|
||||
the way of your workflow.
|
||||
|
||||
Import and Export Tokens
|
||||
|
||||
You can add tokens to ente by one of the following methods:
|
||||
1. Scanning a QR code
|
||||
2. Manually entering (copy-pasting) a 2FA secret
|
||||
3. Bulk importing from a file that contains a list of codes in the following
|
||||
format:
|
||||
|
||||
```
|
||||
otpauth://totp/ACCOUNT?secret=SUPERSECRET&issuer=SERVICE
|
||||
|
||||
```
|
||||
The codes maybe separated by new lines or commas.
|
||||
|
||||
You can also export the codes you have added to ente, to an **unencrypted** text
|
||||
file, that adheres to the above format.
|
||||
|
||||
|
||||
SUPPORT
|
||||
We take pride in offering human support. If you are our paid customer, you can reach out to team@ente.io and expect a response from our team within 24 hours.
|
||||
BIN
fastlane/metadata/android/en-US/images/icon.png
Normal file
BIN
fastlane/metadata/android/en-US/images/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.0 KiB |
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
Normal file
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 123 KiB |
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/2.png
Normal file
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/3.png
Normal file
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/4.png
Normal file
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/5.png
Normal file
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/5.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
1
fastlane/metadata/android/en-US/short_description.txt
Normal file
1
fastlane/metadata/android/en-US/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
ente is an end-to-end encrypted authenticator app
|
||||
1
fastlane/metadata/android/en-US/title.txt
Normal file
1
fastlane/metadata/android/en-US/title.txt
Normal file
@@ -0,0 +1 @@
|
||||
ente Authenticator
|
||||
6
fdroid_flutter_icons.yaml
Normal file
6
fdroid_flutter_icons.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
flutter_icons:
|
||||
android: "launcher_icon"
|
||||
image_path: "assets/icon-light.png"
|
||||
adaptive_icon_foreground: "assets/icon-light-adaptive-fg.png"
|
||||
adaptive_icon_background: "#ffffff"
|
||||
|
||||
1
flutter
Submodule
1
flutter
Submodule
Submodule flutter added at b06b8b2710
@@ -2,7 +2,7 @@ PODS:
|
||||
- connectivity (0.0.1):
|
||||
- Flutter
|
||||
- Reachability
|
||||
- device_info (0.0.1):
|
||||
- device_info_plus (0.0.1):
|
||||
- Flutter
|
||||
- DKImagePickerController/Core (4.3.4):
|
||||
- DKImagePickerController/ImageDataManager
|
||||
@@ -54,7 +54,7 @@ PODS:
|
||||
- Flutter
|
||||
- flutter_native_splash (0.0.1):
|
||||
- Flutter
|
||||
- flutter_secure_storage (3.3.1):
|
||||
- flutter_secure_storage (6.0.0):
|
||||
- Flutter
|
||||
- flutter_sodium (0.0.1):
|
||||
- Flutter
|
||||
@@ -69,38 +69,42 @@ PODS:
|
||||
- move_to_background (0.0.1):
|
||||
- Flutter
|
||||
- MTBBarcodeScanner (5.0.11)
|
||||
- open_filex (0.0.2):
|
||||
- Flutter
|
||||
- OrderedSet (5.0.0)
|
||||
- package_info_plus (0.4.5):
|
||||
- Flutter
|
||||
- path_provider_ios (0.0.1):
|
||||
- path_provider_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- qr_code_scanner (0.2.0):
|
||||
- Flutter
|
||||
- MTBBarcodeScanner
|
||||
- Reachability (3.2)
|
||||
- SDWebImage (5.13.4):
|
||||
- SDWebImage/Core (= 5.13.4)
|
||||
- SDWebImage/Core (5.13.4)
|
||||
- Sentry/HybridSDK (7.30.2)
|
||||
- SDWebImage (5.15.0):
|
||||
- SDWebImage/Core (= 5.15.0)
|
||||
- SDWebImage/Core (5.15.0)
|
||||
- Sentry/HybridSDK (7.31.5)
|
||||
- sentry_flutter (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- Sentry/HybridSDK (= 7.30.2)
|
||||
- Sentry/HybridSDK (= 7.31.5)
|
||||
- share_plus (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences_ios (0.0.1):
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- sqflite (0.0.2):
|
||||
- Flutter
|
||||
- FMDB (>= 2.7.5)
|
||||
- SwiftyGif (5.4.3)
|
||||
- SwiftyGif (5.4.4)
|
||||
- Toast (4.0.0)
|
||||
- url_launcher_ios (0.0.1):
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- connectivity (from `.symlinks/plugins/connectivity/ios`)
|
||||
- device_info (from `.symlinks/plugins/device_info/ios`)
|
||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||
- fk_user_agent (from `.symlinks/plugins/fk_user_agent/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
@@ -113,12 +117,13 @@ DEPENDENCIES:
|
||||
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||
- local_auth (from `.symlinks/plugins/local_auth/ios`)
|
||||
- move_to_background (from `.symlinks/plugins/move_to_background/ios`)
|
||||
- open_filex (from `.symlinks/plugins/open_filex/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
|
||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
|
||||
- qr_code_scanner (from `.symlinks/plugins/qr_code_scanner/ios`)
|
||||
- sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
|
||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
|
||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
|
||||
@@ -138,8 +143,8 @@ SPEC REPOS:
|
||||
EXTERNAL SOURCES:
|
||||
connectivity:
|
||||
:path: ".symlinks/plugins/connectivity/ios"
|
||||
device_info:
|
||||
:path: ".symlinks/plugins/device_info/ios"
|
||||
device_info_plus:
|
||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||
file_picker:
|
||||
:path: ".symlinks/plugins/file_picker/ios"
|
||||
fk_user_agent:
|
||||
@@ -164,18 +169,20 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/local_auth/ios"
|
||||
move_to_background:
|
||||
:path: ".symlinks/plugins/move_to_background/ios"
|
||||
open_filex:
|
||||
:path: ".symlinks/plugins/open_filex/ios"
|
||||
package_info_plus:
|
||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||
path_provider_ios:
|
||||
:path: ".symlinks/plugins/path_provider_ios/ios"
|
||||
path_provider_foundation:
|
||||
:path: ".symlinks/plugins/path_provider_foundation/ios"
|
||||
qr_code_scanner:
|
||||
:path: ".symlinks/plugins/qr_code_scanner/ios"
|
||||
sentry_flutter:
|
||||
:path: ".symlinks/plugins/sentry_flutter/ios"
|
||||
share_plus:
|
||||
:path: ".symlinks/plugins/share_plus/ios"
|
||||
shared_preferences_ios:
|
||||
:path: ".symlinks/plugins/shared_preferences_ios/ios"
|
||||
shared_preferences_foundation:
|
||||
:path: ".symlinks/plugins/shared_preferences_foundation/ios"
|
||||
sqflite:
|
||||
:path: ".symlinks/plugins/sqflite/ios"
|
||||
url_launcher_ios:
|
||||
@@ -183,37 +190,38 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
|
||||
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
|
||||
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
|
||||
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
|
||||
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
|
||||
file_picker: 817ab1d8cd2da9d2da412a417162deee3500fc95
|
||||
file_picker: ce3938a0df3cc1ef404671531facef740d03f920
|
||||
fk_user_agent: 1f47ec39291e8372b1d692b50084b0d54103c545
|
||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||
flutter_email_sender: 02d7443217d8c41483223627972bfdc09f74276b
|
||||
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
|
||||
flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743
|
||||
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
|
||||
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
|
||||
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
|
||||
flutter_sodium: c84426b4de738514b5b66cfdeb8a06634e72fe0b
|
||||
fluttertoast: 74526702fea2c060ea55dde75895b7e1bde1c86b
|
||||
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
local_auth: 1740f55d7af0a2e2a8684ce225fe79d8931e808c
|
||||
move_to_background: 39a5b79b26d577b0372cbe8a8c55e7aa9fcd3a2d
|
||||
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
|
||||
open_filex: 6e26e659846ec990262224a12ef1c528bb4edbe4
|
||||
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
|
||||
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
||||
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
|
||||
path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852
|
||||
qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e
|
||||
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
|
||||
SDWebImage: e5cc87bf736e60f49592f307bdf9e157189298a3
|
||||
Sentry: 9be48e341494bc976c963b05aa4a8ca48308c684
|
||||
sentry_flutter: 544e6376e35b00eef9f0864f8bb7f10a0e204993
|
||||
SDWebImage: 9bec4c5cdd9579e1f57104735ee0c37df274d593
|
||||
Sentry: 4c9babff9034785067c896fd580b1f7de44da020
|
||||
sentry_flutter: b10ae7a5ddcbc7f04648eeb2672b5747230172f1
|
||||
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
|
||||
shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad
|
||||
shared_preferences_foundation: 297b3ebca31b34ec92be11acd7fb0ba932c822ca
|
||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||
SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780
|
||||
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
|
||||
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
|
||||
url_launcher_ios: ae1517e5e344f5544fb090b079e11f399dfbe4d2
|
||||
|
||||
PODFILE CHECKSUM: b4e3a7eabb03395b66e81fc061789f61526ee6bb
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 51;
|
||||
objectVersion = 54;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
@@ -220,6 +220,7 @@
|
||||
};
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
@@ -256,7 +257,7 @@
|
||||
};
|
||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
buildActionMask = 8;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
@@ -264,9 +265,9 @@
|
||||
name = "Run Script";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>12.0</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
|
||||
24
ios/ci_scripts/ci_post_clone.sh
Executable file
24
ios/ci_scripts/ci_post_clone.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
# by default, the execution directory of this script is the ci_scripts directory
|
||||
# CI_WORKSPACE is the directory of your cloned repo
|
||||
echo "🟩 Navigate from ($PWD) to ($CI_WORKSPACE)"
|
||||
cd $CI_WORKSPACE
|
||||
|
||||
echo "🟩 Install Flutter"
|
||||
time git clone https://github.com/flutter/flutter.git -b stable $HOME/flutter
|
||||
export PATH="$PATH:$HOME/flutter/bin"
|
||||
|
||||
echo "🟩 Flutter Precache"
|
||||
time flutter precache --ios
|
||||
|
||||
echo "🟩 Install Flutter Dependencies"
|
||||
time flutter pub get
|
||||
|
||||
echo "🟩 Install CocoaPods via Homebrew"
|
||||
time HOMEBREW_NO_AUTO_UPDATE=1 brew install cocoapods
|
||||
|
||||
echo "🟩 Install CocoaPods dependencies..."
|
||||
time cd ios && pod install
|
||||
|
||||
exit 0
|
||||
@@ -27,6 +27,9 @@ class App extends StatefulWidget {
|
||||
class _AppState extends State<App> {
|
||||
StreamSubscription<SignedOutEvent> _signedOutEvent;
|
||||
StreamSubscription<SignedInEvent> _signedInEvent;
|
||||
static const List<Locale> supportedLocales = <Locale>[
|
||||
Locale('en'),
|
||||
];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -78,13 +81,17 @@ class _AppState extends State<App> {
|
||||
theme: lightTheme,
|
||||
darkTheme: dartTheme,
|
||||
debugShowCheckedModeBanner: false,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
localizationsDelegates: const [
|
||||
AppLocalizations.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: supportedLocales,
|
||||
localeListResolutionCallback: (locales, supportedLocales) {
|
||||
for (Locale locale in locales) {
|
||||
if (supportedLocales.contains(locale)) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
// if device language is not supported by the app, use en as default
|
||||
return const Locale('en');
|
||||
},
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
routes: _getRoutes,
|
||||
),
|
||||
);
|
||||
@@ -95,7 +102,16 @@ class _AppState extends State<App> {
|
||||
theme: lightThemeData,
|
||||
darkTheme: darkThemeData,
|
||||
debugShowCheckedModeBanner: false,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
supportedLocales: supportedLocales,
|
||||
localeListResolutionCallback: (locales, supportedLocales) {
|
||||
for (Locale locale in locales) {
|
||||
if (supportedLocales.contains(locale)) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
// if device language is not supported by the app, use en as default
|
||||
return const Locale('en');
|
||||
},
|
||||
localizationsDelegates: const [
|
||||
AppLocalizations.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
|
||||
@@ -31,7 +31,6 @@ class Configuration {
|
||||
static const emailKey = "email";
|
||||
static const keyAttributesKey = "key_attributes";
|
||||
static const keyKey = "key";
|
||||
static const keyShouldHideFromRecents = "should_hide_from_recents";
|
||||
static const keyShouldShowLockScreen = "should_show_lock_screen";
|
||||
static const lastTempFolderClearTimeKey = "last_temp_folder_clear_time";
|
||||
static const secretKeyKey = "secret_key";
|
||||
@@ -453,14 +452,6 @@ class Configuration {
|
||||
return _preferences.setBool(keyShouldShowLockScreen, value);
|
||||
}
|
||||
|
||||
bool shouldHideFromRecents() {
|
||||
return _preferences.getBool(keyShouldHideFromRecents) ?? false;
|
||||
}
|
||||
|
||||
Future<void> setShouldHideFromRecents(bool value) {
|
||||
return _preferences.setBool(keyShouldHideFromRecents, value);
|
||||
}
|
||||
|
||||
void setVolatilePassword(String volatilePassword) {
|
||||
_volatilePassword = volatilePassword;
|
||||
}
|
||||
|
||||
116
lib/l10n/arb/app_de.arb
Normal file
116
lib/l10n/arb/app_de.arb
Normal file
@@ -0,0 +1,116 @@
|
||||
{
|
||||
"@@locale": "de",
|
||||
"counterAppBarTitle": "Zähler",
|
||||
"@counterAppBarTitle": {
|
||||
"description": "Text, der in der AppBar der Zähler-Seite angezeigt wird"
|
||||
},
|
||||
"onBoardingBody": "Sichern Sie Ihre 2FA-Codes",
|
||||
"onBoardingGetStarted": "Los geht's",
|
||||
"setupFirstAccount": "Ihr erstes Konto einrichten",
|
||||
"importScanQrCode": "Scannen eines QR-Codes",
|
||||
"importEnterSetupKey": "Einen Setup-Schlüssel eingeben",
|
||||
"importAccountPageTitle": "Kontodaten eingeben",
|
||||
"codeIssuerHint": "Aussteller",
|
||||
"codeSecretKeyHint" : "Geheimer Schlüssel",
|
||||
"codeAccountHint": "Konto (you@domain.com)",
|
||||
"accountKeyType": "Art des Schlüssels",
|
||||
"timeBasedKeyType": "Zeitbasiert (TOTP)",
|
||||
"counterBasedKeyType": "Zählerbasiert (HOTP)",
|
||||
"saveAction": "Speichern",
|
||||
"nextTotpTitle": "Weiter",
|
||||
"deleteCodeTitle": "Code löschen?",
|
||||
"deleteCodeMessage": "Sind Sie sicher, dass Sie diesen Code löschen wollen? Diese Aktion ist unumkehrbar.",
|
||||
"viewLogsAction": "Protokolle anzeigen",
|
||||
"sendLogsDescription": "Dadurch werden Protokolle übermittelt, die uns bei der Behebung Ihres Problems helfen. Obwohl wir Vorkehrungen treffen, um sicherzustellen, dass keine sensiblen Informationen protokolliert werden, empfehlen wir Ihnen, diese Protokolle anzusehen, bevor Sie sie weitergeben.",
|
||||
"preparingLogsTitle": "Vorbereiten der Protokolle...",
|
||||
"emailLogsTitle": "Protokolle versenden",
|
||||
"emailLogsMessage": "Bitte senden Sie die Protokolle an {email}",
|
||||
"@emailLogsMessage": {
|
||||
"placeholders": {
|
||||
"email": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"copyEmailAction": "E-Mail kopieren",
|
||||
"exportLogsAction": "Protokolle exportieren",
|
||||
"reportABug": "Fehlermelden",
|
||||
"crashAndErrorReporting": "Absturz- und Fehlerberichte",
|
||||
"reportBug": "Fehlermelden",
|
||||
"emailUsMessage": "Bitte senden Sie uns eine E-Mail an {email}",
|
||||
"@emailUsMessage": {
|
||||
"placeholders": {
|
||||
"email": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"contactSupport": "Support kontaktieren",
|
||||
"verifyPassword": "Passwort überprüfen",
|
||||
"pleaseWaitTitle": "Bitte warten...",
|
||||
"generatingEncryptionKeysTitle": "Generierung von Verschlüsselungsschlüsseln...",
|
||||
"recreatePassword": "Passwort wiederherstellen",
|
||||
"recreatePasswordMessage": "Das aktuelle Gerät ist nicht leistungsfähig genug, um Ihr Passwort zu verifizieren, daher müssen wir es einmalig auf eine Weise neu generieren, die mit allen Geräten funktioniert. \n\nBitte melden Sie sich mit Ihrem Wiederherstellungsschlüssel an und generieren Sie Ihr Passwort neu (Sie können dasselbe erneut verwenden, wenn Sie möchten).",
|
||||
"useRecoveryKeyAction": "Wiederherstellungsschlüssel verwenden",
|
||||
"incorrectPassword": "Falsches Passwort",
|
||||
"welcomeBackTitle": "Willkommen zurück!",
|
||||
"madeWithLoveAtPrefix": "gemacht mit ❤️ bei ",
|
||||
"changeEmail": "E-Mail ändern",
|
||||
"ok": "OK",
|
||||
"cancel": "Abbrechen",
|
||||
"yes": "Ja",
|
||||
"no": "Nein",
|
||||
"email": "E-Mail",
|
||||
"support": "Support",
|
||||
"settings": "Einstellungen",
|
||||
"copied": "Kopiert",
|
||||
"tryAgainMessage": "Bitte versuchen Sie es erneut",
|
||||
"existingUser": "Bestehender Benutzer",
|
||||
"newUser" : "Neu bei ente",
|
||||
"delete": "Löschen",
|
||||
"enterYourPasswordHint": "Geben Sie Ihr Passwort ein",
|
||||
"forgotPassword": "Passwort vergessen",
|
||||
"oops": "Oops",
|
||||
"somethingWentWrongMessage": "Ein Fehler ist aufgetreten, bitte versuchen Sie es erneut",
|
||||
"leaveFamily": "Familie verlassen",
|
||||
"leaveFamilyMessage": "Sind Sie sicher, dass Sie den Familien-Plan verlassen wollen?",
|
||||
"inFamilyPlanMessage": "Sie haben einen Familien-Plan!",
|
||||
"swipeHint": "Wischen Sie nach links, um Codes zu bearbeiten oder zu entfernen",
|
||||
"scan": "Scannen",
|
||||
"scanACode": "Scannen eines Codes",
|
||||
"verify": "Überprüfen Sie",
|
||||
"enterCodeHint": "Geben Sie den 6-stelligen Code \naus Ihrer Authentifikator-App ein.",
|
||||
"lostDeviceTitle": "Gerät verloren?",
|
||||
"twoFactorAuthTitle": "Zwei-Faktor-Authentifizierung",
|
||||
"recoverAccount": "Konto wiederherstellen",
|
||||
"enterRecoveryKeyHint": "Geben Sie Ihren Wiederherstellungsschlüssel ein",
|
||||
"recover": "Wiederherstellen",
|
||||
"contactSupportViaEmailMessage":"Bitte senden Sie eine E-Mail an {email} von Ihrer registrierten E-Mail-Adresse",
|
||||
"@contactSupportViaEmailMessage": {
|
||||
"placeholders": {
|
||||
"email": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"noRecoveryKeyTitle": "Kein Wiederherstellungsschlüssel?",
|
||||
"enterEmailHint": "Geben Sie Ihre E-Mail Adresse ein",
|
||||
"invalidEmailTitle": "Ungültige E-Mail Adresse",
|
||||
"invalidEmailMessage": "Bitte geben Sie eine gültige E-Mail Adresse ein.",
|
||||
"deleteAccount": "Konto löschen",
|
||||
"deleteAccountQuery": "Es wird uns leid tun, Sie gehen zu sehen. Haben Sie ein Problem?",
|
||||
"yesSendFeedbackAction": "Ja, Feedback senden",
|
||||
"noDeleteAccountAction": "Nein, Konto löschen",
|
||||
"initiateAccountDeleteTitle": "Bitte authentifizieren Sie sich, um die Kontolöschung einzuleiten",
|
||||
"confirmAccountDeleteTitle": "Sind Sie sicher, dass Sie Ihr ente Konto löschen wollen?",
|
||||
"confirmAccountDeleteMessage": "Ihre hochgeladenen Daten werden in allen Anwendungen (sowohl Fotos als auch Authenticator) zur Löschung vorgesehen und Ihr Konto wird dauerhaft gelöscht.",
|
||||
"sendEmail": "E-Mail senden",
|
||||
"createNewAccount": "Neues Konto erstellen",
|
||||
"passwordStrengthWeak": "Schwach",
|
||||
"passwordStrengthStrong": "Stark",
|
||||
"passwordStrengthModerate": "Mittel",
|
||||
"confirmPassword": "Bestätigen Sie das Passwort",
|
||||
"close": "Schließen",
|
||||
"oopsSomethingWentWrong": "Ups, da ist etwas schief gelaufen."
|
||||
|
||||
}
|
||||
@@ -67,7 +67,8 @@ class Code {
|
||||
|
||||
static String _getAccount(Uri uri) {
|
||||
try {
|
||||
return uri.path.split(':')[1];
|
||||
final String path = Uri.decodeComponent(uri.path);
|
||||
return path.split(':')[1];
|
||||
} catch (e) {
|
||||
return "";
|
||||
}
|
||||
@@ -75,7 +76,8 @@ class Code {
|
||||
|
||||
static String _getIssuer(Uri uri) {
|
||||
try {
|
||||
return uri.path.split(':')[0].substring(1);
|
||||
final String path = Uri.decodeComponent(uri.path);
|
||||
return path.split(':')[0].substring(1);
|
||||
} catch (e) {
|
||||
return "";
|
||||
}
|
||||
@@ -113,7 +115,12 @@ class Code {
|
||||
}
|
||||
|
||||
static Type _getType(Uri uri) {
|
||||
return uri.host == "totp" ? Type.totp : Type.hotp;
|
||||
if (uri.host == "totp") {
|
||||
return Type.totp;
|
||||
} else if (uri.host == "hotp") {
|
||||
return Type.hotp;
|
||||
}
|
||||
throw UnsupportedError("Unsupported format with host ${uri.host}");
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -104,16 +104,23 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
|
||||
width: 400,
|
||||
child: OutlinedButton(
|
||||
onPressed: () {
|
||||
if (_accountController.text.trim().isEmpty ||
|
||||
if ((_accountController.text.trim().isEmpty &&
|
||||
_issuerController.text.trim().isEmpty) ||
|
||||
_secretController.text.trim().isEmpty) {
|
||||
_showIncorrectDetailsDialog(context);
|
||||
String message;
|
||||
if (_secretController.text.trim().isEmpty) {
|
||||
message = "Secret can not be empty";
|
||||
} else {
|
||||
message = "Both account and issuer can not be empty";
|
||||
}
|
||||
_showIncorrectDetailsDialog(context, message: message);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final code = Code.fromAccountAndSecret(
|
||||
_accountController.text.trim(),
|
||||
_issuerController.text.trim(),
|
||||
_secretController.text.trim(),
|
||||
_secretController.text.trim().replaceAll(' ', ''),
|
||||
);
|
||||
// Verify the validity of the code
|
||||
getTotp(code);
|
||||
@@ -142,11 +149,14 @@ class _SetupEnterSecretKeyPageState extends State<SetupEnterSecretKeyPage> {
|
||||
);
|
||||
}
|
||||
|
||||
void _showIncorrectDetailsDialog(BuildContext context) {
|
||||
void _showIncorrectDetailsDialog(
|
||||
BuildContext context, {
|
||||
String message = "Please verify the entered details",
|
||||
}) {
|
||||
showErrorDialog(
|
||||
context,
|
||||
"Incorrect details",
|
||||
"Please verify the entered details",
|
||||
message,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ class MenuItemWidget extends StatefulWidget {
|
||||
final IconData? trailingIcon;
|
||||
final Widget? trailingSwitch;
|
||||
final bool trailingIconIsMuted;
|
||||
|
||||
/// If provided, add this much extra spacing to the right of the trailing icon.
|
||||
final double trailingExtraMargin;
|
||||
final VoidCallback? onTap;
|
||||
final VoidCallback? onDoubleTap;
|
||||
final Color? menuItemColor;
|
||||
@@ -27,6 +30,7 @@ class MenuItemWidget extends StatefulWidget {
|
||||
this.trailingIcon,
|
||||
this.trailingSwitch,
|
||||
this.trailingIconIsMuted = false,
|
||||
this.trailingExtraMargin = 0.0,
|
||||
this.onTap,
|
||||
this.onDoubleTap,
|
||||
this.menuItemColor,
|
||||
@@ -141,11 +145,15 @@ class _MenuItemWidgetState extends State<MenuItemWidget> {
|
||||
),
|
||||
)
|
||||
: widget.trailingIcon != null
|
||||
? Icon(
|
||||
widget.trailingIcon,
|
||||
color: widget.trailingIconIsMuted
|
||||
? enteColorScheme.strokeMuted
|
||||
: null,
|
||||
? Padding(
|
||||
padding:
|
||||
EdgeInsets.only(right: widget.trailingExtraMargin),
|
||||
child: Icon(
|
||||
widget.trailingIcon,
|
||||
color: widget.trailingIconIsMuted
|
||||
? enteColorScheme.strokeMuted
|
||||
: null,
|
||||
),
|
||||
)
|
||||
: widget.trailingSwitch ?? const SizedBox.shrink(),
|
||||
],
|
||||
|
||||
@@ -34,29 +34,55 @@ class _HomePageState extends State<HomePage> {
|
||||
);
|
||||
bool _hasLoaded = false;
|
||||
bool _isSettingsOpen = false;
|
||||
|
||||
final TextEditingController _textController = TextEditingController();
|
||||
bool _showSearchBox = false;
|
||||
String _searchText = "";
|
||||
List<Code> _codes = [];
|
||||
List<Code> _filteredCodes = [];
|
||||
StreamSubscription<CodesUpdatedEvent>? _streamSubscription;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_textController.addListener(_applyFiltering);
|
||||
_loadCodes();
|
||||
_streamSubscription = Bus.instance.on<CodesUpdatedEvent>().listen((event) {
|
||||
_loadCodes();
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
void _loadCodes() {
|
||||
CodeStore.instance.getAllCodes().then((codes) {
|
||||
_codes = codes;
|
||||
_filteredCodes = codes;
|
||||
|
||||
_hasLoaded = true;
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
void _applyFiltering() {
|
||||
if (_searchText.isNotEmpty && _showSearchBox) {
|
||||
final String val = _searchText.toLowerCase();
|
||||
_filteredCodes = _codes
|
||||
.where(
|
||||
(element) => (element.account.toLowerCase().contains(val) ||
|
||||
element.issuer.toLowerCase().contains(val)),
|
||||
)
|
||||
.toList();
|
||||
} else {
|
||||
_filteredCodes = _codes;
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_streamSubscription?.cancel();
|
||||
_textController.removeListener(_applyFiltering);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -121,7 +147,41 @@ class _HomePageState extends State<HomePage> {
|
||||
),
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: AppBar(
|
||||
title: const Text('ente Authenticator'),
|
||||
title: !_showSearchBox
|
||||
? const Text('ente Authenticator')
|
||||
: TextField(
|
||||
autofocus: _searchText.isEmpty,
|
||||
controller: _textController,
|
||||
onChanged: (val) {
|
||||
_searchText = val;
|
||||
_applyFiltering();
|
||||
},
|
||||
decoration: const InputDecoration(
|
||||
hintText: 'Search...',
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
IconButton(
|
||||
icon: _showSearchBox
|
||||
? const Icon(Icons.clear)
|
||||
: const Icon(Icons.search),
|
||||
tooltip: 'Search',
|
||||
onPressed: () {
|
||||
setState(
|
||||
() {
|
||||
_showSearchBox = !_showSearchBox;
|
||||
if (!_showSearchBox) {
|
||||
_textController.clear();
|
||||
} else {
|
||||
_searchText = _textController.text;
|
||||
}
|
||||
_applyFiltering();
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
floatingActionButton: !_hasLoaded ||
|
||||
_codes.isEmpty ||
|
||||
@@ -134,14 +194,14 @@ class _HomePageState extends State<HomePage> {
|
||||
|
||||
Widget _getBody() {
|
||||
if (_hasLoaded) {
|
||||
if (_codes.isEmpty) {
|
||||
if (_filteredCodes.isEmpty && _searchText.isEmpty) {
|
||||
return _getEmptyState();
|
||||
} else {
|
||||
final list = ListView.builder(
|
||||
itemBuilder: ((context, index) {
|
||||
return CodeWidget(_codes[index]);
|
||||
return CodeWidget(_filteredCodes[index]);
|
||||
}),
|
||||
itemCount: _codes.length,
|
||||
itemCount: _filteredCodes.length,
|
||||
);
|
||||
if (!PreferenceService.instance.hasShownCoachMark()) {
|
||||
return Stack(
|
||||
@@ -150,6 +210,21 @@ class _HomePageState extends State<HomePage> {
|
||||
_getCoachMarkWidget(),
|
||||
],
|
||||
);
|
||||
} else if (_showSearchBox) {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _filteredCodes.isNotEmpty
|
||||
? ListView.builder(
|
||||
itemBuilder: ((context, index) {
|
||||
return CodeWidget(_filteredCodes[index]);
|
||||
}),
|
||||
itemCount: _filteredCodes.length,
|
||||
)
|
||||
: const Center(child: (Text("No result"))),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import 'package:ente_auth/ente_theme_data.dart';
|
||||
import 'package:ente_auth/services/update_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:open_file/open_file.dart';
|
||||
import 'package:open_filex/open_filex.dart';
|
||||
|
||||
class AppUpdateDialog extends StatefulWidget {
|
||||
final LatestVersionInfo latestVersionInfo;
|
||||
@@ -157,7 +157,7 @@ class _ApkDownloaderDialogState extends State<ApkDownloaderDialog> {
|
||||
},
|
||||
);
|
||||
Navigator.of(context, rootNavigator: true).pop('dialog');
|
||||
OpenFile.open(_saveUrl);
|
||||
OpenFilex.open(_saveUrl);
|
||||
} catch (e) {
|
||||
Logger("ApkDownloader").severe(e);
|
||||
final AlertDialog alert = AlertDialog(
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// @dart=2.9
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:ente_auth/core/configuration.dart';
|
||||
import 'package:ente_auth/ente_theme_data.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/services/local_authentication_service.dart';
|
||||
import 'package:ente_auth/theme/ente_theme.dart';
|
||||
@@ -14,7 +11,6 @@ import 'package:ente_auth/ui/components/menu_item_widget.dart';
|
||||
import 'package:ente_auth/ui/components/toggle_switch_widget.dart';
|
||||
import 'package:ente_auth/ui/settings/common_settings.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_windowmanager/flutter_windowmanager.dart';
|
||||
|
||||
class SecuritySectionWidget extends StatefulWidget {
|
||||
const SecuritySectionWidget({Key key}) : super(key: key);
|
||||
@@ -70,97 +66,6 @@ class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
|
||||
),
|
||||
),
|
||||
sectionOptionSpacing,
|
||||
]);
|
||||
if (Platform.isAndroid) {
|
||||
children.addAll(
|
||||
[
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: const CaptionedTextWidget(
|
||||
title: "Hide from recents",
|
||||
),
|
||||
trailingSwitch: ToggleSwitchWidget(
|
||||
value: _config.shouldHideFromRecents(),
|
||||
onChanged: (value) async {
|
||||
if (value) {
|
||||
final AlertDialog alert = AlertDialog(
|
||||
title: const Text("Hide from recents?"),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: const [
|
||||
Text(
|
||||
"Hiding from the task switcher will prevent you from taking screenshots in this app.",
|
||||
style: TextStyle(
|
||||
height: 1.5,
|
||||
),
|
||||
),
|
||||
Padding(padding: EdgeInsets.all(8)),
|
||||
Text(
|
||||
"Are you sure?",
|
||||
style: TextStyle(
|
||||
height: 1.5,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
l10n.no,
|
||||
style: TextStyle(
|
||||
color:
|
||||
Theme.of(context).colorScheme.defaultTextColor,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context, rootNavigator: true)
|
||||
.pop('dialog');
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text(
|
||||
l10n.yes,
|
||||
style: TextStyle(
|
||||
color:
|
||||
Theme.of(context).colorScheme.defaultTextColor,
|
||||
),
|
||||
),
|
||||
onPressed: () async {
|
||||
Navigator.of(context, rootNavigator: true)
|
||||
.pop('dialog');
|
||||
await _config.setShouldHideFromRecents(true);
|
||||
await FlutterWindowManager.addFlags(
|
||||
FlutterWindowManager.FLAG_SECURE,
|
||||
);
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return alert;
|
||||
},
|
||||
);
|
||||
} else {
|
||||
await _config.setShouldHideFromRecents(false);
|
||||
await FlutterWindowManager.clearFlags(
|
||||
FlutterWindowManager.FLAG_SECURE,
|
||||
);
|
||||
setState(() {});
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
sectionOptionSpacing,
|
||||
],
|
||||
);
|
||||
}
|
||||
children.addAll([
|
||||
MenuItemWidget(
|
||||
captionedTextWidget: const CaptionedTextWidget(
|
||||
title: "Active sessions",
|
||||
|
||||
@@ -73,6 +73,7 @@ class _ThemeSwitchWidgetState extends State<ThemeSwitchWidget> {
|
||||
pressedColor: getEnteColorScheme(context).fillFaint,
|
||||
isExpandable: false,
|
||||
trailingIcon: currentThemeMode == themeMode ? Icons.check : null,
|
||||
trailingExtraMargin: 4,
|
||||
onTap: () async {
|
||||
AdaptiveTheme.of(context).setThemeMode(themeMode);
|
||||
currentThemeMode = themeMode;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
/// A widget which handles app lifecycle events for showing and hiding a lock screen.
|
||||
/// This should wrap around a `MyApp` widget (or equivalent).
|
||||
@@ -107,6 +108,8 @@ class _AppLockState extends State<AppLock> with WidgetsBindingObserver {
|
||||
themeMode: ThemeMode.system,
|
||||
theme: widget.lightTheme,
|
||||
darkTheme: widget.darkTheme,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
onGenerateRoute: (settings) {
|
||||
switch (settings.name) {
|
||||
case '/lock-screen':
|
||||
|
||||
@@ -59,7 +59,7 @@ class _LockScreenState extends State<LockScreen> {
|
||||
_logger.info("Showing lockscreen");
|
||||
try {
|
||||
final result = await requestAuthentication(
|
||||
"Please authenticate to view your memories",
|
||||
"Please authenticate to view your secrets",
|
||||
);
|
||||
if (result) {
|
||||
AppLock.of(context).didUnlock();
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'dart:typed_data';
|
||||
import 'package:computer/computer.dart';
|
||||
import 'package:ente_auth/models/derived_key_result.dart';
|
||||
import 'package:ente_auth/models/encryption_result.dart';
|
||||
import 'package:ente_auth/utils/device_info.dart';
|
||||
import 'package:flutter_sodium/flutter_sodium.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
@@ -287,16 +288,38 @@ class CryptoUtil {
|
||||
Uint8List salt,
|
||||
) async {
|
||||
final logger = Logger("pwhash");
|
||||
// Default with 1 GB mem and 4 ops limit
|
||||
int memLimit = Sodium.cryptoPwhashMemlimitSensitive;
|
||||
int opsLimit = Sodium.cryptoPwhashOpslimitSensitive;
|
||||
|
||||
if (await isLowSpecDevice()) {
|
||||
logger.info("low spec device detected");
|
||||
// When sensitive memLimit (1 GB) is used, on low spec device the OS might
|
||||
// kill the app with OOM. To avoid that, start with 256 MB and
|
||||
// corresponding ops limit (16).
|
||||
// This ensures that the product of these two variables
|
||||
// (the area under the graph that determines the amount of work required)
|
||||
// stays the same
|
||||
// SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE: 1073741824
|
||||
// SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE: 268435456
|
||||
// SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE: 4
|
||||
memLimit = Sodium.cryptoPwhashMemlimitModerate;
|
||||
final factor = Sodium.cryptoPwhashMemlimitSensitive ~/
|
||||
Sodium.cryptoPwhashMemlimitModerate; // = 4
|
||||
opsLimit = opsLimit * factor; // = 16
|
||||
}
|
||||
Uint8List key;
|
||||
while (memLimit > Sodium.cryptoPwhashMemlimitMin &&
|
||||
opsLimit < Sodium.cryptoPwhashOpslimitMax) {
|
||||
while (memLimit >= Sodium.cryptoPwhashMemlimitMin &&
|
||||
opsLimit <= Sodium.cryptoPwhashOpslimitMax) {
|
||||
try {
|
||||
key = await deriveKey(password, salt, memLimit, opsLimit);
|
||||
return DerivedKeyResult(key, memLimit, opsLimit);
|
||||
} catch (e, s) {
|
||||
logger.severe(e, s);
|
||||
logger.severe(
|
||||
"failed to derive memLimit: $memLimit and opsLimit: $opsLimit",
|
||||
e,
|
||||
s,
|
||||
);
|
||||
}
|
||||
memLimit = (memLimit / 2).round();
|
||||
opsLimit = opsLimit * 2;
|
||||
|
||||
31
lib/utils/device_info.dart
Normal file
31
lib/utils/device_info.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
late DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
|
||||
|
||||
// https://gist.github.com/adamawolf/3048717
|
||||
late Set<String> iOSLowEndMachineCodes = <String>{
|
||||
"iPhone5,2",
|
||||
"iPhone5,3",
|
||||
"iPhone5,4",
|
||||
"iPhone6,1",
|
||||
"iPhone6,2",
|
||||
"iPhone7,2",
|
||||
"iPhone7,1",
|
||||
};
|
||||
|
||||
Future<bool> isLowSpecDevice() async {
|
||||
try {
|
||||
if (Platform.isIOS) {
|
||||
final IosDeviceInfo iosInfo = await deviceInfoPlugin.iosInfo;
|
||||
debugPrint("ios utc name ${iosInfo.utsname.machine}");
|
||||
return iOSLowEndMachineCodes.contains(iosInfo.utsname.machine);
|
||||
}
|
||||
} catch (e) {
|
||||
Logger("device_info").severe("deviceSpec check failed", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -6,18 +6,20 @@ import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import connectivity_macos
|
||||
import device_info_plus
|
||||
import flutter_local_notifications
|
||||
import flutter_secure_storage_macos
|
||||
import package_info_plus_macos
|
||||
import path_provider_macos
|
||||
import path_provider_foundation
|
||||
import sentry_flutter
|
||||
import share_plus_macos
|
||||
import shared_preferences_macos
|
||||
import shared_preferences_foundation
|
||||
import sqflite
|
||||
import url_launcher_macos
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
|
||||
FlutterSecureStorageMacosPlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStorageMacosPlugin"))
|
||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||
|
||||
248
pubspec.lock
248
pubspec.lock
@@ -7,7 +7,7 @@ packages:
|
||||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "40.0.0"
|
||||
version: "47.0.0"
|
||||
adaptive_theme:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -21,21 +21,21 @@ packages:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
version: "4.7.0"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.3.1"
|
||||
version: "3.3.6"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.1"
|
||||
version: "2.3.2"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -63,14 +63,14 @@ packages:
|
||||
name: bloc
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.0.3"
|
||||
version: "8.1.0"
|
||||
bloc_test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: bloc_test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "9.0.3"
|
||||
version: "9.1.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -84,14 +84,14 @@ packages:
|
||||
name: build
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
version: "2.3.1"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
version: "1.1.1"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -105,21 +105,21 @@ packages:
|
||||
name: build_resolvers
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.9"
|
||||
version: "2.0.10"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.11"
|
||||
version: "2.3.0"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.2.3"
|
||||
version: "7.2.7"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -133,7 +133,7 @@ packages:
|
||||
name: built_value
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.3.2"
|
||||
version: "8.4.3"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -147,7 +147,7 @@ packages:
|
||||
name: checked_yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "2.0.2"
|
||||
clipboard:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -168,7 +168,7 @@ packages:
|
||||
name: code_builder
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
version: "4.4.0"
|
||||
collection:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -224,14 +224,21 @@ packages:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
version: "3.1.1"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.2"
|
||||
version: "1.6.2"
|
||||
cross_file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cross_file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.3+4"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -259,7 +266,7 @@ packages:
|
||||
name: dart_style
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.3"
|
||||
version: "2.2.4"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -267,20 +274,20 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.8"
|
||||
device_info:
|
||||
device_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: device_info
|
||||
name: device_info_plus
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
device_info_platform_interface:
|
||||
version: "8.0.0"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_platform_interface
|
||||
name: device_info_plus_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "7.0.0"
|
||||
diff_match_patch:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -301,7 +308,7 @@ packages:
|
||||
name: dotted_border
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0+2"
|
||||
version: "2.0.0+3"
|
||||
email_validator:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -350,14 +357,14 @@ packages:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.2"
|
||||
version: "6.1.4"
|
||||
file_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file_picker
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.2.4"
|
||||
version: "5.2.5"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -383,28 +390,28 @@ packages:
|
||||
name: flutter_animation_progress_bar
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "2.3.1"
|
||||
flutter_bloc:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_bloc
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.0.1"
|
||||
version: "8.1.1"
|
||||
flutter_email_sender:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_email_sender
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.1.0"
|
||||
version: "5.2.0"
|
||||
flutter_inappwebview:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_inappwebview
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.7.1"
|
||||
version: "5.7.2+3"
|
||||
flutter_launcher_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -418,14 +425,14 @@ packages:
|
||||
name: flutter_local_notifications
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "12.0.3"
|
||||
version: "12.0.4"
|
||||
flutter_local_notifications_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_local_notifications_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
version: "2.0.0"
|
||||
flutter_local_notifications_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -444,7 +451,7 @@ packages:
|
||||
name: flutter_native_splash
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.13"
|
||||
version: "2.2.16"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -458,42 +465,42 @@ packages:
|
||||
name: flutter_secure_storage
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
version: "6.1.0"
|
||||
flutter_secure_storage_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.1.2"
|
||||
flutter_secure_storage_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.1.2"
|
||||
flutter_secure_storage_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
version: "1.0.1"
|
||||
flutter_secure_storage_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.1.1"
|
||||
flutter_secure_storage_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "1.1.3"
|
||||
flutter_slidable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -527,20 +534,13 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_windowmanager:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_windowmanager
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
fluttertoast:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: fluttertoast
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.1.1"
|
||||
version: "8.1.2"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -554,7 +554,7 @@ packages:
|
||||
name: glob
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
version: "2.1.1"
|
||||
google_nav_bar:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -568,7 +568,7 @@ packages:
|
||||
name: graphs
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.2.0"
|
||||
hex:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -596,21 +596,21 @@ packages:
|
||||
name: http_multi_server
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.2.0"
|
||||
version: "3.2.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.1"
|
||||
version: "4.0.2"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
version: "3.3.0"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -624,7 +624,7 @@ packages:
|
||||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "1.0.4"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -638,14 +638,14 @@ packages:
|
||||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.5.0"
|
||||
version: "4.7.0"
|
||||
json_serializable:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: json_serializable
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.2.0"
|
||||
version: "6.5.4"
|
||||
lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@@ -666,7 +666,7 @@ packages:
|
||||
name: logging
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.1.1"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -694,7 +694,7 @@ packages:
|
||||
name: mime
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.0.4"
|
||||
mocktail:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@@ -723,27 +723,27 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
open_file:
|
||||
open_filex:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: open_file
|
||||
name: open_filex
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
version: "4.3.2"
|
||||
otp:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: otp
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
version: "3.1.3"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
version: "2.1.0"
|
||||
package_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -778,7 +778,7 @@ packages:
|
||||
name: package_info_plus_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
version: "1.0.6"
|
||||
package_info_plus_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -820,21 +820,21 @@ packages:
|
||||
name: path_provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.11"
|
||||
version: "2.0.12"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.20"
|
||||
path_provider_ios:
|
||||
version: "2.0.22"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_ios
|
||||
name: path_provider_foundation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.11"
|
||||
version: "2.1.1"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -842,20 +842,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.7"
|
||||
path_provider_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.6"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
version: "2.0.5"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -869,7 +862,7 @@ packages:
|
||||
name: petitparser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
version: "5.1.0"
|
||||
pinput:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -904,7 +897,7 @@ packages:
|
||||
name: pool
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
version: "1.5.1"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -918,21 +911,21 @@ packages:
|
||||
name: provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.3"
|
||||
version: "6.0.5"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "2.1.3"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
qr_code_scanner:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -946,28 +939,28 @@ packages:
|
||||
name: sentry
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.15.1"
|
||||
version: "6.19.0"
|
||||
sentry_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sentry_flutter
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.15.1"
|
||||
version: "6.19.0"
|
||||
share_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: share_plus
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.4.0"
|
||||
version: "4.5.3"
|
||||
share_plus_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: share_plus_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
version: "3.0.1"
|
||||
share_plus_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -981,14 +974,14 @@ packages:
|
||||
name: share_plus_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
version: "3.2.0"
|
||||
share_plus_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: share_plus_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.1.0"
|
||||
share_plus_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1002,35 +995,28 @@ packages:
|
||||
name: shared_preferences
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.15"
|
||||
version: "2.0.17"
|
||||
shared_preferences_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.13"
|
||||
shared_preferences_ios:
|
||||
version: "2.0.15"
|
||||
shared_preferences_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_ios
|
||||
name: shared_preferences_foundation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "2.1.3"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
shared_preferences_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
version: "2.1.3"
|
||||
shared_preferences_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1051,35 +1037,35 @@ packages:
|
||||
name: shared_preferences_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "2.1.3"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.4.0"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
version: "3.0.1"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.3"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@@ -1091,28 +1077,28 @@ packages:
|
||||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
version: "1.2.6"
|
||||
source_helper:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_helper
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.2"
|
||||
version: "1.3.3"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.10"
|
||||
version: "0.10.11"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1126,14 +1112,14 @@ packages:
|
||||
name: sqflite
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.2.4+1"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
version: "2.4.2+2"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1161,7 +1147,7 @@ packages:
|
||||
name: stream_transform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1175,7 +1161,7 @@ packages:
|
||||
name: synchronized
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0+3"
|
||||
version: "3.0.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1210,14 +1196,14 @@ packages:
|
||||
name: timezone
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.0"
|
||||
version: "0.9.1"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
version: "1.0.1"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1238,63 +1224,63 @@ packages:
|
||||
name: url_launcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.5"
|
||||
version: "6.1.8"
|
||||
url_launcher_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.19"
|
||||
version: "6.0.23"
|
||||
url_launcher_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.17"
|
||||
version: "6.0.18"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
url_launcher_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
url_launcher_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
url_launcher_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.13"
|
||||
version: "2.0.14"
|
||||
url_launcher_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.3"
|
||||
uuid:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: uuid
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.6"
|
||||
version: "3.0.7"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1308,42 +1294,42 @@ packages:
|
||||
name: vm_service
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.3.0"
|
||||
version: "9.4.0"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.2"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "2.3.0"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webkit_inspection_protocol
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
version: "3.1.3"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0+2"
|
||||
version: "0.2.0+3"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1360,4 +1346,4 @@ packages:
|
||||
version: "3.1.1"
|
||||
sdks:
|
||||
dart: ">=2.18.0 <3.0.0"
|
||||
flutter: ">=3.3.0-0"
|
||||
flutter: ">=3.3.0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: ente_auth
|
||||
description: ente two-factor authenticator
|
||||
version: 1.0.22+22
|
||||
version: 1.0.28+28
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
@@ -16,7 +16,7 @@ dependencies:
|
||||
confetti: ^0.7.0
|
||||
connectivity: ^3.0.3
|
||||
cupertino_icons: ^1.0.0
|
||||
device_info: ^2.0.2
|
||||
device_info_plus: ^8.0.0
|
||||
dio: ^4.0.6
|
||||
dotted_border: ^2.0.0+2
|
||||
email_validator: ^2.0.1
|
||||
@@ -42,7 +42,6 @@ dependencies:
|
||||
git:
|
||||
url: https://github.com/ente-io/flutter_sodium.git
|
||||
flutter_speed_dial: ^6.2.0
|
||||
flutter_windowmanager: ^0.2.0
|
||||
fluttertoast: ^8.1.1
|
||||
google_nav_bar: ^5.0.5 #supported
|
||||
http: ^0.13.4
|
||||
@@ -51,7 +50,7 @@ dependencies:
|
||||
local_auth: ^1.1.5
|
||||
logging: ^1.0.1
|
||||
move_to_background: ^1.0.2
|
||||
open_file: ^3.2.1
|
||||
open_filex: ^4.3.2
|
||||
otp: ^3.1.1
|
||||
package_info_plus: ^1.0.1
|
||||
password_strength: ^0.2.0
|
||||
|
||||
13
test/models/code_test.dart
Normal file
13
test/models/code_test.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
import 'package:ente_auth/models/code.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
test("parseCodeFromRawData", () {
|
||||
final code1 = Code.fromRawData(
|
||||
"otpauth://totp/example%20finance%3Aee%40ff.gg?secret=ASKZNWOU6SVYAMVS",
|
||||
);
|
||||
expect(code1.issuer, "example finance");
|
||||
expect(code1.account, "ee@ff.gg");
|
||||
expect(code1.secret, "ASKZNWOU6SVYAMVS");
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user