Compare commits

..

1 Commits

Author SHA1 Message Date
Neeraj Gupta
6146350aae [docs] Update custom server section for cli 2024-03-13 12:02:36 +05:30
1313 changed files with 62612 additions and 29740 deletions

BIN
.github/assets/github-badge.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -2,15 +2,15 @@ name: "Sync Crowdin translations (auth)"
on:
push:
branches: [main]
paths:
# Run workflow when auth's intl_en.arb is changed
- "mobile/lib/l10n/arb/app_en.arb"
# Or the workflow itself is changed
- ".github/workflows/auth-crowdin.yml"
branches: [main]
schedule:
# See: [Note: Run workflow on specific days of the week]
- cron: "50 1 * * 2,5"
# See: [Note: Run every 24 hours]
- cron: "50 1 * * *"
# Also allow manually running the workflow
workflow_dispatch:
@@ -28,7 +28,7 @@ jobs:
base_path: "auth/"
config: "auth/crowdin.yml"
upload_sources: true
upload_translations: false
upload_translations: true
download_translations: true
localization_branch_name: crowdin-translations-auth
create_pull_request: true

View File

@@ -3,13 +3,13 @@ name: "Lint (auth)"
on:
# Run on every push to a branch other than main that changes auth/
push:
branches-ignore: [main, "deploy/**"]
branches-ignore: [main]
paths:
- "auth/**"
- ".github/workflows/auth-lint.yml"
env:
FLUTTER_VERSION: "3.19.3"
FLUTTER_VERSION: "3.16.9"
jobs:
lint:

View File

@@ -29,11 +29,11 @@ on:
- "auth-v*"
env:
FLUTTER_VERSION: "3.19.3"
FLUTTER_VERSION: "3.13.4"
jobs:
build-ubuntu:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
defaults:
run:
@@ -72,8 +72,6 @@ jobs:
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
- name: Build PlayStore AAB
# disable this step if release tag contains nightly or beta
if: startsWith(github.ref, 'refs/tags/auth-v') && !contains(github.ref, 'nightly') && !contains(github.ref, 'beta')
run: |
flutter build appbundle --release --flavor playstore --dart-define=app.flavor=playstore
env:
@@ -85,8 +83,7 @@ jobs:
- name: Install dependencies for desktop build
run: |
sudo apt-get update -y
sudo apt-get install -y libsecret-1-dev libsodium-dev libwebkit2gtk-4.0-dev libfuse2 ninja-build libgtk-3-dev dpkg-dev pkg-config rpm libsqlite3-dev locate appindicator3-0.1 libappindicator3-dev libffi-dev libtiff5
sudo updatedb --localpaths='/usr/lib/x86_64-linux-gnu'
sudo apt-get install -y libsecret-1-dev libsodium-dev libwebkit2gtk-4.0-dev libfuse2 ninja-build libgtk-3-dev dpkg-dev pkg-config rpm libsqlite3-dev locate
- name: Install appimagetool
run: |
@@ -95,6 +92,8 @@ jobs:
mv appimagetool /usr/local/bin/
- name: Build desktop app
# Temporarily disable desktop builds
if: false
run: |
flutter config --enable-linux-desktop
dart pub global activate flutter_distributor
@@ -119,8 +118,6 @@ jobs:
updateOnlyUnreleased: true
- name: Upload AAB to PlayStore
# disable this step if release tag contains nightly or beta
if: startsWith(github.ref, 'refs/tags/auth-v') && !contains(github.ref, 'nightly') && !contains(github.ref, 'beta')
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
@@ -152,6 +149,8 @@ jobs:
run: mkdir artifacts
- name: Build Windows installer
# Temporarily disable desktop builds
if: false
run: |
flutter config --enable-windows-desktop
dart pub global activate flutter_distributor
@@ -160,9 +159,13 @@ jobs:
mv dist/**/ente_auth-*-windows-setup.exe artifacts/ente-${{ github.ref_name }}-installer.exe
- name: Retain Windows EXE and DLLs
# Temporarily disable desktop builds
if: false
run: cp -r build/windows/x64/runner/Release ente-${{ github.ref_name }}-windows
- name: Code sign Windows installer and EXE
# Temporarily disable desktop builds
if: false
uses: dlemstra/code-sign-action@v1
with:
certificate: "${{ secrets.WINDOWS_CERTIFICATE }}"
@@ -172,10 +175,9 @@ jobs:
auth/ente-${{ github.ref_name }}-windows/auth.exe
- name: Zip Windows EXE and DLLs
run: tar.exe -a -c -f artifacts/ente-${{ github.ref_name }}-windows.zip ente-${{ github.ref_name }}-windows
- name: Generate checksums
run: sha256sum artifacts/ente-* > artifacts/sha256sum-windows
# Temporarily disable desktop builds
if: false
run: tar.exe -a -c -f auth/artifacts/ente-${{ github.ref_name }}-windows.zip auth/ente-${{ github.ref_name }}-windows
- name: Create a draft GitHub release
uses: ncipollo/release-action@v1
@@ -246,6 +248,8 @@ jobs:
run: mkdir artifacts
- name: Build macOS DMG
# Temporarily disable desktop builds
if: false
run: |
flutter config --enable-macos-desktop
dart pub global activate flutter_distributor
@@ -253,12 +257,16 @@ jobs:
mv dist/**/ente_auth-*-macos.dmg artifacts/ente-${{ github.ref_name }}.dmg
- name: Code sign DMG
# Temporarily disable desktop builds
if: false
run: |
CERT_NAME=$(security find-identity -v -p codesigning | grep "Developer ID Application" | awk -F'"' '{print $2}' | grep -m1 "")
codesign --force --timestamp --sign "$CERT_NAME" --options runtime artifacts/ente-${{ github.ref_name }}.dmg
codesign --verify --verbose=4 artifacts/ente-${{ github.ref_name }}.dmg
- name: Notarize and staple DMG
# Temporarily disable desktop builds
if: false
run: |
xcrun notarytool submit artifacts/ente-${{ github.ref_name }}.dmg \
--wait \
@@ -271,9 +279,6 @@ jobs:
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
- name: Generate checksums
run: shasum -a 256 artifacts/ente-* > artifacts/sha256sum-macos
- name: Create a draft GitHub release
uses: ncipollo/release-action@v1
with:

View File

@@ -1,24 +0,0 @@
name: "Release (copycat-db)"
on:
workflow_dispatch: # Run manually
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
name: Check out code
- uses: mr-smithers-excellent/docker-build-push@v6
name: Build & Push
with:
dockerfile: infra/copycat-db/Dockerfile
directory: infra/copycat-db
image: ente/copycat-db
registry: rg.fr-par.scw.cloud
enableBuildKit: true
buildArgs: GIT_COMMIT=${GITHUB_SHA}
tags: ${GITHUB_SHA}, latest
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

View File

@@ -6,7 +6,7 @@ name: "Verify build (docs)"
on:
# Run on every push to a branch other than main that changes docs/
push:
branches-ignore: [main, "deploy/**"]
branches-ignore: [main]
paths:
- "docs/**"
- ".github/workflows/docs-verify-build.yml"

View File

@@ -2,15 +2,15 @@ name: "Sync Crowdin translations (mobile)"
on:
push:
branches: [main]
paths:
# Run workflow when mobiles's intl_en.arb is changed
- "mobile/lib/l10n/intl_en.arb"
# Or the workflow itself is changed
- ".github/workflows/mobile-crowdin.yml"
branches: [main]
schedule:
# See: [Note: Run workflow on specific days of the week]
- cron: "40 1 * * 2,5"
# See: [Note: Run every 24 hours]
- cron: "40 1 * * *"
# Also allow manually running the workflow
workflow_dispatch:
@@ -28,7 +28,7 @@ jobs:
base_path: "mobile/"
config: "mobile/crowdin.yml"
upload_sources: true
upload_translations: false
upload_translations: true
download_translations: true
localization_branch_name: crowdin-translations-mobile
create_pull_request: true

View File

@@ -3,13 +3,13 @@ name: "Lint (mobile)"
on:
# Run on every push to a branch other than main that changes mobile/
push:
branches-ignore: [main, f-droid, "deploy/**"]
branches-ignore: [main]
paths:
- "mobile/**"
- ".github/workflows/mobile-lint.yml"
env:
FLUTTER_VERSION: "3.19.5"
FLUTTER_VERSION: "3.13.4"
jobs:
lint:

View File

@@ -9,7 +9,7 @@ on:
- "photos-v*"
env:
FLUTTER_VERSION: "3.19.5"
FLUTTER_VERSION: "3.13.4"
jobs:
build:
@@ -49,7 +49,7 @@ jobs:
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD_PHOTOS }}
- name: Checksum
run: sha256sum build/app/outputs/flutter-apk/ente-${{ github.ref_name }}.apk > build/app/outputs/flutter-apk/sha256sum
run: sha256sum build/app/outputs/flutter-apk/ente.apk > build/app/outputs/flutter-apk/sha256sum
- name: Create a draft GitHub release
uses: ncipollo/release-action@v1

View File

@@ -3,7 +3,7 @@ name: "Lint (server)"
on:
# Run on every push to a branch other than main that changes server/
push:
branches-ignore: [main, "deploy/**"]
branches-ignore: [main]
paths:
- "server/**"
- ".github/workflows/server-lint.yml"

View File

@@ -1,40 +0,0 @@
name: "Publish (server)"
on:
# Run manually, providing it the commit.
#
# To obtain the commit from the currently deployed museum, do:
# curl -s https://api.ente.io/ping | jq -r '.id'
#
# See server/docs/publish.md for more details.
workflow_dispatch:
inputs:
commit:
description: "Commit to publish the image from"
type: string
required: true
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ inputs.commit }}
- name: Build and push
uses: mr-smithers-excellent/docker-build-push@v6
with:
dockerfile: server/Dockerfile
directory: server
# Resultant package name will be ghcr.io/ente-io/server
image: server
registry: ghcr.io
enableBuildKit: true
multiPlatform: true
platform: linux/amd64,linux/arm64,linux/arm/v7
buildArgs: GIT_COMMIT=${{ inputs.commit }}
tags: ${{ inputs.commit }}, latest
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -7,11 +7,11 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- uses: actions/checkout@v4
name: Check out code
- name: Build and push
uses: mr-smithers-excellent/docker-build-push@v6
- uses: mr-smithers-excellent/docker-build-push@v6
name: Build & Push
with:
dockerfile: server/Dockerfile
directory: server

View File

@@ -2,21 +2,15 @@ name: "Sync Crowdin translations (web)"
on:
push:
branches: [main]
paths:
# Run workflow when web's en-US/translation.json is changed
- "web/packages/next/locales/en-US/translation.json"
- "web/apps/photos/public/locales/en-US/translation.json"
# Or the workflow itself is changed
- ".github/workflows/web-crowdin.yml"
branches: [main]
schedule:
# [Note: Run workflow on specific days of the week]
#
# The last (5th) component of the cron syntax denotes the day of the
# week, with 0 == SUN and 6 == SAT. So, for example, to run on every TUE
# and FRI, this can be set to `2,5`.
#
# See also: [Note: Run workflow every 24 hours]
- cron: "20 1 * * 2,5"
# See: [Note: Run every 24 hours]
- cron: "20 1 * * *"
# Also allow manually running the workflow
workflow_dispatch:
@@ -34,7 +28,7 @@ jobs:
base_path: "web/"
config: "web/crowdin.yml"
upload_sources: true
upload_translations: false
upload_translations: true
download_translations: true
localization_branch_name: crowdin-translations-web
create_pull_request: true

View File

@@ -24,7 +24,7 @@ jobs:
with:
node-version: 20
cache: "yarn"
cache-dependency-path: "web/yarn.lock"
cache-dependency-path: "docs/yarn.lock"
- name: Install dependencies
run: yarn install

View File

@@ -24,7 +24,7 @@ jobs:
with:
node-version: 20
cache: "yarn"
cache-dependency-path: "web/yarn.lock"
cache-dependency-path: "docs/yarn.lock"
- name: Install dependencies
run: yarn install

View File

@@ -24,7 +24,7 @@ jobs:
with:
node-version: 20
cache: "yarn"
cache-dependency-path: "web/yarn.lock"
cache-dependency-path: "docs/yarn.lock"
- name: Install dependencies
run: yarn install

View File

@@ -1,43 +0,0 @@
name: "Deploy (payments)"
on:
push:
# Run workflow on pushes to the deploy/payments
branches: [deploy/payments]
jobs:
deploy:
runs-on: ubuntu-latest
defaults:
run:
working-directory: web
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
with:
node-version: 20
cache: "yarn"
cache-dependency-path: "web/yarn.lock"
- name: Install dependencies
run: yarn install
- name: Build payments
run: yarn build:payments
- name: Publish payments
uses: cloudflare/pages-action@1
with:
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
projectName: ente
branch: deploy/payments
directory: web/apps/payments/dist
wranglerVersion: "3"

View File

@@ -24,7 +24,7 @@ jobs:
with:
node-version: 20
cache: "yarn"
cache-dependency-path: "web/yarn.lock"
cache-dependency-path: "docs/yarn.lock"
- name: Install dependencies
run: yarn install

View File

@@ -1,48 +0,0 @@
name: "Deploy (staff)"
on:
# Run on every push to main that changes web/apps/staff/
push:
branches: [main]
paths:
- "web/apps/staff/**"
- ".github/workflows/web-deploy-staff.yml"
# Also allow manually running the workflow
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
defaults:
run:
working-directory: web
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup node and enable yarn caching
uses: actions/setup-node@v4
with:
node-version: 20
cache: "yarn"
cache-dependency-path: "web/yarn.lock"
- name: Install dependencies
run: yarn install
- name: Build staff
run: yarn build:staff
- name: Publish staff
uses: cloudflare/pages-action@1
with:
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
projectName: ente
branch: deploy/staff
directory: web/apps/staff/dist
wranglerVersion: "3"

View File

@@ -3,7 +3,7 @@ name: "Lint (web)"
on:
# Run on every push to a branch other than main that changes web/
push:
branches-ignore: [main, "deploy/**"]
branches-ignore: [main]
paths:
- "web/**"
- ".github/workflows/web-lint.yml"

View File

@@ -2,7 +2,7 @@ name: "Nightly (web)"
on:
schedule:
# [Note: Run workflow every 24 hours]
# [Note: Run every 24 hours]
#
# Run every 24 hours - First field is minute, second is hour of the day
# This runs 23:15 UTC everyday - 1 and 15 are just arbitrary offset to
@@ -34,7 +34,7 @@ jobs:
with:
node-version: 20
cache: "yarn"
cache-dependency-path: "web/yarn.lock"
cache-dependency-path: "docs/yarn.lock"
- name: Install dependencies
run: yarn install
@@ -78,19 +78,6 @@ jobs:
directory: web/apps/cast/out
wranglerVersion: "3"
- name: Build payments
run: yarn build:payments
- name: Publish payments
uses: cloudflare/pages-action@1
with:
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
projectName: ente
branch: n-payments
directory: web/apps/payments/dist
wranglerVersion: "3"
- name: Build photos
run: yarn build:photos
env:

View File

@@ -12,7 +12,6 @@ on:
- "accounts"
- "auth"
- "cast"
- "payments"
- "photos"
jobs:
@@ -34,7 +33,7 @@ jobs:
with:
node-version: 20
cache: "yarn"
cache-dependency-path: "web/yarn.lock"
cache-dependency-path: "docs/yarn.lock"
- name: Install dependencies
run: yarn install

13
.gitmodules vendored
View File

@@ -9,9 +9,16 @@
[submodule "auth/assets/simple-icons"]
path = auth/assets/simple-icons
url = https://github.com/simple-icons/simple-icons.git
[submodule "mobile/thirdparty/flutter"]
path = mobile/thirdparty/flutter
url = https://github.com/flutter/flutter.git
branch = stable
[submodule "mobile/plugins/clip_ggml"]
path = mobile/plugins/clip_ggml
url = https://github.com/ente-io/clip-ggml.git
[submodule "mobile/thirdparty/isar"]
path = mobile/thirdparty/isar
url = https://github.com/isar/isar
[submodule "web/apps/photos/thirdparty/ffmpeg-wasm"]
path = web/apps/photos/thirdparty/ffmpeg-wasm
url = https://github.com/abhinavkgrd/ffmpeg.wasm.git
@@ -20,9 +27,3 @@
path = web/apps/photos/thirdparty/photoswipe
url = https://github.com/ente-io/PhotoSwipe.git
branch = single-thread
[submodule "mobile/thirdparty/isar"]
path = mobile/thirdparty/isar
url = https://github.com/isar/isar
[submodule "mobile/thirdparty/flutter"]
path = mobile/thirdparty/flutter
url = https://github.com/flutter/flutter

View File

@@ -59,10 +59,7 @@ See [docs/](docs/README.md) for how to edit these documents.
## Code contributions
Code is a small aspect of community, and the ways mentioned above are more
important in helping us. But if you'd _really_ like to contribute code, it is
best to start small. Consider some well-scoped changes, say like adding more
[custom icons to auth](auth/docs/adding-icons.md).
If you'd like to contribute code, it is best to start small.
Each of the individual product/platform specific directories in this repository
have instructions on setting up a dev environment and making changes. The issues

View File

