1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-05 23:53:33 +00:00

Compare commits

...

42 Commits

Author SHA1 Message Date
Bitwarden DevOps
f0abc269df Bumped version to 2024.3.1 (#3095)
(cherry picked from commit 01bd5a7b8d)
2024-03-19 10:43:57 -04:00
Federico Maccaroni
03de6694a2 [PM-6852 ] Fix F-Droid build constant 2024-03-18 19:14:19 -03:00
Bitwarden DevOps
ffd888bd96 Bumped version to 2024.3.0 (#3080)
(cherry picked from commit e7f9d64edb)
2024-03-14 11:15:28 -04:00
Federico Maccaroni
95f66870c2 [PM-6751]Added missing query intent for CustomTabs that might be responsible for the Exception in WebAuthenticator 2024-03-11 19:37:04 -03:00
Federico Maccaroni
0bd4e62afd [PM-6726] Fix for Android 14 devices crashing when using the Tiles 2024-03-11 18:07:40 -03:00
Vince Grassia
e3441845cd DEVOPS-1866 - Fix F-Droid Signing (#3063) 2024-03-07 23:45:15 +00:00
Vince Grassia
3f463647a0 Add login step to be able to download secrets (#3061) 2024-03-07 07:18:32 -08:00
Bitwarden DevOps
4f169a6fe3 Bumped version to 2024.2.2 (#3060) 2024-03-07 15:07:46 +00:00
Vince Grassia
82c2e91446 Update release workflow with proper paths (#3059) 2024-03-07 15:53:27 +01:00
renovate[bot]
7482808857 [deps]: Update chrnorm/deployment-status action to v2.0.3 (#3050)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-06 13:52:31 -05:00
Opeyemi
fd233fa27f Update Failure Job (#3055) 2024-03-06 13:58:41 +01:00
Federico Maccaroni
19f238d9bb [PM-6539] Fix Autofill Extension TDE without MP flow (#3049)
* PM-6539 Fix Autofill Extension TDE without MP updating PromptSSO to work in MAUI and also Generator view. WebAuthenticator copied with UIWindow gotten as it was in Xamarin forms to work. Also fix one NRE on state migration.

* PM-6539 Remove unnecessary using
2024-03-05 18:09:20 -03:00
Vince Grassia
6f6487ccc9 Fix GoogleServices file location (#3053) 2024-03-04 08:11:54 -07:00
Dinis Vieira
dd3dc82595 PM-6552 Added missing using (#3052) 2024-03-04 13:29:22 +00:00
Dinis Vieira
40c80f082d [PM-6552] Fix for Android Window issues when opening Autofill/Accessibility (#3051)
* PM-6552 Removed several of the Window Workarounds for Android. Now always relying on the AndroidNavigationRedirectPage.
AndroidNavigationRedirectPage now more resilient to failure and navigates to HomePage as fallback.

* Update src/Core/Pages/AndroidNavigationRedirectPage.xaml.cs

Co-authored-by: Federico Maccaroni <fedemkr@gmail.com>

---------

Co-authored-by: Federico Maccaroni <fedemkr@gmail.com>
2024-03-04 13:03:09 +00:00
André Bispo
bca5b95446 [PM-4760] Admin Recovery Permissions prompted to set MP. (#2912)
* [PM-4760] Add force password reset check on sync complete.

* [PM-4760] Log error on exception
2024-03-01 19:43:18 +00:00
Dinis Vieira
602627b5fa PM-6552 Fix for App only showing Home (Login) Page after closed after opening Accessibility Settings (#3047) 2024-03-01 19:17:45 +00:00
github-actions[bot]
6f32afb919 Autosync the updated translations (#3045)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-03-01 12:26:42 +01:00
Daniel James Smith
2ca47a4da4 Update ownership of translations (#3046)
Co-authored-by: Daniel James Smith <djsmith85@users.noreply.github.com>
2024-03-01 11:10:15 +00:00
Dinis Vieira
4ff56ba11e PM-5916 Fix for incorrect fonts in fingerprint phrases (#3042) 2024-02-29 09:57:25 +00:00
Vince Grassia
22d0cc681c Change version to proper value (#3041) 2024-02-28 11:49:30 -07:00
André Bispo
4e0a18cce5 [PM-6506] Fix double execution of command on returnType Go (#3039)
* [PM-6506] Fix double execution of command on returnType Go

* [PM-6506] Hide keyboard on environment page close

* [PM-6506] Task guard

Co-authored-by: Federico Maccaroni <fedemkr@gmail.com>

---------

Co-authored-by: Federico Maccaroni <fedemkr@gmail.com>
2024-02-28 17:49:46 +00:00
Vince Grassia
c9fdfa7a15 DEVOPS-1746 - Update iOS distribution certificate and profiles (#3018) 2024-02-28 09:48:16 -03:00
Vince Grassia
850a7e754a DEVOPS-1834 - Apply fix for signing issue (#3038) 2024-02-27 20:18:24 +00:00
Dinis Vieira
67c5f79625 [PM-5917] Fix for send arrow now being touch sensitive to expand collapse (#3036)
* PM-5917 fix for send arrow not being tappable

* Added min width to send icon button so that it has correct spacing like in Android and old Xamarin Forms app.

* Updated min width from previous commit to 25 instead of 20 for more equivalent look to xamarin forms app on iOS
2024-02-26 23:45:59 +00:00
Federico Maccaroni
04e7cfe06d [PM-6428] Implement Legacy Secure Storage (#3027) 2024-02-26 19:25:08 -03:00
Álison Fernandes
d6c2ebe4c2 [PM-6480] Update MAUI to 8.0.7 (#3035)
* Update MAUI to 8.0.7

Updates MAUI to the future SR2 release version.

* Using the released version instead of nightly
2024-02-26 22:24:44 +00:00
Dinis Vieira
2a28294f91 PM-5912 Added default min height and corner radius for iOS buttons. Also removed incorrect style class from one button. (#3031) 2024-02-26 19:23:06 -03:00
Dinis Vieira
8584bbaecc PM-6301 Removed IsRefreshing=true in RefreshAsync as it can trigger the RefreshView to trigger the RefreshView command again (#3026) 2024-02-26 17:28:18 +00:00
Dinis Vieira
2f3cded9c5 PM-6309 Fix to ensure the Icon and Icon placeholder visibility states is updated correctly based on website icons visibility choice (#3033) 2024-02-26 17:16:54 +00:00
github-actions[bot]
eff0ea7ce7 Autosync the updated translations (#3025)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-02-26 15:29:26 +00:00
renovate[bot]
6c3a53dd76 [deps]: Update dawidd6/action-download-artifact action to v3.1.2 (#3028)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-26 09:37:03 -05:00
Vince Grassia
cf8d801c55 Add .NET 3.1 to fix Google Publisher project signing (#3024) 2024-02-22 13:45:42 -07:00
Federico Maccaroni
eaa6844742 Update build.yml to go back to net3.1 Publisher (#3023) 2024-02-22 17:01:33 -03:00
Federico Maccaroni
29e2f728e0 Update Publisher.csproj to go back to net 3.1 to see if that fixes the build (#3022) 2024-02-22 16:39:09 -03:00
Opeyemi
fe160a570f Add stub for DEVOPS-1822 (#3016) 2024-02-21 15:27:43 +00:00
Dinis Vieira
a508bea4b0 [PM-6291] Fix Device Login Pending Requests screen not displaying anything (#3012)
* PM-6291 Changed Passwordless Request Login Page Layout structure so that it can display properly

* PM-6291 Additional changes to allow iOS to show the correct with on the collectionview items
2024-02-21 10:55:26 +00:00
Dinis Vieira
a73923c4f7 [PM-5909] Fix Font MAUI Sizes (#3014)
* PM-5909 Set the default FontSize for Entry, Editor, SearchBar and Picker on Android so that the fonts have a similar size to the one in the Xamarin Forms app.

* PM-5909 Set the default FontSize for Entry, Editor, SearchBar and Picker on iOS so that the fonts have a similar size to the one in the Xamarin Forms app.

* PM-5909 Added spacing in specific scenario for Send Groups (between icon and text)
2024-02-20 22:06:47 +00:00
renovate[bot]
11465e8975 [deps]: Update gh minor (#3011)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-20 16:01:34 -05:00
André Bispo
4c88524f0e [PM-4615] [PM-6217] Add new DUO frameless 2fa flow (#2956)
* [PM-4615] Update DUO 2FA screen to support DUO frameless flow.
2024-02-20 18:46:47 +00:00
Opeyemi
f1c20e03bc Remove individual linter file (#3010) 2024-02-15 11:15:13 -05:00
github-actions[bot]
920a2273c5 Autosync Crowdin Translations (#3009)
* Autosync the updated translations

* Add whitespace to build.yml to trigger workflow linter

* Remove whitespace from build.yml

---------

Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
Co-authored-by: Daniel James Smith <djsmith85@users.noreply.github.com>
2024-02-15 12:52:13 -03:00
140 changed files with 2597 additions and 598 deletions

6
.github/CODEOWNERS vendored
View File

@@ -30,14 +30,14 @@ src/watchOS @bitwarden/team-vault-dev
src/Core/Services/EmailForwarders @bitwarden/team-tools-dev
## Crowdin Sync files ##
src/App/Resources @bitwarden/team-tools-dev
src/Core/Resources/Localization @bitwarden/team-tools-dev
src/watchOS/bitwarden/bitwarden\ WatchKit\ Extension/Localization @bitwarden/team-tools-dev
store/apple @bitwarden/team-tools-dev
store/google @bitwarden/team-tools-dev
## Locales ##
src/App/Resources/AppResources.Designer.cs
src/App/Resources/AppResources.resx
src/Core/Resources/Localization/AppResources.Designer.cs
src/Core/Resources/Localization/AppResources.resx
src/watchOS/bitwarden/bitwarden\ WatchKit\ Extension/Localization/en.lproj
store/apple/en
store/google/en

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,3 +0,0 @@
<EFBFBD>
 K<>Y#<23>(<28><><EFBFBD><EFBFBD>EI֐߄T?)l<><6C><EFBFBD><18><><10>"=<3D>|<7C>'e<><0E>m<EFBFBD>/~<7E><>' F<><46>><3E><><EFBFBD><EFBFBD>l<EFBFBD>b<EFBFBD>[<5B>+R<><52>iL<69><4C>"<22><><EFBFBD>~V:<3A><>p<EFBFBD>a<17>ڵel%8t<38><74><EFBFBD>y<<3C>n<EFBFBD><6E><EFBFBD>aU<61>w<16>JD<4A><44><1F><>We<57>9<EFBFBD><39><EFBFBD><EFBFBD><x8d<38>O<EFBFBD>j\<14>ד<EFBFBD><D793><EFBFBD>Vq<56><71>֋
Ǻ<EFBFBD>-<2D>#<23><><11><>]$<24>(<28>l,<2C>Br<42><02><>d<><64><EFBFBD>•a-<2D><><EFBFBD>:<3A><>:<3A><04>9b,!Em<02><19><>Qf<>D<EFBFBD>g<EFBFBD><06><0E>x(P<>ȡ~<7E>͹<EFBFBD><CDB9> <09><>[<06><>!:<3A>;f<><66>

Binary file not shown.

Binary file not shown.

Binary file not shown.

5
.github/workflows/build-beta.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
---
name: Build Beta
on:
workflow_dispatch:

View File

@@ -31,6 +31,7 @@ jobs:
- name: Print lines of code
run: cloc --vcs git --exclude-dir Resources,store,test,Properties --include-lang C#,XAML
setup:
name: Setup
runs-on: ubuntu-22.04
@@ -58,6 +59,7 @@ jobs:
echo "hotfix_branch_exists=0" >> $GITHUB_OUTPUT
fi
android:
name: Android
runs-on: windows-2022
@@ -67,7 +69,8 @@ jobs:
matrix:
variant: ["prod", "qa"]
env:
android_folder_path: src/App/Platforms/Android
android_folder_path: src\App\Platforms\Android
android_folder_path_bash: src/App/Platforms/Android
steps:
- name: Setup NuGet
uses: nuget/setup-nuget@296fd3ccf8528660c91106efefe2364482f86d6f # v1.2.0
@@ -82,7 +85,7 @@ jobs:
- name: Set up MSBuild
uses: microsoft/setup-msbuild@ede762b26a2de8d110bb5a3db4d7e0e080c0e917 # v1.3.3
# This step might be obsolete at some point as .NET MAUI workloads
# This step might be obsolete at some point as .NET MAUI workloads
# are starting to come pre-installed on the GH Actions build agents.
- name: Install MAUI Workload
run: dotnet workload install maui --ignore-failed-sources
@@ -93,7 +96,8 @@ jobs:
- name: Install Microsoft OpenJDK 11
run: |
choco install microsoft-openjdk11 --no-progress
Write-Output "JAVA_HOME=$(Get-ChildItem -Path 'C:\Program Files\Microsoft\jdk*' | Select -First 1 -ExpandProperty FullName)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Write-Output "JAVA_HOME=$(Get-ChildItem -Path 'C:\Program Files\Microsoft\jdk*' | `
Select -First 1 -ExpandProperty FullName)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Write-Output "Java Home: $env:JAVA_HOME"
- name: Print environment
@@ -109,27 +113,34 @@ jobs:
with:
fetch-depth: 0
- name: Decrypt secrets
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
run: |
mkdir -p ~/secrets
- name: Login to Azure - CI Subscription
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output ./${{ env.main_app_folder_path }}/app_play-keystore.jks ./.github/secrets/app_play-keystore.jks.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output ./${{ env.main_app_folder_path }}/app_upload-keystore.jks ./.github/secrets/app_upload-keystore.jks.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/play_creds.json ./.github/secrets/play_creds.json.gpg
- name: Download secrets
env:
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile
run: |
mkdir -p $HOME/secrets
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name app_play-keystore.jks --file ./${{ env.android_folder_path_bash }}/app_play-keystore.jks --output none
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name app_upload-keystore.jks --file ./${{ env.android_folder_path_bash }}/app_upload-keystore.jks --output none
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name play_creds.json --file $HOME/secrets/play_creds.json --output none
shell: bash
- name: Decrypt secrets - Google Services
- name: Download secrets - Google Services
if: ${{ matrix.variant == 'prod' }}
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile
run: |
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output ./${{ env.android_folder_path }}/google-services.json ./.github/secrets/google-services.json.gpg
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name google-services.json --file ./${{ env.android_folder_path_bash }}/google-services.json --output none
shell: bash
- name: Increment version
@@ -139,9 +150,9 @@ jobs:
echo "########################################"
echo "##### Setting Version Code $BUILD_NUMBER"
echo "########################################"
sed -i "s/android:versionCode=\"1\"/android:versionCode=\"$BUILD_NUMBER\"/" \
./${{ env.android_folder_path }}/AndroidManifest.xml
./${{ env.android_folder_path_bash }}/AndroidManifest.xml
shell: bash
- name: Restore packages
@@ -150,78 +161,70 @@ jobs:
- name: Restore tools
run: dotnet tool restore
# - name: Verify Format
# run: dotnet tool run dotnet-format --check
# - name: Run Core tests
# run: |
# dotnet test test/Core.Test/Core.Test.csproj --logger "trx;LogFileName=test-results.trx" `
# /p:CustomConstants=UT
- name: Run Core tests
run: dotnet test test/Core.Test/Core.Test.csproj --logger "trx;LogFileName=test-results.trx" /p:CustomConstants=UT
- name: Report test results
uses: dorny/test-reporter@eaa763f6ffc21c7a37837f56cd5f9737f27fc6c8 # v1.8.0
if: always()
with:
name: Test Results
path: "**/test-results.trx"
reporter: dotnet-trx
fail-on-error: true
# - name: Report test results
# uses: dorny/test-reporter@eaa763f6ffc21c7a37837f56cd5f9737f27fc6c8 # v1.8.0
# if: always()
# with:
# name: Test Results
# path: "**/test-results.trx"
# reporter: dotnet-trx
# fail-on-error: true
- name: Build Play Store publisher
if: ${{ matrix.variant == 'prod' }}
run: dotnet build ./store/google/Publisher/Publisher.csproj -p:Configuration=Release
run: dotnet build .\store\google\Publisher\Publisher.csproj /p:Configuration=Release
- name: Setup Android build (${{ matrix.variant }})
run: dotnet cake build.cake --target Android --variant ${{ matrix.variant }}
- name: Build Android
run: |
$configuration = "Release";
$projToBuild = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_project_path }}");
Write-Output "########################################"
Write-Output "##### Build $configuration Configuration"
Write-Output "########################################"
dotnet build $projToBuild -c $configuration -f ${{ env.target-net-version }}-android
- name: Sign Android Build
- name: Build & Sign Android
env:
PLAY_KEYSTORE_PASSWORD: ${{ secrets.PLAY_KEYSTORE_PASSWORD }}
UPLOAD_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }}
run: |
$projToBuild = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_project_path }}");
$projToBuild = "$($env:GITHUB_WORKSPACE)/${{ env.main_app_project_path }}";
$packageName = "com.x8bit.bitwarden";
if ("${{ matrix.variant }}" -ne "prod")
{
$packageName = "com.x8bit.bitwarden.${{ matrix.variant }}";
}
Write-Output "########################################"
Write-Output "##### Sign Google Play Bundle Release Configuration"
Write-Output "########################################"
dotnet publish $projToBuild -c Release -f ${{ env.target-net-version }}-android /p:AndroidPackageFormats=aab /p:AndroidKeyStore=true /p:AndroidSigningKeyStore=$("app_upload-keystore.jks") /p:AndroidSigningKeyAlias=upload /p:AndroidSigningKeyPass="$($env:UPLOAD_KEYSTORE_PASSWORD)" /p:AndroidSigningStorePass="$($env:UPLOAD_KEYSTORE_PASSWORD)" --no-restore
$signingUploadKeyStore = "$($env:GITHUB_WORKSPACE)\${{ env.android_folder_path }}\app_upload-keystore.jks"
dotnet publish $projToBuild -c Release -f ${{ env.target-net-version }}-android `
/p:AndroidPackageFormats=aab `
/p:AndroidKeyStore=true `
/p:AndroidSigningKeyStore=$signingUploadKeyStore `
/p:AndroidSigningKeyAlias=upload `
/p:AndroidSigningKeyPass="$($env:UPLOAD_KEYSTORE_PASSWORD)" `
/p:AndroidSigningStorePass="$($env:UPLOAD_KEYSTORE_PASSWORD)" --no-restore
Write-Output "########################################"
Write-Output "##### Copy Google Play Bundle to project root"
Write-Output "########################################"
$signedAabPath = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_folder_path }}/bin/Release/${{ env.target-net-version }}-android/publish/$($packageName)-Signed.aab");
$signedAabDestPath = $($env:GITHUB_WORKSPACE + "/$($packageName).aab");
$signedAabPath = "$($env:GITHUB_WORKSPACE)\${{ env.main_app_folder_path }}\bin\Release\${{ env.target-net-version }}-android\publish\$($packageName)-Signed.aab";
$signedAabDestPath = "$($env:GITHUB_WORKSPACE)\$($packageName).aab";
Copy-Item $signedAabPath $signedAabDestPath
Write-Output "########################################"
Write-Output "##### Sign APK Release Configuration"
Write-Output "########################################"
dotnet publish $projToBuild -c Release -f ${{ env.target-net-version }}-android /p:AndroidKeyStore=true /p:AndroidSigningKeyStore=$("app_play-keystore.jks") /p:AndroidSigningKeyAlias=bitwarden /p:AndroidSigningKeyPass="$($env:PLAY_KEYSTORE_PASSWORD)" /p:AndroidSigningStorePass="$($env:PLAY_KEYSTORE_PASSWORD)" --no-restore
$signingPlayKeyStore = "$($env:GITHUB_WORKSPACE)\${{ env.android_folder_path }}\app_play-keystore.jks"
dotnet publish $projToBuild -c Release -f ${{ env.target-net-version }}-android `
/p:AndroidKeyStore=true `
/p:AndroidSigningKeyStore=$signingPlayKeyStore `
/p:AndroidSigningKeyAlias=bitwarden `
/p:AndroidSigningKeyPass="$($env:PLAY_KEYSTORE_PASSWORD)" `
/p:AndroidSigningStorePass="$($env:PLAY_KEYSTORE_PASSWORD)" --no-restore
Write-Output "########################################"
Write-Output "##### Copy Release APK to project root"
Write-Output "########################################"
$signedApkPath = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_folder_path }}/bin/Release/${{ env.target-net-version }}-android/publish/$($packageName)-Signed.apk");
$signedApkDestPath = $($env:GITHUB_WORKSPACE + "/$($packageName).apk");
$signedApkPath = "$($env:GITHUB_WORKSPACE)\${{ env.main_app_folder_path }}\bin\Release\${{ env.target-net-version }}-android\publish\$($packageName)-Signed.apk";
$signedApkDestPath = "$($env:GITHUB_WORKSPACE)\$($packageName).apk";
Copy-Item $signedApkPath $signedApkDestPath
- name: Upload Prod .aab artifact
@@ -283,20 +286,20 @@ jobs:
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|| github.ref == 'refs/heads/hotfix-rc' ) }}
run: |
PUBLISHER_PATH="$GITHUB_WORKSPACE/store/google/Publisher/bin/Release/net7.0/Publisher.dll"
CREDS_PATH="$HOME/secrets/play_creds.json"
AAB_PATH="$GITHUB_WORKSPACE/com.x8bit.bitwarden.aab"
TRACK="internal"
$publisherPath = "$($env:GITHUB_WORKSPACE)\store\google\Publisher\bin\Release\net8.0\Publisher.dll"
$credsPath = "$($HOME)\secrets\play_creds.json"
$aabPath = "$($env:GITHUB_WORKSPACE)\com.x8bit.bitwarden.aab"
$track = "internal"
dotnet $PUBLISHER_PATH $CREDS_PATH $AAB_PATH $TRACK
shell: bash
dotnet $publisherPath $credsPath $aabPath $track
f-droid:
name: F-Droid Build
runs-on: windows-2022
env:
android_folder_path: src/App/Platforms/Android
android_folder_path: src\App\Platforms\Android
android_folder_path_bash: src/App/Platforms/Android
android_manifest_path: src/App/Platforms/Android/AndroidManifest.xml
steps:
- name: Setup NuGet
@@ -312,7 +315,7 @@ jobs:
- name: Set up MSBuild
uses: microsoft/setup-msbuild@ede762b26a2de8d110bb5a3db4d7e0e080c0e917 # v1.3.3
# This step might be obsolete at some point as .NET MAUI workloads
# This step might be obsolete at some point as .NET MAUI workloads
# are starting to come pre-installed on the GH Actions build agents.
- name: Install MAUI Workload
run: dotnet workload install maui --ignore-failed-sources
@@ -337,23 +340,25 @@ jobs:
- name: Checkout repo
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Decrypt secrets
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
run: |
mkdir -p ~/secrets
- name: Login to Azure - CI Subscription
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output ./${{ env.main_app_folder_path }}/app_fdroid-keystore.jks ./.github/secrets/app_fdroid-keystore.jks.gpg
- name: Download secrets
env:
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile
FILE: app_fdroid-keystore.jks
run: |
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME --name $FILE \
--file ${{ env.android_folder_path_bash }}/$FILE --output none
shell: bash
- name: Increment version
run: |
BUILD_NUMBER=$((3000 + $GITHUB_RUN_NUMBER))
echo "########################################"
echo "##### Setting Version Code $BUILD_NUMBER"
echo "########################################"
sed -i "s/android:versionCode=\"1\"/android:versionCode=\"$BUILD_NUMBER\"/" \
./${{ env.android_manifest_path }}
@@ -361,21 +366,16 @@ jobs:
- name: Clean for F-Droid
run: |
$appPath = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_project_path }}");
$corePath = $($env:GITHUB_WORKSPACE + "/src/Core/Core.csproj");
$directoryBuildProps = $($env:GITHUB_WORKSPACE + "/Directory.Build.props");
$androidManifest = $($env:GITHUB_WORKSPACE + "/${{ env.android_manifest_path }}");
Write-Output "########################################"
Write-Output "##### Backup project files"
Write-Output "########################################"
Write-Output "##### Back up project files"
Copy-Item $androidManifest $($androidManifest + ".original");
Copy-Item $appPath $($appPath + ".original");
Copy-Item $directoryBuildProps $($directoryBuildProps + ".original");
Write-Output "########################################"
Write-Output "##### Cleanup Android Manifest"
Write-Output "########################################"
$xml=New-Object XML;
$xml.Load($androidManifest);
@@ -385,39 +385,34 @@ jobs:
$xml.Save($androidManifest);
Write-Output "##### Enabling FDROID constant"
(Get-Content $directoryBuildProps).Replace('<!-- <CustomConstants>FDROID</CustomConstants> -->', '<CustomConstants>FDROID</CustomConstants>') | Set-Content $directoryBuildProps
- name: Restore packages
run: dotnet restore
- name: Build for F-Droid
run: |
$configuration = "Release";
$projToBuild = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_project_path }}");
Write-Output "########################################"
Write-Output "##### Build $configuration FDROID
Write-Output "########################################"
dotnet build $projToBuild -c $configuration -f ${{ env.target-net-version }}-android /p:CustomConstants="FDROID"
- name: Sign for F-Droid
- name: Build & Sign F-Droid
env:
FDROID_KEYSTORE_PASSWORD: ${{ secrets.FDROID_KEYSTORE_PASSWORD }}
run: |
$projToBuild = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_project_path }}");
$projToBuild = "$($env:GITHUB_WORKSPACE)\${{ env.main_app_project_path }}";
$packageName = "com.x8bit.bitwarden";
Write-Output "########################################"
Write-Output "##### Sign FDroid"
Write-Output "########################################"
dotnet publish $projToBuild -c Release -f ${{ env.target-net-version }}-android /p:AndroidKeyStore=true /p:AndroidSigningKeyStore=$("app_fdroid-keystore.jks") /p:AndroidSigningKeyAlias=bitwarden /p:AndroidSigningKeyPass="$($env:FDROID_KEYSTORE_PASSWORD)" /p:AndroidSigningStorePass="$($env:FDROID_KEYSTORE_PASSWORD)" /p:CustomConstants="FDROID" --no-restore
$signingFdroidKeyStore = "$($env:GITHUB_WORKSPACE)\${{ env.android_folder_path }}\app_fdroid-keystore.jks"
dotnet build $projToBuild -c Release -f ${{ env.target-net-version }}-android `
/p:AndroidKeyStore=true `
/p:AndroidSigningKeyStore=$signingFdroidKeyStore `
/p:AndroidSigningKeyAlias=bitwarden `
/p:AndroidSigningKeyPass="$($env:FDROID_KEYSTORE_PASSWORD)" `
/p:AndroidSigningStorePass="$($env:FDROID_KEYSTORE_PASSWORD)" ` --no-restore
Write-Output "########################################"
Write-Output "##### Copy FDroid apk to project root"
Write-Output "########################################"
$signedApkPath = $($env:GITHUB_WORKSPACE + "/${{ env.main_app_folder_path }}/bin/Release/${{ env.target-net-version }}-android/publish/$($packageName)-Signed.apk");
$signedApkDestPath = $($env:GITHUB_WORKSPACE + "/com.x8bit.bitwarden-fdroid.apk");
$signedApkPath = "$($env:GITHUB_WORKSPACE)\${{ env.main_app_folder_path }}\bin\Release\${{ env.target-net-version }}-android\$($packageName)-Signed.apk";
$signedApkDestPath = "$($env:GITHUB_WORKSPACE)\com.x8bit.bitwarden-fdroid.apk";
Copy-Item $signedApkPath $signedApkDestPath
@@ -440,6 +435,7 @@ jobs:
path: ./bw-fdroid-apk-sha256.txt
if-no-files-found: error
ios:
name: Apple iOS
runs-on: macos-13
@@ -458,13 +454,13 @@ jobs:
uses: nuget/setup-nuget@296fd3ccf8528660c91106efefe2364482f86d6f # v1.2.0
with:
nuget-version: 6.4.0
- name: Set up .NET
uses: actions/setup-dotnet@3447fd6a9f9e57506b15f895c5b76d3b197dc7c2 # v3.2.0
with:
dotnet-version: '8.0.x'
# This step might be obsolete at some point as .NET MAUI workloads
# This step might be obsolete at some point as .NET MAUI workloads
# are starting to come pre-installed on the GH Actions build agents.
- name: Install MAUI Workload
run: dotnet workload install maui --ignore-failed-sources
@@ -493,42 +489,42 @@ jobs:
keyvault: "bitwarden-ci"
secrets: "appcenter-ios-token"
- name: Decrypt secrets
- name: Download Provisioning Profiles secrets
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: profiles
run: |
mkdir -p ~/secrets
mkdir -p $HOME/secrets
profiles=(
"dist_autofill.mobileprovision"
"dist_bitwarden.mobileprovision"
"dist_extension.mobileprovision"
"dist_share_extension.mobileprovision"
"dist_bitwarden_watch_app.mobileprovision"
"dist_bitwarden_watch_app_extension.mobileprovision"
)
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/bitwarden-mobile-key.p12 ./.github/secrets/bitwarden-mobile-key.p12.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/iphone-distribution-cert.p12 ./.github/secrets/iphone-distribution-cert.p12.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/dist_autofill.mobileprovision ./.github/secrets/dist_autofill.mobileprovision.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/dist_bitwarden.mobileprovision ./.github/secrets/dist_bitwarden.mobileprovision.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/dist_extension.mobileprovision ./.github/secrets/dist_extension.mobileprovision.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/dist_share_extension.mobileprovision \
./.github/secrets/dist_share_extension.mobileprovision.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/dist_watch_app.mobileprovision \
./.github/secrets/dist_watch_app.mobileprovision.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output $HOME/secrets/dist_watch_app_extension.mobileprovision \
./.github/secrets/dist_watch_app_extension.mobileprovision.gpg
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output ./src/watchOS/bitwarden/GoogleService-Info.plist ./.github/secrets/GoogleService-Info.plist.gpg
for FILE in "${profiles[@]}"
do
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME --name $FILE \
--file $HOME/secrets/$FILE --output none
done
- name: Download Google Services secret
env:
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile
FILE: GoogleService-Info.plist
run: |
mkdir -p $HOME/secrets
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME --name $FILE \
--file src/watchOS/bitwarden/$FILE --output none
- name: Increment version
run: |
BUILD_NUMBER=$((100 + $GITHUB_RUN_NUMBER))
echo "########################################"
echo "##### Setting CFBundleVersion $BUILD_NUMBER"
echo "########################################"
echo "### CFBundleVersion $BUILD_NUMBER" >> $GITHUB_STEP_SUMMARY
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./${{ env.ios_folder_path }}/Info.plist
@@ -536,30 +532,30 @@ jobs:
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.Autofill/Info.plist
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.ShareExtension/Info.plist
cd src/watchOS/bitwarden
agvtool new-version -all $BUILD_NUMBER
agvtool new-version -all $BUILD_NUMBER
- name: Update Entitlements
run: |
echo "########################################"
echo "##### Updating Entitlements"
echo "########################################"
perl -0777 -pi.bak -e 's/<key>aps-environment<\/key>\s*<string>development<\/string>/<key>aps-environment<\/key>\n\t<string>production<\/string>/' ./${{ env.ios_folder_path }}/Entitlements.plist
- name: Get certificates
run: |
mkdir -p $HOME/certificates
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/ios-distribution |
jq -r .value | base64 -d > $HOME/certificates/ios-distribution.p12
- name: Set up Keychain
env:
KEYCHAIN_PASSWORD: ${{ secrets.IOS_KEYCHAIN_PASSWORD }}
MOBILE_KEY_PASSWORD: ${{ secrets.IOS_KEY_PASSWORD }}
DIST_CERT_PASSWORD: ${{ secrets.IOS_DIST_CERT_PASSWORD }}
run: |
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain
security set-keychain-settings -lut 1200 build.keychain
security import ~/secrets/bitwarden-mobile-key.p12 -k build.keychain -P $MOBILE_KEY_PASSWORD \
-T /usr/bin/codesign -T /usr/bin/security
security import ~/secrets/iphone-distribution-cert.p12 -k build.keychain -P $DIST_CERT_PASSWORD \
-T /usr/bin/codesign -T /usr/bin/security
security import $HOME/certificates/ios-distribution.p12 -k build.keychain -P "" -T /usr/bin/codesign \
-T /usr/bin/security
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain
- name: Set up provisioning profiles
@@ -568,8 +564,8 @@ jobs:
BITWARDEN_PROFILE_PATH=$HOME/secrets/dist_bitwarden.mobileprovision
EXTENSION_PROFILE_PATH=$HOME/secrets/dist_extension.mobileprovision
SHARE_EXTENSION_PROFILE_PATH=$HOME/secrets/dist_share_extension.mobileprovision
WATCH_APP_PROFILE_PATH=$HOME/secrets/dist_watch_app.mobileprovision
WATCH_APP_EXTENSION_PROFILE_PATH=$HOME/secrets/dist_watch_app_extension.mobileprovision
WATCH_APP_PROFILE_PATH=$HOME/secrets/dist_bitwarden_watch_app.mobileprovision
WATCH_APP_EXTENSION_PROFILE_PATH=$HOME/secrets/dist_bitwarden_watch_app_extension.mobileprovision
PROFILES_DIR_PATH=$HOME/Library/MobileDevice/Provisioning\ Profiles
mkdir -p "$PROFILES_DIR_PATH"
@@ -597,68 +593,44 @@ jobs:
- name: Bulid WatchApp
run: |
echo "########################################"
echo "##### Build WatchApp with Release Configuration"
echo "########################################"
xcodebuild archive -workspace ./src/watchOS/bitwarden/bitwarden.xcodeproj/project.xcworkspace -configuration Release -scheme bitwarden\ WatchKit\ App -archivePath ./src/watchOS/bitwarden
echo "########################################"
echo "##### Done"
echo "########################################"
- name: Archive Build for App Store
run: |
Write-Output "########################################"
Write-Output "##### Archive for Release ios-arm64
Write-Output "########################################"
echo "##### Archive for Release ios-arm64"
dotnet publish ${{ env.main_app_project_path }} -c Release -f ${{ env.target-net-version }}-ios /p:RuntimeIdentifier=ios-arm64 /p:ArchiveOnBuild=true /p:MtouchUseLlvm=false
Write-Output "########################################"
Write-Output "##### Done"
Write-Output "########################################"
shell: pwsh
- name: Archive Build for Mobile Automation
run: |
Write-Output "########################################"
Write-Output "##### Archive Debug for iossimulator-x64
Write-Output "########################################"
echo "##### Archive Debug for iossimulator-x64"
dotnet build ${{ env.main_app_project_path }} -c Debug -f ${{ env.target-net-version }}-ios /p:RuntimeIdentifier=iossimulator-x64 /p:ArchiveOnBuild=true /p:MtouchUseLlvm=false
Write-Output "########################################"
Write-Output "##### Done"
Write-Output "########################################"
ls ~/Library/Developer/Xcode/Archives
shell: pwsh
ls $HOME/Library/Developer/Xcode/Archives
- name: Export .ipa for App Store
env:
EXPORT_OPTIONS_PATH: ./.github/resources/export-options-app-store.plist
EXPORT_PATH: ./bitwarden-export
run: |
EXPORT_OPTIONS_PATH="./.github/resources/export-options-app-store.plist"
ARCHIVE_PATH="$HOME/Library/Developer/Xcode/Archives/*/*.xcarchive"
EXPORT_PATH="./bitwarden-export"
xcodebuild -exportArchive -archivePath $ARCHIVE_PATH -exportPath $EXPORT_PATH \
-exportOptionsPlist $EXPORT_OPTIONS_PATH
- name: Export .app for Automation CI
env:
ARCHIVE_PATH: ./${{ env.main_app_folder_path }}/bin/Debug/${{ env.target-net-version }}-ios/iossimulator-x64
EXPORT_PATH: ./bitwarden-export
run: |
ARCHIVE_PATH="./${{ env.main_app_folder_path }}/bin/Debug/${{ env.target-net-version }}-ios/iossimulator-x64"
EXPORT_PATH="./bitwarden-export"
zip -r -q ${{ env.app_ci_output_filename }}.app.zip $ARCHIVE_PATH
mv ${{ env.app_ci_output_filename }}.app.zip $EXPORT_PATH
- name: Copy all dSYMs files to upload
env:
EXPORT_PATH: ./bitwarden-export
WATCH_ARCHIVE_DSYMS_PATH: ./src/watchOS/bitwarden.xcarchive/dSYMs/
WATCH_DSYMS_EXPORT_PATH: ./bitwarden-export/Watch_dSYMs
run: |
ARCHIVE_DSYMS_PATH="$HOME/Library/Developer/Xcode/Archives/*/*.xcarchive/dSYMs"
EXPORT_PATH="./bitwarden-export"
WATCH_ARCHIVE_DSYMS_PATH="./src/watchOS/bitwarden.xcarchive/dSYMs/"
WATCH_DSYMS_EXPORT_PATH="$EXPORT_PATH/Watch_dSYMs"
cp -r -v $ARCHIVE_DSYMS_PATH $EXPORT_PATH
mkdir $WATCH_DSYMS_EXPORT_PATH
cp -r -v $WATCH_ARCHIVE_DSYMS_PATH $WATCH_DSYMS_EXPORT_PATH
@@ -707,10 +679,7 @@ jobs:
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|| github.ref == 'refs/heads/hotfix-rc'
run: |
echo "########################################"
echo "##### Uploading Watch dSYMs to Firebase"
echo "########################################"
find "$HOME/Library/Developer/XCode/DerivedData" -name "upload-symbols" -exec chmod +x {} \; -exec {} -gsp "./src/watchOS/bitwarden/GoogleService-Info.plist" -p ios "./bitwarden-export/Watch_dSYMs" \;
- name: Validate app in App Store
@@ -726,7 +695,6 @@ jobs:
run: |
xcrun altool --validate-app --type ios --file "./bitwarden-export/Bitwarden.ipa" \
--username "$APPLE_ID_USERNAME" --password "$APPLE_ID_PASSWORD"
shell: bash
- name: Deploy to App Store
if: |
@@ -770,13 +738,13 @@ jobs:
secrets: "crowdin-api-token"
- name: Upload Sources
uses: crowdin/github-action@198daeb2d30636c4608d6a6bb96c009dbefc02a2 # v1.18.0
uses: crowdin/github-action@c953b17499daa6be3e5afbf7a63616fb02d8b18d # v1.19.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
with:
config: crowdin.yml
crowdin_branch_name: main
crowdin_branch_name: main
upload_sources: true
upload_translations: false
@@ -794,27 +762,11 @@ jobs:
steps:
- name: Check if any job failed
if: |
(github.ref == 'refs/heads/main')
|| (github.ref == 'refs/heads/rc')
|| (github.ref == 'refs/heads/hotfix-rc')
env:
CLOC_STATUS: ${{ needs.cloc.result }}
ANDROID_STATUS: ${{ needs.android.result }}
F_DROID_STATUS: ${{ needs.f-droid.result }}
IOS_STATUS: ${{ needs.ios.result }}
CROWDIN_PUSH_STATUS: ${{ needs.crowdin-push.result }}
run: |
if [ "$CLOC_STATUS" = "failure" ]; then
exit 1
elif [ "$ANDROID_STATUS" = "failure" ]; then
exit 1
elif [ "$F_DROID_STATUS" = "failure" ]; then
exit 1
elif [ "$IOS_STATUS" = "failure" ]; then
exit 1
elif [ "$CROWDIN_PUSH_STATUS" = "failure" ]; then
exit 1
fi
(github.ref == 'refs/heads/main'
|| github.ref == 'refs/heads/rc'
|| github.ref == 'refs/heads/hotfix-rc')
&& contains(needs.*.result, 'failure')
run: exit 1
- name: Login to Azure - CI Subscription
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0

View File

@@ -30,7 +30,7 @@ jobs:
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
- name: Download translations
uses: crowdin/github-action@198daeb2d30636c4608d6a6bb96c009dbefc02a2 # v1.18.0
uses: crowdin/github-action@c953b17499daa6be3e5afbf7a63616fb02d8b18d # v1.19.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}

View File

@@ -28,7 +28,7 @@ jobs:
branch-name: ${{ steps.branch.outputs.branch-name }}
steps:
- name: Branch check
if: github.event.inputs.release_type != 'Dry Run'
if: inputs.release_type != 'Dry Run'
run: |
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then
echo "==================================="
@@ -44,9 +44,9 @@ jobs:
id: version
uses: bitwarden/gh-actions/release-version-check@main
with:
release-type: ${{ github.event.inputs.release_type }}
release-type: ${{ inputs.release_type }}
project-type: xamarin
file: src/Android/Properties/AndroidManifest.xml
file: src/App/Platforms/Android/AndroidManifest.xml
- name: Get branch name
id: branch
@@ -55,7 +55,7 @@ jobs:
echo "branch-name=$BRANCH_NAME" >> $GITHUB_OUTPUT
- name: Create GitHub deployment
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
if: ${{ inputs.release_type != 'Dry Run' }}
uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7
id: deployment
with:
@@ -67,16 +67,16 @@ jobs:
- name: Download all artifacts
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d # v3.0.0
if: ${{ inputs.release_type != 'Dry Run' }}
uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
with:
workflow: build.yml
workflow_conclusion: success
branch: ${{ steps.branch.outputs.branch-name }}
- name: Dry Run - Download all artifacts
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d # v3.0.0
if: ${{ inputs.release_type == 'Dry Run' }}
uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
with:
workflow: build.yml
workflow_conclusion: success
@@ -86,7 +86,7 @@ jobs:
run: zip -r Bitwarden\ iOS.zip Bitwarden\ iOS
- name: Create release
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
if: ${{ inputs.release_type != 'Dry Run' }}
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
with:
artifacts: "./com.x8bit.bitwarden.aab/com.x8bit.bitwarden.aab,
@@ -103,16 +103,16 @@ jobs:
draft: true
- name: Update deployment status to Success
if: ${{ github.event.inputs.release_type != 'Dry Run' && success() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
if: ${{ inputs.release_type != 'Dry Run' && success() }}
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'success'
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
- name: Update deployment status to Failure
if: ${{ github.event.inputs.release_type != 'Dry Run' && failure() }}
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
if: ${{ inputs.release_type != 'Dry Run' && failure() }}
uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'failure'
@@ -129,8 +129,8 @@ jobs:
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: Download F-Droid .apk artifact
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d # v3.0.0
if: ${{ inputs.release_type != 'Dry Run' }}
uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
with:
workflow: build.yml
workflow_conclusion: success
@@ -138,8 +138,8 @@ jobs:
name: com.x8bit.bitwarden-fdroid.apk
- name: Dry Run - Download F-Droid .apk artifact
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d # v3.0.0
if: ${{ inputs.release_type == 'Dry Run' }}
uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
with:
workflow: build.yml
workflow_conclusion: success
@@ -176,13 +176,19 @@ jobs:
- name: Install Node dependencies
run: npm install
- name: Decrypt secrets
- name: Login to Azure - CI Subscription
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Download secrets
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile
run: |
mkdir -p ~/secrets
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
--output ./store/fdroid/keystore.jks ./.github/secrets/store_fdroid-keystore.jks.gpg
mkdir -p $HOME/secrets
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name store_fdroid-keystore.jks --file ./store/fdroid/keystore.jks --output none
- name: Compile for F-Droid Store
env:
@@ -211,5 +217,5 @@ jobs:
cd $GITHUB_WORKSPACE
- name: Deploy to gh-pages
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
if: ${{ inputs.release_type != 'Dry Run' }}
run: npm run deploy

View File

@@ -1,11 +0,0 @@
---
name: Workflow Linter
on:
pull_request:
paths:
- .github/workflows/**
jobs:
call-workflow:
uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@main

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<MauiVersion>8.0.4-nightly.*</MauiVersion>
<MauiVersion>8.0.7</MauiVersion>
<ReleaseCodesignProvision>Automatic:AppStore</ReleaseCodesignProvision>
<ReleaseCodesignKey>iPhone Distribution</ReleaseCodesignKey>
<IncludeBitwardeniOSExtensions>True</IncludeBitwardeniOSExtensions>
@@ -9,5 +9,8 @@
<!-- Uncomment this when Unit Testing-->
<!-- <CustomConstants>UT</CustomConstants> -->
<!-- Uncomment this when building FDROID-->
<!-- <CustomConstants>FDROID</CustomConstants> -->
</PropertyGroup>
</Project>
</Project>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2024.2.2" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2024.3.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
@@ -43,6 +43,9 @@
<!-- Support for Xamarin.Essentials.Browser.OpenAsync (for Android > 11) -->
<!-- Related docs: https://learn.microsoft.com/en-us/xamarin/essentials/open-browser?tabs=android -->
<queries>
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http" />

View File

@@ -347,7 +347,7 @@ namespace Bit.Droid.Autofill
// InlinePresentation requires nonNull pending intent (even though we only utilize one for the
// "my vault" presentation) so we're including an empty one here
pendingIntent = PendingIntent.GetService(context, 0, new Intent(),
AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.OneShot | PendingIntentFlags.UpdateCurrent, true));
AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.OneShot | PendingIntentFlags.UpdateCurrent, false));
}
var slice = CreateInlinePresentationSlice(
inlinePresentationSpec,

View File

@@ -8,6 +8,7 @@ using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Bit.Droid.Accessibility;
using Java.Lang;
using Bit.App.Droid.Utilities;
namespace Bit.Droid.Tile
{
@@ -76,7 +77,7 @@ namespace Bit.Droid.Tile
var intent = new Intent(this, typeof(AccessibilityActivity));
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.SingleTop | ActivityFlags.ClearTop);
intent.PutExtra("autofillTileClicked", true);
StartActivityAndCollapse(intent);
this.StartActivityAndCollapseWithIntent(intent, isMutable: true);
}
private void ShowConfigErrorDialog()

View File

@@ -1,15 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Service.QuickSettings;
using Android.Views;
using Android.Widget;
using Bit.App.Droid.Utilities;
using Java.Lang;
namespace Bit.Droid.Tile
@@ -62,7 +55,7 @@ namespace Bit.Droid.Tile
var intent = new Intent(this, typeof(MainActivity));
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.SingleTop | ActivityFlags.ClearTop);
intent.PutExtra("generatorTile", true);
StartActivityAndCollapse(intent);
this.StartActivityAndCollapseWithIntent(intent, isMutable: false);
}
}
}

View File

@@ -1,15 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Service.QuickSettings;
using Android.Views;
using Android.Widget;
using Bit.App.Droid.Utilities;
using Java.Lang;
namespace Bit.Droid.Tile
@@ -63,7 +56,7 @@ namespace Bit.Droid.Tile
var intent = new Intent(this, typeof(MainActivity));
intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.SingleTop | ActivityFlags.ClearTop);
intent.PutExtra("myVaultTile", true);
StartActivityAndCollapse(intent);
this.StartActivityAndCollapseWithIntent(intent, isMutable: false);
}
}
}

View File

@@ -2,6 +2,7 @@
using Android.Content;
using Android.OS;
using Android.Provider;
using Android.Service.QuickSettings;
using Bit.App.Utilities;
namespace Bit.App.Droid.Utilities
@@ -64,5 +65,26 @@ namespace Bit.App.Droid.Utilities
return pendingIntentFlags;
}
public static void StartActivityAndCollapseWithIntent(this TileService service, Intent intent, bool isMutable)
{
//For Android 14+ We need to use PendingIntent instead of Intent directly. Older versions still need to use Intent.
if (Build.VERSION.SdkInt < BuildVersionCodes.UpsideDownCake)
{
service.StartActivityAndCollapse(intent);
return;
}
var pendingIntent = PendingIntent.GetActivity(
service.ApplicationContext,
0,
intent,
AddPendingIntentMutabilityFlag(PendingIntentFlags.UpdateCurrent, isMutable)
);
if (pendingIntent == null)
{
return;
}
service.StartActivityAndCollapse(pendingIntent);
}
}
}

View File

@@ -11,7 +11,7 @@
<key>CFBundleIdentifier</key>
<string>com.8bit.bitwarden</string>
<key>CFBundleShortVersionString</key>
<string>2024.2.2</string>
<string>2024.3.1</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CFBundleIconName</key>

View File

@@ -5,7 +5,8 @@ namespace Bit.Core.Abstractions
{
public enum AwaiterPrecondition
{
EnvironmentUrlsInited
EnvironmentUrlsInited,
AndroidWindowCreated
}
public interface IConditionedAwaiterManager

View File

@@ -46,7 +46,6 @@ namespace Bit.App
// This queue keeps those actions so that when the app has resumed they can still be executed.
// Links: https://github.com/dotnet/maui/issues/11501 and https://bitwarden.atlassian.net/wiki/spaces/NMME/pages/664862722/MainPage+Assignments+not+working+on+Android+on+Background+or+App+resume
private readonly Queue<Action> _onResumeActions = new Queue<Action>();
private bool _hasNavigatedToAutofillWindow;
#if ANDROID
@@ -120,41 +119,8 @@ namespace Bit.App
return new Window(new NavigationPage()); //No actual page needed. Only used for auto-filling the fields directly (externally)
}
//"Internal" Autofill and Uri/Otp/CreateSend. This is where we create the autofill specific Window
if (Options != null && (Options.FromAutofillFramework || Options.Uri != null || Options.OtpData != null || Options.CreateSend != null))
{
_isResumed = true; //Specifically for the Autofill scenario we need to manually set the _isResumed here
_hasNavigatedToAutofillWindow = true;
return new AutoFillWindow(new NavigationPage(new AndroidNavigationRedirectPage()));
}
var homePage = new HomePage(Options);
// WORKAROUND: If the user autofills with Accessibility Services enabled and goes back to the application then there is currently an issue
// where this method is called again
// thus it goes through here and the user goes to HomePage as we see here.
// So to solve this, the next flag check has been added which then turns on a flag on the home page
// that will trigger a navigation on the accounts manager when it loads; workarounding this behavior and navigating the user
// to the proper page depending on its state.
// WARNING: this doens't navigate the user to where they were but it acts as if the user had changed their account.
if(_hasNavigatedToAutofillWindow)
{
homePage.PerformNavigationOnAccountChangedOnLoad = true;
// this is needed because when coming back from AutofillWindow OnResume won't be called and we need this flag
// so that void Navigate(NavigationTarget navTarget, INavigationParams navParams) doesn't enqueue the navigation
// and it performs it directly.
_isResumed = true;
_hasNavigatedToAutofillWindow = false;
}
//If we have an existing MainAppWindow we can use that one
var mainAppWindow = Windows.OfType<MainAppWindow>().FirstOrDefault();
if (mainAppWindow != null)
{
mainAppWindow.PendingPage = new NavigationPage(homePage);
}
//Create new main window
return new MainAppWindow(new NavigationPage(homePage));
_isResumed = true;
return new ResumeWindow(new NavigationPage(new AndroidNavigationRedirectPage(Options)));
}
#else
//iOS doesn't use the CreateWindow override used in Android so we just set the Application.Current.MainPage directly
@@ -171,7 +137,7 @@ namespace Bit.App
Application.Current.MainPage = value;
}
}
}
}
#endif
public App() : this(null)

View File

@@ -47,6 +47,7 @@ namespace Bit.Core
public const string ConfigsKey = "configsKey";
public const string DisplayEuEnvironmentFlag = "display-eu-environment";
public const string RegionEnvironment = "regionEnvironment";
public const string DuoCallback = "bitwarden://duo-callback";
/// <summary>
/// This key is used to store the value of "ShouldConnectToWatch" of the last user that had logged in

View File

@@ -53,12 +53,13 @@ namespace Bit.App.Controls
if (BindingContext is CipherItemViewModel cipherItemVM)
{
cipherItemVM.IconImageSuccesfullyLoaded = true;
MainThread.BeginInvokeOnMainThread(() =>
{
Icon.IsVisible = cipherItemVM.ShowIconImage;
IconPlaceholder.IsVisible = !cipherItemVM.ShowIconImage;
});
}
MainThread.BeginInvokeOnMainThread(() =>
{
Icon.IsVisible = true;
IconPlaceholder.IsVisible = false;
});
}
public void Icon_Error(object sender, FFImageLoading.Maui.CachedImageEvents.ErrorEventArgs e)

View File

@@ -77,6 +77,7 @@
<Folder Include="Resources\Localization\" />
<Folder Include="Controls\Picker\" />
<Folder Include="Controls\Avatar\" />
<Folder Include="Utilities\WebAuthenticatorMAUI\" />
</ItemGroup>
<ItemGroup>
<MauiImage Include="Resources\Images\dotnet_bot.svg">
@@ -107,5 +108,6 @@
<ItemGroup>
<None Remove="Controls\Picker\" />
<None Remove="Controls\Avatar\" />
<None Remove="Utilities\WebAuthenticatorMAUI\" />
</ItemGroup>
</Project>

View File

@@ -1,6 +1,7 @@
using Bit.Core.Abstractions;
using Bit.Core.Resources.Localization;
using Bit.Core.Utilities;
using Microsoft.Maui.Platform;
namespace Bit.App.Pages
{
@@ -26,7 +27,7 @@ namespace Bit.App.Pages
_apiEntry.ReturnCommand = new Command(() => _identityEntry.Focus());
_identityEntry.ReturnType = ReturnType.Next;
_identityEntry.ReturnCommand = new Command(() => _iconsEntry.Focus());
_vm.SubmitSuccessAction = () => MainThread.BeginInvokeOnMainThread(async () => await SubmitSuccessAsync());
_vm.SubmitSuccessTask = () => MainThread.InvokeOnMainThreadAsync(SubmitSuccessAsync);
_vm.CloseAction = async () =>
{
await Navigation.PopModalAsync();
@@ -37,6 +38,12 @@ namespace Bit.App.Pages
{
_platformUtilsService.ShowToast("success", null, AppResources.EnvironmentSaved);
await Navigation.PopModalAsync();
#if ANDROID
if (Platform.CurrentActivity.CurrentFocus != null)
{
Platform.CurrentActivity.HideKeyboard(Platform.CurrentActivity.CurrentFocus);
}
#endif
}
private void Close_Clicked(object sender, EventArgs e)

View File

@@ -44,7 +44,7 @@ namespace Bit.App.Pages
public string WebVaultUrl { get; set; }
public string IconsUrl { get; set; }
public string NotificationsUrls { get; set; }
public Action SubmitSuccessAction { get; set; }
public Func<Task> SubmitSuccessTask { get; set; }
public Action CloseAction { get; set; }
public async Task SubmitAsync()
@@ -73,7 +73,10 @@ namespace Bit.App.Pages
IconsUrl = resUrls.Icons;
NotificationsUrls = resUrls.Notifications;
SubmitSuccessAction?.Invoke();
if (SubmitSuccessTask != null)
{
await SubmitSuccessTask();
}
}
public bool ValidateUrls()

View File

@@ -12,12 +12,14 @@ namespace Bit.App.Pages
private readonly HomeViewModel _vm;
private readonly AppOptions _appOptions;
private IBroadcasterService _broadcasterService;
private IConditionedAwaiterManager _conditionedAwaiterManager;
readonly LazyResolve<ILogger> _logger = new LazyResolve<ILogger>();
public HomePage(AppOptions appOptions = null)
{
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>();
_conditionedAwaiterManager = ServiceContainer.Resolve<IConditionedAwaiterManager>();
_appOptions = appOptions;
InitializeComponent();
_vm = BindingContext as HomeViewModel;
@@ -56,6 +58,8 @@ namespace Bit.App.Pages
PerformNavigationOnAccountChangedOnLoad = false;
accountsManager.NavigateOnAccountChangeAsync().FireAndForget();
}
_conditionedAwaiterManager.SetAsCompleted(AwaiterPrecondition.AndroidWindowCreated);
#endif
}

View File

@@ -39,7 +39,7 @@
FontSize="Small"
FontAttributes="Bold"/>
<controls:MonoLabel
FormattedText="{Binding LoginRequest.FingerprintPhrase}"
Text="{Binding LoginRequest.FingerprintPhrase}"
FontSize="Medium"
TextColor="{DynamicResource FingerprintPhrase}"
Margin="0,0,0,27"
@@ -85,7 +85,6 @@
<Button
Text="{u:I18n DenyLogIn}"
Command="{Binding RejectRequestCommand}"
StyleClass="btn-secundary"
AutomationId="DenyLoginButton" />
</StackLayout>

View File

@@ -41,7 +41,7 @@
FontSize="Small"
FontAttributes="Bold" />
<controls:MonoLabel
FormattedText="{Binding FingerprintPhrase}"
Text="{Binding FingerprintPhrase}"
FontSize="Small"
TextColor="{DynamicResource FingerprintPhrase}"
AutomationId="FingerprintPhraseValue" />

View File

@@ -21,6 +21,7 @@ namespace Bit.App.Pages
InitializeComponent();
_vm = BindingContext as LoginSsoPageViewModel;
_vm.Page = this;
_vm.FromIosExtension = _appOptions?.IosExtension ?? false;
_vm.StartTwoFactorAction = () => MainThread.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
_vm.StartSetPasswordAction = () =>
MainThread.BeginInvokeOnMainThread(async () => await StartSetPasswordAsync());

View File

@@ -15,6 +15,16 @@ using Bit.Core.Utilities;
using Microsoft.Maui.Authentication;
using Microsoft.Maui.Networking;
using NetworkAccess = Microsoft.Maui.Networking.NetworkAccess;
using Org.BouncyCastle.Asn1.Ocsp;
#if IOS
using AuthenticationServices;
using Foundation;
using UIKit;
using WebAuthenticator = Bit.Core.Utilities.MAUI.WebAuthenticator;
using WebAuthenticatorResult = Bit.Core.Utilities.MAUI.WebAuthenticatorResult;
using WebAuthenticatorOptions = Bit.Core.Utilities.MAUI.WebAuthenticatorOptions;
#endif
namespace Bit.App.Pages
{
@@ -64,6 +74,8 @@ namespace Bit.App.Pages
set => SetProperty(ref _orgIdentifier, value);
}
public bool FromIosExtension { get; set; }
public ICommand LogInCommand { get; }
public Action StartTwoFactorAction { get; set; }
public Action StartSetPasswordAction { get; set; }
@@ -153,6 +165,9 @@ namespace Bit.App.Pages
CallbackUrl = new Uri(REDIRECT_URI),
Url = new Uri(url),
PrefersEphemeralWebBrowserSession = _useEphemeralWebBrowserSession,
#if IOS
ShouldUseSharedApplicationKeyWindow = FromIosExtension
#endif
});
var code = GetResultCode(authResult, state);

View File

@@ -132,14 +132,26 @@
</StackLayout>
</StackLayout>
</StackLayout>
<StackLayout Spacing="0" Padding="0" IsVisible="{Binding DuoMethod, Mode=OneWay}"
VerticalOptions="StartAndExpand">
<StackLayout
Spacing="0"
Padding="0"
IsVisible="{Binding DuoMethod, Mode=OneWay}"
VerticalOptions="FillAndExpand">
<Label
StyleClass="box"
Text="{Binding DuoFramelessLabel}"
HorizontalOptions="StartAndExpand"
Margin="10,21"
IsVisible="{Binding IsDuoFrameless}"/>
<controls:HybridWebView
x:Name="_duoWebView"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
HeightRequest="{Binding DuoWebViewHeight, Mode=OneWay}" />
<StackLayout StyleClass="box" VerticalOptions="End">
HeightRequest="{Binding DuoWebViewHeight, Mode=OneWay}"
IsVisible="{Binding IsDuoFrameless, Converter={StaticResource inverseBool}}"/>
<StackLayout
StyleClass="box"
VerticalOptions="End">
<StackLayout StyleClass="box-row, box-row-switch">
<Label
Text="{u:I18n RememberMe}"
@@ -151,6 +163,12 @@
HorizontalOptions="End" />
</StackLayout>
</StackLayout>
<Button Text="{u:I18n LaunchDuo}"
Margin="10,21"
StyleClass="btn-primary"
Command="{Binding AuthenticateWithDuoFramelessCommand}"
AutomationId="DuoFramelessButton"
IsVisible="{Binding IsDuoFrameless}"/>
</StackLayout>
<StackLayout
Spacing="0"

View File

@@ -2,6 +2,7 @@
using System.Windows.Input;
using Bit.App.Abstractions;
using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
@@ -34,6 +35,7 @@ namespace Bit.App.Pages
private string _webVaultUrl = "https://vault.bitwarden.com";
private bool _enableContinue = false;
private bool _showContinue = true;
private bool _isDuoFrameless = false;
private double _duoWebViewHeight;
public TwoFactorPageViewModel()
@@ -56,6 +58,7 @@ namespace Bit.App.Pages
PageTitle = AppResources.TwoStepLogin;
SubmitCommand = CreateDefaultAsyncRelayCommand(() => MainThread.InvokeOnMainThreadAsync(async () => await SubmitAsync()), allowsMultipleExecutions: false);
MoreCommand = CreateDefaultAsyncRelayCommand(MoreAsync, onException: _logger.Exception, allowsMultipleExecutions: false);
AuthenticateWithDuoFramelessCommand = CreateDefaultAsyncRelayCommand(DuoFramelessAuthenticateAsync, allowsMultipleExecutions: false);
}
public string TotpInstruction
@@ -103,6 +106,16 @@ namespace Bit.App.Pages
set => SetProperty(ref _enableContinue, value);
}
public bool IsDuoFrameless
{
get => _isDuoFrameless;
set => SetProperty(ref _isDuoFrameless, value, additionalPropertyNames: new string[] { nameof(DuoFramelessLabel) });
}
public string DuoFramelessLabel => SelectedProviderType == TwoFactorProviderType.OrganizationDuo ?
$"{AppResources.DuoTwoStepLoginIsRequiredForYourAccount} {AppResources.FollowTheStepsFromDuoToFinishLoggingIn}" :
AppResources.FollowTheStepsFromDuoToFinishLoggingIn;
#if IOS
public string YubikeyInstruction => AppResources.YubiKeyInstructionIos;
#else
@@ -125,6 +138,7 @@ namespace Bit.App.Pages
}
public ICommand SubmitCommand { get; }
public ICommand MoreCommand { get; }
public ICommand AuthenticateWithDuoFramelessCommand { get; }
public Action TwoFactorAuthSuccessAction { get; set; }
public Action LockAction { get; set; }
public Action StartDeviceApprovalOptionsAction { get; set; }
@@ -179,15 +193,29 @@ namespace Bit.App.Pages
break;
case TwoFactorProviderType.Duo:
case TwoFactorProviderType.OrganizationDuo:
SetDuoWebViewHeight();
var host = WebUtility.UrlEncode(providerData["Host"] as string);
var req = WebUtility.UrlEncode(providerData["Signature"] as string);
page.DuoWebView.Uri = $"{_webVaultUrl}/duo-connector.html?host={host}&request={req}";
page.DuoWebView.RegisterAction(sig =>
IsDuoFrameless = providerData.ContainsKey("AuthUrl");
if (!IsDuoFrameless)
{
Token = sig;
SubmitCommand.Execute(null);
});
SetDuoWebViewHeight();
var host = WebUtility.UrlEncode(providerData["Host"] as string);
var req = WebUtility.UrlEncode(providerData["Signature"] as string);
page.DuoWebView.Uri = $"{_webVaultUrl}/duo-connector.html?host={host}&request={req}";
page.DuoWebView.RegisterAction(sig =>
{
Token = sig;
MainThread.BeginInvokeOnMainThread(async () =>
{
try
{
await SubmitAsync();
}
catch (Exception ex)
{
HandleException(ex);
}
});
});
}
break;
case TwoFactorProviderType.Email:
TotpInstruction = string.Format(AppResources.EnterVerificationCodeEmail,
@@ -211,6 +239,77 @@ namespace Bit.App.Pages
ShowContinue = !(SelectedProviderType == null || DuoMethod || Fido2Method);
}
private async Task DuoFramelessAuthenticateAsync()
{
await _deviceActionService.ShowLoadingAsync(AppResources.Validating);
if (!_authService.TwoFactorProvidersData.TryGetValue(SelectedProviderType.Value, out var providerData) ||
!providerData.TryGetValue("AuthUrl", out var urlObject))
{
throw new InvalidOperationException("Duo authentication error: Could not get ProviderData or AuthUrl");
}
var url = urlObject as string;
if (string.IsNullOrWhiteSpace(url))
{
throw new ArgumentNullException("Duo authentication error: Could not get valid auth url");
}
WebAuthenticatorResult authResult;
try
{
authResult = await WebAuthenticator.AuthenticateAsync(new WebAuthenticatorOptions
{
Url = new Uri(url),
CallbackUrl = new Uri(Constants.DuoCallback)
});
}
catch (TaskCanceledException)
{
// user canceled
await _deviceActionService.HideLoadingAsync();
return;
}
await _deviceActionService.HideLoadingAsync();
if (authResult == null || authResult.Properties == null)
{
throw new InvalidOperationException("Duo authentication error: Could not get result from authentication");
}
if (authResult.Properties.TryGetValue("error", out var resultError))
{
_logger.Error(resultError);
await _platformUtilsService.ShowDialogAsync(AppResources.AnErrorHasOccurred, AppResources.Ok);
return;
}
string code = null;
if (authResult.Properties.TryGetValue("code", out var resultCodeData))
{
code = Uri.UnescapeDataString(resultCodeData);
}
if (string.IsNullOrWhiteSpace(code))
{
throw new ArgumentException("Duo authentication error: response code is null or empty/whitespace");
}
string state = null;
if (authResult.Properties.TryGetValue("state", out var resultStateData))
{
state = Uri.UnescapeDataString(resultStateData);
}
if (string.IsNullOrWhiteSpace(state))
{
throw new ArgumentException("Duo authentication error: response state is null or empty/whitespace");
}
Token = $"{code}|{state}";
await SubmitAsync(true);
}
public void SetDuoWebViewHeight()
{
var screenHeight = DeviceDisplay.MainDisplayInfo.Height / DeviceDisplay.MainDisplayInfo.Density;

View File

@@ -1,20 +1,40 @@
using Bit.App.Abstractions;
using Bit.App.Models;
using Bit.App.Pages;
using Bit.Core.Abstractions;
using Bit.Core.Services;
using Bit.Core.Utilities;
namespace Bit.Core.Pages;
public partial class AndroidNavigationRedirectPage : ContentPage
{
private readonly IAccountsManager _accountsManager;
public AndroidNavigationRedirectPage()
private AppOptions _options;
public AndroidNavigationRedirectPage(AppOptions options)
{
_accountsManager = ServiceContainer.Resolve<IAccountsManager>("accountsManager");
_options = options ?? new AppOptions();
InitializeComponent();
}
private void AndroidNavigationRedirectPage_OnLoaded(object sender, EventArgs e)
{
_accountsManager.NavigateOnAccountChangeAsync().FireAndForget();
if (ServiceContainer.TryResolve<IAccountsManager>(out var accountsManager))
{
accountsManager.NavigateOnAccountChangeAsync().FireAndForget();
}
else
{
Bit.App.App.MainPage = new NavigationPage(new HomePage(_options)); //Fallback scenario to load HomePage just in case something goes wrong when resolving IAccountsManager
}
if (ServiceContainer.TryResolve<IConditionedAwaiterManager>(out var conditionedAwaiterManager))
{
conditionedAwaiterManager?.SetAsCompleted(AwaiterPrecondition.AndroidWindowCreated);
}
else
{
LoggerHelper.LogEvenIfCantBeResolved(new InvalidOperationException("ConditionedAwaiterManager can't be resolved on Android Navigation redirection"));
}
}
}

View File

@@ -266,6 +266,8 @@
AutomationId="SendShowHideOptionsButton" />
<controls:IconButton
x:Name="_btnOptionsUp"
InputTransparent="True"
MinimumWidthRequest="25"
Text="{Binding Source={x:Static core:BitwardenIcons.ChevronUp}}"
StyleClass="box-row-button"
TextColor="{DynamicResource PrimaryColor}"
@@ -274,6 +276,8 @@
AutomationId="SendOptionsDisplayed" />
<controls:IconButton
x:Name="_btnOptionsDown"
InputTransparent="True"
MinimumWidthRequest="25"
Text="{Binding Source={x:Static core:BitwardenIcons.AngleDown}}"
StyleClass="box-row-button"
TextColor="{DynamicResource PrimaryColor}"

View File

@@ -50,6 +50,7 @@
x:DataType="pages:SendGroupingsPageListItem">
<controls:ExtendedStackLayout Orientation="Horizontal"
StyleClass="list-row, list-row-platform"
Spacing="6"
AutomationId="{Binding AutomationId}">
<controls:IconLabel Text="{Binding Icon, Mode=OneWay}"
HorizontalOptions="Start"

View File

@@ -37,10 +37,9 @@
<Label
Text="{u:I18n FingerprintPhrase}"
FontSize="Small"
Padding="0, 10, 0 ,0"
FontAttributes="Bold"/>
<controls:MonoLabel
FormattedText="{Binding FingerprintPhrase}"
Text="{Binding FingerprintPhrase}"
Grid.Row="1"
Grid.ColumnSpan="2"
FontSize="Small"
@@ -70,64 +69,70 @@
Grid.ColumnSpan="2"/>
</Grid>
</DataTemplate>
<StackLayout
x:Key="mainLayout"
x:Name="_mainLayout"
Padding="0, 10">
<RefreshView
IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshCommand}"
VerticalOptions="FillAndExpand"
BackgroundColor="{DynamicResource BackgroundColor}">
<StackLayout>
<Image
x:Name="_emptyPlaceholder"
Source="empty_login_requests"
HorizontalOptions="Center"
WidthRequest="160"
HeightRequest="160"
Margin="0,70,0,0"
IsVisible="{Binding HasLoginRequests, Converter={StaticResource inverseBool}}"
SemanticProperties.Description="{u:I18n NoPendingRequests}" />
<controls:CustomLabel
StyleClass="box-label-regular"
Text="{u:I18n NoPendingRequests}"
IsVisible="{Binding HasLoginRequests, Converter={StaticResource inverseBool}}"
FontAttributes="{OnPlatform iOS=Bold}"
FontWeight="500"
HorizontalTextAlignment="Center"
Margin="14,10,14,0"/>
<controls:ExtendedCollectionView
ItemsSource="{Binding LoginRequests}"
ItemTemplate="{StaticResource loginRequestTemplate}"
SelectionMode="Single"
IsVisible="{Binding HasLoginRequests}"
ExtraDataForLogging="Login requests page" >
<controls:ExtendedCollectionView.Behaviors>
<xct:EventToCommandBehavior
EventName="SelectionChanged"
Command="{Binding AnswerRequestCommand}"
EventArgsConverter="{StaticResource SelectionChangedEventArgsConverter}" />
</controls:ExtendedCollectionView.Behaviors>
</controls:ExtendedCollectionView>
</StackLayout>
</RefreshView>
<controls:IconLabelButton
VerticalOptions="End"
Margin="10,0"
Icon="{Binding Source={x:Static core:BitwardenIcons.Trash}}"
Label="{u:I18n DeclineAllRequests}"
ButtonCommand="{Binding DeclineAllRequestsCommand}"
IsVisible="{Binding HasLoginRequests}"
AutomationId="DeleteAllRequestsButton" />
</StackLayout>
</ResourceDictionary>
</ContentPage.Resources>
<ContentView
x:Name="_mainContent">
</ContentView>
<Grid
RowDefinitions="*, Auto"
Padding="0, 10">
<RefreshView
Grid.Row="0"
IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshCommand}"
VerticalOptions="Fill"
BackgroundColor="{DynamicResource BackgroundColor}">
<Grid RowDefinitions="Auto, *">
<VerticalStackLayout Grid.Row="0"
HorizontalOptions="Center">
<Image
x:Name="_emptyPlaceholder"
Source="empty_login_requests"
WidthRequest="160"
HeightRequest="160"
Margin="0,70,0,0"
IsVisible="{Binding HasLoginRequests, Converter={StaticResource inverseBool}}"
SemanticProperties.Description="{u:I18n NoPendingRequests}" />
<controls:CustomLabel
StyleClass="box-label-regular"
Text="{u:I18n NoPendingRequests}"
IsVisible="{Binding HasLoginRequests, Converter={StaticResource inverseBool}}"
FontAttributes="{OnPlatform iOS=Bold}"
FontWeight="500"
Margin="14,10,14,0"/>
</VerticalStackLayout>
<controls:ExtendedCollectionView
Grid.Row="1"
ItemsSource="{Binding LoginRequests}"
ItemTemplate="{StaticResource loginRequestTemplate}"
SelectionMode="Single"
IsVisible="{Binding HasLoginRequests}"
ExtraDataForLogging="Login requests page" >
<controls:ExtendedCollectionView.Behaviors>
<xct:EventToCommandBehavior
EventName="SelectionChanged"
Command="{Binding AnswerRequestCommand}"
EventArgsConverter="{StaticResource SelectionChangedEventArgsConverter}" />
</controls:ExtendedCollectionView.Behaviors>
</controls:ExtendedCollectionView>
</Grid>
</RefreshView>
<controls:IconLabelButton
Grid.Row="1"
VerticalOptions="End"
Margin="10,0"
Icon="{Binding Source={x:Static core:BitwardenIcons.Trash}}"
Label="{u:I18n DeclineAllRequests}"
ButtonCommand="{Binding DeclineAllRequestsCommand}"
IsVisible="{Binding HasLoginRequests}"
AutomationId="DeleteAllRequestsButton" />
<Grid x:Name="_activityIndicatorGrid" Grid.Row="0" Grid.RowSpan="2" BackgroundColor="{DynamicResource BackgroundColor}">
<ActivityIndicator IsRunning="True"
VerticalOptions="Center"
HorizontalOptions="Center" />
</Grid>
</Grid>
</pages:BaseContentPage>

View File

@@ -5,6 +5,7 @@ using System.Threading.Tasks;
using Bit.App.Utilities;
using Bit.Core.Abstractions;
using Bit.Core.Models.Response;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Microsoft.Maui.ApplicationModel;
using Microsoft.Maui.Controls;
@@ -19,7 +20,6 @@ namespace Bit.App.Pages
public LoginPasswordlessRequestsListPage()
{
InitializeComponent();
SetActivityIndicator(_mainContent);
_vm = BindingContext as LoginPasswordlessRequestsListViewModel;
_vm.Page = this;
}
@@ -27,9 +27,21 @@ namespace Bit.App.Pages
protected override async void OnAppearing()
{
base.OnAppearing();
await LoadOnAppearedAsync(_mainLayout, false, _vm.RefreshAsync, _mainContent);
try
{
_activityIndicatorGrid.IsVisible = true;
UpdatePlaceholder();
await _vm.RefreshAsync();
UpdatePlaceholder();
}
catch (Exception ex)
{
LoggerHelper.LogEvenIfCantBeResolved(ex);
}
finally
{
_activityIndicatorGrid.IsVisible = false;
}
}
private async void Close_Clicked(object sender, System.EventArgs e)

View File

@@ -66,7 +66,6 @@ namespace Bit.App.Pages
{
try
{
IsRefreshing = true;
LoginRequests.ReplaceRange(await _authService.GetActivePasswordlessLoginRequestsAsync());
}
catch (Exception ex)
@@ -108,7 +107,7 @@ namespace Bit.App.Pages
Origin = loginRequestData.Origin
});
await Device.InvokeOnMainThreadAsync(() => Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page)));
await MainThread.InvokeOnMainThreadAsync(() => Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page)));
}
private async Task DeclineAllRequestsAsync()

View File

@@ -96,6 +96,14 @@ namespace Bit.App.Pages
if (message.Command == "syncCompleted")
{
MainThread.BeginInvokeOnMainThread(async () => await UpdateVaultButtonTitleAsync());
try
{
await ForcePasswordResetIfNeededAsync();
}
catch (Exception ex)
{
_logger.Value.Exception(ex);
}
}
});
await UpdateVaultButtonTitleAsync();

View File

@@ -2335,6 +2335,15 @@ namespace Bit.Core.Resources.Localization {
}
}
/// <summary>
/// Looks up a localized string similar to Duo two-step login is required for your account. .
/// </summary>
public static string DuoTwoStepLoginIsRequiredForYourAccount {
get {
return ResourceManager.GetString("DuoTwoStepLoginIsRequiredForYourAccount", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Edit.
/// </summary>
@@ -3199,6 +3208,15 @@ namespace Bit.Core.Resources.Localization {
}
}
/// <summary>
/// Looks up a localized string similar to Follow the steps from Duo to finish logging in..
/// </summary>
public static string FollowTheStepsFromDuoToFinishLoggingIn {
get {
return ResourceManager.GetString("FollowTheStepsFromDuoToFinishLoggingIn", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to {0} is not correctly formatted..
/// </summary>
@@ -3793,6 +3811,15 @@ namespace Bit.Core.Resources.Localization {
}
}
/// <summary>
/// Looks up a localized string similar to Launch Duo.
/// </summary>
public static string LaunchDuo {
get {
return ResourceManager.GetString("LaunchDuo", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Bitwarden allows you to share your vault items with others by using an organization. Learn more on the bitwarden.com website..
/// </summary>

View File

@@ -2876,4 +2876,13 @@ Wil u na die rekening omskakel?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -276,7 +276,7 @@
<value>هل أنت متأكد من أنك تريد تسجيل الخروج؟</value>
</data>
<data name="RemoveAccount" xml:space="preserve">
<value>إزالة الحساب</value>
<value>أزِل الحساب</value>
</data>
<data name="RemoveAccountConfirmation" xml:space="preserve">
<value>هل أنت متأكد من أنك تريد إزالة هذا الحساب؟</value>
@@ -2822,7 +2822,7 @@
<value>مواصلة الاتصال بالدعم؟</value>
</data>
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
<value>Continue to privacy policy?</value>
<value>هل تريد المتابعة إلى سياسة الخصوصية؟</value>
</data>
<data name="ContinueToAppStore" xml:space="preserve">
<value>هل تريد المتابعة إلى متجر التطبيقات؟</value>
@@ -2844,7 +2844,7 @@
<value>لا يمكن العثور على ما تبحث عنه؟ قم بالتواصل مع دعم Bitwarden على bitwarden.com.</value>
</data>
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
<value>Check out our privacy policy on bitwarden.com.</value>
<value>اطلع على سياستنا للخصوصية على bitwarden.com.</value>
</data>
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
<value>استكشف المزيد من الميزات لحساب Bitwarden الخاص بك على تطبيق الويب.</value>
@@ -2877,4 +2877,13 @@
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>أعدنّ ميزة إلغاء القُفْل لتغيير إجراء مهلة المخزن الخاص بك.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2875,4 +2875,13 @@ Bu hesaba keçmək istəyirsiniz?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Anbar vaxt bitməsi əməliyyatınızı dəyişdirmək üçün bir kilid açma seçimi qurun.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Hesabınız üçün Duo iki addımlı giriş tələb olunur. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Giriş etməni tamamlamaq üçün Duo-dakı addımları izləyin.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Duo-nu başlat</value>
</data>
</root>

View File

@@ -2876,4 +2876,13 @@
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2876,4 +2876,13 @@
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Задайте начин за отключване, за да може да промените действието при изтичане на времето за достъп до трезора.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Вашата регистрация изисква двустепенно удостоверяване чрез Duo. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Следвайте стъпките от Duo, за да завършите вписването.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Стартиране на Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2875,4 +2875,13 @@ Skeniranje će biti izvršeno automatski.</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2876,4 +2876,13 @@ Voleu canviar a aquest compte?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Configura una opció de desbloqueig per canviar l'acció de temps d'espera de la caixa forta.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Es requereix l'inici de sessió en dos passos de DUO al vostre compte. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Seguiu els passos de Duo per acabar d'iniciar la sessió.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Inicia DUO</value>
</data>
</root>

View File

@@ -2875,4 +2875,13 @@ Chcete se přepnout na tento účet?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Nastavte volbu odemknutí, abyste změnili časový limit Vašeho trezoru.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Pro Váš účet je vyžadováno dvoufázové přihlášení DUO. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Postupujte podle kroků od DUO pro dokončení přihlášení.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Spustit DUO</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -907,7 +907,7 @@ Skanning vil ske automatisk.</value>
<value>Kopiér TOTP</value>
</data>
<data name="CopyTotpAutomaticallyDescription" xml:space="preserve">
<value>Har et login en godkendelsesnøgle, kopiér TOTP-bekræftelseskoden til udklipsholderen, når login auto-udfyldes.</value>
<value>Har et login en godkendelsesnøgle, kopiér da TOTP-bekræftelseskoden til udklipsholderen, når login autoudfyldes.</value>
</data>
<data name="CopyTotpAutomatically" xml:space="preserve">
<value>Kopiér TOTP automatisk</value>
@@ -2128,7 +2128,7 @@ Skanning vil ske automatisk.</value>
<value>Denne organisation har en virksomhedspolitik, der automatisk tilmelder dig til nulstilling af adgangskode. Tilmelding giver organisationsadministratorer mulighed for at skifte din hovedadgangskode.</value>
</data>
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
<value>Dine organisationspolitikker påvirker din boks-timeout. Maksimum tilladte boks-timeout er {0} time(r) og {1} minut(ter)</value>
<value>Organisationspolitikkerne har sat den maksimalt tilladte bokstimeout til {0} tim(er) og {1} minut(ter).</value>
</data>
<data name="VaultTimeoutPolicyWithActionInEffect" xml:space="preserve">
<value>Organisationspolitikkerne påvirker boks-timeout. Maks. tilladt boks-timeout er {0} time(r) og {1} minut(ter). Boks-timeout er pt. sat til {2}.</value>
@@ -2354,7 +2354,7 @@ vælg Tilføj TOTP for at gemme nøglen sikkert</value>
<value>Godkend loginanmodninger</value>
</data>
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
<value>Brug denne enhed til at godkende loginanmodninger fra andre enheder.</value>
<value>Brug denne enhed til at godkende loginanmodninger fra andre enheder</value>
</data>
<data name="AllowNotifications" xml:space="preserve">
<value>Tillad notifikationer</value>
@@ -2668,7 +2668,7 @@ Vil du skifte til denne konto?</value>
<value>Hjælp til genanmodning om hovedadgangskode</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings or set up biometric unlock to resolve.</value>
<value>Oplåsning kan fejle grundet utilstrækkelig hukommelse. Reducér KDF-hukommelsesindstillinger eller opsæt biometrisk oplåsning for at afhjælpe.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Ugyldig API-nøgle</value>
@@ -2876,4 +2876,13 @@ Vil du skifte til denne konto?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Opsæt en oplåsningsmetode for at ændre Bokstimeouthandlingen.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo-totrinsindlogning kræves for kontoen. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Følg trinnene fra Duo for at færdiggøre indlogningen.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Start Duo</value>
</data>
</root>

View File

@@ -2875,4 +2875,13 @@ Möchtest du zu diesem Konto wechseln?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Richte eine Entsperroption ein, um deine Aktion bei Tresor-Timeout zu ändern.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Für dein Konto ist die Duo Zwei-Faktor-Authentifizierung erforderlich. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Folge den Schritten von Duo, um die Anmeldung abzuschließen.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Duo starten</value>
</data>
</root>

View File

@@ -2820,7 +2820,7 @@
<value>Συνέχεια στην επικοινωνία με την υποστήριξη;</value>
</data>
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
<value>Continue to privacy policy?</value>
<value>Συνέχεια στην πολιτική απορρήτου;</value>
</data>
<data name="ContinueToAppStore" xml:space="preserve">
<value>Συνέχεια στο κατάστημα εφαρμογών;</value>
@@ -2842,7 +2842,7 @@
<value>Δεν μπορείτε να βρείτε αυτό που ψάχνετε; Επικοινωνήστε με την υποστήριξη Bitwarden στο bitwarden.com.</value>
</data>
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
<value>Check out our privacy policy on bitwarden.com.</value>
<value>Δείτε την πολιτική απορρήτου μας στο bitwarden.com.</value>
</data>
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
<value>Εξερευνήστε περισσότερες δυνατότητες του Bitwarden λογαριασμού σας, στην εφαρμογή διαδικτύου.</value>
@@ -2875,4 +2875,13 @@
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Ρυθμίστε μια επιλογή κλειδώματος για να αλλάξετε την ενέργεια στη λήξη χρόνου του vault σας.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2876,4 +2876,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2890,4 +2890,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2878,4 +2878,13 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Configura una opción de desbloqueo para cambiar tu acción de tiempo de espera de tu caja fuerte.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2876,4 +2876,13 @@ Soovid selle konto peale lülituda?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2875,4 +2875,13 @@ Kontu honetara aldatu nahi duzu?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Haluatko vaihtaa tähän tiliin?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Muuta holvisi aikakatkaisutoimintoa määrittämällä lukituksen avaustapa.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Tilillesi kirjautuminen vaatii Duo-vahvistuksen.</value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Viimeistele kirjautuminen seuraamalla Duon ohjeita.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Avaa Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Gusto mo bang pumunta sa account na ito?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Voulez-vous basculer vers ce compte ?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Configurez une méthode de déverrouillage pour modifier l'action après délai d'expiration de votre coffre.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2879,4 +2879,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2876,4 +2876,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2874,4 +2874,13 @@
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Za promjenu vremena isteka trezora, odredi način otključavanja.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2875,4 +2875,13 @@ Szeretnénk átváltani erre a fiókra?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Állítsunk be egy feloldási módot a széf időkifutási műveletének módosításához.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>DUO kétlépéses bejelentkezés szükséges a fiókhoz. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Kövessük a Duo lépéseit a bejelentkezés befejezéséhez.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Duo indítása</value>
</data>
</root>

View File

@@ -2876,4 +2876,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -172,7 +172,7 @@
<comment>Message shown when interacting with the server</comment>
</data>
<data name="DoYouReallyWantToDelete" xml:space="preserve">
<value>Vuoi davvero eliminarlo? Questa operazione non può essere annullata.</value>
<value>Sei sicuro di volerlo eliminare? Questa operazione è irreversibile.</value>
<comment>Confirmation alert message when deleteing something.</comment>
</data>
<data name="Edit" xml:space="preserve">
@@ -193,10 +193,10 @@
<value>Contattaci</value>
</data>
<data name="EmailUsDescription" xml:space="preserve">
<value>Mandaci un'email per ottenere aiuto o lasciare un feedback</value>
<value>Inviaci un'email per ottenere aiuto o lasciare un feedback.</value>
</data>
<data name="EnterPIN" xml:space="preserve">
<value>Digita il tuo PIN.</value>
<value>Inserisci il tuo PIN.</value>
</data>
<data name="Favorites" xml:space="preserve">
<value>Preferiti</value>
@@ -2876,4 +2876,13 @@ Vuoi passare a questo account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Imposta un metodo di sblocco per modificare l'azione timeout cassaforte.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2876,4 +2876,13 @@
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>保管庫のタイムアウト動作を変更するには、ロック解除方法を設定してください。</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>アカウントには Duo 二段階認証が必要です。</value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Duo の手順に従ってログインを完了してください。</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Duo を起動</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2876,4 +2876,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Ar norite pereiti prie šios paskyros?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -172,7 +172,7 @@
<comment>Message shown when interacting with the server</comment>
</data>
<data name="DoYouReallyWantToDelete" xml:space="preserve">
<value>Vai jūs tiešām vēlaties dzēst? Šo darbību nav iespējams atsaukt.</value>
<value>Vai tiešām izdzēst? To nevar atsaukt.</value>
<comment>Confirmation alert message when deleteing something.</comment>
</data>
<data name="Edit" xml:space="preserve">
@@ -193,10 +193,10 @@
<value>Nosūtīt mums e-pasta ziņu</value>
</data>
<data name="EmailUsDescription" xml:space="preserve">
<value>Sūti mums e-pasta ziņu, lai saņemtu palīdzību vai sniegtu atsauksmes!</value>
<value>Nosūtīt mums e-pasta ziņu, lai saņemtu palīdzību vai sniegtu atsauksmes.</value>
</data>
<data name="EnterPIN" xml:space="preserve">
<value>Ievadīt PIN kodu.</value>
<value>Jāievada PIN kods.</value>
</data>
<data name="Favorites" xml:space="preserve">
<value>Izlase</value>
@@ -232,7 +232,7 @@
<value>Mape atjaunota.</value>
</data>
<data name="GoToWebsite" xml:space="preserve">
<value>Doties uz tīmekļa vietni</value>
<value>Doties uz tīmekļvietni</value>
<comment>The button text that allows user to launch the website to their web browser.</comment>
</data>
<data name="HelpAndFeedback" xml:space="preserve">
@@ -243,18 +243,18 @@
<comment>Hide a secret value that is currently shown (password).</comment>
</data>
<data name="InternetConnectionRequiredMessage" xml:space="preserve">
<value>Lūgums izveidot savienojumu ar tīmekli, lai varētu turpināt.</value>
<value>Lūgums izveidot savienojumu ar internetu, lai varētu turpināt.</value>
<comment>Description message for the alert when internet connection is required to continue.</comment>
</data>
<data name="InternetConnectionRequiredTitle" xml:space="preserve">
<value>Nepieciešams tīmekļa savienojums</value>
<value>Nepieciešams interneta savienojums</value>
<comment>Title for the alert when internet connection is required to continue.</comment>
</data>
<data name="InvalidMasterPassword" xml:space="preserve">
<value>Nederīga galvenā parole. Mēģini vēlreiz!</value>
<value>Nederīga galvenā parole. Jāmēģina vēlreiz.</value>
</data>
<data name="InvalidPIN" xml:space="preserve">
<value>Nederīgs PIN. Mēģini vēlreiz!</value>
<value>Nederīgs PIN. Jāmēģina vēlreiz.</value>
</data>
<data name="Launch" xml:space="preserve">
<value>Palaist</value>
@@ -394,10 +394,10 @@
<value>Skatīt</value>
</data>
<data name="VisitOurWebsite" xml:space="preserve">
<value>Apmeklēt mūsu tīmekļa vietni</value>
<value>Apmeklēt mūsu tīmekļvietni</value>
</data>
<data name="Website" xml:space="preserve">
<value>Tīmekļa vietne</value>
<value>Tīmekļvietne</value>
<comment>Label for a website.</comment>
</data>
<data name="Yes" xml:space="preserve">
@@ -419,7 +419,7 @@
<value>Izmantot Bitwarden pieejamības pakalpojumu, lai automātiski aizpildītu pieteikšanās veidnes dažādās lietotnēs un tīmeklī.</value>
</data>
<data name="AutofillService" xml:space="preserve">
<value>Automātiskā aizpilde</value>
<value>Automātiskās aizpildes pakalpojums</value>
</data>
<data name="AvoidAmbiguousCharacters" xml:space="preserve">
<value>Izvairīties no viegli sajaucamām rakstzīmēm</value>
@@ -434,7 +434,7 @@
<value>Izmantot Bitwarden Safari un citās lietotnēs, lai automātiski ievadītu pieteikšanās vienumus.</value>
</data>
<data name="BitwardenAutofillService" xml:space="preserve">
<value>Bitwarden automātiskā aizpilde</value>
<value>Bitwarden automātiskās aizpildes pakalpojums</value>
</data>
<data name="BitwardenAutofillAccessibilityServiceDescription" xml:space="preserve">
<value>Izmantot Bitwarden pieejamības pakalpojumu, lai automātiski aizpildītu pieteikšanās veidnes.</value>
@@ -443,7 +443,7 @@
<value>Mainīt e-pasta adresi</value>
</data>
<data name="ChangeEmailConfirmation" xml:space="preserve">
<value>E-pasta adresi ir iespējams nomainīt bitwarden.com tīmekļa glabātavā. Vai apmeklēt tīmekļa vietni?</value>
<value>E-pasta adresi ir iespējams nomainīt bitwarden.com tīmekļa glabātavā. Vai tagad apmeklēt tīmekļvietni?</value>
</data>
<data name="ChangeMasterPassword" xml:space="preserve">
<value>Mainīt galveno paroli</value>
@@ -517,7 +517,7 @@
<value>Ievietot vienumus</value>
</data>
<data name="ImportItemsConfirmation" xml:space="preserve">
<value>Daudzu vienumu ievietošanu var veikt bitwarden.com tīmekļa glabātavā. Vai apmeklēt tīmekļa vietni?</value>
<value>Daudzu vienumu ievietošanu var veikt bitwarden.com tīmekļa glabātavā. Vai tagad apmeklēt tīmekļvietni?</value>
</data>
<data name="ImportItemsDescription" xml:space="preserve">
<value>Ātri ievietot daudzus vienumus no citām paroļu pārvaldības lietotnēm.</value>
@@ -607,7 +607,7 @@
<value>Glabātavā nav vienumu.</value>
</data>
<data name="NoItemsTap" xml:space="preserve">
<value>Glabātāvā nav vienumu, ko izmantot šajā tīmekļa vietnē/lietotnē. Piesist, lai pievienotu.</value>
<value>Glabātāvā nav vienumu, ko izmantot šajā tīmekļvietnē/lietotnē. Piesist, lai pievienotu.</value>
</data>
<data name="NoUsernamePasswordConfigured" xml:space="preserve">
<value>Šajā pieteikšanās vienumā nav norādīts lietotājvārds vai parole.</value>
@@ -748,7 +748,7 @@
<value>Kad tiek atlasīts ievades lauks un parādās Bitwarden automātiskās aizpildes lodziņš, jāpiesit tam, lai palaistu automātiskās aizpildes pakalpojumu.</value>
</data>
<data name="BitwardenAutofillServiceNotificationContent" xml:space="preserve">
<value>Piesist šim paziņojumam, lai automātiski aizpildītu, izmantojot vienumu no glabātavas.</value>
<value>Jāpiesit šim paziņojumam, lai automātiski aizpildītu ar vienumu no glabātavas.</value>
</data>
<data name="BitwardenAutofillServiceOpenAccessibilitySettings" xml:space="preserve">
<value>Atvērt pieejamības iestatījumus</value>
@@ -775,7 +775,7 @@
<value>Stāvoklis</value>
</data>
<data name="BitwardenAutofillServiceAlert2" xml:space="preserve">
<value>Vieglākais veids, kā glabātavā pievienot jaunus pieteikšanās vienumus, ir no Bitwarden automātiskās aizpildes pakalpojuma. Vairāk par Bitwarden automātiskās aizpildi var uzzināt iestatījumu skatā.</value>
<value>Vieglākais veids, kā glabātavā pievienot jaunus pieteikšanās vienumus, ir ar Bitwarden automātiskās aizpildes pakalpojumu. Vairāk par Bitwarden automātisko aizpildi var uzzināt iestatījumu skatā.</value>
</data>
<data name="Autofill" xml:space="preserve">
<value>Automātiskā aizpilde</value>
@@ -1134,7 +1134,7 @@ Nolasīšana notiks automātiski.</value>
<value>Derīgums</value>
</data>
<data name="ShowWebsiteIcons" xml:space="preserve">
<value>Rādīt vietņu ikonas</value>
<value>Rādīt tīmekļvietņu ikonas</value>
</data>
<data name="ShowWebsiteIconsDescription" xml:space="preserve">
<value>Attēlot atpazīstamu attēlu pie katra pieteikšanās vienuma.</value>
@@ -1143,7 +1143,7 @@ Nolasīšana notiks automātiski.</value>
<value>Ikonu servera URL</value>
</data>
<data name="AutofillWithBitwarden" xml:space="preserve">
<value>Automātiskā aizpilde ar Bitwarden</value>
<value>Automātiski aizpildīt ar Bitwarden</value>
</data>
<data name="VaultIsLocked" xml:space="preserve">
<value>Glabātava ir slēgta</value>
@@ -1170,7 +1170,7 @@ Nolasīšana notiks automātiski.</value>
<value>Bitwarden automātiskās aizpildes pakalpojums izmanto Android automātiskās aizpildes ietvaru, lai palīdzētu aizpildīt pieteikšanās, kredītkartes, un identitātes informācijas veidnes citās ierīces lietotnēs.</value>
</data>
<data name="BitwardenAutofillServiceDescription" xml:space="preserve">
<value>Bitwarden automātiskās aizpilde tiek izmantota, lai aizpildītu pieteikšanās, kredītkaršu un identitātes informācijas veidnes citās lietotnēs.</value>
<value>Bitwarden automātiskā aizpilde ir izmantojama, lai aizpildītu pieteikšanās, kredītkaršu un identitātes informācijas veidnes citās lietotnēs.</value>
</data>
<data name="BitwardenAutofillServiceOpenAutofillSettings" xml:space="preserve">
<value>Atvērt automātiskās aizpildes iestatījumus</value>
@@ -1289,7 +1289,7 @@ Nolasīšana notiks automātiski.</value>
<value>Vispirms ir jāpiesakās galvenajā Bitwarden lietotnē, lai varētu izmantot automātisko aizpildi.</value>
</data>
<data name="AutofillSetup" xml:space="preserve">
<value>Pieteikšanāš vienumi tagad ir viegli pieejami tastatūrā, kad notiek pieteikšanās lietotnēs un tīmekļa vietnēs.</value>
<value>Pieteikšanās vienumi tagad ir viegli pieejami tastatūrā, kad notiek pieteikšanās lietotnēs un tīmekļvietnēs.</value>
</data>
<data name="AutofillSetup2" xml:space="preserve">
<value>Mēs iesakām atspējot jebkuras citas automātiskās aizpildes lietotnes iestatījumos, ja nav iecerēts izmantot tās.</value>
@@ -1462,7 +1462,7 @@ Nolasīšana notiks automātiski.</value>
<comment>A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing.</comment>
</data>
<data name="LearnOrgConfirmation" xml:space="preserve">
<value>Bitwarden nodrošina iespēju kopīgot glabātavas vienumus ar citiem, kad tiek izmantots apvienības konts. Vai apmeklēt bitwarden.com tīmekļa vietni, lai uzzinātu vairāk?</value>
<value>Bitwarden nodrošina iespēju kopīgot glabātavas vienumus ar citiem, kad tiek izmantots apvienības konts. Vai apmeklēt bitwarden.com tīmekļvietni, lai uzzinātu vairāk?</value>
</data>
<data name="ExportVault" xml:space="preserve">
<value>Izgūt glabātavas saturu</value>
@@ -1586,7 +1586,7 @@ Nolasīšana notiks automātiski.</value>
<value>Pārsāknējot lietotni</value>
</data>
<data name="AutofillServiceNotEnabled" xml:space="preserve">
<value>Automātiskā aizpilde padara drošu piekļuvi Bitwarden galbātavai vienkāršu no citām 0tīmekļa vietnēm un lietotnēm. Izskatās, ka nav iespējota Bitwarden automātiskā aizpilde. To var izdarīt iestatījumu sadaļā.</value>
<value>Automātiskā aizpildīšana padara drošu piekļuvi Bitwarden galbātavai vienkāršu no citām tīmekļvietnēm un lietotnēm. Izskatās, ka nav iespējota Bitwarden automātiskā aizpildīšana. To var izdarīt iestatījumu sadaļā.</value>
</data>
<data name="ThemeAppliedOnRestart" xml:space="preserve">
<value>Izskata izmaiņas tiks pielietotas pēc lietotnes pārsāknēšanas.</value>
@@ -1729,7 +1729,7 @@ Nolasīšana notiks automātiski.</value>
<comment>(action prompt) Label for the search text field when viewing the trash folder</comment>
</data>
<data name="DoYouReallyWantToPermanentlyDeleteCipher" xml:space="preserve">
<value>Vai tiešām vēlaties neatgriezeniski dzēst? To nevar atsaukt.</value>
<value>Vai tiešām neatgriezeniski izdzēst? To nevar atsaukt.</value>
<comment>Confirmation alert message when permanently deleteing a cipher.</comment>
</data>
<data name="DoYouReallyWantToRestoreCipher" xml:space="preserve">
@@ -2213,7 +2213,7 @@ Nolasīšana notiks automātiski.</value>
<value>Atgadījās kļūda, kad apliecinājuma kods tika sūtīts uz e-pastu. Lūgums mēģināt vēlreiz</value>
</data>
<data name="EnterTheVerificationCodeThatWasSentToYourEmail" xml:space="preserve">
<value>Ievadīt pārbaudes kodu, kas tika nosūtīts e-pastā</value>
<value>Jāievada apliecinājuma kods, kas tika nosūtīts e-pastā</value>
</data>
<data name="SubmitCrashLogs" xml:space="preserve">
<value>Iesniegt avāriju ierakstus</value>
@@ -2442,7 +2442,7 @@ jāizvēlas "Pievienot TOTP", lai droši glabātu atslēgu.</value>
<value>E-pasta veids</value>
</data>
<data name="WebsiteRequired" xml:space="preserve">
<value>Mājaslapa (nepieciešama)</value>
<value>Tīmekļviente (nepieciešama)</value>
</data>
<data name="UnknownXErrorMessage" xml:space="preserve">
<value>Notika nezināma kļūda {0}.</value>
@@ -2466,7 +2466,7 @@ jāizvēlas "Pievienot TOTP", lai droši glabātu atslēgu.</value>
<value>Pieejamības pakalpojuma izmantošanas skaidrojums</value>
</data>
<data name="AccessibilityDisclosureText" xml:space="preserve">
<value>Bitwarden izmanto pieejamības pakalpojumu, lai meklētu pieteikšanās laukus lietotnēs un tīmekļa vietnēs, tad noskaidro atbistošus lauku identifikatorus lietotājvārda un paroles ievadīšanai, kad ir atrasta atbilstība lietotnei vai vietnei. Bitwarden neglabā neko no informācijas, ko nodrošina pakalpojums, kā arī nemēģina pārvaldīt ekrānā redzamās daļas, kas nav saistītas ar pieteikšanās datu ievadi.</value>
<value>Bitwarden izmanto pieejamības pakalpojumu, lai meklētu pieteikšanās laukus lietotnēs un tīmekļvietnēs, tad noskaidro atbistošus lauku identifikatorus lietotājvārda un paroles ievadīšanai, kad ir atrasta atbilstība lietotnei vai vietnei. Bitwarden neglabā neko no informācijas, ko nodrošina pakalpojums, kā arī nemēģina pārvaldīt ekrānā redzamās daļas, kas nav saistītas ar pieteikšanās datu ievadi.</value>
</data>
<data name="Accept" xml:space="preserve">
<value>Pieņemt</value>
@@ -2850,7 +2850,7 @@ Vai pārslēgties uz šo kontu?</value>
<value>Vairāk sava Bitwarden konta iespēju var izpētīt tīmekļa vietnē.</value>
</data>
<data name="LearnAboutOrganizationsDescriptionLong" xml:space="preserve">
<value>Bitwarden nodrošina iespēju kopīgot savas glabātavas vienumus ar citiem, kad tiek izmantota apvienība. Vairāk var uzzināt bitwarden.com tīmekļa vietnē.</value>
<value>Bitwarden nodrošina iespēju kopīgot savas glabātavas vienumus ar citiem, kad tiek izmantota apvienība. Vairāk var uzzināt bitwarden.com tīmekļvietnē.</value>
</data>
<data name="RateAppDescriptionLong" xml:space="preserve">
<value>Var palīdzēt citiem noskaidrot, vai Bitwarden tiem der. To var izdarīt lietotņu veikalā, atstājot vērtējumu.</value>
@@ -2877,4 +2877,13 @@ Vai pārslēgties uz šo kontu?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Jāuzstāda atslēgšanas iespēja, lai mainītu glabātavas noildzes darbību.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Kontam ir nepieciešama Duo divpakāpju pieteikšanās. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Jāseko Duo norādēm, lai pabeigtu pieteikšanos.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Palaist Duo</value>
</data>
</root>

View File

@@ -2876,4 +2876,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Vil du bytte til denne kontoen?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2876,4 +2876,13 @@ Wilt u naar dit account wisselen?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Stel een ontgrendelingsmethode in om je kluis time-out actie te wijzigen.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Jouw account vereist Duo-tweestapsaanmelding. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Volg de stappen van Duo om in te loggen.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Duo starten</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2876,4 +2876,13 @@ Czy chcesz przełączyć się na to konto?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Ustaw opcje odblokowania, aby zmienić czas blokowania sejfu.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Dwustopniowe logowanie Duo jest wymagane dla Twojego konta. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Wykonaj kroki od Duo, aby zakończyć logowanie.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Uruchom Duo</value>
</data>
</root>

View File

@@ -2822,16 +2822,16 @@ Você deseja mudar para esta conta?</value>
<value>Continuar e contatar o suporte?</value>
</data>
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
<value>Continue to privacy policy?</value>
<value>Continuar para a política de privacidade?</value>
</data>
<data name="ContinueToAppStore" xml:space="preserve">
<value>Continuar para a loja de apps?</value>
</data>
<data name="TwoStepLoginDescriptionLong" xml:space="preserve">
<value>Make your account more secure by setting up two-step login in the Bitwarden web app.</value>
<value>Torne sua conta mais segura configurando o login em duas etapas no aplicativo web do Bitwarden.</value>
</data>
<data name="ChangeMasterPasswordDescriptionLong" xml:space="preserve">
<value>You can change your master password on the Bitwarden web app.</value>
<value>Você pode alterar a sua senha mestra no aplicativo web Bitwarden.</value>
</data>
<data name="YouCanImportDataToYourVaultOnX" xml:space="preserve">
<value>Você pode importar dados para o seu cofre no {0}.</value>
@@ -2841,19 +2841,19 @@ Você deseja mudar para esta conta?</value>
<value>Saiba mais sobre como usar o Bitwarden no centro de ajuda.</value>
</data>
<data name="ContactSupportDescriptionLong" xml:space="preserve">
<value>Cant find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
<value>Não encontrou o que está procurando? Entre em contato com o suporte do Bitwarden em bitwarden.com.</value>
</data>
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
<value>Check out our privacy policy on bitwarden.com.</value>
<value>Confira a nossa política de privacidade em bitwarden.com.</value>
</data>
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
<value>Explore more features of your Bitwarden account on the web app.</value>
<value>Explore mais recursos da sua conta no Bitwarden no aplicativo web.</value>
</data>
<data name="LearnAboutOrganizationsDescriptionLong" xml:space="preserve">
<value>Bitwarden allows you to share your vault items with others by using an organization. Learn more on the bitwarden.com website.</value>
<value>O Bitwarden permite compartilhar os seus itens do cofre com outros ao utilizar uma organização. Gostaria de visitar o site bitwarden.com para saber mais?</value>
</data>
<data name="RateAppDescriptionLong" xml:space="preserve">
<value>Help others find out if Bitwarden is right for them. Visit the app store and leave a rating now.</value>
<value>Ajude outros a descobrir se o Bitwarden é adequado para eles. Visite a loja de aplicativos e deixe uma avaliação agora.</value>
</data>
<data name="DefaultDarkThemeDescriptionLong" xml:space="preserve">
<value>Usar o tema escuro quando o modo escuro do seu dispositivo estiver ativado</value>
@@ -2869,12 +2869,21 @@ Você deseja mudar para esta conta?</value>
<value>Conta desconectada.</value>
</data>
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
<value>Your organization permissions were updated, requiring you to set a master password.</value>
<value>As permissões da sua organização foram atualizadas, exigindo que você defina uma senha mestra.</value>
</data>
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
<value>Your organization requires you to set a master password.</value>
<value>Sua organização requer que você defina uma senha mestra.</value>
</data>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
<value>Configure um método de desbloqueio para alterar o tempo limite do cofre.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -172,7 +172,7 @@
<comment>Message shown when interacting with the server</comment>
</data>
<data name="DoYouReallyWantToDelete" xml:space="preserve">
<value>Pretende mesmo eliminar? Isto não pode ser anulado.</value>
<value>Pretende mesmo eliminar? Esta ação não pode ser anulada.</value>
<comment>Confirmation alert message when deleteing something.</comment>
</data>
<data name="Edit" xml:space="preserve">
@@ -193,7 +193,7 @@
<value>Enviar-nos um e-mail</value>
</data>
<data name="EmailUsDescription" xml:space="preserve">
<value>Envie-nos um e-mail diretamente para obter ajuda ou deixar feedback.</value>
<value>Envie-nos um e-mail diretamente para obter ajuda ou dar feedback.</value>
</data>
<data name="EnterPIN" xml:space="preserve">
<value>Introduza o seu código PIN.</value>
@@ -206,7 +206,7 @@
<value>Apresentar um relatório de erros</value>
</data>
<data name="FileBugReportDescription" xml:space="preserve">
<value>Abrir um issue no nosso repositório do GitHub.</value>
<value>Abra um problema no nosso repositório do GitHub.</value>
</data>
<data name="FingerprintDirection" xml:space="preserve">
<value>Utilize a sua impressão digital para verificar.</value>
@@ -443,7 +443,7 @@
<value>Alterar e-mail</value>
</data>
<data name="ChangeEmailConfirmation" xml:space="preserve">
<value>Pode alterar o seu endereço de e-mail no cofre do site bitwarden.com. Deseja visitar o site agora?</value>
<value>Pode alterar o seu endereço de e-mail no cofre do site bitwarden.com. Pretende visitar o site agora?</value>
</data>
<data name="ChangeMasterPassword" xml:space="preserve">
<value>Alterar palavra-passe mestra</value>
@@ -511,13 +511,13 @@
<value>Gerar palavra-passe</value>
</data>
<data name="GetPasswordHint" xml:space="preserve">
<value>Obter dica da palavra-passe mestra</value>
<value>Obter a dica da sua palavra-passe mestra</value>
</data>
<data name="ImportItems" xml:space="preserve">
<value>Importar itens</value>
</data>
<data name="ImportItemsConfirmation" xml:space="preserve">
<value>Pode importar itens em massa do cofre do site bitwarden.com. Deseja visitar o site agora?</value>
<value>Pode importar itens em massa do cofre do site bitwarden.com. Pretende visitar o site agora?</value>
</data>
<data name="ImportItemsDescription" xml:space="preserve">
<value>Importe rapidamente e em massa os seus itens de outras aplicações de gestão de palavras-passe.</value>
@@ -613,7 +613,7 @@
<value>Esta credencial não tem um nome de utilizador ou palavra-passe configurados.</value>
</data>
<data name="OkGotIt" xml:space="preserve">
<value>Ok, entendido!</value>
<value>Ok, percebido!</value>
<comment>Confirmation, like "Ok, I understand it"</comment>
</data>
<data name="OptionDefaults" xml:space="preserve">
@@ -718,7 +718,7 @@
<value>Ver item</value>
</data>
<data name="WebVault" xml:space="preserve">
<value>Cofre web Bitwarden</value>
<value>Cofre Web Bitwarden</value>
</data>
<data name="Lost2FAApp" xml:space="preserve">
<value>Perdeu a aplicação de autenticação?</value>
@@ -895,7 +895,7 @@
A leitura será efetuada automaticamente.</value>
</data>
<data name="ScanQrTitle" xml:space="preserve">
<value>Digitalizar código QR</value>
<value>Ler código QR</value>
</data>
<data name="Camera" xml:space="preserve">
<value>Câmara</value>
@@ -964,7 +964,7 @@ A leitura será efetuada automaticamente.</value>
<value>Os URLs de ambiente foram guardados.</value>
</data>
<data name="FormattedIncorrectly" xml:space="preserve">
<value>{0} não está formatado corretamente.</value>
<value>{0} não está corretamente formatado.</value>
<comment>Validation error when something is not formatted correctly, such as a URL or email address.</comment>
</data>
<data name="IdentityUrl" xml:space="preserve">
@@ -981,7 +981,7 @@ A leitura será efetuada automaticamente.</value>
<value>URL do servidor</value>
</data>
<data name="WebVaultUrl" xml:space="preserve">
<value>URL do servidor do cofre web</value>
<value>URL do servidor do cofre Web</value>
</data>
<data name="BitwardenAutofillServiceNotificationContentOld" xml:space="preserve">
<value>Toque nesta notificação para ver itens do seu cofre.</value>
@@ -1131,7 +1131,7 @@ A leitura será efetuada automaticamente.</value>
<value>Endereço</value>
</data>
<data name="Expiration" xml:space="preserve">
<value>Expiração</value>
<value>Prazo de validade</value>
</data>
<data name="ShowWebsiteIcons" xml:space="preserve">
<value>Mostrar ícones do site</value>
@@ -1201,7 +1201,7 @@ A leitura será efetuada automaticamente.</value>
<value>Booleano</value>
</data>
<data name="FieldTypeHidden" xml:space="preserve">
<value>Ocultado</value>
<value>Oculto</value>
</data>
<data name="FieldTypeLinked" xml:space="preserve">
<value>Associado</value>
@@ -1263,7 +1263,7 @@ A leitura será efetuada automaticamente.</value>
<comment>An entity of multiple related people (ex. a team or business organization).</comment>
</data>
<data name="HoldYubikeyNearTop" xml:space="preserve">
<value>Segure a sua Yubikey perto do topo do dispositivo.</value>
<value>Segure a sua Yubikey perto da parte superior do dispositivo.</value>
</data>
<data name="TryAgain" xml:space="preserve">
<value>Tentar novamente</value>
@@ -1310,7 +1310,7 @@ A leitura será efetuada automaticamente.</value>
<value>3. Toque em "Autopreenchimento de palavras-passe"</value>
</data>
<data name="AutofillTurnOn4" xml:space="preserve">
<value>4. Ligue o Autopreenchimento</value>
<value>4. Ative o Autopreenchimento</value>
</data>
<data name="AutofillTurnOn5" xml:space="preserve">
<value>5. Selecione "Bitwarden"</value>
@@ -1369,10 +1369,10 @@ A leitura será efetuada automaticamente.</value>
<value>Tipos</value>
</data>
<data name="NoPasswordsToList" xml:space="preserve">
<value>Nenhuma palavra-passe para listar.</value>
<value>Não há palavras-passe a enumerar.</value>
</data>
<data name="NoItemsToList" xml:space="preserve">
<value>Não existem itens para listar.</value>
<value>Não há itens a enumerar.</value>
</data>
<data name="SearchCollection" xml:space="preserve">
<value>Procurar na coleção</value>
@@ -1406,7 +1406,7 @@ A leitura será efetuada automaticamente.</value>
<value>Quem é o proprietário deste item?</value>
</data>
<data name="NoCollectionsToList" xml:space="preserve">
<value>Não existem coleções para listar.</value>
<value>Não coleções a enumerar.</value>
</data>
<data name="MovedItemToOrg" xml:space="preserve">
<value>{0} movido para {1}.</value>
@@ -1428,7 +1428,7 @@ A leitura será efetuada automaticamente.</value>
<value>Mover para organização</value>
</data>
<data name="NoOrgsToList" xml:space="preserve">
<value>Nenhuma organização para listar.</value>
<value>Não há organizações a enumerar.</value>
</data>
<data name="MoveToOrgDesc" xml:space="preserve">
<value>Escolha uma organização para a qual pretende mover este item. Mover para uma organização transfere a propriedade do item para essa organização. Deixará de ser o proprietário direto deste item depois de este ter sido movido.</value>
@@ -1451,7 +1451,7 @@ A leitura será efetuada automaticamente.</value>
<comment>Short for "Password Generator"</comment>
</data>
<data name="NoFoldersToList" xml:space="preserve">
<value>Não existem pastas para listar.</value>
<value>Não pastas a enumerar.</value>
</data>
<data name="FingerprintPhrase" xml:space="preserve">
<value>Frase de impressão digital</value>
@@ -1556,7 +1556,7 @@ A leitura será efetuada automaticamente.</value>
<value>Sair</value>
</data>
<data name="ExitConfirmation" xml:space="preserve">
<value>Tem a certeza de que deseja sair do Bitwarden?</value>
<value>Tem a certeza de que pretende sair do Bitwarden?</value>
</data>
<data name="PINRequireMasterPasswordRestart" xml:space="preserve">
<value>Pretende exigir o desbloqueio com a sua palavra-passe mestra quando a aplicação é reiniciada?</value>
@@ -1570,7 +1570,7 @@ A leitura será efetuada automaticamente.</value>
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
</data>
<data name="SolarizedDark" xml:space="preserve">
<value>Solarized (escuro)</value>
<value>Solarized Dark</value>
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
</data>
<data name="AutofillBlockedUris" xml:space="preserve">
@@ -1583,7 +1583,7 @@ A leitura será efetuada automaticamente.</value>
<value>Pedir para adicionar um item se não o encontrar no seu cofre.</value>
</data>
<data name="OnRestart" xml:space="preserve">
<value>Quando reiniciar a aplicação</value>
<value>Ao reiniciar a aplicação</value>
</data>
<data name="AutofillServiceNotEnabled" xml:space="preserve">
<value>O preenchimento automático facilita o acesso seguro ao seu cofre do Bitwarden a partir de outros sites e aplicações. Parece que o utilizador não configurou um serviço de preenchimento automático do Bitwarden. Configure o preenchimento automático do Bitwarden a partir do ecrã "Definições".</value>
@@ -1617,7 +1617,7 @@ A leitura será efetuada automaticamente.</value>
<value>Biometria</value>
</data>
<data name="UseBiometricsToUnlock" xml:space="preserve">
<value>Utilizar biometria para desbloquear</value>
<value>Utilizar a biometria para desbloquear</value>
</data>
<data name="AccessibilityOverlayPermissionAlert" xml:space="preserve">
<value>O Bitwarden precisa de atenção - Veja o "Serviço de acessibilidade de preenchimento automático" nas definições do Bitwarden</value>
@@ -1689,7 +1689,7 @@ A leitura será efetuada automaticamente.</value>
<comment>Button text for an open operation (verb).</comment>
</data>
<data name="UnableToSaveAttachment" xml:space="preserve">
<value>Houve um problema ao guardar este anexo. Se o problema persistir, poderá guardá-lo através do cofre web.</value>
<value>Houve um problema ao guardar este anexo. Se o problema persistir, poderá guardá-lo através do cofre Web.</value>
</data>
<data name="SaveAttachmentSuccess" xml:space="preserve">
<value>Anexo guardado com sucesso</value>
@@ -1701,7 +1701,7 @@ A leitura será efetuada automaticamente.</value>
<value>Nenhum campo de palavra-passe detetado</value>
</data>
<data name="SoftDeleting" xml:space="preserve">
<value>A enviar para o lixo...</value>
<value>A mover para o lixo...</value>
<comment>Message shown when interacting with the server</comment>
</data>
<data name="ItemSoftDeleted" xml:space="preserve">
@@ -1729,7 +1729,7 @@ A leitura será efetuada automaticamente.</value>
<comment>(action prompt) Label for the search text field when viewing the trash folder</comment>
</data>
<data name="DoYouReallyWantToPermanentlyDeleteCipher" xml:space="preserve">
<value>Pretende mesmo eliminar permanentemente? Isto não pode ser anulado.</value>
<value>Pretende mesmo eliminar permanentemente? Esta ação não pode ser anulada.</value>
<comment>Confirmation alert message when permanently deleteing a cipher.</comment>
</data>
<data name="DoYouReallyWantToRestoreCipher" xml:space="preserve">
@@ -1737,7 +1737,7 @@ A leitura será efetuada automaticamente.</value>
<comment>Confirmation alert message when restoring a soft-deleted cipher.</comment>
</data>
<data name="DoYouReallyWantToSoftDeleteCipher" xml:space="preserve">
<value>Pretende mesmo enviar para o lixo?</value>
<value>Pretende mesmo mover para o lixo?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="AccountBiometricInvalidated" xml:space="preserve">
@@ -1762,10 +1762,10 @@ A leitura será efetuada automaticamente.</value>
<value>Identificador da organização</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Não foi possível iniciar sessão com SSO</value>
<value>Atualmente não é possível iniciar sessão com SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Definir palavra-passe mestra</value>
<value>Definir a palavra-passe mestra</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Para concluir o início de sessão com SSO, por favor, defina uma palavra-passe mestra para aceder e proteger o seu cofre.</value>
@@ -1880,7 +1880,7 @@ A leitura será efetuada automaticamente.</value>
<value>Texto</value>
</data>
<data name="TypeTextInfo" xml:space="preserve">
<value>O texto que deseja enviar.</value>
<value>O texto que pretende enviar.</value>
</data>
<data name="HideTextByDefault" xml:space="preserve">
<value>Ao aceder ao Send, ocultar o texto por defeito</value>
@@ -1890,7 +1890,7 @@ A leitura será efetuada automaticamente.</value>
<value>Ficheiro</value>
</data>
<data name="TypeFileInfo" xml:space="preserve">
<value>O ficheiro que deseja enviar.</value>
<value>O ficheiro que pretende enviar.</value>
</data>
<data name="FileTypeIsSelected" xml:space="preserve">
<value>O tipo de ficheiro está selecionado.</value>
@@ -1908,7 +1908,7 @@ A leitura será efetuada automaticamente.</value>
<value>Data de eliminação</value>
</data>
<data name="DeletionTime" xml:space="preserve">
<value>Hora da eliminação</value>
<value>Hora de eliminação</value>
</data>
<data name="DeletionDateInfo" xml:space="preserve">
<value>O Send será permanentemente eliminado na data e hora especificadas.</value>
@@ -1918,7 +1918,7 @@ A leitura será efetuada automaticamente.</value>
<value>Eliminação pendente</value>
</data>
<data name="ExpirationDate" xml:space="preserve">
<value>Data de validade</value>
<value>Prazo de validade</value>
</data>
<data name="ExpirationTime" xml:space="preserve">
<value>Hora de validade</value>
@@ -1954,7 +1954,7 @@ A leitura será efetuada automaticamente.</value>
<value>Remover palavra-passe</value>
</data>
<data name="AreYouSureRemoveSendPassword" xml:space="preserve">
<value>Tem a certeza de que pretende remover a palavras-passe?</value>
<value>Tem a certeza de que pretende remover a palavra-passe?</value>
</data>
<data name="RemovingSendPassword" xml:space="preserve">
<value>A remover palavra-passe</value>
@@ -2009,7 +2009,7 @@ A leitura será efetuada automaticamente.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="SendUpdated" xml:space="preserve">
<value>Send atualizado</value>
<value>Send guardado</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="NewSendCreated" xml:space="preserve">
@@ -2058,7 +2058,7 @@ A leitura será efetuada automaticamente.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="SendFileEmailVerificationRequired" xml:space="preserve">
<value>Tem de verificar o seu e-mail para utilizar ficheiros com o Send. Pode verificar o seu e-mail no cofre web.</value>
<value>Tem de verificar o seu e-mail para utilizar ficheiros com o Send. Pode verificar o seu e-mail no cofre Web.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="PasswordPrompt" xml:space="preserve">
@@ -2080,7 +2080,7 @@ A leitura será efetuada automaticamente.</value>
<value>Palavra-passe mestra atualizada</value>
</data>
<data name="UpdateMasterPassword" xml:space="preserve">
<value>Atualizar palavra-passe mestra</value>
<value>Atualizar a palavra-passe mestra</value>
</data>
<data name="UpdateMasterPasswordWarning" xml:space="preserve">
<value>A sua palavra-passe mestra foi recentemente alterada por um administrador da sua organização. Para aceder ao cofre, tem de atualizar a sua palavra-passe mestra agora. Ao prosseguir, terminará a sua sessão atual e terá de iniciar sessão novamente. As sessões ativas noutros dispositivos poderão continuar ativas até uma hora.</value>
@@ -2221,10 +2221,10 @@ A leitura será efetuada automaticamente.</value>
<value>Ajude o Bitwarden a melhorar a estabilidade da aplicação ao enviar relatórios de falhas.</value>
</data>
<data name="OptionsExpanded" xml:space="preserve">
<value>As opções foram expandidas, clique para fechar.</value>
<value>As opções estão expandidas, clique para as fechar.</value>
</data>
<data name="OptionsCollapsed" xml:space="preserve">
<value>As opções foram fechadas, clique para expandir.</value>
<value>As opções estão fechadas, clique para as expandir.</value>
</data>
<data name="UppercaseAtoZ" xml:space="preserve">
<value>Maiúsculas (A-Z)</value>
@@ -2311,7 +2311,7 @@ A leitura será efetuada automaticamente.</value>
<value>Tem a certeza de que pretende ativar a captura de ecrã?</value>
</data>
<data name="LogInRequested" xml:space="preserve">
<value>Início de sessão pedido</value>
<value>Pedido de início de sessão</value>
</data>
<data name="AreYouTryingToLogIn" xml:space="preserve">
<value>Está a tentar iniciar sessão?</value>
@@ -2326,7 +2326,7 @@ A leitura será efetuada automaticamente.</value>
<value>Endereço IP</value>
</data>
<data name="Time" xml:space="preserve">
<value>Tempo</value>
<value>Hora</value>
</data>
<data name="Near" xml:space="preserve">
<value>Perto</value>
@@ -2458,7 +2458,7 @@ A leitura será efetuada automaticamente.</value>
<value>Aleatório</value>
</data>
<data name="ConnectToWatch" xml:space="preserve">
<value>Ligar ao relógio</value>
<value>Ligar ao Relógio</value>
</data>
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
<value>Divulgação do serviço de acessibilidade</value>
@@ -2484,7 +2484,7 @@ Deseja mudar para esta conta?</value>
<value>É novo por cá?</value>
</data>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Obter dica da palavra-passe mestra</value>
<value>Obter a dica da palavra-passe mestra</value>
</data>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>A iniciar sessão como {0} em {1}</value>
@@ -2758,10 +2758,10 @@ Deseja mudar para esta conta?</value>
<value>Segurança da conta</value>
</data>
<data name="BitwardenHelpCenter" xml:space="preserve">
<value>Centro de ajuda Bitwarden</value>
<value>Centro de ajuda do Bitwarden</value>
</data>
<data name="ContactBitwardenSupport" xml:space="preserve">
<value>Contactar o suporte Bitwarden</value>
<value>Contactar o suporte do Bitwarden</value>
</data>
<data name="CopyAppInformation" xml:space="preserve">
<value>Copiar informações da aplicação</value>
@@ -2807,7 +2807,7 @@ Deseja mudar para esta conta?</value>
<value>Opções adicionais</value>
</data>
<data name="ContinueToWebApp" xml:space="preserve">
<value>Continuar para a aplicação web?</value>
<value>Continuar para a aplicação Web?</value>
</data>
<data name="ContinueToX" xml:space="preserve">
<value>Continuar para {0}?</value>
@@ -2826,10 +2826,10 @@ Deseja mudar para esta conta?</value>
<value>Continuar para a loja de aplicações?</value>
</data>
<data name="TwoStepLoginDescriptionLong" xml:space="preserve">
<value>Torne a sua conta mais segura configurando o login em duas etapas na aplicação web Bitwarden.</value>
<value>Torne a sua conta mais segura configurando a verificação de dois passos na aplicação Web Bitwarden.</value>
</data>
<data name="ChangeMasterPasswordDescriptionLong" xml:space="preserve">
<value>Pode alterar a sua palavra-passe mestra na aplicação web Bitwarden.</value>
<value>Pode alterar a sua palavra-passe mestra na aplicação Web Bitwarden.</value>
</data>
<data name="YouCanImportDataToYourVaultOnX" xml:space="preserve">
<value>Pode importar dados para o seu cofre em {0}.</value>
@@ -2845,13 +2845,13 @@ Deseja mudar para esta conta?</value>
<value>Consulte a nossa política de privacidade em bitwarden.com.</value>
</data>
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
<value>Explore mais funcionalidades da sua conta Bitwarden na aplicação web.</value>
<value>Explore mais funcionalidades da sua conta Bitwarden na aplicação Web.</value>
</data>
<data name="LearnAboutOrganizationsDescriptionLong" xml:space="preserve">
<value>O Bitwarden permite-lhe partilhar os seus itens do cofre com outras pessoas através da utilização de uma organização. Saiba mais no site bitwarden.com.</value>
</data>
<data name="RateAppDescriptionLong" xml:space="preserve">
<value>Ajude outras pessoas a descobrir se o Bitwarden é adequado para elas. Visite a loja de aplicações e deixe uma avaliação agora.</value>
<value>Ajude outras pessoas a descobrir se o Bitwarden lhes é adequado. Visite a loja de aplicações e deixe uma avaliação agora.</value>
</data>
<data name="DefaultDarkThemeDescriptionLong" xml:space="preserve">
<value>Escolha o tema escuro a utilizar quando o modo escuro do seu dispositivo estiver a ser utilizado</value>
@@ -2875,4 +2875,13 @@ Deseja mudar para esta conta?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Configure uma opção de desbloqueio para alterar a ação de tempo limite do seu cofre.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>A verificação de dois passos Duo é necessária para a sua conta. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Siga os passos do Duo para concluir o início de sessão.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Iniciar o Duo</value>
</data>
</root>

View File

@@ -2877,4 +2877,13 @@ Do you want to switch to this account?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2876,4 +2876,13 @@ Doriți să comutați la acest cont?</value>
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Set up an unlock option to change your vault timeout action.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Duo two-step login is required for your account. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Follow the steps from Duo to finish logging in.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Launch Duo</value>
</data>
</root>

View File

@@ -2878,4 +2878,13 @@
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
<value>Настройте опцию разблокировки для изменения действия по тайм-ауту хранилища.</value>
</data>
<data name="DuoTwoStepLoginIsRequiredForYourAccount" xml:space="preserve">
<value>Для вашего аккаунта требуется двухэтапная аутентификация Duo. </value>
</data>
<data name="FollowTheStepsFromDuoToFinishLoggingIn" xml:space="preserve">
<value>Следуйте указаниям Duo, чтобы завершить авторизацию.</value>
</data>
<data name="LaunchDuo" xml:space="preserve">
<value>Запустить Duo</value>
</data>
</root>

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