Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df0964ba70 | ||
|
|
2407552c1c | ||
|
|
cf55c48b4c | ||
|
|
2fa0f27581 | ||
|
|
56290b1df6 | ||
|
|
8d468dbc91 | ||
|
|
1a654fe748 | ||
|
|
1606b74b40 | ||
|
|
8d82851741 | ||
|
|
a6ca5697d9 | ||
|
|
e01ba961a6 | ||
|
|
a256bc9922 | ||
|
|
77632b3241 | ||
|
|
d02e02a326 | ||
|
|
7fe314a16a | ||
|
|
504fa939d2 | ||
|
|
17f5a7996a |
@@ -1,36 +1,49 @@
|
||||
# Contributing
|
||||
|
||||
Thank you for showing interest in contributing to ente Authenticator. There are a couple of ways to help
|
||||
out. This document contains some general guidelines for each type of
|
||||
contribution.
|
||||
Thank you for showing interest in contributing to ente Authenticator. There are
|
||||
a couple of ways to help out. This document contains some general guidelines for
|
||||
each type of contribution.
|
||||
|
||||
|
||||
## Translations
|
||||
[](https://crowdin.com/project/ente-authenticator-app)
|
||||
|
||||
We use [Crowdin](https://crowdin.com/project/ente-authenticator-app) to crowdsource
|
||||
translations of ente Authenticator.
|
||||
If your language is not listed for translation, feel free to [create a GitHub issue](https://github.com/ente-io/auth/issues/new?title=Request+for+New+Language+Translation&body=Language+name%3A) to have it added.
|
||||
We use [Crowdin](https://crowdin.com/project/ente-authenticator-app) to
|
||||
crowdsource translations of ente Authenticator. If your language is not listed
|
||||
for translation, feel free to [create a GitHub
|
||||
issue](https://github.com/ente-io/auth/issues/new?title=Request+for+New+Language+Translation&body=Language+name%3A)
|
||||
to have it added.
|
||||
|
||||
## Icons
|
||||
|
||||
ente Auth supports the icon pack provided by
|
||||
[simple-icons](https://github.com/simple-icons/simple-icons).
|
||||
|
||||
If you would like to add your own custom icon, please open a pull-request
|
||||
with the relevant SVG and color
|
||||
code ([example PR](https://github.com/ente-io/auth/pull/213/files)).
|
||||
If you would like to add your own custom icon, please open a pull-request with
|
||||
the relevant SVG placed within `assets/custom-icons/icons` and add the
|
||||
corresponding entry within `assets/custom-icons/_data/custom-icons.json`.
|
||||
|
||||
This JSON file contains the following attributes:
|
||||
|
||||
| Attribute | Usecase | Required |
|
||||
|---|---|---|
|
||||
| `title` | Name of the service. | Yes |
|
||||
| `slug` | If the icon's SVG file has a name different from the `title` | No |
|
||||
| `hex` | Color code for the icon | No |
|
||||
| `altNames` | If the same service goes by different names or has different instances (eg. Mastodon) | No |
|
||||
|
||||
Here is an [example PR](https://github.com/ente-io/auth/pull/213/files).
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
If you're planning on adding a new feature or making other changes, please
|
||||
discuss it with us by creating [an
|
||||
issue](https://github.com/ente-io/auth/issues/new)
|
||||
on GitHub. Discussing your idea with us first ensures that everyone is on the
|
||||
same page before you start working on your change.
|
||||
issue](https://github.com/ente-io/auth/issues/new) on GitHub. Discussing your
|
||||
idea with us first ensures that everyone is on the same page before you start
|
||||
working on your change.
|
||||
|
||||
### 💻 Setup
|
||||
### Setup
|
||||
|
||||
1. [Install Flutter v3.10.6](https://flutter.dev/docs/get-started/install)
|
||||
2. Clone this repository with `git clone git@github.com:ente-io/auth.git`
|
||||
@@ -43,9 +56,12 @@ same page before you start working on your change.
|
||||
|
||||
|
||||
#### Localization
|
||||
If the feature requires adding new strings, you can do that by following these steps:
|
||||
If the feature requires adding new strings, you can do that by following these
|
||||
steps:
|
||||
|
||||
1. Add a new entry inside [app_en.arb](https://github.com/ente-io/auth/blob/main/lib/l10n/arb/app_en.arb) (Remember to save)
|
||||
1. Add a new entry inside
|
||||
[app_en.arb](https://github.com/ente-io/auth/blob/main/lib/l10n/arb/app_en.arb)
|
||||
(Remember to save)
|
||||
2. In your dart file, add follwing import
|
||||
```dart
|
||||
import "package:ente_auth/l10n/l10n.dart";
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
"title": "Addy.io",
|
||||
"slug": "addy_io"
|
||||
},
|
||||
{
|
||||
"title": "Airtable"
|
||||
},
|
||||
{
|
||||
"title": "Anycoin Direct",
|
||||
"slug": "anycoindirect"
|
||||
@@ -43,6 +46,13 @@
|
||||
"slug": "controld",
|
||||
"hex": "5FD800"
|
||||
},
|
||||
{
|
||||
"title": "Discourse"
|
||||
},
|
||||
{
|
||||
"title": "dus.net",
|
||||
"slug": "dusnet"
|
||||
},
|
||||
{
|
||||
"title": "ente",
|
||||
"hex": "1DB954"
|
||||
@@ -65,6 +75,9 @@
|
||||
{
|
||||
"title": "ING"
|
||||
},
|
||||
{
|
||||
"title": "INWX"
|
||||
},
|
||||
{
|
||||
"title": "Instagram"
|
||||
},
|
||||
@@ -91,9 +104,9 @@
|
||||
"title": "KuCoin",
|
||||
"hex": "01BC8D"
|
||||
},
|
||||
{
|
||||
{
|
||||
"title": "La Poste",
|
||||
"slug": "laposte"
|
||||
"slug": "laposte"
|
||||
},
|
||||
{
|
||||
"title": "Mastodon",
|
||||
@@ -170,9 +183,15 @@
|
||||
"title": "Revolt",
|
||||
"hex": "858585"
|
||||
},
|
||||
{
|
||||
"title": "service-bw"
|
||||
},
|
||||
{
|
||||
"title": "SimpleLogin"
|
||||
},
|
||||
{
|
||||
"title": "Sipgate"
|
||||
},
|
||||
{
|
||||
"title": "Snapchat"
|
||||
},
|
||||
|
||||
1
assets/custom-icons/icons/airtable.svg
Normal file
1
assets/custom-icons/icons/airtable.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Airtable</title><path fill="#ffba05" d="M11.992 1.966c-.434 0-.87.086-1.28.257L1.779 5.917c-.503.208-.49.908.012 1.116l8.982 3.558a3.266 3.266 0 0 0 2.454 0l8.982-3.558c.503-.196.503-.908.012-1.116l-8.957-3.694a3.255 3.255 0 0 0-1.272-.257z"/><path fill="#39caff" d="M23.4 8.056a.589.589 0 0 0-.222.045l-10.012 3.877a.612.612 0 0 0-.38.564v8.896a.6.6 0 0 0 .821.552L23.62 18.1a.583.583 0 0 0 .38-.551V8.653a.6.6 0 0 0-.6-.596z"/><path fill="#dc043b" d="M.676 8.095a.644.644 0 0 0-.48.19C.086 8.396 0 8.53 0 8.69v8.355c0 .442.515.737.908.54l6.27-3.006.307-.147 2.969-1.436c.466-.22.43-.908-.061-1.092L.883 8.138a.57.57 0 0 0-.207-.044z"/><path fill-opacity="0.25" d="M10.451,12.997l-2.972,1.434l-7.287,-6.144c0.046,-0.046 0.098,-0.084 0.152,-0.114c0.15,-0.09 0.363,-0.114 0.545,-0.042l9.512,3.769c0.483,0.191 0.521,0.869 0.05,1.097"/></svg>
|
||||
|
After Width: | Height: | Size: 918 B |
1
assets/custom-icons/icons/discourse.svg
Normal file
1
assets/custom-icons/icons/discourse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Discourse</title><path d="M11.992 0C5.482 0 0 5.278 0 11.791V24l11.99-.012c6.51 0 11.79-5.481 11.79-11.991C23.78 5.486 18.495 0 11.992 0"/><path d="M12.108 4.564c-4.009.002-7.306 3.301-7.306 7.31 0 1.215.302 2.411.881 3.479L4.36 19.607l4.749-1.072a7.312 7.312 0 0 0 3.002.645c4.009 0 7.308-3.299 7.308-7.308 0-4.008-3.297-7.306-7.305-7.308z" fill="#fff9ae"/><path d="M17.822 16.395a7.307 7.307 0 0 1-8.713 2.128L4.36 19.61l4.834-.571a7.306 7.306 0 0 0 8.712-11.613 7.306 7.306 0 0 1-.084 8.969" fill="#00aeef"/><path d="M17.413 15.006a7.307 7.307 0 0 1-8.443 3.027L4.36 19.61l4.749-1.075A7.306 7.306 0 0 0 16.56 6.078a7.305 7.305 0 0 1 .853 8.928" fill="#00a94f"/><path d="M6.12 15.515a7.308 7.308 0 0 1 11.79-8.091 7.308 7.308 0 0 0-12.227 7.929L4.36 19.607z" fill="#f15d22"/><path d="M5.683 15.353A7.308 7.308 0 0 1 16.56 6.078 7.308 7.308 0 0 0 5.232 15.24l-.869 4.37z" fill="#d0232b"/></svg>
|
||||
|
After Width: | Height: | Size: 973 B |
1
assets/custom-icons/icons/dusnet.svg
Normal file
1
assets/custom-icons/icons/dusnet.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>dus.net</title><circle cx="12" cy="21.799" r="2.201"/><path d="M5.467 0a2.202 2.202 0 1 0 .001 4.403A2.202 2.202 0 0 0 5.467 0M12 0a2.201 2.201 0 1 0 0 4.402A2.201 2.201 0 0 0 12 0m6.533 4.402a2.201 2.201 0 1 0 0-4.402 2.201 2.201 0 0 0 0 4.402M5.467 6.533a2.201 2.201 0 1 0 0 4.402 2.201 2.201 0 0 0 0-4.402m6.533 0a2.2 2.2 0 1 0-.001 4.4 2.2 2.2 0 0 0 .001-4.4m6.533 0a2.201 2.201 0 1 0-.001 4.403 2.201 2.201 0 0 0 .001-4.403M5.467 13.065a2.202 2.202 0 1 0 .001 4.403 2.202 2.202 0 0 0-.001-4.403m6.533 0a2.201 2.201 0 1 0 0 4.402 2.201 2.201 0 0 0 0-4.402m6.533 0a2.202 2.202 0 1 0 0 4.404 2.202 2.202 0 0 0 0-4.404" fill="#eb311b"/></svg>
|
||||
|
After Width: | Height: | Size: 721 B |
1
assets/custom-icons/icons/inwx.svg
Normal file
1
assets/custom-icons/icons/inwx.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 4.9 KiB |
1
assets/custom-icons/icons/service-bw.svg
Normal file
1
assets/custom-icons/icons/service-bw.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg rols="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>service-bw</title><path fill="#f8dd15" d="M7.926 7.962c-.582.086-.083.499-.083.499l.618-.477s.035-.09-.535-.022 M9.571 10.864c.144-1.248-1.379-2.88-1.379-2.88l.592-.794-1.478.407s-1.581-.691-3.946.793a1.717 1.717 0 0 0 0 .989c.097.322.925-.48 1.107.154-.269.078-.548.12-.829.125a1.239 1.239 0 0 1-.758-.196 2.065 2.065 0 0 1-.48-.96c-.073-.356-.342 1.447 1.21 1.447.293.026.588-.004.87-.09-.051.858-.829.215-.829.215v.988s1.258-.163 1.488-.339c-.064.221-.173.819-.173.819l-2.025-.08S.691 9.478 0 11.856l1.581.099 3.651 2.378-1.677 1.28s-2.56-.858-2.464 1.123l3.251.058 5.095-1.184v-.586s1.449-.099 1.747-.099a15.308 15.308 0 0 0 1.862-.778v-3.232c-1.724.202-3.193.269-3.475-.051m-3.859-2.88-.618.493s-.499-.416.084-.499c.582-.084.534.022.534.022z M11.546 8.883c-.298-.601.492-1.683.492-1.683s-2.169.595-1.776 1.981c.304 1.069 2.01.96 2.778.854v-.96c-.618.103-1.334.135-1.494-.192"/><path d="M13.28 14.024v4.056h-.32V5.92h.32v3.146c.247-.045.493-.099.736-.164 0 0 5.203-1.52 5.622-1.6.42-.08 2.269-.396 2.762 1.485.176 1.415-.48 1.776-.995 2.279.883.08 1.184 2.393 1.184 3.068 1.062-.371 1.283.298 1.382.298.099 0-.089 2.179-.089 2.179l-2.762-.096s-.352-1.017 1.28-1.081c-2.275-.692-3.261-2.068-3.261-2.068s-.889 1.104-1.184 1.6c-.294.496-.393 1.642-.393 1.642H14.01c.06-.55.182-.858.588-1.046l1.476.041.387-2.771-.413-.099s-1.449.677-2.768 1.291m0-3.995v.845c2.485-.308 5.388-.857 5.958-.912a1.866 1.866 0 0 1 1.479.396s.598.496.79-.988c.192-1.485-1.974-1.204-2.368-1.088-.393.115-5.705 1.718-5.705 1.718s-.057.012-.154.029"/></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
1
assets/custom-icons/icons/sipgate.svg
Normal file
1
assets/custom-icons/icons/sipgate.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 14 KiB |
@@ -96,7 +96,7 @@
|
||||
"importCodeDelimiterInfo": "The codes can be separated by a comma or a new line",
|
||||
"selectFile": "Select file",
|
||||
"emailVerificationToggle": "Email verification",
|
||||
"emailVerificationEnableWarning": "If you are storing the 2FA to your email with us, turning on email verification could result in a deadlock. If you are locked out of one service, you might not be able to log in to the other.",
|
||||
"emailVerificationEnableWarning": "To avoid getting locked out of your account, be sure to store a copy of your email 2FA outside of Ente Auth before enabling email verification.",
|
||||
"authToChangeEmailVerificationSetting": "Please authenticate to change email verification",
|
||||
"authToViewYourRecoveryKey": "Please authenticate to view your recovery key",
|
||||
"authToChangeYourEmail": "Please authenticate to change your email",
|
||||
@@ -398,5 +398,11 @@
|
||||
"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": "No internet connection",
|
||||
"pleaseCheckYourInternetConnectionAndTryAgain": "Please check your internet connection and try again."
|
||||
"pleaseCheckYourInternetConnectionAndTryAgain": "Please check your internet connection and try again.",
|
||||
"signOutFromOtherDevices": "Sign out from other devices",
|
||||
"signOutOtherBody": "If you think someone might know your password, you can force all other devices using your account to sign out.",
|
||||
"signOutOtherDevices": "Sign out other devices",
|
||||
"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!"
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
"importScanQrCode": "QR კოდის დასკანერება",
|
||||
"qrCode": "QR კოდი",
|
||||
"importEnterSetupKey": "შეიყვანეთ დაყენების კოდი",
|
||||
"importAccountPageTitle": "შეიყვანეთ ანგარიშის დეტალები",
|
||||
"importAccountPageTitle": "შეიყვანეთ ანგარიშის მონაცემები",
|
||||
"secretCanNotBeEmpty": "გასაღების ველი არ შეიძლება ცარიელი იყოს",
|
||||
"bothIssuerAndAccountCanNotBeEmpty": "ანგარიშის მომწოდებლისა და ანგარიშის ველი არ შეიძლება ცარიელი იყოს",
|
||||
"bothIssuerAndAccountCanNotBeEmpty": "მომწოდებლისა და ანგარიშის ველი არ შეიძლება ცარიელი იყოს",
|
||||
"incorrectDetails": "არასწორი მონაცემები",
|
||||
"pleaseVerifyDetails": "გთხოვთ, გადაამოწმოთ დეტალები და სცადოთ ხელახლა",
|
||||
"pleaseVerifyDetails": "გთხოვთ, გადაამოწმოთ მონაცემები და სცადოთ ხელახლა",
|
||||
"codeIssuerHint": "მომწოდებელი",
|
||||
"codeSecretKeyHint": "გასაღები",
|
||||
"codeAccountHint": "ანგარიში (you@domain.com)",
|
||||
@@ -88,5 +88,29 @@
|
||||
"copied": "დაკოპირებულია",
|
||||
"pleaseTryAgain": "გთხოვთ, სცადოთ ხელახლა",
|
||||
"existingUser": "არსებული მომხმარებელი",
|
||||
"delete": "წაშლა"
|
||||
"delete": "წაშლა",
|
||||
"androidBiometricNotRecognized": "ამოცნობა ვერ მოხერხდა. გთხოვთ, სცადოთ ხელახლა.",
|
||||
"@androidBiometricNotRecognized": {
|
||||
"description": "Message to let the user know that authentication was failed. It is used on Android side. Maximum 60 characters."
|
||||
},
|
||||
"androidBiometricSuccess": "წარმატებით",
|
||||
"@androidBiometricSuccess": {
|
||||
"description": "Message to let the user know that authentication was successful. It is used on Android side. Maximum 60 characters."
|
||||
},
|
||||
"androidCancelButton": "გაუქმება",
|
||||
"@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": "საჭიროა აუთენთიფიკაცია",
|
||||
"@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."
|
||||
},
|
||||
"noInternetConnection": "ინტერნეტთან კავშირი არ არის",
|
||||
"pleaseCheckYourInternetConnectionAndTryAgain": "გთხოვთ, შეამოწმოთ თქვენი ინტერნეტ კავშირი და სცადოთ ხელახლა.",
|
||||
"signOutFromOtherDevices": "ყველა მოწყობილობიდან გამოსვლა",
|
||||
"signOutOtherBody": "თუ ფიქრობთ, რომ ვინმემ შესაძლოა იცოდეს თქვენი პაროლი, შეგიძლიათ ყველა მოწყობილობაზე იძულებითი გამოსვლა, რომელიც იყენებს თქვენს ანგარიშს.",
|
||||
"signOutOtherDevices": "სხვა მოწყობილობებიდან გამოსვლა",
|
||||
"doNotSignOut": "არ მოხდეს გამოსვლა",
|
||||
"hearUsWhereTitle": "როგორ შეიტყვეთ Ente-ს შესახებ? (არასავალდებულო)",
|
||||
"hearUsExplanation": "ჩვენ არ ვაკონტროლებთ აპლიკაციის ინსტალაციას. სასარგებლო იქნებოდა, თუ გვეტყოდით, სად გვიპოვეთ!"
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"account": "Account",
|
||||
"unlock": "Ontgrendelen",
|
||||
"recoveryKey": "Herstelsleutel",
|
||||
"counterAppBarTitle": "Teller",
|
||||
"@counterAppBarTitle": {
|
||||
@@ -83,9 +84,12 @@
|
||||
"importFromApp": "Importeer codes van {appName}",
|
||||
"importGoogleAuthGuide": "Exporteer uw accounts van Google Authenticator naar een QR-code met behulp van de optie \"Transfer Accounts\". Met een ander apparaat scan je de QR-code.\n\nTip: Je kunt de webcam van je laptop gebruiken om een foto van de QR-code te maken.",
|
||||
"importSelectJsonFile": "Selecteer JSON bestand",
|
||||
"importSelectAppExport": "Selecteer {appName} exportbestand",
|
||||
"importEnteEncGuide": "Selecteer het versleutelde JSON-bestand dat vanuit ente geëxporteerd is",
|
||||
"importRaivoGuide": "Gebruik de optie \"Export OTPs to Zip archive\" in Raivo's instellingen.\n\nPak het zip-bestand uit en importeer het JSON-bestand.",
|
||||
"importBitwardenGuide": "Gebruik de optie \"Exporteer kluis\" binnen Bitwarden Tools en importeer het niet-versleutelde JSON-bestand.",
|
||||
"importAegisGuide": "Gebruik de optie \"Exporteer de kluis\" in de instellingen van Aegis.\n\nAls uw kluis is versleuteld, moet u het wachtwoord invoeren om de kluis te ontsleutelen.",
|
||||
"import2FasGuide": "Gebruik de optie \"Instellingen->Backup -Export\" in 2FAS.\n\nAls uw back-up is versleuteld, moet u het wachtwoord invoeren om de back-up te ontsleutelen",
|
||||
"exportCodes": "Codes exporteren",
|
||||
"importLabel": "Importeren",
|
||||
"importInstruction": "Selecteer een bestand dat een lijst van uw codes in de volgende indeling bevat",
|
||||
@@ -97,6 +101,8 @@
|
||||
"authToViewYourRecoveryKey": "Graag verifiëren om uw herstelsleutel te bekijken",
|
||||
"authToChangeYourEmail": "Graag verifiëren om je e-mailadres te wijzigen",
|
||||
"authToChangeYourPassword": "Graag verifiëren om je wachtwoord te wijzigen",
|
||||
"authToViewSecrets": "Graag verifiëren om uw herstelsleutel te bekijken",
|
||||
"authToInitiateSignIn": "Verifiëren om in te kunnen loggen voor back-up.",
|
||||
"ok": "Oké",
|
||||
"cancel": "Annuleer",
|
||||
"yes": "Ja",
|
||||
@@ -329,6 +335,7 @@
|
||||
"offlineModeWarning": "Je hebt ervoor gekozen om verder te gaan zonder back-ups. Neem handmatige back-ups om ervoor te zorgen dat jouw codes veilig zijn.",
|
||||
"showLargeIcons": "Grote iconen",
|
||||
"shouldHideCode": "Verberg codes",
|
||||
"doubleTapToViewHiddenCode": "Je kunt dubbel klikken op een item om code te bekijken",
|
||||
"focusOnSearchBar": "Focus zoekveld na starten app",
|
||||
"confirmUpdatingkey": "Weet u zeker dat u de geheime sleutel wilt bijwerken?",
|
||||
"minimizeAppOnCopy": "Na kopiëren app minimaliseren",
|
||||
@@ -336,5 +343,65 @@
|
||||
"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."
|
||||
},
|
||||
"androidBiometricNotRecognized": "Niet herkend. Probeer het opnieuw.",
|
||||
"@androidBiometricNotRecognized": {
|
||||
"description": "Message to let the user know that authentication was failed. It is used on Android side. Maximum 60 characters."
|
||||
},
|
||||
"androidBiometricSuccess": "Succes",
|
||||
"@androidBiometricSuccess": {
|
||||
"description": "Message to let the user know that authentication was successful. It is used on Android side. Maximum 60 characters."
|
||||
},
|
||||
"androidCancelButton": "Annuleren",
|
||||
"@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": "Verificatie vereist",
|
||||
"@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": "Biometrische verificatie vereist",
|
||||
"@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": "Apparaatgegevens vereist",
|
||||
"@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": "Apparaatgegevens vereist",
|
||||
"@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": "Ga naar instellingen",
|
||||
"@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": "Biometrische verificatie is niet ingesteld op uw apparaat. Ga naar 'Instellingen > Beveiliging' om biometrische verificatie toe te voegen.",
|
||||
"@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": "Biometrische verificatie is uitgeschakeld. Vergrendel en ontgrendel uw scherm om het in te schakelen.",
|
||||
"@iOSLockOut": {
|
||||
"description": "Message advising the user to re-enable biometrics on their device. It shows in a dialog on iOS side."
|
||||
},
|
||||
"iOSGoToSettingsDescription": "Biometrische authenticatie is niet ingesteld op uw apparaat. Schakel Touch ID of Face ID in op uw telefoon.",
|
||||
"@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": "Geen internetverbinding",
|
||||
"pleaseCheckYourInternetConnectionAndTryAgain": "Controleer je internetverbinding en probeer het opnieuw.",
|
||||
"signOutFromOtherDevices": "Afmelden bij andere apparaten",
|
||||
"signOutOtherBody": "Als je denkt dat iemand je wachtwoord zou kunnen kennen, kun je alle andere apparaten die je account gebruiken dwingen om uit te loggen.",
|
||||
"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!"
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"account": "Konto",
|
||||
"unlock": "Odblokuj",
|
||||
"recoveryKey": "Klucz odzyskiwania",
|
||||
"counterAppBarTitle": "Licznik",
|
||||
"@counterAppBarTitle": {
|
||||
@@ -97,6 +98,7 @@
|
||||
"authToViewYourRecoveryKey": "Proszę uwierzytelnić, aby wyświetlić swój klucz odzyskiwania",
|
||||
"authToChangeYourEmail": "Proszę uwierzytelnić, aby zmienić swój adres e-mail",
|
||||
"authToChangeYourPassword": "Proszę uwierzytelnić, aby zmienić hasło",
|
||||
"authToViewSecrets": "Proszę uwierzytelnić, aby wyświetlić swoje sekrety",
|
||||
"ok": "Ok",
|
||||
"cancel": "Anuluj",
|
||||
"yes": "Tak",
|
||||
|
||||
@@ -84,10 +84,12 @@
|
||||
"importFromApp": "从 {appName} 导入代码",
|
||||
"importGoogleAuthGuide": "使用“转移帐户”选项将您的帐户从 Google 身份验证器导出到二维码。然后使用另一台设备扫描二维码。\n\n提示:您可以使用笔记本电脑的网络摄像头拍摄二维码的照片。",
|
||||
"importSelectJsonFile": "选择 JSON 文件",
|
||||
"importSelectAppExport": "选择 {appName} 的导出文件",
|
||||
"importEnteEncGuide": "选择从ente导出的加密JSON文件",
|
||||
"importRaivoGuide": "使用 Raivo 设置中的“将 OTP 导出到 Zip 存档”选项。\n\n解压 zip 文件并导入 JSON 文件。",
|
||||
"importBitwardenGuide": "使用 Bitwarden 工具中的“导出保管库”选项并导入未加密的 JSON 文件。",
|
||||
"importAegisGuide": "在Aegis的设置中使用\"导出密码库\"选项。\n\n如果您的密码库已加密,您需要输入密码才能解密密码库。",
|
||||
"import2FasGuide": "使用 2FAS 中的“设置 -> 备份 - 导出”选项。\n\n如果您的备份已被加密,则需要输入密码才能解密备份",
|
||||
"exportCodes": "导出代码",
|
||||
"importLabel": "导入",
|
||||
"importInstruction": "请以以下格式选择包含代码列表的文件",
|
||||
@@ -395,5 +397,11 @@
|
||||
"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": "无互联网连接",
|
||||
"pleaseCheckYourInternetConnectionAndTryAgain": "请检查您的互联网连接,然后重试。"
|
||||
"pleaseCheckYourInternetConnectionAndTryAgain": "请检查您的互联网连接,然后重试。",
|
||||
"signOutFromOtherDevices": "从其他设备退出登录",
|
||||
"signOutOtherBody": "如果你认为有人可能知道你的密码,你可以强制所有使用你账户的其他设备退出登录。",
|
||||
"signOutOtherDevices": "登出其他设备",
|
||||
"doNotSignOut": "不要退登",
|
||||
"hearUsWhereTitle": "您是如何知道Ente的? (可选的)",
|
||||
"hearUsExplanation": "我们不跟踪应用程序安装情况。如果您告诉我们您是在哪里找到我们的,将会有所帮助!"
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import "package:flutter/material.dart";
|
||||
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';
|
||||
|
||||
final _logger = Logger("main");
|
||||
|
||||
@@ -31,6 +32,22 @@ void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
final savedThemeMode = await AdaptiveTheme.getThemeMode();
|
||||
await _runInForeground(savedThemeMode);
|
||||
await PrivacyScreen.instance.enable(
|
||||
iosOptions: const PrivacyIosOptions(
|
||||
enablePrivacy: true,
|
||||
privacyImageName: "LaunchImage",
|
||||
lockTrigger: IosLockTrigger.didEnterBackground,
|
||||
),
|
||||
androidOptions: const PrivacyAndroidOptions(
|
||||
enableSecure: true,
|
||||
),
|
||||
backgroundColor: savedThemeMode == AdaptiveThemeMode.dark
|
||||
? Colors.black
|
||||
: Colors.white,
|
||||
blurEffect: savedThemeMode == AdaptiveThemeMode.dark
|
||||
? PrivacyBlurEffect.dark
|
||||
: PrivacyBlurEffect.extraLight,
|
||||
);
|
||||
FlutterDisplayMode.setHighRefreshRate();
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ import "package:uuid/uuid.dart";
|
||||
class UserService {
|
||||
static const keyHasEnabledTwoFactor = "has_enabled_two_factor";
|
||||
static const keyUserDetails = "user_details";
|
||||
static const kReferralSource = "referral_source";
|
||||
static const kCanDisableEmailMFA = "can_disable_email_mfa";
|
||||
static const kIsEmailMFAEnabled = "is_email_mfa_enabled";
|
||||
final SRP6GroupParameters kDefaultSrpGroup = SRP6StandardGroups.rfc5054_4096;
|
||||
@@ -270,13 +271,17 @@ class UserService {
|
||||
}) async {
|
||||
final dialog = createProgressDialog(context, context.l10n.pleaseWait);
|
||||
await dialog.show();
|
||||
final verifyData = {
|
||||
"email": _config.getEmail(),
|
||||
"ott": ott,
|
||||
};
|
||||
if (!_config.isLoggedIn()) {
|
||||
verifyData["source"] = 'auth:' + _getRefSource();
|
||||
}
|
||||
try {
|
||||
final response = await _dio.post(
|
||||
_config.getHttpEndpoint() + "/users/verify-email",
|
||||
data: {
|
||||
"email": _config.getEmail(),
|
||||
"ott": ott,
|
||||
},
|
||||
data: verifyData,
|
||||
);
|
||||
await dialog.hide();
|
||||
if (response.statusCode == 200) {
|
||||
@@ -441,6 +446,7 @@ class UserService {
|
||||
Future<void> registerOrUpdateSrp(
|
||||
Uint8List loginKey, {
|
||||
SetKeysRequest? setKeysRequest,
|
||||
bool logOutOtherDevices = false,
|
||||
}) async {
|
||||
try {
|
||||
final String username = const Uuid().v4().toString();
|
||||
@@ -496,6 +502,7 @@ class UserService {
|
||||
'setupID': setupSRPResponse.setupID,
|
||||
'srpM1': base64Encode(SRP6Util.encodeBigInt(clientM!)),
|
||||
'updatedKeyAttr': setKeysRequest.toMap(),
|
||||
'logOutOtherDevices': logOutOtherDevices,
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -608,8 +615,9 @@ class UserService {
|
||||
|
||||
Future<void> updateKeyAttributes(
|
||||
KeyAttributes keyAttributes,
|
||||
Uint8List loginKey,
|
||||
) async {
|
||||
Uint8List loginKey, {
|
||||
required bool logoutOtherDevices,
|
||||
}) async {
|
||||
try {
|
||||
final setKeyRequest = SetKeysRequest(
|
||||
kekSalt: keyAttributes.kekSalt,
|
||||
@@ -618,11 +626,11 @@ class UserService {
|
||||
memLimit: keyAttributes.memLimit,
|
||||
opsLimit: keyAttributes.opsLimit,
|
||||
);
|
||||
await registerOrUpdateSrp(loginKey, setKeysRequest: setKeyRequest);
|
||||
// await _enteDio.put(
|
||||
// "/users/keys",
|
||||
// data: setKeyRequest.toMap(),
|
||||
// );
|
||||
await registerOrUpdateSrp(
|
||||
loginKey,
|
||||
setKeysRequest: setKeyRequest,
|
||||
logOutOtherDevices: logoutOtherDevices,
|
||||
);
|
||||
await _config.setKeyAttributes(keyAttributes);
|
||||
} catch (e) {
|
||||
_logger.severe(e);
|
||||
@@ -887,4 +895,12 @@ class UserService {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> setRefSource(String refSource) async {
|
||||
await _preferences.setString(kReferralSource, refSource);
|
||||
}
|
||||
|
||||
String _getRefSource() {
|
||||
return _preferences.getString(kReferralSource) ?? "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@ import 'package:ente_auth/core/configuration.dart';
|
||||
import 'package:ente_auth/ente_theme_data.dart';
|
||||
import 'package:ente_auth/l10n/l10n.dart';
|
||||
import 'package:ente_auth/services/user_service.dart';
|
||||
import 'package:ente_auth/theme/ente_theme.dart';
|
||||
import 'package:ente_auth/ui/common/dynamic_fab.dart';
|
||||
import 'package:ente_auth/ui/common/web_page.dart';
|
||||
import 'package:ente_auth/utils/toast_util.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:password_strength/password_strength.dart';
|
||||
@@ -30,6 +32,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
|
||||
String? _email;
|
||||
String? _password;
|
||||
String _cnfPassword = '';
|
||||
String _referralSource = '';
|
||||
double _passwordStrength = 0.0;
|
||||
bool _emailIsValid = false;
|
||||
bool _hasAgreedToTOS = true;
|
||||
@@ -104,6 +107,7 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
|
||||
onPressedFunction: () {
|
||||
_config.setVolatilePassword(_passwordController1.text);
|
||||
UserService.instance.setEmail(_email!);
|
||||
UserService.instance.setRefSource(_referralSource);
|
||||
UserService.instance
|
||||
.sendOtt(context, _email!, isCreateAccountScreen: true);
|
||||
FocusScope.of(context).unfocus();
|
||||
@@ -325,6 +329,51 @@ class _EmailEntryPageState extends State<EmailEntryPage> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 0, horizontal: 20),
|
||||
child: Text(
|
||||
context.l10n.hearUsWhereTitle,
|
||||
style: getEnteTextTheme(context).smallFaint,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
|
||||
child: TextFormField(
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
decoration: InputDecoration(
|
||||
fillColor: null,
|
||||
filled: true,
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 14,
|
||||
),
|
||||
border: UnderlineInputBorder(
|
||||
borderSide: BorderSide.none,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
suffixIcon: InkWell(
|
||||
onTap: () {
|
||||
showToast(
|
||||
context,
|
||||
context.l10n.hearUsExplanation,
|
||||
);
|
||||
},
|
||||
child: Icon(
|
||||
Icons.info_outline_rounded,
|
||||
color: getEnteColorScheme(context).strokeMuted,
|
||||
),
|
||||
),
|
||||
),
|
||||
onChanged: (value) {
|
||||
_referralSource = value.trim();
|
||||
},
|
||||
autocorrect: false,
|
||||
keyboardType: TextInputType.text,
|
||||
textInputAction: TextInputAction.next,
|
||||
),
|
||||
),
|
||||
const Divider(thickness: 1),
|
||||
const SizedBox(height: 12),
|
||||
_getAgreement(),
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:ente_auth/services/user_service.dart';
|
||||
import 'package:ente_auth/ui/account/recovery_key_page.dart';
|
||||
import 'package:ente_auth/ui/common/dynamic_fab.dart';
|
||||
import 'package:ente_auth/ui/common/web_page.dart';
|
||||
import 'package:ente_auth/ui/components/models/button_type.dart';
|
||||
import 'package:ente_auth/ui/home_page.dart';
|
||||
import 'package:ente_auth/utils/dialog_util.dart';
|
||||
import 'package:ente_auth/utils/navigation_util.dart';
|
||||
@@ -24,8 +25,7 @@ enum PasswordEntryMode {
|
||||
class PasswordEntryPage extends StatefulWidget {
|
||||
final PasswordEntryMode mode;
|
||||
|
||||
const PasswordEntryPage({required this.mode, Key? key})
|
||||
: super(key: key);
|
||||
const PasswordEntryPage({required this.mode, Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<PasswordEntryPage> createState() => _PasswordEntryPageState();
|
||||
@@ -180,10 +180,11 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
|
||||
.copyWith(fontSize: 14),
|
||||
tags: {
|
||||
'underline': StyledTextTag(
|
||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(
|
||||
fontSize: 14,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
style:
|
||||
Theme.of(context).textTheme.titleMedium!.copyWith(
|
||||
fontSize: 14,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
),
|
||||
},
|
||||
),
|
||||
@@ -356,10 +357,11 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: context.l10n.howItWorks,
|
||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(
|
||||
fontSize: 14,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
style:
|
||||
Theme.of(context).textTheme.titleMedium!.copyWith(
|
||||
fontSize: 14,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -374,13 +376,18 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
|
||||
}
|
||||
|
||||
void _updatePassword() async {
|
||||
final logOutFromOthers = await logOutFromOtherDevices(context);
|
||||
final dialog =
|
||||
createProgressDialog(context, context.l10n.generatingEncryptionKeys);
|
||||
await dialog.show();
|
||||
try {
|
||||
final result = await Configuration.instance
|
||||
.getAttributesForNewPassword(_passwordController1.text);
|
||||
await UserService.instance.updateKeyAttributes(result.item1, result.item2);
|
||||
await UserService.instance.updateKeyAttributes(
|
||||
result.item1,
|
||||
result.item2,
|
||||
logoutOtherDevices: logOutFromOthers,
|
||||
);
|
||||
await dialog.hide();
|
||||
showShortToast(context, context.l10n.passwordChangedSuccessfully);
|
||||
Navigator.of(context).pop();
|
||||
@@ -394,13 +401,34 @@ class _PasswordEntryPageState extends State<PasswordEntryPage> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> logOutFromOtherDevices(BuildContext context) async {
|
||||
bool logOutFromOther = true;
|
||||
await showChoiceDialog(
|
||||
context,
|
||||
title: context.l10n.signOutFromOtherDevices,
|
||||
body: context.l10n.signOutOtherBody,
|
||||
isDismissible: false,
|
||||
firstButtonLabel: context.l10n.signOutOtherDevices,
|
||||
firstButtonType: ButtonType.critical,
|
||||
firstButtonOnTap: () async {
|
||||
logOutFromOther = true;
|
||||
},
|
||||
secondButtonLabel: context.l10n.doNotSignOut,
|
||||
secondButtonOnTap: () async {
|
||||
logOutFromOther = false;
|
||||
},
|
||||
);
|
||||
return logOutFromOther;
|
||||
}
|
||||
|
||||
Future<void> _showRecoveryCodeDialog(String password) async {
|
||||
final l10n = context.l10n;
|
||||
final dialog =
|
||||
createProgressDialog(context, l10n.generatingEncryptionKeysTitle);
|
||||
await dialog.show();
|
||||
try {
|
||||
final KeyGenResult result = await Configuration.instance.generateKey(password);
|
||||
final KeyGenResult result =
|
||||
await Configuration.instance.generateKey(password);
|
||||
Configuration.instance.setVolatilePassword(null);
|
||||
await dialog.hide();
|
||||
onDone() async {
|
||||
|
||||
@@ -83,13 +83,19 @@ class IconUtils {
|
||||
.loadString('assets/simple-icons/_data/simple-icons.json');
|
||||
final simpleIcons = json.decode(simpleIconData);
|
||||
for (final icon in simpleIcons["icons"]) {
|
||||
_simpleIcons[icon["title"].toString().toLowerCase()] = icon["hex"];
|
||||
_simpleIcons[icon["title"]
|
||||
.toString()
|
||||
.replaceAll(' ', '')
|
||||
.toLowerCase()] = icon["hex"];
|
||||
}
|
||||
final customIconData = await rootBundle
|
||||
.loadString('assets/custom-icons/_data/custom-icons.json');
|
||||
final customIcons = json.decode(customIconData);
|
||||
for (final icon in customIcons["icons"]) {
|
||||
_customIcons[icon["title"].toString().toLowerCase()] = CustomIconData(
|
||||
_customIcons[icon["title"]
|
||||
.toString()
|
||||
.replaceAll(' ', '')
|
||||
.toLowerCase()] = CustomIconData(
|
||||
icon["slug"],
|
||||
icon["hex"],
|
||||
);
|
||||
@@ -108,7 +114,7 @@ class IconUtils {
|
||||
}
|
||||
|
||||
String _getProviderTitle(String provider) {
|
||||
return provider.split(RegExp(r'[.(]'))[0].trim().toLowerCase();
|
||||
return provider.split(RegExp(r'[.(]'))[0].replaceAll(' ', '').toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@ A user on GitHub has written a guide to export our data from Authy (morpheus on
|
||||
## Exporting from Authy
|
||||
To export your data, please follow [this guide](https://gist.github.com/gboudreau/94bb0c11a6209c82418d01a59d958c93). This will create a new JSON file with all your Authy TOTP data in it. **Do not share this file with anyone!**
|
||||
|
||||
Or, you can [use this tool by Neeraj](https://github.com/ua741/authy-export/releases/tag/v0.0.4) to simplify things and skip to importing to ente Authenticator.
|
||||
### *Do note that these tools may not export ALL of your codes. Make sure that all your accounts have been imported successfully before deleting any codes from your Authy account!*
|
||||
|
||||
## Converting the export for ente Authenticator
|
||||
So now that you have the JSON file, does that mean it can be imported into ente Authenticator? Nope.
|
||||
|
||||
@@ -17,7 +20,7 @@ This is because the code in the guide exports your Authy data for Bitwarden, not
|
||||
|
||||
<img width="454" alt="ente Authenticator Screenshot" src="https://github.com/gweeeen/auth/assets/41323182/30566a69-cfa0-4de0-9f0d-95967d4c5cad">
|
||||
|
||||
So, this means that even if you try to import this file, nothing will happen. But don't worry, I've written a program in Python that converts the JSON file into a TXT file that ente Authenticator can use!
|
||||
So, this means that even if you try to import this file, nothing will happen. But don't worry, I've written a program in Python that converts the JSON file into a TXT file that ente Authenticator can use! (It's definitely not written **professionaly**, but hey it gets the job done so I'm happy with that.)
|
||||
|
||||
You can download my program [here](https://github.com/gweeeen/ducky/blob/main/duckys_other_stuff/authy_to_ente.py). Or if you **really like making life hard**, then you can make a new Python file and copy this code to it:
|
||||
|
||||
|
||||
@@ -1047,6 +1047,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
privacy_screen:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: privacy_screen
|
||||
sha256: b80297d2726d96e8a8341149e81a415302755f02d3af7c05c820d9e191bbfbee
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.6"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: ente_auth
|
||||
description: ente two-factor authenticator
|
||||
version: 2.0.25+225
|
||||
version: 2.0.27+227
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
@@ -67,6 +67,7 @@ dependencies:
|
||||
path_provider: ^2.0.11
|
||||
pinput: ^1.2.2
|
||||
pointycastle: ^3.7.3
|
||||
privacy_screen: ^0.0.6
|
||||
protobuf: ^3.0.0
|
||||
qr_code_scanner: ^1.0.1
|
||||
qr_flutter: 4.0.0
|
||||
|
||||
Reference in New Issue
Block a user