@@ -70,7 +70,7 @@ existing users will be grandfathered in.
[<img height="42" src=".github/assets/app-store-badge.svg">](https://apps.apple.com/app/id6444121398)
[<img height="42" src=".github/assets/play-store-badge.png">](https://play.google.com/store/apps/details?id=io.ente.auth)
[<img height="42" src=".github/assets/f-droid-badge.png">](https://f-droid.org/packages/io.ente.auth/)
[<img height="42" src=".github/assets/desktop-badge.png">](https://github.com/ente-io/ente/releases?q=tag%3Aauth-v2)
[<img height="42" src=".github/assets/github-badge.png">](https://github.com/ente-io/ente/releases?q=tag%3Aauth-v2)
[<img height="42" src=".github/assets/web-badge.svg">](https://auth.ente.io)
</div>

9
auth/.gitignore vendored
View File

@@ -9,20 +9,12 @@
.history
.svn/
# Editors
.vscode/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
@@ -40,4 +32,3 @@ lib/generated_plugin_registrant.dart
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
android/key.properties
dist/

View File

@@ -1,11 +1,11 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
# This file should be version controlled.
version:
revision: "ba393198430278b6595976de84fe170f553cc728"
channel: "[user-branch]"
revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
channel: unknown
project_type: app
@@ -13,26 +13,17 @@ project_type: app
migration:
platforms:
- platform: root
create_revision: ba393198430278b6595976de84fe170f553cc728
base_revision: ba393198430278b6595976de84fe170f553cc728
- platform: android
create_revision: ba393198430278b6595976de84fe170f553cc728
base_revision: ba393198430278b6595976de84fe170f553cc728
- platform: ios
create_revision: ba393198430278b6595976de84fe170f553cc728
base_revision: ba393198430278b6595976de84fe170f553cc728
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
- platform: linux
create_revision: ba393198430278b6595976de84fe170f553cc728
base_revision: ba393198430278b6595976de84fe170f553cc728
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
- platform: macos
create_revision: ba393198430278b6595976de84fe170f553cc728
base_revision: ba393198430278b6595976de84fe170f553cc728
- platform: web
create_revision: ba393198430278b6595976de84fe170f553cc728
base_revision: ba393198430278b6595976de84fe170f553cc728
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
- platform: windows
create_revision: ba393198430278b6595976de84fe170f553cc728
base_revision: ba393198430278b6595976de84fe170f553cc728
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
# User provided section

View File

@@ -31,16 +31,14 @@ You can alternatively install the build from PlayStore or F-Droid.
<img height="59" src="../.github/assets/app-store-badge.svg">
</a>
### Desktop
You can [**download**](https://github.com/ente-io/ente/releases?q=tag%3Aauth-v2)
a native desktop app from this repository's GitHub releases. The desktop app
works on Windows, Linux and macOS.
### Web
You can view your 2FA codes at [auth.ente.io](https://auth.ente.io). For adding
or managing your secrets, please use our mobile or desktop app.
or managing your secrets, please use our mobile app.
### Desktop
A native desktop app is coming soon!
## 🧑‍💻 Build from source

View File

@@ -32,7 +32,7 @@ if (keystorePropertiesFile.exists()) {
}
android {
compileSdkVersion 34
compileSdkVersion 33
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
@@ -46,7 +46,7 @@ android {
defaultConfig {
applicationId "io.ente.auth"
minSdkVersion 21
minSdkVersion 20
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
@@ -56,11 +56,11 @@ android {
signingConfigs {
release {
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : System.getenv("SIGNING_KEY_PATH") ? file(System.getenv("SIGNING_KEY_PATH")) : null
keyAlias keystoreProperties['keyAlias'] ? keystoreProperties['keyAlias'] : System.getenv("SIGNING_KEY_ALIAS")
keyPassword keystoreProperties['keyPassword'] ? keystoreProperties['keyPassword'] : System.getenv("SIGNING_KEY_PASSWORD")
storePassword keystoreProperties['storePassword'] ? keystoreProperties['storePassword'] : System.getenv("SIGNING_STORE_PASSWORD")
}
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : System.getenv("SIGNING_KEY_PATH") ? file(System.getenv("SIGNING_KEY_PATH")) : null
keyAlias keystoreProperties['keyAlias'] ? keystoreProperties['keyAlias'] : System.getenv("SIGNING_KEY_ALIAS")
keyPassword keystoreProperties['keyPassword'] ? keystoreProperties['keyPassword'] : System.getenv("SIGNING_KEY_PASSWORD")
storePassword keystoreProperties['storePassword'] ? keystoreProperties['storePassword'] : System.getenv("SIGNING_STORE_PASSWORD")
}
}
flavorDimensions "default"
@@ -109,7 +109,6 @@ dependencies {
implementation 'io.sentry:sentry-android:2.0.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:multidex:1.0.3'
implementation 'com.google.guava:guava:28.2-android'
implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'

View File

@@ -1,40 +0,0 @@
Ente Auth helps you generate and store 2 step verification (2FA)
tokens on your mobile devices.
FEATURES
- Secure Backups
Auth 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 uses to encrypt
and preserve your data.
- Multi Device Synchronization
Auth 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.
- Web access
You can access your 2FA code from any web browser by visiting https://auth.ente.io .
- Offline Mode
Auth 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 Auth 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/provider.com:you@email.com?secret=YOUR_SECRET
The codes maybe separated by new lines or commas.
You can also export the codes you have added to Auth, to an **unencrypted** text
file, that adheres to the above format.
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 an issue @ https://github.com/ente-io/ente

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -1 +0,0 @@
Auth is a FOSS authenticator app that provides end-to-end encrypted backups for your 2FA secrets.

View File

@@ -1 +0,0 @@
Ente Auth

View File

@@ -36,9 +36,7 @@
},
{
"title": "BorgBase",
"altNames": [
"borg"
],
"altNames": ["borg"],
"slug": "BorgBase"
},
{
@@ -48,17 +46,11 @@
{
"title": "Bybit"
},
{
"title": "CERN"
},
{
"title": "Channel Island Hosting",
"slug": "cih",
"hex": "D14633"
},
{
"title": "ConfigCat"
},
{
"title": "Cloudflare"
},
@@ -70,13 +62,6 @@
{
"title": "Crowdpear"
},
{
"title": "DCS",
"altNames": [
"Digital Combat Simulator"
],
"slug": "dcs"
},
{
"title": "DEGIRO"
},
@@ -122,14 +107,9 @@
},
{
"title": "Gosuslugi",
"altNames": [
"Госуслуги"
],
"altNames": ["Госуслуги"],
"slug": "Gosuslugi"
},
{
"title": "Habbo"
},
{
"title": "Healthchecks.io",
"slug": "healthchecks"
@@ -192,24 +172,13 @@
},
{
"title": "Mastodon",
"altNames": [
"mstdn",
"fediscience",
"mathstodon",
"fosstodon"
],
"altNames": ["mstdn", "fediscience", "mathstodon", "fosstodon"],
"slug": "mastodon",
"hex": "6364FF"
},
{
"title": "Mercado Livre",
"slug": "mercado_livre"
},
{
"title": "Murena",
"altNames": [
"eCloud"
],
"altNames": ["eCloud"],
"slug": "ecloud"
},
{
@@ -298,18 +267,11 @@
"title": "Revolt",
"hex": "858585"
},
{
"title": "Rockstar Games",
"slug": "rockstar_games"
},
{
"title": "Rust Language Forum",
"slug": "rust_language_forum",
"hex": "000000"
},
{
"title": "Sendgrid"
},
{
"title": "service-bw"
},
@@ -394,24 +356,15 @@
{
"title": "Wise"
},
{
"title": "WYZE",
"slug": "wyze"
},
{
"title": "X",
"altNames": [
"twitter"
],
"altNames": ["twitter"],
"slug": "x"
},
{
"title": "Yandex",
"altNames": [
"Ya",
"Яндекс"
],
"altNames": ["Ya", "Яндекс"],
"slug": "Yandex"
}
]
}
}

View File

@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 283.465 283.465" enable-background="new 0 0 283.465 283.465" xml:space="preserve">
<rect x="0.752" y="-0.337" fill="#FFFFFF" width="283.465" height="283.465"/>
<path fill="#0033A0" d="M210.282,120.915c0.429,24.998-11.023,41.967-14.629,47.856c-3.143,5.13-10.654,15.024-25.11,30.374
c-18.235,19.365-75.231,79.947-79.029,83.983h154.558l-35.636-162.227L210.282,120.915z M224.498,203.72l1.277,5.803
c-15.302,16.528-38.73,28.912-66,28.912c-5.841,0-11.941-0.565-18.719-2.005c1.375-1.463,2.693-2.867,3.937-4.188
c4.352,0.773,9.361,1.284,14.506,1.286C186.023,233.541,209.198,221.605,224.498,203.72z M0.752-0.337v283.465h84.595l83.686-88.992
l-0.117-0.107c-13.455,9.491-30.532,14.646-48.943,14.646c-34.121,0-64.191-20.244-77.232-45.437l-0.132,0.088l17.755,59.9h-4.806
c0,0-8.809-30.352-16.33-56.812c-5.692-20.026-9.198-34.861-9.154-48.029c0.156-45.284,35.77-86.809,83.128-89.874
c1.3-0.086,5.328-0.506,11.328-0.511c36.48-0.022,148.884,0.84,159.687,0.923v-29.26H0.752z M100.261,210.453
c6.786,5.88,17.542,13.273,30.838,18.05c-1.113,1.185-2.321,2.469-3.603,3.833c-13.279-5.257-26.271-13.409-36.369-24.392
C93.969,208.901,97.099,209.768,100.261,210.453z M145.883,32.427c13.977,3.923,27.086,11.109,37.504,20.825
c-3.006-0.803-6.071-1.451-9.188-1.939c-14.647-11.578-33.714-18.482-53.64-18.482c-47.069,0-85.592,38.386-85.592,85.565
c0,47.18,38.382,85.564,85.565,85.564c47.179,0,85.565-38.384,85.565-85.564c0-18.252-6.876-36.487-16.318-49.367
c2.255,0.678,5.004,1.841,8.162,3.708c6.393,9.69,12.32,25.515,17.398,49.787c5.33,25.462,32.732,147.426,35.694,160.605h33.182
V33.152l-138.333-0.85C145.883,32.303,145.883,32.311,145.883,32.427z M50.595,116.383c0-11.441,8.652-19.051,20.412-19.051
c4.577,0,9.814,1.409,12.738,2.664c-0.611,1.353-1.113,3.142-1.326,4.258l-0.319,0.106c-2.261-2.503-5.898-4.672-11.279-4.672
c-6.83,0-14.689,5.528-14.689,16.557c0,10.737,8.009,16.442,15.169,16.442c6.434,0,9.513-3,12.278-5.337l0.212,0.213l-0.783,4.172
c-1.268,0.96-5.664,3.695-12.279,3.695C58.754,135.429,50.595,127.885,50.595,116.383z M78.765,187.656
c-6.344-12.899-9.219-25.995-9.6-38.519c1.612,0,3.481,0.067,5.093,0.067c0.556,11.987,3.274,26.892,12.648,43.087
C83.521,191.047,80.974,189.405,78.765,187.656z M112.787,134.755c0,0.001,0,0.001,0,0.001c-1.911-0.098-4.565-0.176-7.084-0.221
c-1.451-0.024-2.861-0.041-3.973-0.044c-0.158,0-0.319,0-0.47,0c-3.247,0-8.227,0.105-11.475,0.266
c0.214-4.631,0.429-9.26,0.429-13.836v-9.15c0-4.578-0.215-9.206-0.429-13.728c3.193,0.16,8.121,0.265,11.313,0.265
c3.193,0,9.149-0.141,10.991-0.265c-0.078,0.498-0.127,1.089-0.127,1.815c0,0.725,0.071,1.473,0.127,1.836
c-3.505-0.263-9.766-0.692-16.682-0.692c-0.056,2.287-0.162,11.991-0.162,13.324c6.278,0,10.301-0.269,13.441-0.532
c-0.105,0.532-0.16,1.486-0.16,2.017c0,0.532,0.054,1.32,0.16,1.853c-3.671-0.374-11.887-0.48-13.441-0.48
c-0.095,1.779-0.012,13.294,0.053,14.266c3.889-0.057,13.857-0.359,17.489-0.693c-0.057,0.403-0.125,1.233-0.125,2.042
C112.661,133.608,112.708,134.198,112.787,134.755z M144.039,134.58c-0.485,0-2.321,0.017-3.334,0.177
c-2.103-3.205-8.839-13.302-13.419-18.015c-0.137,0-2.708,0.003-2.708,0.003v4.23c0,4.575,0.212,9.205,0.426,13.781
c-0.906-0.161-2.542-0.177-2.877-0.177c-0.335,0-1.971,0.017-2.878,0.177c0.214-4.577,0.428-9.206,0.428-13.781v-9.152
c0-4.577-0.213-9.207-0.428-13.782c2.024,0.16,4.584,0.265,6.606,0.265c2.021,0,4.043-0.265,6.064-0.265
c6.013,0,11.523,1.776,11.523,8.472c0,7.084-7.06,9.632-11.104,10.163c2.606,3.246,11.946,14.619,15.032,18.08
C146.309,134.596,144.525,134.58,144.039,134.58z M184.319,135.253l-1.742-0.017c-2.13-2.888-24.461-26.18-26.395-28.237
c-0.053,1.967-0.055,6.062-0.055,10.043c0,5.287,0.4,13.354,0.634,17.714c-0.54-0.098-1.338-0.195-2.268-0.195
c-0.939,0-1.709,0.086-2.331,0.195c0.436-5.625,0.558-14.755,0.558-23.337c0-6.704-0.099-10.38-0.178-13.762l1.744,0.015
c2.256,2.45,24.457,25.428,26.392,27.487c0.053-1.967,0.057-5.441,0.057-9.424c0-5.285-0.402-13.354-0.636-17.711
c0.542,0.094,1.338,0.192,2.269,0.192c0.942,0,1.71-0.084,2.332-0.192c-0.438,5.624-0.56,14.753-0.56,23.336
C184.14,128.063,184.239,131.868,184.319,135.253z M230.093,88.11c9.889,12.128,17.896,31.314,19.065,47.379h0.156l8.24-85.104
l4.646-0.003c0,0-5.271,55.013-8.341,82.351c-3.844,34.241-8.729,48.448-18.071,63.403l-1.43-6.508
c7.28-12.787,9.357-23.946,10.306-29.823c2.956-18.304-1.273-43.291-14.025-62.789c-14.291-21.849-39.84-37.924-71.2-37.924
c-25.762,0-48.143,11.327-63.766,28.993l-3.789-3.003c16.539-18.764,40.576-30.737,67.558-30.737
C187.735,54.346,212.924,67.058,230.093,88.11z M138.305,107.241c0-5.29-4.629-6.973-8.248-6.973c-2.448,0-4.043,0.161-5.162,0.268
c-0.159,3.885-0.318,7.457-0.318,11.287v2.926c0.529,0.071,3.021,0.059,3.566,0.049
C132.537,114.707,138.305,113.312,138.305,107.241z"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.9 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;">
<g transform="matrix(1.59257,0,0,1.59257,0,9.06171)">
<path d="M0.87,0.08L3.17,0.08C4.2,0.08 5.13,0.51 5.13,1.67C5.13,2.92 3.91,3.6 2.78,3.6L0.06,3.6C0.06,3.6 0.87,0.09 0.87,0.08ZM2.85,2.82C3.44,2.82 4.14,2.39 4.14,1.74C4.14,1.19 3.7,0.85 3.17,0.85L1.71,0.85L1.26,2.81L2.85,2.81L2.85,2.82Z" style="fill:rgb(245,158,15);fill-rule:nonzero;stroke:rgb(245,158,15);stroke-width:0.09px;"/>
<path d="M11.95,1.33C11.87,1.31 11.65,1.26 11.65,1.14C11.65,0.81 12.52,0.81 12.74,0.81C13.25,0.81 13.96,0.91 14.4,1.17L15,0.59C14.39,0.18 13.59,0.04 12.86,0.04C12.07,0.04 10.65,0.18 10.65,1.24C10.65,2.45 13.65,1.96 13.65,2.52C13.65,2.86 12.89,2.88 12.66,2.88C11.9,2.88 11.39,2.74 10.77,2.29C10.57,2.48 10.36,2.67 10.16,2.86C10.95,3.44 11.7,3.64 12.67,3.64C13.4,3.64 14.68,3.36 14.68,2.42C14.68,1.34 12.67,1.5 11.97,1.32L11.95,1.32L11.95,1.33Z" style="fill:rgb(245,158,15);fill-rule:nonzero;stroke:rgb(245,158,15);stroke-width:0.09px;"/>
<path d="M9.18,2.35L9.16,2.35C9.07,2.43 8.41,2.95 7.67,2.87C7.14,2.81 6.41,2.44 6.41,1.95C6.41,1.15 7.26,0.83 7.94,0.83C8.39,0.83 8.82,0.93 9.17,1.18C9.48,1.07 9.8,0.97 10.11,0.86C9.59,0.3 8.82,0.07 8.06,0.07C6.92,0.07 5.43,0.73 5.43,2.06C5.43,3.22 6.65,3.63 7.61,3.63C8.41,3.63 9.18,3.4 9.78,2.88C9.78,2.88 9.18,2.38 9.17,2.37L9.16,2.37L9.18,2.35Z" style="fill:rgb(245,158,15);fill-rule:nonzero;stroke:rgb(245,158,15);stroke-width:0.09px;"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 26 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 57 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="6.525 7.459 339.266 319.582"><path fill="orange" d="M71.598 11.25H280.72c33.844 0 61.282 25.782 61.282 57.586v196.512c0 31.804-27.437 57.586-61.282 57.586H71.598c-33.845 0-61.28-25.782-61.28-57.586V68.836c0-31.804 27.435-57.586 61.28-57.586z"/><path d="M280.719 326.725H71.598c-35.881 0-65.072-27.533-65.072-61.377V68.836c0-33.844 29.19-61.377 65.072-61.377H280.72c35.88 0 65.072 27.533 65.072 61.377v196.512c0 33.844-29.192 61.377-65.073 61.377zM71.598 15.042c-31.7 0-57.49 24.131-57.49 53.794v196.512c0 29.662 25.79 53.794 57.49 53.794H280.72c31.7 0 57.49-24.132 57.49-53.794V68.836c0-29.662-25.79-53.794-57.49-53.794H71.598z"/><path d="M127.423 64.013l62.975.149c13.161-.099 22.989 2.002 29.48 6.303 7.928 5.272 11.89 14.343 11.89 27.213 0 21.19-9.828 33.195-29.482 36.012v.297c8.667 2.159 13.048 9.335 13.146 21.528 0 6.245-.233 14.245-.7 24 0 6.542 1.384 12.202 4.156 16.98H184.38c-1.611-1.747-2.416-5.305-2.416-10.677.66-8.98.99-16.347.99-22.098 0-11.617-5.582-17.425-16.746-17.425h-22.329l-9.738 46.987h-33.613l26.895-129.269zm53.236 26.941h-24.744l-6.453 31.192h26.775c14.967 0 22.497-5.906 22.595-17.721.001-8.98-6.058-13.47-18.173-13.47z"/><path d="M223.456 196.346l24.915-43.18 6.717 43.478h42.506l-38.349 27.534 6.14 43.18-33.204-26.05-44.633 27.089 20.878-45.973-24.333-26.2 39.363.122zm113.568 113.887c1.38 0 2.726.362 4.04 1.086 1.315.723 2.339 1.76 3.07 3.108.735 1.348 1.101 2.753 1.101 4.216 0 1.449-.36 2.841-1.084 4.177a7.735 7.735 0 01-3.039 3.114c-1.302.74-2.665 1.108-4.09 1.108-1.421 0-2.784-.37-4.089-1.108a7.762 7.762 0 01-3.044-3.114c-.725-1.336-1.089-2.73-1.089-4.177 0-1.463.369-2.868 1.106-4.216.738-1.348 1.763-2.384 3.077-3.108 1.316-.725 2.662-1.086 4.04-1.086zm0 1.391c-1.154 0-2.278.303-3.37.909a6.451 6.451 0 00-2.566 2.594c-.617 1.126-.926 2.297-.926 3.514 0 1.211.304 2.372.91 3.482a6.542 6.542 0 002.542 2.596c1.089.619 2.224.93 3.409.93 1.183 0 2.32-.311 3.41-.93a6.498 6.498 0 002.536-2.596c.603-1.11.904-2.27.904-3.482 0-1.218-.308-2.388-.92-3.514a6.39 6.39 0 00-2.565-2.594c-1.094-.606-2.216-.909-3.364-.909zm-3.604 11.664v-9.045h3.038c1.039 0 1.79.083 2.254.25.466.167.835.459 1.11.875.277.416.415.857.415 1.325 0 .661-.23 1.237-.692 1.726-.46.49-1.072.764-1.835.824.312.135.563.294.75.48.358.356.792.954 1.308 1.792l1.078 1.772h-1.742l-.783-1.426c-.617-1.12-1.115-1.823-1.492-2.105-.262-.209-.643-.313-1.145-.313h-.838v3.844h-1.426zm1.426-5.092h1.732c.829 0 1.393-.126 1.694-.38.3-.25.451-.586.451-1.002a1.24 1.24 0 00-.218-.718 1.302 1.302 0 00-.604-.473c-.258-.103-.734-.157-1.431-.157h-1.624v2.73z"/><path fill="#FFF" d="M252.503 221.088l25.47-18.142h-28.177l-4.881-31.464-17.882 31.168h-28.467l17.302 18.587-14.305 31.193 31.052-18.735 24.48 19.18-4.592-31.787z"/></svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 59 KiB

View File

@@ -1 +0,0 @@
<svg fill="#1DF0BB" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Wyze</title><path d="M5.475 13.171 7.3 9.469h.974L5.779 14.53h-.608l-1.034-2.082-1.034 2.082h-.609L0 9.469h.973l1.826 3.673.851-1.706-.973-1.967h.973l1.825 3.702Zm8.457-3.702-2.251 3.442v1.591h-.882v-1.591L8.517 9.469h1.034l1.673 2.545 1.673-2.545h1.035Zm5.444 4.194H24v.867h-4.624v-.867Zm0-4.194H24v.868h-4.624v-.868Zm0 2.083H24v.867h-4.624v-.867Zm-.273-2.083-3.438 4.223h3.133v.838H13.84l3.407-4.222h-3.042v-.839h4.898Z"/></svg>

Before

Width:  |  Height:  |  Size: 523 B

View File

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -1,25 +0,0 @@
output: dist/
releases:
- name: dev
jobs:
- name: release-dev-linux-zip
package:
platform: linux
target: zip
- name: release-dev-linux-deb
package:
platform: linux
target: deb
- name: release-dev-linux-appimage
package:
platform: linux
target: appimage
- name: release-dev-windows-exe
package:
platform: windows
target: exe
- name: release-dev-macos-dmg
package:
platform: macos
target: dmg

View File

@@ -1,14 +1,7 @@
# Releases
Create a PR to bump up the version in `pubspec.yaml`.
> [!NOTE]
>
> Use [semver](https://semver.org/) for the tags, with `auth-` as a prefix.
> Multiple beta releases for the same upcoming version can be done by adding
> build metadata at the end, e.g. `auth-v1.2.3-beta+3`.
Once that is merged, tag main, and push the tag.
Create a PR to bump up the version in `pubspec.yaml`. Once that is merged, tag
main, and push the tag.
```sh
git tag auth-v1.2.3
@@ -23,11 +16,6 @@ This'll trigger a GitHub workflow that:
* Creates a new release in the internal track on Play Store.
Once the workflow completes, go to the draft GitHub release that was created.
> [!NOTE]
>
> Keep the title of the release same as the tag.
Set "Previous tag" to the last release of auth and press "Generate release
notes". The generated release note will contain all PRs and new contributors
from all the releases in the monorepo, so you'll need to filter them to keep

View File

@@ -37,4 +37,4 @@ file, that adheres to the above format.
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 an issue @ https://github.com/ente-io/ente
If you have feature requests, please create an issue @ https://github.com/ente-io/auth

View File

@@ -1 +1 @@
Ente Authenticator
ente Authenticator

View File

@@ -1,6 +1,6 @@
flutter_icons:
android: "launcher_icon"
image_path: "assets/generation-icons/icon-light.png"
adaptive_icon_foreground: "assets/generation-icons/icon-light-adaptive-fg.png"
adaptive_icon_background: "#ffffff"
flutter_icons:
android: "launcher_icon"
image_path: "assets/icon-light.png"
adaptive_icon_foreground: "assets/icon-light-adaptive-fg.png"
adaptive_icon_background: "#ffffff"

View File

@@ -1,9 +1,7 @@
PODS:
- app_links (0.0.1):
- connectivity (0.0.1):
- Flutter
- connectivity_plus (0.0.1):
- Flutter
- ReachabilitySwift
- Reachability
- device_info_plus (0.0.1):
- Flutter
- DKImagePickerController/Core (4.3.4):
@@ -47,25 +45,28 @@ PODS:
- Flutter (1.0.0)
- flutter_email_sender (0.0.1):
- Flutter
- flutter_inappwebview_ios (0.0.1):
- flutter_inappwebview (0.0.1):
- Flutter
- flutter_inappwebview_ios/Core (= 0.0.1)
- flutter_inappwebview/Core (= 0.0.1)
- OrderedSet (~> 5.0)
- flutter_inappwebview_ios/Core (0.0.1):
- flutter_inappwebview/Core (0.0.1):
- Flutter
- OrderedSet (~> 5.0)
- flutter_local_authentication (1.2.0):
- Flutter
- flutter_local_notifications (0.0.1):
- Flutter
- flutter_native_splash (0.0.1):
- Flutter
- flutter_secure_storage (6.0.0):
- Flutter
- flutter_sodium (0.0.1):
- Flutter
- fluttertoast (0.0.2):
- Flutter
- Toast
- local_auth_darwin (0.0.1):
- FMDB (2.7.5):
- FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5)
- local_auth_ios (0.0.1):
- Flutter
- move_to_background (0.0.1):
- Flutter
@@ -81,63 +82,47 @@ PODS:
- qr_code_scanner (0.2.0):
- Flutter
- MTBBarcodeScanner
- ReachabilitySwift (5.2.1)
- SDWebImage (5.19.0):
- SDWebImage/Core (= 5.19.0)
- SDWebImage/Core (5.19.0)
- Sentry/HybridSDK (8.21.0):
- SentryPrivate (= 8.21.0)
- Reachability (3.2)
- SDWebImage (5.17.0):
- SDWebImage/Core (= 5.17.0)
- SDWebImage/Core (5.17.0)
- Sentry/HybridSDK (8.9.1):
- SentryPrivate (= 8.9.1)
- sentry_flutter (0.0.1):
- Flutter
- FlutterMacOS
- Sentry/HybridSDK (= 8.21.0)
- SentryPrivate (8.21.0)
- Sentry/HybridSDK (= 8.9.1)
- SentryPrivate (8.9.1)
- share_plus (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- sodium_libs (2.2.1):
- Flutter
- sqflite (0.0.3):
- Flutter
- FlutterMacOS
- sqlite3 (3.45.1):
- sqlite3/common (= 3.45.1)
- sqlite3/common (3.45.1)
- sqlite3/fts5 (3.45.1):
- sqlite3/common
- sqlite3/perf-threadsafe (3.45.1):
- sqlite3/common
- sqlite3/rtree (3.45.1):
- sqlite3/common
- sqlite3_flutter_libs (0.0.1):
- Flutter
- sqlite3 (~> 3.45.1)
- sqlite3/fts5
- sqlite3/perf-threadsafe
- sqlite3/rtree
- FMDB (>= 2.7.5)
- SwiftyGif (5.4.4)
- Toast (4.1.0)
- Toast (4.0.0)
- uni_links (0.0.1):
- Flutter
- url_launcher_ios (0.0.1):
- Flutter
DEPENDENCIES:
- app_links (from `.symlinks/plugins/app_links/ios`)
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- connectivity (from `.symlinks/plugins/connectivity/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- file_saver (from `.symlinks/plugins/file_saver/ios`)
- fk_user_agent (from `.symlinks/plugins/fk_user_agent/ios`)
- Flutter (from `Flutter`)
- flutter_email_sender (from `.symlinks/plugins/flutter_email_sender/ios`)
- flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
- flutter_local_authentication (from `.symlinks/plugins/flutter_local_authentication/ios`)
- flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`)
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- flutter_sodium (from `.symlinks/plugins/flutter_sodium/ios`)
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- local_auth_darwin (from `.symlinks/plugins/local_auth_darwin/darwin`)
- local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`)
- move_to_background (from `.symlinks/plugins/move_to_background/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
@@ -146,30 +131,27 @@ DEPENDENCIES:
- sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- sodium_libs (from `.symlinks/plugins/sodium_libs/ios`)
- sqflite (from `.symlinks/plugins/sqflite/darwin`)
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`)
- uni_links (from `.symlinks/plugins/uni_links/ios`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
SPEC REPOS:
trunk:
- DKImagePickerController
- DKPhotoGallery
- FMDB
- MTBBarcodeScanner
- OrderedSet
- ReachabilitySwift
- Reachability
- SDWebImage
- Sentry
- SentryPrivate
- sqlite3
- SwiftyGif
- Toast
EXTERNAL SOURCES:
app_links:
:path: ".symlinks/plugins/app_links/ios"
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/ios"
connectivity:
:path: ".symlinks/plugins/connectivity/ios"
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
file_picker:
@@ -182,20 +164,20 @@ EXTERNAL SOURCES:
:path: Flutter
flutter_email_sender:
:path: ".symlinks/plugins/flutter_email_sender/ios"
flutter_inappwebview_ios:
:path: ".symlinks/plugins/flutter_inappwebview_ios/ios"
flutter_local_authentication:
:path: ".symlinks/plugins/flutter_local_authentication/ios"
flutter_inappwebview:
:path: ".symlinks/plugins/flutter_inappwebview/ios"
flutter_local_notifications:
:path: ".symlinks/plugins/flutter_local_notifications/ios"
flutter_native_splash:
:path: ".symlinks/plugins/flutter_native_splash/ios"
flutter_secure_storage:
:path: ".symlinks/plugins/flutter_secure_storage/ios"
flutter_sodium:
:path: ".symlinks/plugins/flutter_sodium/ios"
fluttertoast:
:path: ".symlinks/plugins/fluttertoast/ios"
local_auth_darwin:
:path: ".symlinks/plugins/local_auth_darwin/darwin"
local_auth_ios:
:path: ".symlinks/plugins/local_auth_ios/ios"
move_to_background:
:path: ".symlinks/plugins/move_to_background/ios"
package_info_plus:
@@ -212,54 +194,50 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/share_plus/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
sodium_libs:
:path: ".symlinks/plugins/sodium_libs/ios"
sqflite:
:path: ".symlinks/plugins/sqflite/darwin"
sqlite3_flutter_libs:
:path: ".symlinks/plugins/sqlite3_flutter_libs/ios"
:path: ".symlinks/plugins/sqflite/ios"
uni_links:
:path: ".symlinks/plugins/uni_links/ios"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"
SPEC CHECKSUMS:
app_links: e70ca16b4b0f88253b3b3660200d4a10b4ea9795
connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d
device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
file_picker: 15fd9539e4eb735dc54bae8c0534a7a9511a03de
file_picker: ce3938a0df3cc1ef404671531facef740d03f920
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
fk_user_agent: 1f47ec39291e8372b1d692b50084b0d54103c545
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_email_sender: 02d7443217d8c41483223627972bfdc09f74276b
flutter_inappwebview_ios: 97215cf7d4677db55df76782dbd2930c5e1c1ea0
flutter_local_authentication: 1172a4dd88f6306dadce067454e2c4caf07977bb
flutter_local_notifications: 4cde75091f6327eb8517fa068a0a5950212d2086
flutter_native_splash: edf599c81f74d093a4daf8e17bd7a018854bc778
flutter_inappwebview: acd4fc0f012cefd09015000c241137d82f01ba62
flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
flutter_sodium: c84426b4de738514b5b66cfdeb8a06634e72fe0b
fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265
local_auth_darwin: c7e464000a6a89e952235699e32b329457608d98
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
local_auth_ios: c6cf091ded637a88f24f86a8875d8b0f526e2605
move_to_background: 39a5b79b26d577b0372cbe8a8c55e7aa9fcd3a2d
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
package_info_plus: fd030dabf36271f146f1f3beacd48f564b0f17f7
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
privacy_screen: 1a131c052ceb3c3659934b003b0d397c2381a24e
qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e
ReachabilitySwift: 5ae15e16814b5f9ef568963fb2c87aeb49158c66
SDWebImage: 981fd7e860af070920f249fd092420006014c3eb
Sentry: ebc12276bd17613a114ab359074096b6b3725203
sentry_flutter: dff1df05dc39c83d04f9330b36360fc374574c5e
SentryPrivate: d651efb234cf385ec9a1cdd3eff94b5e78a0e0fe
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
SDWebImage: 750adf017a315a280c60fde706ab1e552a3ae4e9
Sentry: e3203780941722a1fcfee99e351de14244c7f806
sentry_flutter: 8f0ffd53088e6a4d50c095852c5cad9e4405025c
SentryPrivate: 5e3683390f66611fc7c6215e27645873adb55d13
share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
sodium_libs: 1faae17af662384acbd13e41867a0008cd2e2318
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
sqlite3: 73b7fc691fdc43277614250e04d183740cb15078
sqlite3_flutter_libs: af0e8fe9bce48abddd1ffdbbf839db0302d72d80
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
Toast: ec33c32b8688982cecc6348adeae667c1b9938da
url_launcher_ios: 6116280ddcfe98ab8820085d8d76ae7449447586
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4
PODFILE CHECKSUM: b4e3a7eabb03395b66e81fc061789f61526ee6bb

View File

@@ -159,7 +159,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1510;
LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
@@ -365,7 +365,7 @@
DEVELOPMENT_TEAM = 6Z68YJY9Q2;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Ente Auth";
INFOPLIST_KEY_CFBundleDisplayName = auth;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -439,7 +439,7 @@
DEVELOPMENT_TEAM = 6Z68YJY9Q2;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Ente Auth";
INFOPLIST_KEY_CFBundleDisplayName = auth;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -513,7 +513,7 @@
DEVELOPMENT_TEAM = 6Z68YJY9Q2;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Ente Auth";
INFOPLIST_KEY_CFBundleDisplayName = auth;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -587,7 +587,7 @@
DEVELOPMENT_TEAM = 6Z68YJY9Q2;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Ente Auth";
INFOPLIST_KEY_CFBundleDisplayName = auth;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -661,7 +661,7 @@
DEVELOPMENT_TEAM = 6Z68YJY9Q2;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Ente Auth";
INFOPLIST_KEY_CFBundleDisplayName = auth;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,6 +1,5 @@
import Flutter
import UIKit
import app_links
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
@@ -9,15 +8,6 @@ import app_links
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
super.application(application, didFinishLaunchingWithOptions: launchOptions)
if let url = AppLinks.shared.getLink(launchOptions: launchOptions) {
AppLinks.shared.handleLink(url: url)
}
return false
// return super.application(application, didFinishLaunchingWithOptions: launchOptions)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

View File

@@ -78,9 +78,5 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>UIFileSharingEnabled</key>
<true/>
</dict>
</plist>

View File

@@ -12,18 +12,15 @@ import 'package:ente_auth/locale.dart';
import "package:ente_auth/onboarding/view/onboarding_page.dart";
import 'package:ente_auth/services/update_service.dart';
import 'package:ente_auth/services/user_service.dart';
import 'package:ente_auth/services/window_listener_service.dart';
import 'package:ente_auth/ui/home_page.dart';
import 'package:ente_auth/ui/settings/app_update_dialog.dart';
import 'package:flutter/foundation.dart';
import "package:flutter/material.dart";
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:tray_manager/tray_manager.dart';
import 'package:window_manager/window_manager.dart';
class App extends StatefulWidget {
final Locale locale;
const App({super.key, this.locale = const Locale("en")});
const App({Key? key, this.locale = const Locale("en")}) : super(key: key);
static void setLocale(BuildContext context, Locale newLocale) {
_AppState state = context.findAncestorStateOfType<_AppState>()!;
@@ -34,7 +31,7 @@ class App extends StatefulWidget {
State<App> createState() => _AppState();
}
class _AppState extends State<App> with WindowListener, TrayListener {
class _AppState extends State<App> {
late StreamSubscription<SignedOutEvent> _signedOutEvent;
late StreamSubscription<SignedInEvent> _signedInEvent;
Locale? locale;
@@ -44,19 +41,8 @@ class _AppState extends State<App> with WindowListener, TrayListener {
});
}
Future<void> initWindowManager() async {
windowManager.addListener(this);
}
Future<void> initTrayManager() async {
trayManager.addListener(this);
}
@override
void initState() {
initWindowManager();
initTrayManager();
_signedOutEvent = Bus.instance.on<SignedOutEvent>().listen((event) {
if (mounted) {
setState(() {});
@@ -90,10 +76,6 @@ class _AppState extends State<App> with WindowListener, TrayListener {
@override
void dispose() {
super.dispose();
windowManager.removeListener(this);
trayManager.removeListener(this);
_signedOutEvent.cancel();
_signedInEvent.cancel();
}
@@ -152,45 +134,4 @@ class _AppState extends State<App> with WindowListener, TrayListener {
: const OnboardingPage(),
};
}
@override
void onWindowResize() {
WindowListenerService.instance.onWindowResize().ignore();
}
@override
void onTrayIconMouseDown() {
if (Platform.isWindows) {
windowManager.show();
} else {
trayManager.popUpContextMenu();
}
}
@override
void onTrayIconRightMouseDown() {
if (Platform.isWindows) {
trayManager.popUpContextMenu();
} else {
windowManager.show();
}
}
@override
void onTrayIconRightMouseUp() {}
@override
void onTrayMenuItemClick(MenuItem menuItem) {
switch (menuItem.key) {
case 'hide_window':
windowManager.hide();
break;
case 'show_window':
windowManager.show();
break;
case 'exit_app':
windowManager.close();
break;
}
}
}

View File

@@ -0,0 +1,4 @@
class AppRoute {
static const String enterSecretKeyPage = "enterSecretKeyPage";
static const String settings = "settings";
}

View File

@@ -0,0 +1,163 @@
import "package:flutter/material.dart";
final lightTheme = ThemeData(
fontFamily: "Inter",
brightness: Brightness.light,
scaffoldBackgroundColor: Colors.white,
appBarTheme: const AppBarTheme().copyWith(
backgroundColor: Colors.white,
foregroundColor: Colors.black,
iconTheme: const IconThemeData(color: Colors.black),
elevation: 0,
),
colorScheme: const ColorScheme.light(
primary: Colors.black,
),
textTheme: _buildTextTheme(Colors.black),
outlinedButtonTheme: buildOutlinedButtonThemeData(
bgDisabled: Colors.grey.shade500,
bgEnabled: Colors.black,
fgDisabled: Colors.white,
fgEnabled: Colors.white,
),
inputDecorationTheme: InputDecorationTheme(
fillColor: null,
filled: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 14,
),
border: UnderlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(6),
),
),
);
final darkTheme = ThemeData(
fontFamily: "Inter",
brightness: Brightness.dark,
scaffoldBackgroundColor: Colors.black,
appBarTheme: const AppBarTheme(color: Colors.orange),
textTheme: _buildTextTheme(Colors.white),
outlinedButtonTheme: buildOutlinedButtonThemeData(
bgDisabled: Colors.grey.shade500,
bgEnabled: Colors.white,
fgDisabled: Colors.white,
fgEnabled: Colors.black,
),
inputDecorationTheme: InputDecorationTheme(
fillColor: null,
filled: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 14,
),
border: UnderlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(6),
),
), colorScheme: const ColorScheme.dark(primary: Colors.white).copyWith(background: Colors.black),
);
TextTheme _buildTextTheme(Color textColor) {
return const TextTheme().copyWith(
headlineMedium: TextStyle(
color: textColor,
fontSize: 32,
fontWeight: FontWeight.w700,
fontFamily: "Inter",
),
headlineSmall: TextStyle(
color: textColor,
fontSize: 24,
fontWeight: FontWeight.w600,
fontFamily: "Inter",
),
// AG: Body
titleLarge: TextStyle(
color: textColor,
fontSize: 18,
fontFamily: "Inter",
fontWeight: FontWeight.w500,
),
// Use labels for buttons or notifications
labelMedium: TextStyle(
color: textColor,
fontFamily: "Inter",
fontSize: 18,
fontWeight: FontWeight.w700,
height: 28,
),
titleMedium: TextStyle(
color: textColor,
fontFamily: "Inter",
fontSize: 16,
fontWeight: FontWeight.w500,
),
titleSmall: TextStyle(
color: textColor,
fontFamily: "Inter",
fontSize: 14,
fontWeight: FontWeight.w500,
),
bodyLarge: TextStyle(
fontFamily: "Inter",
color: textColor,
fontSize: 16,
fontWeight: FontWeight.w500,
),
bodyMedium: TextStyle(
fontFamily: "Inter",
color: textColor,
fontSize: 14,
fontWeight: FontWeight.w500,
),
bodySmall: TextStyle(
color: textColor.withOpacity(0.6),
fontSize: 14,
fontWeight: FontWeight.w500,
),
);
}
OutlinedButtonThemeData buildOutlinedButtonThemeData({
required Color bgDisabled,
required Color bgEnabled,
required Color fgDisabled,
required Color fgEnabled,
}) {
return OutlinedButtonThemeData(
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 50),
textStyle: const TextStyle(
fontWeight: FontWeight.w700,
fontFamily: "Inter",
fontSize: 18,
),
).copyWith(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return bgDisabled;
}
return bgEnabled;
},
),
foregroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return fgDisabled;
}
return fgEnabled;
},
),
alignment: Alignment.center,
),
);
}

View File

@@ -1,5 +1,3 @@
// ignore_for_file: deprecated_member_use
import "dart:async";
import "dart:developer";

View File

@@ -13,12 +13,12 @@ import 'package:ente_auth/models/key_attributes.dart';
import 'package:ente_auth/models/key_gen_result.dart';
import 'package:ente_auth/models/private_key_attributes.dart';
import 'package:ente_auth/store/authenticator_db.dart';
import 'package:ente_crypto_dart/ente_crypto_dart.dart';
import 'package:ente_auth/utils/crypto_util.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_sodium/flutter_sodium.dart';
import 'package:logging/logging.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:tuple/tuple.dart';
class Configuration {
@@ -72,10 +72,9 @@ class Configuration {
Future<void> init() async {
_preferences = await SharedPreferences.getInstance();
sqfliteFfiInit();
_secureStorage = const FlutterSecureStorage();
_documentsDirectory = (await getApplicationDocumentsDirectory()).path;
_tempDirectory = "$_documentsDirectory/temp/";
_tempDirectory = _documentsDirectory + "/temp/";
final tempDirectory = io.Directory(_tempDirectory);
try {
final currentTime = DateTime.now().microsecondsSinceEpoch;
@@ -163,7 +162,7 @@ class Configuration {
// decrypt the master key
final kekSalt = CryptoUtil.getSaltToDeriveKey();
final derivedKeyResult = await CryptoUtil.deriveSensitiveKey(
utf8.encode(password),
utf8.encode(password) as Uint8List,
kekSalt,
);
final loginKey = await CryptoUtil.deriveLoginKey(derivedKeyResult.key);
@@ -173,28 +172,28 @@ class Configuration {
CryptoUtil.encryptSync(masterKey, derivedKeyResult.key);
// Generate a public-private keypair and encrypt the latter
final keyPair = CryptoUtil.generateKeyPair();
final keyPair = await CryptoUtil.generateKeyPair();
final encryptedSecretKeyData =
CryptoUtil.encryptSync(keyPair.secretKey.extractBytes(), masterKey);
CryptoUtil.encryptSync(keyPair.sk, masterKey);
final attributes = KeyAttributes(
CryptoUtil.bin2base64(kekSalt),
CryptoUtil.bin2base64(encryptedKeyData.encryptedData!),
CryptoUtil.bin2base64(encryptedKeyData.nonce!),
CryptoUtil.bin2base64(keyPair.publicKey),
CryptoUtil.bin2base64(encryptedSecretKeyData.encryptedData!),
CryptoUtil.bin2base64(encryptedSecretKeyData.nonce!),
Sodium.bin2base64(kekSalt),
Sodium.bin2base64(encryptedKeyData.encryptedData!),
Sodium.bin2base64(encryptedKeyData.nonce!),
Sodium.bin2base64(keyPair.pk),
Sodium.bin2base64(encryptedSecretKeyData.encryptedData!),
Sodium.bin2base64(encryptedSecretKeyData.nonce!),
derivedKeyResult.memLimit,
derivedKeyResult.opsLimit,
CryptoUtil.bin2base64(encryptedMasterKey.encryptedData!),
CryptoUtil.bin2base64(encryptedMasterKey.nonce!),
CryptoUtil.bin2base64(encryptedRecoveryKey.encryptedData!),
CryptoUtil.bin2base64(encryptedRecoveryKey.nonce!),
Sodium.bin2base64(encryptedMasterKey.encryptedData!),
Sodium.bin2base64(encryptedMasterKey.nonce!),
Sodium.bin2base64(encryptedRecoveryKey.encryptedData!),
Sodium.bin2base64(encryptedRecoveryKey.nonce!),
);
final privateAttributes = PrivateKeyAttributes(
CryptoUtil.bin2base64(masterKey),
CryptoUtil.bin2hex(recoveryKey),
CryptoUtil.bin2base64(keyPair.secretKey.extractBytes()),
Sodium.bin2base64(masterKey),
Sodium.bin2hex(recoveryKey),
Sodium.bin2base64(keyPair.sk),
);
return KeyGenResult(attributes, privateAttributes, loginKey);
}
@@ -209,7 +208,7 @@ class Configuration {
// decrypt the master key
final kekSalt = CryptoUtil.getSaltToDeriveKey();
final derivedKeyResult = await CryptoUtil.deriveSensitiveKey(
utf8.encode(password),
utf8.encode(password) as Uint8List,
kekSalt,
);
final loginKey = await CryptoUtil.deriveLoginKey(derivedKeyResult.key);
@@ -221,9 +220,9 @@ class Configuration {
final existingAttributes = getKeyAttributes();
final updatedAttributes = existingAttributes!.copyWith(
kekSalt: CryptoUtil.bin2base64(kekSalt),
encryptedKey: CryptoUtil.bin2base64(encryptedKeyData.encryptedData!),
keyDecryptionNonce: CryptoUtil.bin2base64(encryptedKeyData.nonce!),
kekSalt: Sodium.bin2base64(kekSalt),
encryptedKey: Sodium.bin2base64(encryptedKeyData.encryptedData!),
keyDecryptionNonce: Sodium.bin2base64(encryptedKeyData.nonce!),
memLimit: derivedKeyResult.memLimit,
opsLimit: derivedKeyResult.opsLimit,
);
@@ -241,8 +240,8 @@ class Configuration {
}) async {
_logger.info('Start decryptAndSaveSecrets');
keyEncryptionKey ??= await CryptoUtil.deriveKey(
utf8.encode(password),
CryptoUtil.base642bin(attributes.kekSalt),
utf8.encode(password) as Uint8List,
Sodium.base642bin(attributes.kekSalt),
attributes.memLimit,
attributes.opsLimit,
);
@@ -251,31 +250,31 @@ class Configuration {
Uint8List key;
try {
key = CryptoUtil.decryptSync(
CryptoUtil.base642bin(attributes.encryptedKey),
Sodium.base642bin(attributes.encryptedKey),
keyEncryptionKey,
CryptoUtil.base642bin(attributes.keyDecryptionNonce),
Sodium.base642bin(attributes.keyDecryptionNonce),
);
} catch (e) {
_logger.severe('master-key failed, incorrect password?', e);
throw Exception("Incorrect password");
}
_logger.info("master-key done");
await setKey(CryptoUtil.bin2base64(key));
await setKey(Sodium.bin2base64(key));
final secretKey = CryptoUtil.decryptSync(
CryptoUtil.base642bin(attributes.encryptedSecretKey),
Sodium.base642bin(attributes.encryptedSecretKey),
key,
CryptoUtil.base642bin(attributes.secretKeyDecryptionNonce),
Sodium.base642bin(attributes.secretKeyDecryptionNonce),
);
_logger.info("secret-key done");
await setSecretKey(CryptoUtil.bin2base64(secretKey));
await setSecretKey(Sodium.bin2base64(secretKey));
final token = CryptoUtil.openSealSync(
CryptoUtil.base642bin(getEncryptedToken()!),
CryptoUtil.base642bin(attributes.publicKey),
Sodium.base642bin(getEncryptedToken()!),
Sodium.base642bin(attributes.publicKey),
secretKey,
);
_logger.info('appToken done');
await setToken(
CryptoUtil.bin2base64(token, urlSafe: true),
Sodium.bin2base64(token, variant: Sodium.base64VariantUrlsafe),
);
return keyEncryptionKey;
}
@@ -294,28 +293,28 @@ class Configuration {
Uint8List masterKey;
try {
masterKey = await CryptoUtil.decrypt(
CryptoUtil.base642bin(attributes!.masterKeyEncryptedWithRecoveryKey),
CryptoUtil.hex2bin(recoveryKey),
CryptoUtil.base642bin(attributes.masterKeyDecryptionNonce),
Sodium.base642bin(attributes!.masterKeyEncryptedWithRecoveryKey),
Sodium.hex2bin(recoveryKey),
Sodium.base642bin(attributes.masterKeyDecryptionNonce),
);
} catch (e) {
_logger.severe(e);
rethrow;
}
await setKey(CryptoUtil.bin2base64(masterKey));
await setKey(Sodium.bin2base64(masterKey));
final secretKey = CryptoUtil.decryptSync(
CryptoUtil.base642bin(attributes.encryptedSecretKey),
Sodium.base642bin(attributes.encryptedSecretKey),
masterKey,
CryptoUtil.base642bin(attributes.secretKeyDecryptionNonce),
Sodium.base642bin(attributes.secretKeyDecryptionNonce),
);
await setSecretKey(CryptoUtil.bin2base64(secretKey));
await setSecretKey(Sodium.bin2base64(secretKey));
final token = CryptoUtil.openSealSync(
CryptoUtil.base642bin(getEncryptedToken()!),
CryptoUtil.base642bin(attributes.publicKey),
Sodium.base642bin(getEncryptedToken()!),
Sodium.base642bin(attributes.publicKey),
secretKey,
);
await setToken(
CryptoUtil.bin2base64(token, urlSafe: true),
Sodium.bin2base64(token, variant: Sodium.base64VariantUrlsafe),
);
}
@@ -408,31 +407,27 @@ class Configuration {
}
Uint8List? getKey() {
return _key == null ? null : CryptoUtil.base642bin(_key!);
return _key == null ? null : Sodium.base642bin(_key!);
}
Uint8List? getSecretKey() {
return _secretKey == null ? null : CryptoUtil.base642bin(_secretKey!);
return _secretKey == null ? null : Sodium.base642bin(_secretKey!);
}
Uint8List? getAuthSecretKey() {
return _authSecretKey == null
? null
: CryptoUtil.base642bin(_authSecretKey!);
return _authSecretKey == null ? null : Sodium.base642bin(_authSecretKey!);
}
Uint8List? getOfflineSecretKey() {
return _offlineAuthKey == null
? null
: CryptoUtil.base642bin(_offlineAuthKey!);
return _offlineAuthKey == null ? null : Sodium.base642bin(_offlineAuthKey!);
}
Uint8List getRecoveryKey() {
final keyAttributes = getKeyAttributes()!;
return CryptoUtil.decryptSync(
CryptoUtil.base642bin(keyAttributes.recoveryKeyEncryptedWithMasterKey),
Sodium.base642bin(keyAttributes.recoveryKeyEncryptedWithMasterKey),
getKey()!,
CryptoUtil.base642bin(keyAttributes.recoveryKeyDecryptionNonce),
Sodium.base642bin(keyAttributes.recoveryKeyDecryptionNonce),
);
}
@@ -459,7 +454,7 @@ class Configuration {
iOptions: _secureStorageOptionsIOS,
);
} else {
_offlineAuthKey = CryptoUtil.bin2base64(CryptoUtil.generateKey());
_offlineAuthKey = Sodium.bin2base64(CryptoUtil.generateKey());
await _secureStorage.write(
key: offlineAuthSecretKey,
value: _offlineAuthKey,

View File

@@ -7,8 +7,7 @@ const String sentryDSN =
"https://ed4ddd6309b847ba8849935e26e9b648@sentry.ente.io/9";
const String sentryTunnel = "https://sentry-reporter.ente.io";
const String roadmapURL = "https://roadmap.ente.io";
const String githubIssuesUrl =
"https://github.com/ente-io/ente/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc";
const String githubDiscussionsUrl = "https://github.com/ente-io/ente/discussions";
const int microSecondsInDay = 86400000000;
const int android11SDKINT = 30;
const int galleryLoadStartTime = -8000000000000000; // Wednesday, March 6, 1748

View File

@@ -1,9 +1,9 @@
class InvalidFileError extends ArgumentError {
InvalidFileError(String super.message);
InvalidFileError(String message) : super(message);
}
class InvalidFileUploadState extends AssertionError {
InvalidFileUploadState(String super.message);
InvalidFileUploadState(String message) : super(message);
}
class SubscriptionAlreadyClaimedError extends Error {}
@@ -30,15 +30,19 @@ class UnauthorizedError extends Error {}
class RequestCancelledError extends Error {}
class InvalidSyncStatusError extends AssertionError {
InvalidSyncStatusError(String super.message);
InvalidSyncStatusError(String message) : super(message);
}
class UnauthorizedEditError extends AssertionError {}
class InvalidStateError extends AssertionError {
InvalidStateError(String super.message);
InvalidStateError(String message) : super(message);
}
class KeyDerivationError extends Error {}
class LoginKeyDerivationError extends Error {}
class SrpSetupNotCompleteError extends Error {}
class AuthenticatorKeyNotFound extends Error {}

View File

@@ -235,14 +235,14 @@ class SuperLogging {
extraLines = null;
}
final str = "${config.prefix} ${rec.toPrettyString(extraLines)}";
final str = (config.prefix) + " " + rec.toPrettyString(extraLines);
// write to stdout
printLog(str);
// push to log queue
if (fileIsEnabled) {
fileQueueEntries.add('$str\n');
fileQueueEntries.add(str + '\n');
if (fileQueueEntries.length == 1) {
flushQueue();
}
@@ -275,7 +275,7 @@ class SuperLogging {
static var logChunkSize = 800;
static void printLog(String text) {
text.chunked(logChunkSize).forEach(debugPrint);
text.chunked(logChunkSize).forEach(print);
}
/// A queue to be consumed by [setupSentry].
@@ -354,7 +354,7 @@ class SuperLogging {
final date = config.dateFmt!.parse(basename(file.path));
dates[file as File] = date;
files.add(file);
} on Exception catch (_) {}
} on FormatException {}
}
final nowTime = DateTime.now();
@@ -374,7 +374,7 @@ class SuperLogging {
"deleting log file ${file.path}",
);
await file.delete();
} on Exception catch (_) {}
} catch (ignore) {}
}
}

View File

@@ -46,7 +46,7 @@ class TunneledTransport implements Transport {
_options.logger(
SentryLevel.error,
'API returned an error, statusCode = ${response.statusCode}, '
'body = ${response.body}',
'body = ${response.body}',
);
}
return const SentryId.empty();
@@ -65,8 +65,8 @@ class TunneledTransport implements Transport {
}
Future<StreamedRequest> _createStreamedRequest(
SentryEnvelope envelope,
) async {
SentryEnvelope envelope,
) async {
final streamedRequest = StreamedRequest('POST', _tunnel);
envelope
.envelopeStream(_options)
@@ -91,10 +91,10 @@ class _CredentialBuilder {
_clock = clock;
factory _CredentialBuilder(
Dsn? dsn,
String sdkIdentifier,
ClockProvider clock,
) {
Dsn? dsn,
String sdkIdentifier,
ClockProvider clock,
) {
final authHeader = _buildAuthHeader(
publicKey: dsn?.publicKey,
secretKey: dsn?.secretKey,

View File

@@ -4,10 +4,9 @@ import 'package:dio/dio.dart';
import 'package:ente_auth/core/configuration.dart';
import 'package:ente_auth/core/event_bus.dart';
import 'package:ente_auth/events/endpoint_updated_event.dart';
import 'package:ente_auth/utils/package_info_util.dart';
import 'package:ente_auth/utils/platform_util.dart';
import 'package:fk_user_agent/fk_user_agent.dart';
import 'package:flutter/foundation.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:uuid/uuid.dart';
int kConnectTimeout = 15000;
@@ -17,41 +16,34 @@ class Network {
late Dio _enteDio;
Future<void> init() async {
if (PlatformUtil.isMobile()) await FkUserAgent.init();
final packageInfo = await PackageInfoUtil().getPackageInfo();
final version = PackageInfoUtil().getVersion(packageInfo);
final packageName = PackageInfoUtil().getPackageName(packageInfo);
await FkUserAgent.init();
final packageInfo = await PackageInfo.fromPlatform();
final endpoint = Configuration.instance.getHttpEndpoint();
_dio = Dio(
BaseOptions(
connectTimeout: Duration(milliseconds: kConnectTimeout),
connectTimeout: kConnectTimeout,
headers: {
HttpHeaders.userAgentHeader: PlatformUtil.isMobile()
? FkUserAgent.userAgent
: Platform.operatingSystem,
'X-Client-Version': version,
'X-Client-Package': packageName,
HttpHeaders.userAgentHeader: FkUserAgent.userAgent,
'X-Client-Version': packageInfo.version,
'X-Client-Package': packageInfo.packageName,
},
),
);
_enteDio = Dio(
BaseOptions(
baseUrl: endpoint,
connectTimeout: Duration(milliseconds: kConnectTimeout),
connectTimeout: kConnectTimeout,
headers: {
if (PlatformUtil.isMobile())
HttpHeaders.userAgentHeader: FkUserAgent.userAgent
else
HttpHeaders.userAgentHeader: Platform.operatingSystem,
'X-Client-Version': version,
'X-Client-Package': packageName,
HttpHeaders.userAgentHeader: FkUserAgent.userAgent,
'X-Client-Version': packageInfo.version,
'X-Client-Package': packageInfo.packageName,
},
),
);
_setupInterceptors(endpoint);
Bus.instance.on<EndpointUpdatedEvent>().listen((event) {
final endpoint = Configuration.instance.getHttpEndpoint();
_enteDio.options.baseUrl = endpoint;

View File

@@ -5,16 +5,12 @@ import 'package:flutter/material.dart';
final lightThemeData = ThemeData(
fontFamily: 'Inter',
brightness: Brightness.light,
dividerTheme: const DividerThemeData(
color: Colors.black12,
),
hintColor: const Color.fromRGBO(158, 158, 158, 1),
primaryColor: const Color.fromRGBO(255, 110, 64, 1),
primaryColorLight: const Color.fromRGBO(0, 0, 0, 0.541),
iconTheme: const IconThemeData(color: Colors.black),
primaryIconTheme:
const IconThemeData(color: Colors.red, opacity: 1.0, size: 50.0),
buttonTheme: const ButtonThemeData(),
outlinedButtonTheme: buildOutlinedButtonThemeData(
bgDisabled: const Color.fromRGBO(158, 158, 158, 1),
bgEnabled: const Color.fromRGBO(0, 0, 0, 1),
@@ -76,42 +72,24 @@ final lightThemeData = ThemeData(
? const Color.fromRGBO(255, 255, 255, 1)
: const Color.fromRGBO(0, 0, 0, 1);
}),
),
radioTheme: RadioThemeData(
fillColor:
MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return null;
}
if (states.contains(MaterialState.selected)) {
return const Color.fromRGBO(102, 187, 106, 1);
}
return null;
}),
),
switchTheme: SwitchThemeData(
thumbColor:
MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return null;
}
if (states.contains(MaterialState.selected)) {
return const Color.fromRGBO(102, 187, 106, 1);
}
return null;
}),
trackColor:
MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return null;
}
if (states.contains(MaterialState.selected)) {
return const Color.fromRGBO(102, 187, 106, 1);
}
return null;
}),
),
colorScheme: const ColorScheme.light(
), radioTheme: RadioThemeData(
fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) { return null; }
if (states.contains(MaterialState.selected)) { return const Color.fromRGBO(102, 187, 106, 1); }
return null;
}),
), switchTheme: SwitchThemeData(
thumbColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) { return null; }
if (states.contains(MaterialState.selected)) { return const Color.fromRGBO(102, 187, 106, 1); }
return null;
}),
trackColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) { return null; }
if (states.contains(MaterialState.selected)) { return const Color.fromRGBO(102, 187, 106, 1); }
return null;
}),
), colorScheme: const ColorScheme.light(
primary: Colors.black,
secondary: Color.fromARGB(255, 163, 163, 163),
).copyWith(background: const Color.fromRGBO(255, 255, 255, 1)),
@@ -120,9 +98,6 @@ final lightThemeData = ThemeData(
final darkThemeData = ThemeData(
fontFamily: 'Inter',
brightness: Brightness.dark,
dividerTheme: const DividerThemeData(
color: Colors.white12,
),
primaryColorLight: const Color.fromRGBO(255, 255, 255, 0.702),
iconTheme: const IconThemeData(color: Colors.white),
primaryIconTheme:
@@ -130,7 +105,6 @@ final darkThemeData = ThemeData(
hintColor: const Color.fromRGBO(158, 158, 158, 1),
buttonTheme: const ButtonThemeData().copyWith(
buttonColor: const Color.fromRGBO(45, 194, 98, 1.0),
height: 56,
),
textTheme: _buildTextTheme(const Color.fromRGBO(255, 255, 255, 1)),
outlinedButtonTheme: buildOutlinedButtonThemeData(
@@ -190,43 +164,24 @@ final darkThemeData = ThemeData(
return const Color.fromRGBO(158, 158, 158, 1);
}
}),
),
radioTheme: RadioThemeData(
fillColor:
MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return null;
}
if (states.contains(MaterialState.selected)) {
return const Color.fromRGBO(102, 187, 106, 1);
}
return null;
}),
),
switchTheme: SwitchThemeData(
thumbColor:
MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return null;
}
if (states.contains(MaterialState.selected)) {
return const Color.fromRGBO(102, 187, 106, 1);
}
return null;
}),
trackColor:
MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
return null;
}
if (states.contains(MaterialState.selected)) {
return const Color.fromRGBO(102, 187, 106, 1);
}
return null;
}),
),
colorScheme: const ColorScheme.dark(primary: Colors.white)
.copyWith(background: const Color.fromRGBO(0, 0, 0, 1)),
), radioTheme: RadioThemeData(
fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) { return null; }
if (states.contains(MaterialState.selected)) { return const Color.fromRGBO(102, 187, 106, 1); }
return null;
}),
), switchTheme: SwitchThemeData(
thumbColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) { return null; }
if (states.contains(MaterialState.selected)) { return const Color.fromRGBO(102, 187, 106, 1); }
return null;
}),
trackColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) { return null; }
if (states.contains(MaterialState.selected)) { return const Color.fromRGBO(102, 187, 106, 1); }
return null;
}),
), colorScheme: const ColorScheme.dark(primary: Colors.white).copyWith(background: const Color.fromRGBO(0, 0, 0, 1)),
);
TextTheme _buildTextTheme(Color textColor) {
@@ -445,7 +400,6 @@ OutlinedButtonThemeData buildOutlinedButtonThemeData({
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
fixedSize: const Size.fromHeight(56),
alignment: Alignment.center,
padding: const EdgeInsets.fromLTRB(50, 16, 50, 16),
textStyle: const TextStyle(
@@ -482,9 +436,7 @@ ElevatedButtonThemeData buildElevatedButtonThemeData({
}) {
return ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
foregroundColor: onPrimary,
backgroundColor: primary,
elevation: elevation,
foregroundColor: onPrimary, backgroundColor: primary, elevation: elevation,
alignment: Alignment.center,
textStyle: const TextStyle(
fontWeight: FontWeight.w600,

View File

@@ -25,7 +25,7 @@ class AuthenticatorGateway {
try {
final response = await _enteDio.get("/authenticator/key");
return AuthKey.fromMap(response.data);
} on DioException catch (e) {
} on DioError catch (e) {
if (e.response != null && (e.response!.statusCode ?? 0) == 404) {
throw AuthenticatorKeyNotFound();
} else {
@@ -90,7 +90,7 @@ class AuthenticatorGateway {
}
return authEntities;
} catch (e) {
if (e is DioException && e.response?.statusCode == 401) {
if (e is DioError && e.response?.statusCode == 401) {
throw UnauthorizedError();
} else {
rethrow;

View File

@@ -78,12 +78,14 @@
"data": "البيانات",
"importCodes": "رمزالاستيراد",
"importTypePlainText": "نص عادي",
"importTypeEnteEncrypted": "تصدير مشفر ente",
"passwordForDecryptingExport": "كلمة المرور لفك تشفير التصدير",
"passwordEmptyError": "لا يمكن أن تكون كلمة المرور فارغة",
"importFromApp": "استيراد الرموز من {appName}",
"importGoogleAuthGuide": "قم بتصدير حساباتك من Google Authenticator إلى رمز QR code باستخدام خيار \"Transfer Accounts\" ثم استخدم جهازًا آخر لمسح رمز الاستجابة السريعة ضوئيًا.\n\nنصيحة: يمكنك استخدام كاميرا الويب الخاصة بالكمبيوتر المحمول لالتقاط صورة لرمز الاستجابة السريعة.",
"importSelectJsonFile": "حدد ملف JSON",
"importSelectAppExport": "حدد ملف التصدير {appName}",
"importEnteEncGuide": "حدد ملف JSON المشفر الذي تم تصديره من ente",
"importRaivoGuide": "استخدم خيار تصدير OTP إلى أرشيف Zip في إعدادات Raivo.\n\nاستخرج ملف zip واسترد ملف JSON.",
"importBitwardenGuide": "استخدم خيار \"تصدير خزانة\" داخل أدوات Bitwarden واستيراد ملف JSON غير مشفر.",
"importAegisGuide": "استخدم خيار \"Export the vault\" في إعدادات Aegis.\n\nإذا كان المخزن الخاص بك مشفرًا، فستحتاج إلى إدخال كلمة مرور المخزن لفك تشفير المخزن.",
@@ -113,18 +115,22 @@
"copied": "تم النسخ",
"pleaseTryAgain": "حاول مرة اخرى",
"existingUser": "المستخدم موجود",
"newUser": "جديد إلى Ente",
"delete": "حذف",
"enterYourPasswordHint": "أدخل كلمة المرور الخاصة بك",
"forgotPassword": "هل نسيت كلمة المرور",
"oops": "عذرًا",
"suggestFeatures": "اقتراح ميزة",
"faq": "الأسئلة الأكثر شيوعاً",
"faq_q_1": "ما مدى أمان المصادقة؟",
"faq_a_1": "يتم تشفير جميع الرموز التي تقوم بنسخها احتياطا عبر Ente. وهذا يعني أنه يمكنك فقط الوصول إلى الرموز الخاصة بك. تطبيقاتنا مفتوحة المصدر وقد تم مراجعة التشفير خارجيا.",
"faq_q_2": "هل يمكنني الوصول إلى رموزي على سطح المكتب؟",
"faq_a_2": "يمكنك الوصول إلى رموزك على الويب @ auth.ente.io.",
"faq_q_3": "كيف يمكنني حذف الرموز؟",
"faq_a_3": "يمكنك حذف الرمز عن طريق السحب لليسار على هذا العنصر.",
"faq_q_4": "كيف يمكنني دعم هذا المشروع؟",
"faq_a_4": "يمكنك دعم تطوير هذا المشروع عن طريق الاشتراك في تطبيق الصور @ ente.io.",
"faq_q_5": "كيف يمكنني تمكين قفل FaceID في المصادقة Ente",
"faq_a_5": "يمكنك تمكين قفل FaceID تحت الإعدادات => الحماية => قفل الشاشة.",
"somethingWentWrongMessage": "حدث خطأ ما، يرجى المحاولة مرة أخرى",
"leaveFamily": "مغادرة خطة العائلة",
@@ -138,8 +144,6 @@
"enterCodeHint": "أدخل الرمز المكون من 6 أرقام من\nتطبيق المصادقة",
"lostDeviceTitle": "جهاز مفقود ؟",
"twoFactorAuthTitle": "المصادقة الثنائية",
"passkeyAuthTitle": "التحقق من مفتاح المرور",
"verifyPasskey": "تحقق من مفتاح المرور",
"recoverAccount": "إسترجاع الحساب",
"enterRecoveryKeyHint": "أدخل رمز الاسترداد",
"recover": "استرداد",
@@ -193,8 +197,6 @@
"recoveryKeySaveDescription": "نحن لا نخزن هذا المفتاح، يرجى حفظ مفتاح الـ 24 كلمة هذا في مكان آمن.",
"doThisLater": "قم بهذا لاحقاً",
"saveKey": "حفظ المفتاح",
"save": "حفظ",
"send": "إرسال",
"back": "الرجوع",
"createAccount": "إنشاء حساب",
"passwordStrength": "قوة كلمة المرور: {passwordStrengthValue}",
@@ -342,6 +344,7 @@
"deleteCodeAuthMessage": "المصادقة لحذف الرمز",
"showQRAuthMessage": "المصادقة لإظهار رمز QR",
"confirmAccountDeleteTitle": "تأكيد حذف الحساب",
"confirmAccountDeleteMessage": "هذا الحساب مرتبط بتطبيقات Ente أخرى، إذا كنت تستخدم أي منها.\n\nبياناتك التي تم تحميلها، عبر جميع تطبيقات Ente سيتم جدولتها للحذف، وسيتم حذف حسابك بشكل دائم.",
"androidBiometricHint": "التحقق من الهوية",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
@@ -401,7 +404,5 @@
"signOutOtherDevices": "تسجيل الخروج من الأجهزة الأخرى",
"doNotSignOut": "لا تقم بتسجيل الخروج",
"hearUsWhereTitle": "كيف سمعت عن Ente؟ (اختياري)",
"hearUsExplanation": "نحن لا نتتبع تثبيت التطبيق. سيكون من المفيد إذا أخبرتنا أين وجدتنا!",
"passkey": "مفتاح المرور",
"developerSettings": "اعدادات المطور"
"hearUsExplanation": "نحن لا نتتبع تثبيت التطبيق. سيكون من المفيد إذا أخبرتنا أين وجدتنا!"
}

View File

@@ -1 +0,0 @@
{}

View File

@@ -78,12 +78,14 @@
"data": "Datei",
"importCodes": "Codes importieren",
"importTypePlainText": "Klartext",
"importTypeEnteEncrypted": "ente verschlüsselt exportieren",
"passwordForDecryptingExport": "Passwort um den Export zu entschlüsseln",
"passwordEmptyError": "Passwort kann nicht leer sein",
"importFromApp": "Importiere Codes von {appName}",
"importGoogleAuthGuide": "Exportiere deine Accounts von Google Authenticator zu einem QR-Code, durch die \"Konten übertragen\" Option. Scanne den QR-Code danach mit einem anderen Gerät.\n\nTipp: Du kannst die Kamera eines Laptops verwenden, um ein Foto den dem QR-Code zu erstellen.",
"importSelectJsonFile": "Wähle eine JSON-Datei",
"importSelectAppExport": "{appName} Exportdatei auswählen",
"importEnteEncGuide": "Wähle die von ente exportierte, verschlüsselte JSON-Datei",
"importRaivoGuide": "Verwenden Sie die Option \"Export OTPs to Zip archive\" in den Raivo-Einstellungen.\n\nEntpacken Sie die Zip-Datei und importieren Sie die JSON-Datei.",
"importBitwardenGuide": "Verwenden Sie die Option \"Tresor exportieren\" innerhalb der Bitwarden Tools und importieren Sie die unverschlüsselte JSON-Datei.",
"importAegisGuide": "Verwenden Sie die Option \"Tresor exportieren\" in den Aegis-Einstellungen.\n\nFalls Ihr Tresor verschlüsselt ist, müssen Sie das Passwort für den Tresor eingeben, um ihn zu entschlüsseln.",
@@ -113,18 +115,22 @@
"copied": "Kopiert",
"pleaseTryAgain": "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": "Hopla",
"suggestFeatures": "Features vorschlagen",
"faq": "FAQ",
"faq_q_1": "Wie sicher ist ente Auth?",
"faq_a_1": "Alle Codes, die Sie über ente sichern, werden Ende-zu-Ende-verschlüsselt gespeichert. Das bedeutet, dass nur Sie auf Ihre Codes zugreifen können. Unsere Apps sind Open Source und unsere Kryptografie wurde extern überprüft.",
"faq_q_2": "Kann ich auf meine Codes auf dem Desktop zugreifen?",
"faq_a_2": "Sie können auf Ihre Codes im Web via auth.ente.io zugreifen.",
"faq_q_3": "Wie kann ich Codes löschen?",
"faq_a_3": "Sie können einen Code löschen, indem Sie auf dem Code nach links wischen.",
"faq_q_4": "Wie kann ich das Projekt unterstützen?",
"faq_a_4": "Sie können die Entwicklung dieses Projekts unterstützen, indem Sie unsere Fotos-App auf ente.io abonnieren.",
"faq_q_5": "Wie kann ich FaceID Sperre in ente Auth aktivieren",
"faq_a_5": "Sie können FaceID unter Einstellungen → Sicherheit → Sperrbildschirm aktivieren.",
"somethingWentWrongMessage": "Ein Fehler ist aufgetreten, bitte versuchen Sie es erneut",
"leaveFamily": "Familie verlassen",
@@ -138,8 +144,6 @@
"enterCodeHint": "Geben Sie den 6-stelligen Code \naus Ihrer Authentifikator-App ein.",
"lostDeviceTitle": "Gerät verloren?",
"twoFactorAuthTitle": "Zwei-Faktor-Authentifizierung",
"passkeyAuthTitle": "Passkey Authentifizierung",
"verifyPasskey": "Passkey verifizieren",
"recoverAccount": "Konto wiederherstellen",
"enterRecoveryKeyHint": "Geben Sie Ihren Wiederherstellungsschlüssel ein",
"recover": "Wiederherstellen",
@@ -340,6 +344,7 @@
"deleteCodeAuthMessage": "Authentifizieren, um Code zu löschen",
"showQRAuthMessage": "Authentifizieren, um QR-Code anzuzeigen",
"confirmAccountDeleteTitle": "Kontolöschung bestätigen",
"confirmAccountDeleteMessage": "Dieses Konto ist mit anderen ente Apps verknüpft, sofern du diese benutzt.\n\nDeine hochgeladenen Daten werden zur permanenten Löschung freigegeben. Dies gilt für alle ente Apps.",
"androidBiometricHint": "Identität bestätigen",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
@@ -399,15 +404,5 @@
"signOutOtherDevices": "Andere Geräte abmelden",
"doNotSignOut": "Nicht abmelden",
"hearUsWhereTitle": "Wie hast du von Ente erfahren? (optional)",
"hearUsExplanation": "Wir tracken keine App-Installationen. Es würde uns jedoch helfen, wenn du uns mitteilst, wie du von uns erfahren hast!",
"waitingForBrowserRequest": "Warten auf Browseranfrage...",
"waitingForVerification": "Warte auf Bestätigung...",
"passkey": "Passkey",
"developerSettingsWarning": "Sind Sie sicher, dass Sie die Entwicklereinstellungen ändern möchten?",
"developerSettings": "Entwicklereinstellungen",
"serverEndpoint": "Server Endpunkt",
"invalidEndpoint": "Ungültiger Endpunkt",
"invalidEndpointMessage": "Der eingegebene Endpunkt ist ungültig. Bitte geben Sie einen gültigen Endpunkt ein und versuchen Sie es erneut.",
"endpointUpdatedMessage": "Endpunkt erfolgreich aktualisiert",
"customEndpoint": "Mit {endpoint} verbunden"
"hearUsExplanation": "Wir tracken keine App-Installationen. Es würde uns jedoch helfen, wenn du uns mitteilst, wie du von uns erfahren hast!"
}

View File

@@ -78,14 +78,14 @@
"data": "Data",
"importCodes": "Import codes",
"importTypePlainText": "Plain text",
"importTypeEnteEncrypted": "Ente Encrypted export",
"importTypeEnteEncrypted": "ente Encrypted export",
"passwordForDecryptingExport": "Password to decrypt export",
"passwordEmptyError": "Password can not be empty",
"importFromApp": "Import codes from {appName}",
"importGoogleAuthGuide": "Export your accounts from Google Authenticator to a QR code using the \"Transfer Accounts\" option. Then using another device, scan the QR code.\n\nTip: You can use your laptop's webcam to take a picture of the QR code.",
"importSelectJsonFile": "Select JSON file",
"importSelectAppExport": "Select {appName} export file",
"importEnteEncGuide": "Select the encrypted JSON file exported from Ente",
"importEnteEncGuide": "Select the encrypted JSON file exported from ente",
"importRaivoGuide": "Use the \"Export OTPs to Zip archive\" option in Raivo's Settings.\n\nExtract the zip file and import the JSON file.",
"importBitwardenGuide": "Use the \"Export vault\" option within Bitwarden Tools and import the unencrypted JSON file.",
"importAegisGuide": "Use the \"Export the vault\" option in Aegis's Settings.\n\nIf your vault is encrypted, you will need to enter vault password to decrypt the vault.",
@@ -115,22 +115,22 @@
"copied": "Copied",
"pleaseTryAgain": "Please try again",
"existingUser": "Existing User",
"newUser": "New to Ente",
"newUser": "New to ente",
"delete": "Delete",
"enterYourPasswordHint": "Enter your password",
"forgotPassword": "Forgot password",
"oops": "Oops",
"suggestFeatures": "Suggest features",
"faq": "FAQ",
"faq_q_1": "How secure is Auth?",
"faq_a_1": "All codes you backup via Auth is stored end-to-end encrypted. This means only you can access your codes. Our apps are open source and our cryptography has been externally audited.",
"faq_q_1": "How secure is ente Auth?",
"faq_a_1": "All codes you backup via ente is stored end-to-end encrypted. This means only you can access your codes. Our apps are open source and our cryptography has been externally audited.",
"faq_q_2": "Can I access my codes on desktop?",
"faq_a_2": "You can access your codes on the web @ auth.ente.io.",
"faq_q_3": "How can I delete codes?",
"faq_a_3": "You can delete a code by swiping left on that item.",
"faq_q_4": "How can I support this project?",
"faq_a_4": "You can support the development of this project by subscribing to our Photos app @ ente.io.",
"faq_q_5": "How can I enable FaceID lock in Auth",
"faq_q_5": "How can I enable FaceID lock in ente Auth",
"faq_a_5": "You can enable FaceID lock under Settings → Security → Lockscreen.",
"somethingWentWrongMessage": "Something went wrong, please try again",
"leaveFamily": "Leave family",
@@ -199,10 +199,6 @@
"recoveryKeySaveDescription": "We don't store this key, please save this 24 word key in a safe place.",
"doThisLater": "Do this later",
"saveKey": "Save key",
"save": "Save",
"send": "Send",
"saveOrSendDescription": "Do you want to save this to your storage (Downloads folder by default) or send it to other apps?",
"saveOnlyDescription": "Do you want to save this to your storage (Downloads folder by default)?",
"back": "Back",
"createAccount": "Create account",
"passwordStrength": "Password strength: {passwordStrengthValue}",
@@ -350,7 +346,7 @@
"deleteCodeAuthMessage": "Authenticate to delete code",
"showQRAuthMessage": "Authenticate to show QR code",
"confirmAccountDeleteTitle": "Confirm account deletion",
"confirmAccountDeleteMessage": "This account is linked to other Ente apps, if you use any.\n\nYour uploaded data, across all Ente apps, will be scheduled for deletion, and your account will be permanently deleted.",
"confirmAccountDeleteMessage": "This account is linked to other ente apps, if you use any.\n\nYour uploaded data, across all ente apps, will be scheduled for deletion, and your account will be permanently deleted.",
"androidBiometricHint": "Verify identity",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
@@ -411,7 +407,6 @@
"doNotSignOut": "Do not sign out",
"hearUsWhereTitle": "How did you hear about Ente? (optional)",
"hearUsExplanation": "We don't track app installs. It'd help if you told us where you found us!",
"recoveryKeySaved": "Recovery key saved in Downloads folder!",
"waitingForBrowserRequest": "Waiting for browser request...",
"waitingForVerification": "Waiting for verification...",
"passkey": "Passkey",

View File

@@ -78,12 +78,14 @@
"data": "Datos",
"importCodes": "Importar códigos",
"importTypePlainText": "Texto sin formato",
"importTypeEnteEncrypted": "Exportación cifrada ente",
"passwordForDecryptingExport": "Contraseña para descifrar exportación",
"passwordEmptyError": "La contraseña no puede estar vacía",
"importFromApp": "Importar códigos de {appName}",
"importGoogleAuthGuide": "Exportar tus cuentas desde Google Authenticator a un código QR usando la opción \"Transferir Cuentas\". A continuación, usando otro dispositivo, escanee el código QR.\n\nConsejo: Puede usar la webcam de su portátil para tomar una foto del código QR.",
"importSelectJsonFile": "Seleccione el archivo JSON",
"importSelectAppExport": "Seleccione el archivo de exportación de {appName}",
"importEnteEncGuide": "Seleccione el archivo JSON cifrado exportado desde ente",
"importRaivoGuide": "Utilice la opción \"Exportar códigos a un archivo de Zip\" en la configuración de Raivo.\n\nExtraiga el archivo zip e importe el archivo JSON.",
"importBitwardenGuide": "Use la opción \"Exportar caja fuerte\" dentro del menú Herramientas de Bitwarden e importe el fichero JSON no crifrado.",
"importAegisGuide": "Utilice la opción \"Exportar la bóveda\" en ajustes de Aegis.\n\nSi tu bóveda es cifrada, necesitara entrar contraseña de bóveda para descifrar la bóveda.",
@@ -113,18 +115,22 @@
"copied": "Copiado",
"pleaseTryAgain": "Por favor, inténtalo nuevamente",
"existingUser": "Usuario existente",
"newUser": "Nuevo en ente",
"delete": "Borrar",
"enterYourPasswordHint": "Ingrese su contraseña",
"forgotPassword": "Olvidé mi contraseña",
"oops": "Ups",
"suggestFeatures": "Sugerir funcionalidades",
"faq": "Preguntas Frecuentes",
"faq_q_1": "¿Cuán seguro es ente Auth?",
"faq_a_1": "Todos los códigos que copia de seguridad vía ente se almacenan cifrados de extremo a extremo. Esto significa que solo usted puede acceder a sus códigos. Nuestras aplicaciones son de código abierto y nuestra criptografía ha sido auditada externamente.",
"faq_q_2": "¿Puedo acceder a mis códigos en el escritorio?",
"faq_a_2": "Puede acceder a tus códigos en la web en auth.ente.io.",
"faq_q_3": "¿Cómo puedo borrar códigos?",
"faq_a_3": "Puede eliminar un código deslizando a la izquierda en ese elemento.",
"faq_q_4": "¿Cómo puedo apoyar este proyecto?",
"faq_a_4": "Puedes apoyar el desarrollo de este proyecto suscribiéndote a nuestra app de Fotos en ente.io.",
"faq_q_5": "¿Cómo puedo habilitar bloqueo FaceID en ente Auth",
"faq_a_5": "Puede activar el bloqueo FaceID en Ajustes → Seguridad → Pantalla de bloqueo.",
"somethingWentWrongMessage": "Algo ha ido mal, por favor, prueba otra vez",
"leaveFamily": "Dejar plan familiar",
@@ -338,6 +344,7 @@
"deleteCodeAuthMessage": "Autenticar para borrar código",
"showQRAuthMessage": "Autenticar para mostrar código QR",
"confirmAccountDeleteTitle": "Confirmar eliminación de la cuenta",
"confirmAccountDeleteMessage": "Esta cuenta está vinculada a otras aplicaciones de ente, si utiliza alguna.\n\nSe programará la eliminación de los datos que cargue en todas las aplicaciones de ente y su cuenta se eliminará permanentemente.",
"androidBiometricHint": "Verificar identidad",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."

View File

@@ -85,6 +85,7 @@
"copied": "کپی شد",
"pleaseTryAgain": "لطفا دوباره تلاش کنید",
"existingUser": "کاربر موجود",
"newUser": "کاربر جدید ente",
"delete": "حذف",
"enterYourPasswordHint": "رمز عبور خود را وارد کنید",
"forgotPassword": "فراموشی رمز عبور",

View File

@@ -74,6 +74,7 @@
"copied": "Jäljennetty",
"pleaseTryAgain": "Yritä uudestaan",
"existingUser": "Jo valmiiksi olemassaoleva käyttäjä",
"newUser": "Uusi Ente-käyttäjä",
"delete": "Poista",
"enterYourPasswordHint": "Syötä salasanasi",
"forgotPassword": "Olen unohtanut salasanani",

View File

@@ -1,6 +1,5 @@
{
"account": "Compte",
"unlock": "Déverrouiller",
"recoveryKey": "Clé de récupération",
"counterAppBarTitle": "Compteur",
"@counterAppBarTitle": {
@@ -78,17 +77,15 @@
"data": "Données",
"importCodes": "Importer les codes",
"importTypePlainText": "Texte brut",
"importTypeEnteEncrypted": "ente Exportation chiffrée",
"passwordForDecryptingExport": "Mot de passe pour déchiffrer l'exportation",
"passwordEmptyError": "Le mot de passe ne peut pas être vide",
"importFromApp": "Importer des codes depuis {appName}",
"importGoogleAuthGuide": "Exportez vos comptes depuis Google Authenticator vers un code QR en utilisant l'option \"Transférer des comptes\". Ensuite, en utilisant un autre appareil, scannez le code QR.\n\nAstuce : Vous pouvez utiliser la webcam de votre ordinateur portable pour prendre une photo du code QR.",
"importSelectJsonFile": "Sélectionnez un fichier JSON",
"importSelectAppExport": "Sélectionnez le fichier d'exportation {appName}",
"importEnteEncGuide": "Sélectionnez le fichier JSON chiffré exporté à partir de ente",
"importRaivoGuide": "Utilisez l'option \"Exporter les OTPs vers l'archive Zip\" dans les paramètres de Raivo.\n\nExtrayez le fichier zip et importez le fichier JSON.",
"importBitwardenGuide": "Utilisez l'option « Exporter le coffre » dans les outils Bitwarden et importez le fichier JSON non chiffré.",
"importAegisGuide": "Utilisez l'option \"Exporter le coffre-fort\" dans les paramètres d'Aegis.\n\nSi votre coffre-fort est crypté, vous devrez saisir le mot de passe du coffre-fort pour déchiffrer le coffre-fort.",
"import2FasGuide": "Utilisez l'option \"Paramètres->Sauvegarde -Export\" dans 2FAS.\n\nSi votre sauvegarde est chiffrée, vous devrez entrer le mot de passe pour déchiffrer la sauvegarde",
"importLastpassGuide": "Utilisez l'option \"Transférer des comptes\" dans les paramètres de l'authentificateur Lastpass et appuyez sur \"Exporter des comptes vers un fichier\". Importez le JSON téléchargé.",
"exportCodes": "Exporter les codes",
"importLabel": "Importer",
"importInstruction": "Veuillez sélectionner un fichier qui contient une liste de vos codes dans le format suivant",
@@ -100,8 +97,6 @@
"authToViewYourRecoveryKey": "Veuillez vous authentifier pour afficher votre clé de récupération",
"authToChangeYourEmail": "Veuillez vous authentifier pour modifier votre adresse e-mail",
"authToChangeYourPassword": "Veuillez vous authentifier pour modifier votre mot de passe",
"authToViewSecrets": "Veuillez vous authentifier pour voir vos souvenirs",
"authToInitiateSignIn": "Veuillez vous authentifier pour ouvrir une session de sauvegarde.",
"ok": "Ok",
"cancel": "Annuler",
"yes": "Oui",
@@ -113,18 +108,22 @@
"copied": "Copié",
"pleaseTryAgain": "Veuillez réessayer",
"existingUser": "Utilisateur existant",
"newUser": "Nouveau sur ente",
"delete": "Supprimer",
"enterYourPasswordHint": "Saisir votre mot de passe",
"forgotPassword": "Mot de passe oublié",
"oops": "Oups",
"suggestFeatures": "Suggérer des fonctionnalités",
"faq": "FAQ",
"faq_q_1": "À quel point ente Auth est-il sécurisé ?",
"faq_a_1": "Tous les codes que vous sauvegardez via ente sont chiffrés de bout en bout. Cela signifie que vous seul pouvez accéder à vos codes. Nos applications sont open source et notre cryptographie a fait l'objet d'un audit externe.",
"faq_q_2": "Puis-je accéder à mes codes sur mon ordinateur ?",
"faq_a_2": "Vous pouvez accéder à vos codes sur le web via auth.ente.io.",
"faq_q_3": "Comment puis-je supprimer des codes ?",
"faq_a_3": "Vous pouvez supprimer un code en glissant vers la gauche.",
"faq_q_4": "Comment puis-je soutenir le projet ?",
"faq_a_4": "Vous pouvez soutenir le développement de ce projet en vous abonnant à notre application Photos, ente.io.",
"faq_q_5": "Comment puis-je activer le verrouillage FaceID sur ente Auth",
"faq_a_5": "Vous pouvez activer le verrouillage FaceID dans Paramètres → Sécurité → Écran de verrouillage.",
"somethingWentWrongMessage": "Quelque chose s'est mal passé, veuillez recommencer",
"leaveFamily": "Quitter le plan familial",
@@ -138,8 +137,6 @@
"enterCodeHint": "Saisir le code à 6 caractères de votre appli d'authentification",
"lostDeviceTitle": "Appareil perdu ?",
"twoFactorAuthTitle": "Authentification à deux facteurs",
"passkeyAuthTitle": "Vérification du code d'accès",
"verifyPasskey": "Vérifier le code d'accès",
"recoverAccount": "Récupérer un compte",
"enterRecoveryKeyHint": "Saisissez votre clé de récupération",
"recover": "Restaurer",
@@ -193,10 +190,6 @@
"recoveryKeySaveDescription": "Nous ne stockons pas cette clé, veuillez enregistrer cette clé de 24 mots dans un endroit sûr.",
"doThisLater": "Plus tard",
"saveKey": "Enregistrer la clé",
"save": "Sauvegarder",
"send": "Envoyer",
"saveOrSendDescription": "Voulez-vous enregistrer ceci sur votre stockage (dossier Téléchargements par défaut) ou l'envoyer à d'autres applications ?",
"saveOnlyDescription": "Voulez-vous enregistrer ceci sur votre stockage (dossier Téléchargements par défaut) ?",
"back": "Retour",
"createAccount": "Créer un compte",
"passwordStrength": "Force du mot de passe : {passwordStrengthValue}",
@@ -336,7 +329,6 @@
"offlineModeWarning": "Vous avez choisi de procéder sans sauvegarde. Veuillez prendre des sauvegardes manuelles pour vous assurer que vos codes sont sûrs.",
"showLargeIcons": "Afficher les grandes icônes",
"shouldHideCode": "Cacher les codes",
"doubleTapToViewHiddenCode": "Vous pouvez appuyer deux fois sur une entrée pour afficher le code",
"focusOnSearchBar": "Cibler le champ de recherche au démarrage de l'application",
"confirmUpdatingkey": "Êtes-vous sûr de vouloir mettre à jour la clé secrète ?",
"minimizeAppOnCopy": "Réduire l'application après la copie",
@@ -344,75 +336,5 @@
"deleteCodeAuthMessage": "Authentification requise pour supprimer le code",
"showQRAuthMessage": "Authentification requise pour afficher le code QR",
"confirmAccountDeleteTitle": "Confirmer la suppression du compte",
"androidBiometricHint": "Vérifier lidentité",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
},
"androidBiometricNotRecognized": "Non reconnu. Veuillez réessayer.",
"@androidBiometricNotRecognized": {
"description": "Message to let the user know that authentication was failed. It is used on Android side. Maximum 60 characters."
},
"androidBiometricSuccess": "Parfait",
"@androidBiometricSuccess": {
"description": "Message to let the user know that authentication was successful. It is used on Android side. Maximum 60 characters."
},
"androidCancelButton": "Annuler",
"@androidCancelButton": {
"description": "Message showed on a button that the user can click to leave the current dialog. It is used on Android side. Maximum 30 characters."
},
"androidSignInTitle": "Authentification requise",
"@androidSignInTitle": {
"description": "Message showed as a title in a dialog which indicates the user that they need to scan biometric to continue. It is used on Android side. Maximum 60 characters."
},
"androidBiometricRequiredTitle": "Empreinte digitale requise",
"@androidBiometricRequiredTitle": {
"description": "Message showed as a title in a dialog which indicates the user has not set up biometric authentication on their device. It is used on Android side. Maximum 60 characters."
},
"androidDeviceCredentialsRequiredTitle": "Identifiants de l'appareil requis",
"@androidDeviceCredentialsRequiredTitle": {
"description": "Message showed as a title in a dialog which indicates the user has not set up credentials authentication on their device. It is used on Android side. Maximum 60 characters."
},
"androidDeviceCredentialsSetupDescription": "Identifiants de l'appareil requis",
"@androidDeviceCredentialsSetupDescription": {
"description": "Message advising the user to go to the settings and configure device credentials on their device. It shows in a dialog on Android side."
},
"goToSettings": "Allez dans les paramètres",
"@goToSettings": {
"description": "Message showed on a button that the user can click to go to settings pages from the current dialog. It is used on both Android and iOS side. Maximum 30 characters."
},
"androidGoToSettingsDescription": "L'authentification biométrique n'est pas configurée sur votre appareil. Allez dans 'Paramètres > Sécurité' pour l'ajouter.",
"@androidGoToSettingsDescription": {
"description": "Message advising the user to go to the settings and configure biometric on their device. It shows in a dialog on Android side."
},
"iOSLockOut": "L'authentification biométrique est désactivée. Veuillez verrouiller et déverrouiller votre écran pour l'activer.",
"@iOSLockOut": {
"description": "Message advising the user to re-enable biometrics on their device. It shows in a dialog on iOS side."
},
"iOSGoToSettingsDescription": "L'authentification biométrique n'est pas configurée sur votre appareil. Veuillez activer Touch ID ou Face ID sur votre téléphone.",
"@iOSGoToSettingsDescription": {
"description": "Message advising the user to go to the settings and configure Biometrics for their device. It shows in a dialog on iOS side."
},
"iOSOkButton": "Ok",
"@iOSOkButton": {
"description": "Message showed on a button that the user can click to leave the current dialog. It is used on iOS side. Maximum 30 characters."
},
"noInternetConnection": "Aucune connexion internet",
"pleaseCheckYourInternetConnectionAndTryAgain": "Veuillez vérifier votre connexion internet puis réessayer.",
"signOutFromOtherDevices": "Déconnexion des autres appareils",
"signOutOtherBody": "Si vous pensez que quelqu'un connaît peut-être votre mot de passe, vous pouvez forcer tous les autres appareils utilisant votre compte à se déconnecter.",
"signOutOtherDevices": "Déconnecter les autres appareils",
"doNotSignOut": "Ne pas se déconnecter",
"hearUsWhereTitle": "Comment avez-vous entendu parler de Ente? (facultatif)",
"hearUsExplanation": "Nous ne suivons pas les installations d'applications. Il serait utile que vous nous disiez comment vous nous avez trouvés !",
"recoveryKeySaved": "Clé de récupération enregistrée dans le dossier Téléchargements !",
"waitingForBrowserRequest": "En attente de la requête du navigateur...",
"waitingForVerification": "En attente de vérification...",
"passkey": "Code d'accès",
"developerSettingsWarning": "Êtes-vous sûr de vouloir modifier les paramètres du développeur ?",
"developerSettings": "Paramètres du développeur",
"serverEndpoint": "Point de terminaison serveur",
"invalidEndpoint": "Point de terminaison non valide",
"invalidEndpointMessage": "Désolé, le point de terminaison que vous avez entré n'est pas valide. Veuillez en entrer un valide puis réessayez.",
"endpointUpdatedMessage": "Point de terminaison mis à jour avec succès",
"customEndpoint": "Connecté à {endpoint}"
"confirmAccountDeleteMessage": "Ce compte peut être lié à d'autres applications ente.\n\nVos données seront bientôt effacées de toutes les applications et votre compte sera définitivement supprimé."
}

View File

@@ -77,11 +77,13 @@
"data": "נתונים",
"importCodes": "ייבא קוד",
"importTypePlainText": "טקסט רגיל",
"importTypeEnteEncrypted": "ייצוא ente מוצפן",
"passwordForDecryptingExport": "סיסמא כדי לפענח יצוא",
"passwordEmptyError": "הסיסמה אינה יכולה להיות ריקה",
"importFromApp": "יבא קודים מ-{appName}",
"importGoogleAuthGuide": "יצא את החשבונות שלך מ-Google Authenticator לקוד QR תוך שימוש באפשרות \"Transfer Accounts\". אז, תוך שימוש במכשיר אחר, סרוק את הקוד QR.",
"importSelectJsonFile": "בחר קובץ JSON",
"importEnteEncGuide": "בחר את קובץ ה-JSON המוצפן שייוצא מ-ente",
"importRaivoGuide": "השתמש באפוציה של \"Export OTPs to Zip archive\" בהגדרות של Raivo.",
"importAegisGuide": "אנא השתמש באפשרות של \"ייצוא של הכספת\" בתוך ההגדרות של Aegis.",
"exportCodes": "ייצא קודים",
@@ -106,18 +108,22 @@
"copied": "הועתק",
"pleaseTryAgain": "אנא נסה שנית",
"existingUser": "משתמש קיים",
"newUser": "חדש בente",
"delete": "למחוק",
"enterYourPasswordHint": "הכנס סיסמא",
"forgotPassword": "שכחתי סיסמה",
"oops": "אופס",
"suggestFeatures": "הציעו מאפיינים",
"faq": "שאלות נפוצות",
"faq_q_1": "כמה מאובטח ente Auth?",
"faq_a_1": "כל הקודים שאתה מגבה דרך ente מאוחסנים מקצה לקצה בהצפנה. הכוונה שרק אתה יכול לגשת לקודים שלך. האפליקציות שלנו הם מפותחות דרך קוד פתוח והקריפטוגרפיה שלנו מבוקרת חיצונית.",
"faq_q_2": "האם ישנה אפשרות להשתמש בקודים שלי במחשב?",
"faq_a_2": "אתה יכול לגשת לקודים שלך ברשת ב- auth.ente.io.",
"faq_q_3": "איך אפשר למחוק קודים?",
"faq_a_3": "אתה יכול למחוק את הקוד על-ידי החלקה שמאלה על הפריט הזה.",
"faq_q_4": "איך אפשר לתמוך בפרויקט זה?",
"faq_a_4": "אתה יכול לתמוך בפיתוח של הפרויקט הזה על ידי שתירשם לאפליקצית תמונות שלנו ב-ente.io.",
"faq_q_5": "איך אני יכול להפעיל מנעול FaceID ב-ente Auth",
"faq_a_5": "אתה יכול להפעיל מנעול FaceID תחת הגדרות -> אבטחה -> מסך נעילה.",
"somethingWentWrongMessage": "משהו השתבש, אנא נסה שנית",
"leaveFamily": "עזוב משפחה",

View File

@@ -78,12 +78,14 @@
"data": "Dati",
"importCodes": "Importa codici",
"importTypePlainText": "Testo in chiaro",
"importTypeEnteEncrypted": "ente Esportazione criptata",
"passwordForDecryptingExport": "Password per decriptare il file esportato",
"passwordEmptyError": "La password è obbligatoria",
"importFromApp": "Importa codici da {appName}",
"importGoogleAuthGuide": "Esporta i tuoi account da Google Authenticator in un codice QR utilizzando l'opzione \"Trasferisci Account\". Quindi, usando un altro dispositivo, scansiona il codice QR.\n\nSuggerimento: Puoi usare la webcam del tuo computer portatile per scattare una foto del codice QR.",
"importSelectJsonFile": "Seleziona file JSON",
"importSelectAppExport": "Seleziona il file di esportazione {appName}",
"importEnteEncGuide": "Seleziona il file JSON criptato esportato da ente",
"importRaivoGuide": "Utilizza l'opzione \"Esporta i codici OTP in archivio Zip\" nelle impostazioni di Raivo.\n\nEstrai il file zip e importa il file JSON.",
"importBitwardenGuide": "Utilizzare l'opzione \"Esporta vault\" all'interno di Bitwarden Tools e importa il file JSON non crittografato.",
"importAegisGuide": "Usa l'opzione \"Esporta la cassaforte\" nelle impostazioni di Aegis.\n\nSe la tua cassaforte è criptata, dovrai inserire la password della cassaforte per decriptarla.",
@@ -112,18 +114,22 @@
"copied": "Copiato",
"pleaseTryAgain": "Per favore riprova",
"existingUser": "Accedi",
"newUser": "Nuovo utente",
"delete": "Cancella",
"enterYourPasswordHint": "Inserisci la tua password",
"forgotPassword": "Password dimenticata",
"oops": "Oops",
"suggestFeatures": "Suggerisci funzionalità",
"faq": "FAQ",
"faq_q_1": "Quanto è sicuro ente Auth?",
"faq_a_1": "Tutti i codici di cui fai il backup tramite ente sono memorizzati con crittografia end-to-end. Ciò significa che solo tu puoi accedere ai tuoi codici. Le nostre app sono open source e la nostra crittografia è stata verificata esternamente.",
"faq_q_2": "Posso accedere ai miei codici sul desktop?",
"faq_a_2": "Puoi accedere ai tuoi codici sul web @ auth.ente.io.",
"faq_q_3": "Come posso cancellare i codici?",
"faq_a_3": "Puoi eliminare un codice scorrendo il dito a sinistra sul codice in questione.",
"faq_q_4": "Come posso supportare questo progetto?",
"faq_a_4": "Puoi supportare lo sviluppo di questo progetto abbonandoti alla nostra app Photos @ ente.io.",
"faq_q_5": "Come posso abilitare il blocco FaceID in ente Auth",
"faq_a_5": "Puoi abilitare il blocco FaceID in Impostazioni → Sicurezza → Schermata di blocco.",
"somethingWentWrongMessage": "Qualcosa è andato storto, per favore riprova",
"leaveFamily": "Abbandona il piano famiglia",
@@ -337,6 +343,7 @@
"deleteCodeAuthMessage": "Autenticarsi per cancellare il codice",
"showQRAuthMessage": "Autenticarsi per mostrare il codice QR",
"confirmAccountDeleteTitle": "Conferma l'eliminazione dell'account",
"confirmAccountDeleteMessage": "Questo account è collegato ad altre app di ente, se ne utilizzi.\n\nI tuoi dati caricati, su tutte le app di ente, saranno pianificati per la cancellazione e il tuo account verrà eliminato definitivamente.",
"androidBiometricHint": "Verifica l'identità",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."

View File

@@ -78,13 +78,14 @@
"data": "データ",
"importCodes": "コードをインポート",
"importTypePlainText": "プレーンテキスト",
"importTypeEnteEncrypted": "ente 暗号化エクスポート",
"passwordForDecryptingExport": "復号化用パスワード",
"passwordEmptyError": "パスワードは空欄にできません",
"importFromApp": "{appName} からコードをインポート",
"importGoogleAuthGuide": "Google Authenticator の \"アカウントを転送\" オプションを使用してあなたのアカウントを QR コードにエクスポートしてください。その後、他のデバイスで QR コードを読み取ってください。\n\nヒント: ノートパソコンのウェブカメラを使用して QR コードを撮影することができます。",
"importSelectJsonFile": "JSON ファイルを選択",
"importSelectAppExport": "{appName} のエクスポートファイルを選択",
"importEnteEncGuide": "Enteからエクスポートた暗号化されたJSONファイルを選択してください",
"importEnteEncGuide": "ente からエクスポートされた暗号化 JSON ファイルを選択",
"importRaivoGuide": "Raivo の設定の \"OTP を zip アーカイブにエクスポート\" を使用してください。\n\nzip ファイルを解凍し JSON ファイルをインポートしてください。",
"importBitwardenGuide": "Bitwarden Tools の \"保管庫のエクスポート\" オプションを使用後、平文の JSON ファイルをインポートしてください。",
"importAegisGuide": "Aegis の設定の \"保管庫をエクスポート\" を使用してください。\n\n保管庫が暗号化されている場合、保管庫を復号するためにパスワードの入力が必要になります。",
@@ -114,21 +115,22 @@
"copied": "コピーしました",
"pleaseTryAgain": "再度お試しください",
"existingUser": "既存のユーザー",
"newUser": "Enteを初めて使用",
"newUser": "ente 新規ユーザー",
"delete": "削除",
"enterYourPasswordHint": "パスワードを入力してください",
"forgotPassword": "パスワードを忘れた場合",
"oops": "おっと",
"suggestFeatures": "機能を提案",
"faq": "FAQ",
"faq_q_1": "Authはどのくらい安全ですか",
"faq_q_1": "ente Auth はどのくらい安全ですか?",
"faq_a_1": "ente でバックアップされたすべてのコードはエンドツーエンドで暗号化されて保管されます。これはあなただけがコードにアクセスできることを意味します。私たちのアプリはオープンソースであり、私たちの暗号は外部有識者によって検証済みです。",
"faq_q_2": "パソコンから私のコードにアクセスできますか?",
"faq_a_2": "auth.ente.io で Web からコードにアクセス可能です。",
"faq_q_3": "コードを削除するにはどうすればいいですか?",
"faq_a_3": "その項目を左にスワイプすることでコードを削除できます。",
"faq_q_4": "このプロジェクトを支援するにはどうすればいいですか?",
"faq_a_4": "ente.io で私たちの写真アプリを購読することでこのプロジェクトの開発を支援できます。",
"faq_q_5": "AuthFaceIDロックを有効にするにはどうすればいいですか",
"faq_q_5": "ente AuthFaceID ロックを有効にするにはどうすればいいですか?",
"faq_a_5": "設定→セキュリティ→画面のロックから FaceID ロックを有効にできます。",
"somethingWentWrongMessage": "問題が発生しました、再試行してください",
"leaveFamily": "ファミリープランから退会",
@@ -142,8 +144,6 @@
"enterCodeHint": "認証アプリに表示された 6 桁のコードを入力してください",
"lostDeviceTitle": "デバイスを紛失しましたか?",
"twoFactorAuthTitle": "2 要素認証",
"passkeyAuthTitle": "パスキー認証",
"verifyPasskey": "パスキーの認証",
"recoverAccount": "アカウントを回復",
"enterRecoveryKeyHint": "回復キーを入力",
"recover": "回復",
@@ -197,10 +197,6 @@
"recoveryKeySaveDescription": "私たちはこのキーを保存しません。この 24 単語のキーを安全な場所に保存してください。",
"doThisLater": "後で行う",
"saveKey": "キーを保存",
"save": "保存",
"send": "送信",
"saveOrSendDescription": "これをストレージ (デフォルトではダウンロードフォルダ) に保存しますか、もしくは他のアプリに送信しますか?",
"saveOnlyDescription": "これをストレージに保存しますか? (デフォルトではダウンロードフォルダに保存)",
"back": "戻る",
"createAccount": "アカウント作成",
"passwordStrength": "パスワードの強度: {passwordStrengthValue}",
@@ -348,6 +344,7 @@
"deleteCodeAuthMessage": "コードを削除するためには認証が必要です",
"showQRAuthMessage": "QR コードを表示するためには認証が必要です",
"confirmAccountDeleteTitle": "アカウントの削除に同意",
"confirmAccountDeleteMessage": "このアカウントは他の ente アプリも使用している場合はそれらに結びつけられています。\n\nすべての ente アプリであなたがアップロードしたデータは削除がスケジュールされ、あなたのアカウントは永久に削除されます。",
"androidBiometricHint": "本人を確認する",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
@@ -407,16 +404,5 @@
"signOutOtherDevices": "他のデバイスからサインアウトする",
"doNotSignOut": "サインアウトしない",
"hearUsWhereTitle": "Ente についてどのようにお聞きになりましたか?(任意)",
"hearUsExplanation": "私たちはアプリのインストールを追跡していません。私たちをお知りになった場所を教えてください!",
"recoveryKeySaved": "リカバリキーをダウンロードフォルダに保存しました!",
"waitingForBrowserRequest": "ブラウザのリクエストを待っています...",
"waitingForVerification": "認証を待っています...",
"passkey": "パスキー",
"developerSettingsWarning": "開発者向け設定を変更してもよろしいですか?",
"developerSettings": "開発者向け設定",
"serverEndpoint": "サーバーエンドポイント",
"invalidEndpoint": "無効なエンドポイントです",
"invalidEndpointMessage": "入力されたエンドポイントは無効です。有効なエンドポイントを入力して再試行してください。",
"endpointUpdatedMessage": "エンドポイントの更新に成功しました",
"customEndpoint": "{endpoint} に接続しました"
"hearUsExplanation": "私たちはアプリのインストールを追跡していません。私たちをお知りになった場所を教えてください!"
}

View File

@@ -74,6 +74,7 @@
"data": "მონაცემები",
"importCodes": "კოდების იმპორტირება",
"importTypePlainText": "სტანდარტული ტექსტი",
"importTypeEnteEncrypted": "ente დაშიფრული ექსპორტი",
"passwordForDecryptingExport": "ექსპორტის გაშიფრვის პაროლი",
"passwordEmptyError": "პაროლის ველი არ შეიძლება იყოს ცარიელი",
"emailVerificationToggle": "ელექტრონული ფოსტის ვერიფიკაცია",

View File

@@ -1 +0,0 @@
{}

View File

@@ -78,7 +78,7 @@
"data": "Gegevens",
"importCodes": "Codes importeren",
"importTypePlainText": "Kale tekst",
"importTypeEnteEncrypted": "Ente versleutelde export",
"importTypeEnteEncrypted": "ente versleutelde export",
"passwordForDecryptingExport": "Wachtwoord voor het decoderen van export",
"passwordEmptyError": "Wachtwoord kan niet leeg zijn",
"importFromApp": "Importeer codes van {appName}",
@@ -115,15 +115,15 @@
"copied": "Gekopieerd",
"pleaseTryAgain": "Probeer het nog eens",
"existingUser": "Bestaande gebruiker",
"newUser": "Nieuw bij Ente",
"newUser": "Nieuw bij ente",
"delete": "Verwijderen",
"enterYourPasswordHint": "Voer je wachtwoord in",
"forgotPassword": "Wachtwoord vergeten",
"oops": "Oeps",
"suggestFeatures": "Features voorstellen",
"faq": "Veelgestelde vragen",
"faq_q_1": "Hoe veilig is Ente Auth?",
"faq_a_1": "Alle codes in Auth zijn versleuteld opgeslagen met end-to-end encryptie. Dit betekent dat alleen jij toegang hebt tot je codes. Onze apps zijn open source en onze cryptografie is extern gecontroleerd.",
"faq_q_1": "Hoe veilig is ente Auth?",
"faq_a_1": "Alle codes in ente zijn versleuteld opgeslagen met end-to-end encryptie. Dit betekent dat alleen jij toegang hebt tot je codes. Onze apps zijn open source en onze cryptografie is extern gecontroleerd.",
"faq_q_2": "Kan ik toegang krijgen tot mijn codes op desktop?",
"faq_a_2": "U heeft toegang tot uw codes op het web @ auth.ente.io.",
"faq_q_3": "Hoe kan ik codes verwijderen?",
@@ -144,8 +144,6 @@
"enterCodeHint": "Voer de 6-cijferige code van je verificatie-app in",
"lostDeviceTitle": "Apparaat verloren?",
"twoFactorAuthTitle": "Tweestapsverificatie",
"passkeyAuthTitle": "Passkey verificatie",
"verifyPasskey": "Bevestig passkey",
"recoverAccount": "Account herstellen",
"enterRecoveryKeyHint": "Voer je herstelsleutel in",
"recover": "Herstellen",
@@ -199,10 +197,6 @@
"recoveryKeySaveDescription": "We slaan deze code niet op, bewaar deze code met 24 woorden op een veilige plaats.",
"doThisLater": "Doe dit later",
"saveKey": "Sleutel opslaan",
"save": "Opslaan",
"send": "Verzenden",
"saveOrSendDescription": "Wil je dit opslaan naar je opslagruimte (Downloads map) of naar andere apps versturen?",
"saveOnlyDescription": "Wil je dit opslaan naar je opslagruimte (Downloads map)?",
"back": "Terug",
"createAccount": "Account aanmaken",
"passwordStrength": "Wachtwoord sterkte: {passwordStrengthValue}",
@@ -350,7 +344,7 @@
"deleteCodeAuthMessage": "Authenticeren om code te verwijderen",
"showQRAuthMessage": "Authenticeren om QR-code te tonen",
"confirmAccountDeleteTitle": "Account verwijderen bevestigen",
"confirmAccountDeleteMessage": "Dit account is gekoppeld aan andere Ente apps, als je er gebruik van maakt.\n\nJe geüploade gegevens worden in alle Ente apps gepland voor verwijdering, en je account wordt permanent verwijderd voor alle Ente diensten.",
"confirmAccountDeleteMessage": "Dit account is gekoppeld aan andere ente apps, als je er gebruik van maakt.\n\nJe geüploade gegevens worden in alle ente apps gepland voor verwijdering, en je account wordt permanent verwijderd voor alle ente diensten.",
"androidBiometricHint": "Identiteit verifiëren",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
@@ -410,16 +404,5 @@
"signOutOtherDevices": "Afmelden bij andere apparaten",
"doNotSignOut": "Niet uitloggen",
"hearUsWhereTitle": "Hoe hoorde je over Ente? (optioneel)",
"hearUsExplanation": "Wij gebruiken geen tracking. Het zou helpen als je ons vertelt waar je ons gevonden hebt!",
"recoveryKeySaved": "Herstelsleutel opgeslagen in de Downloads map!",
"waitingForBrowserRequest": "Wachten op browserverzoek...",
"waitingForVerification": "Wachten op verificatie...",
"passkey": "Passkey",
"developerSettingsWarning": "Weet u zeker dat u de ontwikkelaarsinstellingen wilt wijzigen?",
"developerSettings": "Ontwikkelaarsinstellingen",
"serverEndpoint": "Server eindpunt",
"invalidEndpoint": "Ongeldig eindpunt",
"invalidEndpointMessage": "Sorry, het eindpunt dat u hebt ingevoerd is ongeldig. Voer een geldig eindpunt in en probeer het opnieuw.",
"endpointUpdatedMessage": "Eindpunt met succes bijgewerkt",
"customEndpoint": "Verbonden met {endpoint}"
"hearUsExplanation": "Wij gebruiken geen tracking. Het zou helpen als je ons vertelt waar je ons gevonden hebt!"
}

View File

@@ -78,11 +78,13 @@
"data": "Dane",
"importCodes": "Importuj kody",
"importTypePlainText": "Zwykły tekst",
"importTypeEnteEncrypted": "Zaszyfrowany eksport ente",
"passwordForDecryptingExport": "Hasło do odszyfrowania eksportu",
"passwordEmptyError": "Pole hasło nie może być puste",
"importFromApp": "Importuj kody z {appName}",
"importGoogleAuthGuide": "Wyeksportuj twoje konta z Google Authenticator do kodu QR używając opcji \"Przenieś konta\". Potem używając innego urządzenia, zeskanuj kod QR.",
"importSelectJsonFile": "Wybierz plik JSON",
"importEnteEncGuide": "Wybierz zaszyfrowany plik JSON wyeksportowany z ente",
"importRaivoGuide": "Użyj opcji \"Eksportuj OTP do archiwum ZIP\" w Ustawieniach Raivo.\n\nWyodrębnij plik zip i zaimportuj plik JSON.",
"importAegisGuide": "Użyj opcji \"Eksportuj sejf\" w ustawieniach Aegis.\n\nJeśli twój sejf jest zaszyfrowany, musisz wprowadzić hasło sejfu, aby odszyfrować sejf.",
"exportCodes": "Eksportuj kody",
@@ -108,18 +110,22 @@
"copied": "Skopiowano",
"pleaseTryAgain": "Proszę spróbować ponownie",
"existingUser": "Istniejący użytkownik",
"newUser": "Nowy do ente",
"delete": "Usuń",
"enterYourPasswordHint": "Wprowadź swoje hasło",
"forgotPassword": "Nie pamiętam hasła",
"oops": "Ups",
"suggestFeatures": "Zaproponuj funkcje",
"faq": "Najczęściej zadawane pytania (FAQ)",
"faq_q_1": "Jak bezpieczny jest ente Auth?",
"faq_a_1": "Wszystkie kody, których tworzysz kopię zapasową za pomocą ente są przechowywane zaszyfrowane end-to-end. Oznacza to, że tylko Ty możesz uzyskać dostęp do swoich kodów. Nasze aplikacje są otwarto-źródłowe, a nasza kryptografia została poddana sprawdzeniu z zewnątrz.",
"faq_q_2": "Czy mogę uzyskać dostęp do moich kodów na komputerze?",
"faq_a_2": "Możesz uzyskać dostęp do swoich kodów na stronie auth.ente.io.",
"faq_q_3": "Jak mogę usunąć kody?",
"faq_a_3": "Możesz usunąć kod, przesuwając go w lewo.",
"faq_q_4": "Jak mogę wesprzeć ten projekt?",
"faq_a_4": "Możesz wspierać rozwój tego projektu, subskrybując do naszej aplikacji Zdjęcia na ente.io.",
"faq_q_5": "Jak mogę włączyć blokadę FaceID w ente Auth?",
"faq_a_5": "Możesz włączyć blokadę FaceID w Ustawienia → Bezpieczeństwo→ Ekran blokady.",
"somethingWentWrongMessage": "Coś poszło nie tak. Proszę, spróbuj ponownie",
"leaveFamily": "Opuść rodzinę",
@@ -332,21 +338,5 @@
"deleteCodeAuthMessage": "Uwierzytelnij, aby usunąć kod",
"showQRAuthMessage": "Uwierzytelnij, aby pokazać kod QR",
"confirmAccountDeleteTitle": "Potwierdź usunięcie konta",
"androidBiometricNotRecognized": "Nie rozpoznano. Spróbuj ponownie.",
"@androidBiometricNotRecognized": {
"description": "Message to let the user know that authentication was failed. It is used on Android side. Maximum 60 characters."
},
"androidSignInTitle": "Wymagana autoryzacja",
"@androidSignInTitle": {
"description": "Message showed as a title in a dialog which indicates the user that they need to scan biometric to continue. It is used on Android side. Maximum 60 characters."
},
"goToSettings": "Przejdź do Ustawień",
"@goToSettings": {
"description": "Message showed on a button that the user can click to go to settings pages from the current dialog. It is used on both Android and iOS side. Maximum 30 characters."
},
"noInternetConnection": "Brak połączenia z Internetem",
"pleaseCheckYourInternetConnectionAndTryAgain": "Proszę sprawdzić połączenie internetowe i spróbować ponownie.",
"hearUsWhereTitle": "Jak usłyszałeś o Ente? (opcjonalnie)",
"waitingForVerification": "Oczekiwanie na weryfikację...",
"developerSettings": "Ustawienia deweloperskie"
"confirmAccountDeleteMessage": "To konto jest połączone z innymi aplikacjami ente, jeśli ich używasz.\n\nTwoje przesłane dane, we wszystkich aplikacjach ente, zostaną zaplanowane do usunięcia, a Twoje konto zostanie trwale usunięte."
}

View File

@@ -47,9 +47,9 @@
},
"copyEmailAction": "Copiar e-mail",
"exportLogsAction": "Exportar logs",
"reportABug": "Reportar um problema",
"reportABug": "Reportar um bug",
"crashAndErrorReporting": "Reporte de erros e falhas",
"reportBug": "Reportar problema",
"reportBug": "Reportar bug",
"emailUsMessage": "Por favor, envie um e-mail para {email}",
"@emailUsMessage": {
"placeholders": {
@@ -78,12 +78,14 @@
"data": "Dados",
"importCodes": "Importar códigos",
"importTypePlainText": "Texto simples",
"importTypeEnteEncrypted": "ente Exportação criptografada",
"passwordForDecryptingExport": "Senha para descriptografar a exportação",
"passwordEmptyError": "O campo senha não pode estar vazio",
"importFromApp": "Importar códigos do {appName}",
"importGoogleAuthGuide": "Exporte suas contas do Google Authenticator para um QR code usando a opção \"Transferir contas\". Então, usando outro dispositivo, escaneie o QR code.\n\nDica: Você pode usar a câmera do seu notebook para fotografar o QR code.",
"importSelectJsonFile": "Selecione o arquivo JSON",
"importSelectAppExport": "Selecione o arquivo de exportação do aplicativo {appName}",
"importEnteEncGuide": "Selecione o arquivo JSON criptografado exportado pelo ente",
"importRaivoGuide": "Use a opção \"Exportar OTPs para arquivo Zip\" nas configurações do Raivo.\n\nExtraia o arquivo zip e importe o arquivo JSON.",
"importBitwardenGuide": "Use a opção \"Exportar cofre\" nas configurações do Bitwarden e importe o arquivo JSON não criptografado.",
"importAegisGuide": "Use a opção \"Exportar cofre\" nas Configurações do Aegis.\n\nSe o seu cofre estiver criptografado, você precisará inserir a senha do cofre para descriptografá-lo.",
@@ -113,18 +115,22 @@
"copied": "Copiado",
"pleaseTryAgain": "Por favor, tente novamente",
"existingUser": "Usuário Existente",
"newUser": "Novo no ente",
"delete": "Excluir",
"enterYourPasswordHint": "Insira sua senha",
"forgotPassword": "Esqueci a senha",
"oops": "Oops",
"suggestFeatures": "Sugerir funcionalidades",
"faq": "Perguntas frequentes",
"faq_q_1": "Quão seguro é o ente Auth?",
"faq_a_1": "Todos os códigos que você faz cópia de segurança via ente são armazenados criptografados de ponta a ponta. Isso significa que somente você pode acessar seus códigos. Nossos aplicativos são de código aberto e nossa criptografia foi auditada externamente.",
"faq_q_2": "Eu posso acessar meus códigos no computador?",
"faq_a_2": "Você pode acessar seus códigos na web em auth.ente.io.",
"faq_q_3": "Como faço para excluir códigos?",
"faq_a_3": "Você pode excluir um código deslizando para a esquerda sobre esse item.",
"faq_q_4": "Como posso apoiar este projeto?",
"faq_a_4": "Você pode apoiar o desenvolvimento deste projeto assinando nosso aplicativo de Fotos em ente.io.",
"faq_q_5": "Como posso ativar o bloqueio facial no ente Auth",
"faq_a_5": "Você pode ativar o bloqueio facial em Configurações → Segurança → Tela de bloqueio.",
"somethingWentWrongMessage": "Algo deu errado. Por favor, tente outra vez",
"leaveFamily": "Sair da família",
@@ -138,8 +144,6 @@
"enterCodeHint": "Digite o código de 6 dígitos de\nseu aplicativo autenticador",
"lostDeviceTitle": "Perdeu seu dispositivo?",
"twoFactorAuthTitle": "Autenticação de dois fatores",
"passkeyAuthTitle": "Autenticação via Chave de acesso",
"verifyPasskey": "Verificar chave de acesso",
"recoverAccount": "Recuperar conta",
"enterRecoveryKeyHint": "Digite sua chave de recuperação",
"recover": "Recuperar",
@@ -157,7 +161,7 @@
"invalidEmailMessage": "Por favor, insira um endereço de e-mail válido.",
"deleteAccount": "Excluir conta",
"deleteAccountQuery": "Sentiremos muito por vê-lo partir. Você está enfrentando algum problema?",
"yesSendFeedbackAction": "Sim, enviar comentário",
"yesSendFeedbackAction": "Sim, enviar feedback",
"noDeleteAccountAction": "Não, excluir conta",
"initiateAccountDeleteTitle": "Por favor, autentique-se para iniciar a exclusão de conta",
"sendEmail": "Enviar e-mail",
@@ -193,10 +197,6 @@
"recoveryKeySaveDescription": "Não armazenamos essa chave, por favor, salve essa chave de 24 palavras em um lugar seguro.",
"doThisLater": "Fazer isso mais tarde",
"saveKey": "Salvar chave",
"save": "Salvar",
"send": "Enviar",
"saveOrSendDescription": "Você deseja salvar isso no seu armazenamento (pasta de downloads por padrão) ou enviá-lo para outros aplicativos?",
"saveOnlyDescription": "Você deseja salvar isto no seu armazenamento (pasta de downloads por padrão)?",
"back": "Voltar",
"createAccount": "Criar uma conta",
"passwordStrength": "Força da senha: {passwordStrengthValue}",
@@ -344,6 +344,7 @@
"deleteCodeAuthMessage": "Autenticar para excluir o código",
"showQRAuthMessage": "Autenticar para mostrar o QR code",
"confirmAccountDeleteTitle": "Confirmar exclusão de conta",
"confirmAccountDeleteMessage": "Esta conta está vinculada a outros aplicativos ente, se você usa algum.\n\nSeus dados enviados, em todos os aplicativos ente, serão agendados para exclusão, e sua conta será excluída permanentemente.",
"androidBiometricHint": "Verificar identidade",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
@@ -403,16 +404,5 @@
"signOutOtherDevices": "Terminar sessão em outros dispositivos",
"doNotSignOut": "Não encerrar sessão",
"hearUsWhereTitle": "Como você ouviu sobre o Ente? (opcional)",
"hearUsExplanation": "Não rastreamos instalações do aplicativo. Seria útil se você nos contasse onde nos encontrou!",
"recoveryKeySaved": "Chave de recuperação salva na pasta Downloads!",
"waitingForBrowserRequest": "Aguardando solicitação do navegador...",
"waitingForVerification": "Esperando por verificação...",
"passkey": "Chave de acesso",
"developerSettingsWarning": "Tem certeza de que deseja modificar as configurações de Desenvolvedor?",
"developerSettings": "Configurações de desenvolvedor",
"serverEndpoint": "Endpoint do servidor",
"invalidEndpoint": "Endpoint inválido",
"invalidEndpointMessage": "Desculpe, o endpoint que você inseriu é inválido. Por favor, insira um endpoint válido e tente novamente.",
"endpointUpdatedMessage": "Endpoint atualizado com sucesso",
"customEndpoint": "Conectado a {endpoint}"
"hearUsExplanation": "Não rastreamos instalações do aplicativo. Seria útil se você nos contasse onde nos encontrou!"
}

View File

@@ -78,12 +78,14 @@
"data": "Данные",
"importCodes": "Импортировать коды",
"importTypePlainText": "Обычный текст",
"importTypeEnteEncrypted": "ente Зашифрованный экспорт",
"passwordForDecryptingExport": "Пароль для расшифровки экспорта",
"passwordEmptyError": "Пароль не может быть пустым",
"importFromApp": "Импорт кодов из {appName}",
"importGoogleAuthGuide": "Экспортируйте учетные записи из Google Authenticator в QR-код, используя опцию «Перенести учетные записи». Затем с помощью другого устройства отсканируйте QR-код.\n\nСовет: Чтобы сфотографировать QR-код, можно воспользоваться веб-камерой ноутбука.",
"importSelectJsonFile": "Выбрать JSON-файл",
"importSelectAppExport": "Выбрать файл экспорта {appName}",
"importEnteEncGuide": "Выберите зашифрованный JSON-файл, экспортированный из ente",
"importRaivoGuide": "Используйте опцию «Export OTPs to Zip archive» в настройках Raivo.\n\nРаспакуйте zip-архив и импортируйте JSON-файл.",
"importBitwardenGuide": "Используйте опцию \"Экспортировать хранилище\" в Bitwarden Tools и импортируйте незашифрованный JSON файл.",
"importAegisGuide": "Используйте опцию «Экспортировать хранилище» в настройках Aegis.\n\nЕсли ваше хранилище зашифровано, то для его расшифровки потребуется ввести пароль хранилища.",
@@ -111,18 +113,22 @@
"copied": "Скопировано",
"pleaseTryAgain": "Пожалуйста, попробуйте ещё раз",
"existingUser": "Существующий пользователь",
"newUser": "Новый аккаунт",
"delete": "Удалить",
"enterYourPasswordHint": "Введите пароль",
"forgotPassword": "Забыл пароль",
"oops": "Ой",
"suggestFeatures": "Предложить идеи",
"faq": "FAQ",
"faq_q_1": "Насколько безопасен ente Auth?",
"faq_a_1": "Все коды, которые вы резервируете с помощью ente, хранятся в зашифрованном виде. Это означает, что только вы можете получить доступ к своим кодам. Наши приложения имеют открытый исходный код, а наша криптография прошла внешний аудит.",
"faq_q_2": "Могу ли я получить доступ к моим кодам на компьютере?",
"faq_a_2": "Вы можете получить доступ к своим кодам на сайте @ auth.ente.io.",
"faq_q_3": "Как я могу удалить коды?",
"faq_a_3": "Вы можете удалить код, проведя пальцем влево по этому элементу.",
"faq_q_4": "Как я могу поддержать этот проект?",
"faq_a_4": "Вы можете поддержать развитие этого проекта, подписавшись на наше приложение Photos @ ente.io.",
"faq_q_5": "Как мне включить блокировку FaceID в ente Auth?",
"faq_a_5": "Вы можете включить блокировку FaceID в Настройки → Безопасность → Экран блокировки.",
"somethingWentWrongMessage": "Что-то пошло не так. Попробуйте еще раз",
"leaveFamily": "Покинуть семью",
@@ -336,6 +342,7 @@
"deleteCodeAuthMessage": "Аутентификация для удаления кода",
"showQRAuthMessage": "Аутентификация для отображения QR-кода",
"confirmAccountDeleteTitle": "Подтвердить удаление аккаунта",
"confirmAccountDeleteMessage": "Эта учетная запись связана с другими приложениями ente, если вы ими пользуетесь.\n\nЗагруженные вами данные во всех приложениях ente будут запланированы к удалению, а ваша учетная запись будет удалена без возможности восстановления.",
"androidBiometricHint": "Подтвердите личность",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."

View File

@@ -73,6 +73,7 @@
"oops": "Hoppsan",
"suggestFeatures": "Föreslå funktionalitet",
"faq": "FAQ",
"faq_q_1": "Hur säkert är ente Auth?",
"scan": "Skanna",
"twoFactorAuthTitle": "Tvåfaktorsautentisering",
"enterRecoveryKeyHint": "Ange din återställningsnyckel",
@@ -104,7 +105,6 @@
"recoveryKeyCopiedToClipboard": "Återställningsnyckel kopierad till urklipp",
"recoveryKeyOnForgotPassword": "Om du glömmer ditt lösenord är det enda sättet du kan återställa dina data med denna nyckel.",
"saveKey": "Spara nyckel",
"save": "Spara",
"back": "Tillbaka",
"createAccount": "Skapa konto",
"password": "Lösenord",
@@ -131,16 +131,6 @@
"about": "Om",
"terms": "Villkor",
"warning": "Varning",
"importSuccessDesc": "Du har importerat {count} koder!",
"@importSuccessDesc": {
"placeholders": {
"count": {
"description": "The number of codes imported",
"type": "int",
"example": "1"
}
}
},
"pendingSyncs": "Varning",
"activeSessions": "Aktiva sessioner",
"enterPassword": "Ange lösenord",
@@ -153,7 +143,5 @@
"iOSOkButton": "OK",
"@iOSOkButton": {
"description": "Message showed on a button that the user can click to leave the current dialog. It is used on iOS side. Maximum 30 characters."
},
"noInternetConnection": "Ingen internetanslutning",
"pleaseCheckYourInternetConnectionAndTryAgain": "Kontrollera din internetanslutning och försök igen."
}
}

View File

@@ -78,12 +78,14 @@
"data": "ሓበሬታ",
"importCodes": "ኮድ ኣእቱ",
"importTypePlainText": "Plain text",
"importTypeEnteEncrypted": "ente Encrypted export",
"passwordForDecryptingExport": "Password to decrypt export",
"passwordEmptyError": "Password can not be empty",
"importFromApp": "Import codes from {appName}",
"importGoogleAuthGuide": "Export your accounts from Google Authenticator to a QR code using the \"Transfer Accounts\" option. Then using another device, scan the QR code.\n\nTip: You can use your laptop's webcam to take a picture of the QR code.",
"importSelectJsonFile": "Select JSON file",
"importSelectAppExport": "Select {appName} export file",
"importEnteEncGuide": "Select the encrypted JSON file exported from ente",
"importRaivoGuide": "Use the \"Export OTPs to Zip archive\" option in Raivo's Settings.\n\nExtract the zip file and import the JSON file.",
"importBitwardenGuide": "Use the \"Export vault\" option within Bitwarden Tools and import the unencrypted JSON file.",
"importAegisGuide": "Use the \"Export the vault\" option in Aegis's Settings.\n\nIf your vault is encrypted, you will need to enter vault password to decrypt the vault.",
@@ -112,18 +114,22 @@
"copied": "Copied",
"pleaseTryAgain": "Please try again",
"existingUser": "Existing User",
"newUser": "New to ente",
"delete": "Delete",
"enterYourPasswordHint": "Enter your password",
"forgotPassword": "Forgot password",
"oops": "ዉዉኡ",
"suggestFeatures": "Suggest features",
"faq": "FAQ",
"faq_q_1": "How secure is ente Auth?",
"faq_a_1": "All codes you backup via ente is stored end-to-end encrypted. This means only you can access your codes. Our apps are open source and our cryptography has been externally audited.",
"faq_q_2": "Can I access my codes on desktop?",
"faq_a_2": "You can access your codes on the web @ auth.ente.io.",
"faq_q_3": "How can I delete codes?",
"faq_a_3": "You can delete a code by swiping left on that item.",
"faq_q_4": "How can I support this project?",
"faq_a_4": "You can support the development of this project by subscribing to our Photos app @ ente.io.",
"faq_q_5": "How can I enable FaceID lock in ente Auth",
"faq_a_5": "You can enable FaceID lock under Settings → Security → Lockscreen.",
"somethingWentWrongMessage": "Something went wrong, please try again",
"leaveFamily": "Leave family",
@@ -337,6 +343,7 @@
"deleteCodeAuthMessage": "Authenticate to delete code",
"showQRAuthMessage": "Authenticate to show QR code",
"confirmAccountDeleteTitle": "Confirm account deletion",
"confirmAccountDeleteMessage": "This account is linked to other ente apps, if you use any.\n\nYour uploaded data, across all ente apps, will be scheduled for deletion, and your account will be permanently deleted.",
"androidBiometricHint": "Verify identity",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."

View File

@@ -78,12 +78,14 @@
"data": "Veri",
"importCodes": "Kodu içe aktar",
"importTypePlainText": "Salt metin",
"importTypeEnteEncrypted": "ente Şifreli dışa aktarma",
"passwordForDecryptingExport": "Dışa aktarımın şifresini çözmek için parola",
"passwordEmptyError": "Şifre boş olamaz",
"importFromApp": "Kodları {appName} uygulamasından içe aktarın",
"importGoogleAuthGuide": "\"Hesapları Aktar\" seçeneğini kullanarak hesaplarınızı Google Authenticator'dan bir QR koduna aktarın. Ardından başka bir cihaz kullanarak QR kodunu tarayın.\n\nİpucu: QR kodunun fotoğrafını çekmek için dizüstü bilgisayarınızın kamerasını kullanabilirsiniz.",
"importSelectJsonFile": "JSON dosyasını seçin",
"importSelectAppExport": "{appName} dışarı aktarma dosyasını seçin",
"importEnteEncGuide": "Ente'den dışa aktarılan şifrelenmiş JSON dosyasını seçin",
"importRaivoGuide": "Raivo'nun ayarlarında \"OTP'leri Zip arşivine aktar\" seçeneğini kullanın.\n\nZip dosyasını çıkarın ve JSON dosyasını içe aktarın.",
"importBitwardenGuide": "Bitwarden Tools içindeki \"Kasayı dışa aktar\" seçeneğini kullanın ve şifrelenmemiş JSON dosyasını içe aktarın.",
"importAegisGuide": "Aegis'in Ayarlarında \"Kasayı dışa aktar\" seçeneğini kullanın.\n\nKasanız şifrelenmişse, kasanın şifresini çözmek için kasa parolasını girmeniz gerekecektir.",
@@ -113,18 +115,22 @@
"copied": "Kopyalandı",
"pleaseTryAgain": "Lütfen tekrar deneyin",
"existingUser": "Mevcut kullanıcı",
"newUser": "Yeni ente kullanıcısı",
"delete": "Sil",
"enterYourPasswordHint": "Parolanızı girin",
"forgotPassword": "Şifremi unuttum",
"oops": "Hay aksi",
"suggestFeatures": "Özellik önerin",
"faq": "SSS",
"faq_q_1": "Ente Auth ne kadar güvenli?",
"faq_a_1": "Ente aracılığıyla yedeklediğiniz tüm kodlar uçtan uca şifrelenmiş olarak saklanır. Bu, kodlarınıza yalnızca sizin erişebileceğiniz anlamına gelir. Uygulamalarımız açık kaynaklıdır ve kriptografimiz harici olarak denetlenmiştir.",
"faq_q_2": "Kodlarıma masaüstünden erişebilir miyim?",
"faq_a_2": "Kodlarınıza internet üzerinden @ auth.ente.io adresinden erişebilirsiniz.",
"faq_q_3": "Kodları nasıl silebilirim?",
"faq_a_3": "Bir kodu, o öğenin üzerinde sola kaydırarak silebilirsiniz.",
"faq_q_4": "Bu projeye nasıl destek olabilirim?",
"faq_a_4": "Fotoğraflar uygulamamıza @ ente.io abone olarak bu projenin geliştirilmesine destek olabilirsiniz.",
"faq_q_5": "FaceID kilidini ente Auth'ta nasıl etkinleştirebilirim",
"faq_a_5": "FaceID kilidini Ayarlar → Güvenlik → Kilit Ekranı altında etkinleştirebilirsiniz.",
"somethingWentWrongMessage": "Bir şeyler ters gitti, lütfen tekrar deneyin",
"leaveFamily": "Aile planından ayrıl",
@@ -338,6 +344,7 @@
"deleteCodeAuthMessage": "Kodu silmek için doğrulama yapın",
"showQRAuthMessage": "QR kodunu göstermek için doğrulama yapın",
"confirmAccountDeleteTitle": "Hesap silme işlemini onayla",
"confirmAccountDeleteMessage": "Bu hesap, eğer kullanıyorsanız, diğer ente uygulamalarıyla bağlantılıdır.\n\nTüm ente uygulamalarında yüklediğiniz veriler silinmek üzere programlanacak ve hesabınız kalıcı olarak silinecektir.",
"androidBiometricHint": "Kimliği doğrula",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."

View File

@@ -78,12 +78,14 @@
"data": "Dữ liệu",
"importCodes": "Nhập mã",
"importTypePlainText": "Văn bản thuần",
"importTypeEnteEncrypted": "xuất ente đã mã hóa",
"passwordForDecryptingExport": "Mật khẩu để giải mã xuất",
"passwordEmptyError": "Mật khẩu không thể để trống",
"importFromApp": "Nhập mã từ {appName}",
"importGoogleAuthGuide": "Xuất dữ liệu tài khoản của bạn từ Google Authenticator sang mã QR bằng tùy chọn \"Chuyển tài khoản\". Sau đó dùng thiết bị khác quét mã QR.",
"importSelectJsonFile": "Chọn tệp JSON",
"importSelectAppExport": "Chọn {appName} tệp dữ liệu xuất",
"importEnteEncGuide": "Chọn tệp JSON được mã hóa đã xuất từ ente",
"importRaivoGuide": "Sử dụng tùy chọn \"Xuất OTP sang lưu trữ Zip\" trong cài đặt của Raivo.",
"importBitwardenGuide": "Sử dụng tùy chọn \"Xuất vault\" trong công cụ Bitwarden và nhập tệp JSON không được mã hóa.",
"importAegisGuide": "Nếu vault của bạn được mã hóa, bạn sẽ cần nhập mật khẩu vault để giải mã vault.",
@@ -112,18 +114,22 @@
"copied": "\u001dĐã sao chép",
"pleaseTryAgain": "Vui lòng thử lại",
"existingUser": "Người dùng hiện tại",
"newUser": "Mới tham gia ente",
"delete": "Xóa",
"enterYourPasswordHint": "Nhập mật khẩu của bạn",
"forgotPassword": "Quên mật khẩu",
"oops": "Rất tiếc",
"suggestFeatures": "Tính năng đề nghị",
"faq": "Câu hỏi thường gặp",
"faq_q_1": "Mức độ an toàn của ente Auth như thế nào?",
"faq_a_1": "Tất cả các mã bạn sao lưu qua ente đều được lưu trữ dưới dạng mã hóa đầu cuối. Điều này có nghĩa là chỉ bạn mới có thể truy cập mã của mình. Ứng dụng của chúng tôi là nguồn mở và mật mã của chúng tôi đã được kiểm toán độc lập.",
"faq_q_2": "Tôi có thể truy cập mã của mình trên máy tính không?",
"faq_a_2": "Bạn có thể truy cập mã của mình trên web @ auth.ente.io.",
"faq_q_3": "Làm cách nào để xóa mã?",
"faq_a_3": "Bạn có thể xóa mã bằng cách vuốt sang trái vào mục đó.",
"faq_q_4": "Tôi có thể hỗ trợ dự án này như thế nào?",
"faq_a_4": "Bạn có thể hỗ trợ sự phát triển của dự án này bằng cách đăng ký ứng dụng Ảnh @ ente.io của chúng tôi.",
"faq_q_5": "Tôi có thể bật khóa FaceID trong ente Auth như thế nào",
"faq_a_5": "Bạn có thể bật khóa FaceID trong Cài đặt → Bảo mật → Màn hình khóa.",
"somethingWentWrongMessage": "Phát hiện có lỗi, xin thử lại",
"leaveFamily": "Rời khỏi gia đình",
@@ -337,6 +343,7 @@
"deleteCodeAuthMessage": "Xác minh để xóa mã",
"showQRAuthMessage": "Xác minh để hiển thị mã QR",
"confirmAccountDeleteTitle": "Xác nhận xóa tài khoản",
"confirmAccountDeleteMessage": "Tài khoản này được liên kết với các ứng dụng ente khác, nếu bạn sử dụng bất kỳ ứng dụng nào.\n\nDữ liệu đã tải lên của bạn, trên tất cả các ứng dụng, sẽ bị lên lịch xóa và tài khoản của bạn sẽ bị xóa vĩnh viễn.",
"androidBiometricHint": "Xác định danh tính",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."

View File

@@ -78,14 +78,14 @@
"data": "数据",
"importCodes": "导入代码",
"importTypePlainText": "纯文本",
"importTypeEnteEncrypted": "Ente 加密导出",
"importTypeEnteEncrypted": "ente 加密导出",
"passwordForDecryptingExport": "用来解密导出的密码",
"passwordEmptyError": "密码不能为空",
"importFromApp": "从 {appName} 导入代码",
"importGoogleAuthGuide": "使用“转移帐户”选项将您的帐户从 Google 身份验证器导出到二维码。然后使用另一台设备扫描二维码。\n\n提示您可以使用笔记本电脑的网络摄像头拍摄二维码的照片。",
"importSelectJsonFile": "选择 JSON 文件",
"importSelectAppExport": "选择 {appName} 的导出文件",
"importEnteEncGuide": "选择从 Ente 导出的 JSON 加密文件",
"importEnteEncGuide": "选择从ente导出的加密JSON文件",
"importRaivoGuide": "使用 Raivo 设置中的“将 OTP 导出到 Zip 存档”选项。\n\n解压 zip 文件并导入 JSON 文件。",
"importBitwardenGuide": "使用 Bitwarden 工具中的“导出保管库”选项并导入未加密的 JSON 文件。",
"importAegisGuide": "在Aegis的设置中使用\"导出密码库\"选项。\n\n如果您的密码库已加密您需要输入密码才能解密密码库。",
@@ -115,22 +115,22 @@
"copied": "已复制",
"pleaseTryAgain": "请重试",
"existingUser": "已注册用户",
"newUser": "初来 Ente",
"newUser": "刚来到ente",
"delete": "删除",
"enterYourPasswordHint": "输入您的密码",
"forgotPassword": "忘记密码",
"oops": "哎呀",
"suggestFeatures": "建议新功能",
"faq": "常见问题",
"faq_q_1": "Auth 的安全如何?",
"faq_a_1": "您通过 Auth 备份的所有代码均以端到端加密方式存储。这意味着只有您可以访问您的代码。我们的应用程序是开源的并且我们的加密技术已经过外部审计。",
"faq_q_1": "ente Auth的安全程度如何?",
"faq_a_1": "您通过 ente 备份的所有代码均以端到端加密方式存储。这意味着只有您可以访问您的代码。 我们的应用程序是开源的我们的加密技术已经过外部审计。",
"faq_q_2": "我可以在桌面上访问我的代码吗?",
"faq_a_2": "您可以在 web @auth.ente.io 上访问您的代码。",
"faq_q_3": "我如何删除代码?",
"faq_a_3": "您可以通过向左滑动该项目来删除该代码。",
"faq_q_4": "我该如何支持该项目?",
"faq_a_4": "您可以通过订阅我们的照片应用程序@ente.io来支持该项目的开发。",
"faq_q_5": "如何启用 Auth 中的面容 ID 锁",
"faq_q_5": "如何在 ente Auth 中启用 FaceID 锁",
"faq_a_5": "您可以在“设置”→“安全”→“锁屏”下启用 FaceID 锁定。",
"somethingWentWrongMessage": "出了点问题,请重试",
"leaveFamily": "离开家庭",
@@ -143,9 +143,8 @@
"verifyEmail": "验证电子邮件",
"enterCodeHint": "从你的身份验证器应用中\n输入6位数字代码",
"lostDeviceTitle": "丢失了设备吗?",
"twoFactorAuthTitle": "双认证",
"twoFactorAuthTitle": "双因素认证",
"passkeyAuthTitle": "通行密钥认证",
"verifyPasskey": "验证通行密钥",
"recoverAccount": "恢复账户",
"enterRecoveryKeyHint": "输入您的恢复密钥",
"recover": "恢复",
@@ -199,10 +198,6 @@
"recoveryKeySaveDescription": "我们不会存储此密钥请将此24个单词密钥保存在一个安全的地方。",
"doThisLater": "稍后再做",
"saveKey": "保存密钥",
"save": "保存",
"send": "发送",
"saveOrSendDescription": "您想将其保存到您的内置存储(默认情况下为“下载”文件夹)还是将其发送到其他应用程序?",
"saveOnlyDescription": "您想将其保存到您的内置存储中(默认情况下为“下载”文件夹)吗?",
"back": "返回",
"createAccount": "创建账户",
"passwordStrength": "密码强度: {passwordStrengthValue}",
@@ -325,7 +320,7 @@
"emailChangedTo": "电子邮件已更改为 {newEmail}",
"authenticationFailedPleaseTryAgain": "认证失败,请重试",
"authenticationSuccessful": "认证成功!",
"twofactorAuthenticationSuccessfullyReset": "双重认证已成功重置",
"twofactorAuthenticationSuccessfullyReset": "双因素身份验证已成功重置",
"incorrectRecoveryKey": "恢复密钥不正确",
"theRecoveryKeyYouEnteredIsIncorrect": "您输入的恢复密钥不正确",
"enterPassword": "输入密码",
@@ -350,7 +345,7 @@
"deleteCodeAuthMessage": "删除代码需要身份验证",
"showQRAuthMessage": "显示QR码需要身份验证",
"confirmAccountDeleteTitle": "确认删除账户",
"confirmAccountDeleteMessage": "如果您使用其他 Ente 应用程序,该账户将会与其他应用程序链接。\n\n在所有 Ente 应用程序中,您上传的数据将被安排用于删除,并且您的账户将被永久删除。",
"confirmAccountDeleteMessage": "该账户已链接到其他ente旗下的应用程序如果您使用任何相关的应用程序。\n\n在所有ente旗下应用程序中上传的数据将被安排删除,并且您的账户将被永久删除。",
"androidBiometricHint": "验证身份",
"@androidBiometricHint": {
"description": "Hint message advising the user how to authenticate with biometrics. It is used on Android side. Maximum 60 characters."
@@ -411,15 +406,7 @@
"doNotSignOut": "不要退登",
"hearUsWhereTitle": "您是如何知道Ente的 (可选的)",
"hearUsExplanation": "我们不跟踪应用程序安装情况。如果您告诉我们您是在哪里找到我们的,将会有所帮助!",
"recoveryKeySaved": "恢复密钥已保存在下载文件夹中!",
"waitingForBrowserRequest": "正在等待浏览器请求...",
"waitingForVerification": "等待验证...",
"passkey": "通行密钥",
"developerSettingsWarning": "您确定要修改开发者设置吗?",
"developerSettings": "开发者设置",
"serverEndpoint": "服务器端点",
"invalidEndpoint": "端点无效",
"invalidEndpointMessage": "抱歉,您输入的端点无效。请输入有效的端点,然后重试。",
"endpointUpdatedMessage": "端点更新成功",
"customEndpoint": "已连接至 {endpoint}"
"launchPasskeyUrlAgain": "再次启动 通行密钥 URL",
"passkey": "通行密钥"
}

View File

@@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:io';
import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:computer/computer.dart';
import "package:ente_auth/app/view/app.dart";
import 'package:ente_auth/core/configuration.dart';
import 'package:ente_auth/core/constants.dart';
@@ -16,14 +17,11 @@ import 'package:ente_auth/services/preference_service.dart';
import 'package:ente_auth/services/update_service.dart';
import 'package:ente_auth/services/user_remote_flag_service.dart';
import 'package:ente_auth/services/user_service.dart';
import 'package:ente_auth/services/window_listener_service.dart';
import 'package:ente_auth/store/code_store.dart';
import 'package:ente_auth/ui/tools/app_lock.dart';
import 'package:ente_auth/ui/tools/lock_screen.dart';
import 'package:ente_auth/ui/utils/icon_utils.dart';
import 'package:ente_auth/utils/platform_util.dart';
import 'package:ente_auth/utils/window_protocol_handler.dart';
import 'package:ente_crypto_dart/ente_crypto_dart.dart';
import 'package:ente_auth/utils/crypto_util.dart';
import 'package:flutter/foundation.dart';
import "package:flutter/material.dart";
import 'package:flutter/scheduler.dart';
@@ -31,52 +29,11 @@ import 'package:flutter_displaymode/flutter_displaymode.dart';
import 'package:logging/logging.dart';
import 'package:path_provider/path_provider.dart';
import 'package:privacy_screen/privacy_screen.dart';
import 'package:tray_manager/tray_manager.dart';
import 'package:window_manager/window_manager.dart';
final _logger = Logger("main");
Future<void> initSystemTray() async {
String path = Platform.isWindows
? 'assets/icons/auth-icon.ico'
: 'assets/icons/auth-icon.png';
await trayManager.setIcon(path);
Menu menu = Menu(
items: [
MenuItem(
key: 'hide_window',
label: 'Hide Window',
),
MenuItem(
key: 'show_window',
label: 'Show Window',
),
MenuItem.separator(),
MenuItem(
key: 'exit_app',
label: 'Exit App',
),
],
);
await trayManager.setContextMenu(menu);
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
initSystemTray().ignore();
if (PlatformUtil.isDesktop()) {
await windowManager.ensureInitialized();
await WindowListenerService.instance.init();
WindowOptions windowOptions = WindowOptions(
size: WindowListenerService.instance.getWindowSize(),
);
await windowManager.waitUntilReadyToShow(windowOptions, () async {
await windowManager.show();
await windowManager.focus();
});
}
await _runInForeground();
await _setupPrivacyScreen();
if (Platform.isAndroid) {
@@ -113,14 +70,10 @@ ThemeMode _themeMode(AdaptiveThemeMode? savedThemeMode) {
}
Future _runWithLogs(Function() function, {String prefix = ""}) async {
String dir = "";
try {
dir = "${(await getApplicationSupportDirectory()).path}/logs";
} catch (_) {}
await SuperLogging.main(
LogConfig(
body: function,
logDirPath: dir,
logDirPath: (await getApplicationSupportDirectory()).path + "/logs",
maxLogFiles: 5,
sentryDsn: sentryDSN,
enableInDebugMode: true,
@@ -129,19 +82,10 @@ Future _runWithLogs(Function() function, {String prefix = ""}) async {
);
}
void _registerWindowsProtocol() {
const kWindowsScheme = 'ente';
// Register our protocol only on Windows platform
if (!kIsWeb && Platform.isWindows) {
WindowsProtocolHandler()
.register(kWindowsScheme, executable: null, arguments: null);
}
}
Future<void> _init(bool bool, {String? via}) async {
_registerWindowsProtocol();
await initCryptoUtil();
// Start workers asynchronously. No need to wait for them to start
Computer.shared().turnOn(workersCount: 4, verbose: kDebugMode).ignore();
CryptoUtil.init();
await PreferenceService.instance.init();
await CodeStore.instance.init();
await Configuration.instance.init();
@@ -156,7 +100,6 @@ Future<void> _init(bool bool, {String? via}) async {
}
Future<void> _setupPrivacyScreen() async {
if (!PlatformUtil.isMobile()) return;
final brightness =
SchedulerBinding.instance.platformDispatcher.platformBrightness;
bool isInDarkMode = brightness == Brightness.dark;

View File

@@ -57,7 +57,14 @@ class Code {
updatedAlgo,
updatedType,
updatedCounter,
"otpauth://${updatedType.name}/$updateIssuer:$updateAccount?algorithm=${updatedAlgo.name}&digits=$updatedDigits&issuer=$updateIssuer&period=$updatePeriod&secret=$updatedSecret${updatedType == Type.hotp ? "&counter=$updatedCounter" : ""}",
"otpauth://${updatedType.name}/" +
updateIssuer +
":" +
updateAccount +
"?algorithm=${updatedAlgo.name}&digits=$updatedDigits&issuer=" +
updateIssuer +
"&period=$updatePeriod&secret=" +
updatedSecret + (updatedType == Type.hotp ? "&counter=$updatedCounter" : ""),
generatedID: generatedID,
);
}
@@ -76,28 +83,35 @@ class Code {
Algorithm.sha1,
Type.totp,
0,
"otpauth://totp/$issuer:$account?algorithm=SHA1&digits=6&issuer=$issuer&period=30&secret=$secret",
"otpauth://totp/" +
issuer +
":" +
account +
"?algorithm=SHA1&digits=6&issuer=" +
issuer +
"&period=30&secret=" +
secret,
);
}
static Code fromRawData(String rawData) {
Uri uri = Uri.parse(rawData);
try {
return Code(
_getAccount(uri),
_getIssuer(uri),
_getDigits(uri),
_getPeriod(uri),
getSanitizedSecret(uri.queryParameters['secret']!),
_getAlgorithm(uri),
_getType(uri),
_getCounter(uri),
rawData,
);
} catch (e) {
return Code(
_getAccount(uri),
_getIssuer(uri),
_getDigits(uri),
_getPeriod(uri),
getSanitizedSecret(uri.queryParameters['secret']!),
_getAlgorithm(uri),
_getType(uri),
_getCounter(uri),
rawData,
);
} catch(e) {
// if account name contains # without encoding,
// rest of the url are treated as url fragment
if (rawData.contains("#")) {
if(rawData.contains("#")) {
return Code.fromRawData(rawData.replaceAll("#", '%23'));
} else {
rethrow;
@@ -127,7 +141,7 @@ class Code {
if (uri.queryParameters.containsKey("issuer")) {
String issuerName = uri.queryParameters['issuer']!;
// Handle issuer name with period
// See https://github.com/ente-io/ente/pull/77
// See https://github.com/ente-io/auth/pull/77
if (issuerName.contains("period=")) {
return issuerName.substring(0, issuerName.indexOf("period="));
}

View File

@@ -0,0 +1,9 @@
import 'dart:typed_data';
class DerivedKeyResult {
final Uint8List key;
final int memLimit;
final int opsLimit;
DerivedKeyResult(this.key, this.memLimit, this.opsLimit);
}

Some files were not shown because too many files have changed in this diff Show More