mirror of
https://github.com/bitwarden/mobile
synced 2025-12-05 23:53:33 +00:00
Merge branch 'main' into feature/maui-migration-passkeys
# Conflicts: # .github/workflows/build.yml # nuget.config # src/App/App.csproj # src/App/Platforms/Android/AndroidManifest.xml # src/App/Platforms/iOS/AppDelegate.cs # src/Core/Core.csproj # src/Core/Pages/Settings/AutofillSettingsPageViewModel.android.cs # src/Core/Utilities/ThemeManager.cs # src/iOS.Autofill/CredentialProviderViewController.cs # src/iOS.Autofill/iOS.Autofill.csproj
This commit is contained in:
4
.github/CODEOWNERS
vendored
4
.github/CODEOWNERS
vendored
@@ -11,11 +11,11 @@
|
|||||||
.github/workflows @bitwarden/dept-devops
|
.github/workflows @bitwarden/dept-devops
|
||||||
|
|
||||||
# DevOps for Version Bumping
|
# DevOps for Version Bumping
|
||||||
src/Android/Properties/AndroidManifest.xml
|
src/App/Platforms/Android/AndroidManifest.xml
|
||||||
src/iOS.Autofill/Info.plist
|
src/iOS.Autofill/Info.plist
|
||||||
src/iOS.Extension/Info.plist
|
src/iOS.Extension/Info.plist
|
||||||
src/iOS.ShareExtension/Info.plist
|
src/iOS.ShareExtension/Info.plist
|
||||||
src/iOS/Info.plist
|
src/App/Platforms/iOS/Info.plist
|
||||||
|
|
||||||
## Auth team files ##
|
## Auth team files ##
|
||||||
|
|
||||||
|
|||||||
22
.github/workflows/build.yml
vendored
22
.github/workflows/build.yml
vendored
@@ -226,7 +226,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload Prod .aab artifact
|
- name: Upload Prod .aab artifact
|
||||||
if: ${{ matrix.variant == 'prod' }}
|
if: ${{ matrix.variant == 'prod' }}
|
||||||
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||||
with:
|
with:
|
||||||
name: com.x8bit.bitwarden.aab
|
name: com.x8bit.bitwarden.aab
|
||||||
path: ./com.x8bit.bitwarden.aab
|
path: ./com.x8bit.bitwarden.aab
|
||||||
@@ -234,7 +234,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload Prod .apk artifact
|
- name: Upload Prod .apk artifact
|
||||||
if: ${{ matrix.variant == 'prod' }}
|
if: ${{ matrix.variant == 'prod' }}
|
||||||
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||||
with:
|
with:
|
||||||
name: com.x8bit.bitwarden.apk
|
name: com.x8bit.bitwarden.apk
|
||||||
path: ./com.x8bit.bitwarden.apk
|
path: ./com.x8bit.bitwarden.apk
|
||||||
@@ -242,7 +242,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload Other .apk artifact
|
- name: Upload Other .apk artifact
|
||||||
if: ${{ matrix.variant != 'prod' }}
|
if: ${{ matrix.variant != 'prod' }}
|
||||||
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||||
with:
|
with:
|
||||||
name: com.x8bit.bitwarden.${{ matrix.variant }}.apk
|
name: com.x8bit.bitwarden.${{ matrix.variant }}.apk
|
||||||
path: ./com.x8bit.bitwarden.${{ matrix.variant }}.apk
|
path: ./com.x8bit.bitwarden.${{ matrix.variant }}.apk
|
||||||
@@ -262,7 +262,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload .apk sha file for prod
|
- name: Upload .apk sha file for prod
|
||||||
if: ${{ matrix.variant == 'prod' }}
|
if: ${{ matrix.variant == 'prod' }}
|
||||||
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||||
with:
|
with:
|
||||||
name: bw-android-apk-sha256.txt
|
name: bw-android-apk-sha256.txt
|
||||||
path: ./bw-android-apk-sha256.txt
|
path: ./bw-android-apk-sha256.txt
|
||||||
@@ -270,7 +270,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload .apk sha file for other
|
- name: Upload .apk sha file for other
|
||||||
if: ${{ matrix.variant != 'prod' }}
|
if: ${{ matrix.variant != 'prod' }}
|
||||||
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||||
with:
|
with:
|
||||||
name: bw-android-${{ matrix.variant }}-apk-sha256.txt
|
name: bw-android-${{ matrix.variant }}-apk-sha256.txt
|
||||||
path: ./bw-android-${{ matrix.variant }}-apk-sha256.txt
|
path: ./bw-android-${{ matrix.variant }}-apk-sha256.txt
|
||||||
@@ -422,7 +422,7 @@ jobs:
|
|||||||
Copy-Item $signedApkPath $signedApkDestPath
|
Copy-Item $signedApkPath $signedApkDestPath
|
||||||
|
|
||||||
- name: Upload F-Droid .apk artifact
|
- name: Upload F-Droid .apk artifact
|
||||||
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||||
with:
|
with:
|
||||||
name: com.x8bit.bitwarden-fdroid.apk
|
name: com.x8bit.bitwarden-fdroid.apk
|
||||||
path: ./com.x8bit.bitwarden-fdroid.apk
|
path: ./com.x8bit.bitwarden-fdroid.apk
|
||||||
@@ -434,7 +434,7 @@ jobs:
|
|||||||
-t sha256 | Out-File -Encoding ASCII ./bw-fdroid-apk-sha256.txt
|
-t sha256 | Out-File -Encoding ASCII ./bw-fdroid-apk-sha256.txt
|
||||||
|
|
||||||
- name: Upload F-Droid sha file
|
- name: Upload F-Droid sha file
|
||||||
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||||
with:
|
with:
|
||||||
name: bw-fdroid-apk-sha256.txt
|
name: bw-fdroid-apk-sha256.txt
|
||||||
path: ./bw-fdroid-apk-sha256.txt
|
path: ./bw-fdroid-apk-sha256.txt
|
||||||
@@ -529,6 +529,8 @@ jobs:
|
|||||||
echo "##### Setting CFBundleVersion $BUILD_NUMBER"
|
echo "##### Setting CFBundleVersion $BUILD_NUMBER"
|
||||||
echo "########################################"
|
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
|
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
|
||||||
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.Extension/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.Extension/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.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.Autofill/Info.plist
|
||||||
@@ -662,7 +664,7 @@ jobs:
|
|||||||
cp -r -v $WATCH_ARCHIVE_DSYMS_PATH $WATCH_DSYMS_EXPORT_PATH
|
cp -r -v $WATCH_ARCHIVE_DSYMS_PATH $WATCH_DSYMS_EXPORT_PATH
|
||||||
|
|
||||||
- name: Upload App Store .ipa & dSYMs artifacts
|
- name: Upload App Store .ipa & dSYMs artifacts
|
||||||
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||||
with:
|
with:
|
||||||
name: Bitwarden iOS
|
name: Bitwarden iOS
|
||||||
path: |
|
path: |
|
||||||
@@ -671,7 +673,7 @@ jobs:
|
|||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .app file for Automation CI
|
- name: Upload .app file for Automation CI
|
||||||
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||||
with:
|
with:
|
||||||
name: ${{ env.app_ci_output_filename }}.app.zip
|
name: ${{ env.app_ci_output_filename }}.app.zip
|
||||||
path: ./bitwarden-export/${{ env.app_ci_output_filename }}.app.zip
|
path: ./bitwarden-export/${{ env.app_ci_output_filename }}.app.zip
|
||||||
@@ -768,7 +770,7 @@ jobs:
|
|||||||
secrets: "crowdin-api-token"
|
secrets: "crowdin-api-token"
|
||||||
|
|
||||||
- name: Upload Sources
|
- name: Upload Sources
|
||||||
uses: crowdin/github-action@97bef4fd3f1b853eb105bc99b8d0d563760e024c # v1.17.0
|
uses: crowdin/github-action@198daeb2d30636c4608d6a6bb96c009dbefc02a2 # v1.18.0
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
||||||
|
|||||||
2
.github/workflows/crowdin-pull.yml
vendored
2
.github/workflows/crowdin-pull.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
|||||||
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
|
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
|
||||||
|
|
||||||
- name: Download translations
|
- name: Download translations
|
||||||
uses: crowdin/github-action@97bef4fd3f1b853eb105bc99b8d0d563760e024c # v1.17.0
|
uses: crowdin/github-action@198daeb2d30636c4608d6a6bb96c009dbefc02a2 # v1.18.0
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
||||||
|
|||||||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create GitHub deployment
|
- name: Create GitHub deployment
|
||||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||||
uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5
|
uses: chrnorm/deployment-action@55729fcebec3d284f60f5bcabbd8376437d696b1 # v2.0.7
|
||||||
id: deployment
|
id: deployment
|
||||||
with:
|
with:
|
||||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
@@ -87,7 +87,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||||
uses: ncipollo/release-action@6c75be85e571768fa31b40abf38de58ba0397db5 # v1.13.0
|
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
|
||||||
with:
|
with:
|
||||||
artifacts: "./com.x8bit.bitwarden.aab/com.x8bit.bitwarden.aab,
|
artifacts: "./com.x8bit.bitwarden.aab/com.x8bit.bitwarden.aab,
|
||||||
./com.x8bit.bitwarden.apk/com.x8bit.bitwarden.apk,
|
./com.x8bit.bitwarden.apk/com.x8bit.bitwarden.apk,
|
||||||
@@ -147,7 +147,7 @@ jobs:
|
|||||||
name: com.x8bit.bitwarden-fdroid.apk
|
name: com.x8bit.bitwarden-fdroid.apk
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||||
with:
|
with:
|
||||||
node-version: '16.x'
|
node-version: '16.x'
|
||||||
|
|
||||||
|
|||||||
37
.github/workflows/version-auto-bump.yml
vendored
37
.github/workflows/version-auto-bump.yml
vendored
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
name: Version Auto Bump
|
name: Auto Bump Mobile Version
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -7,14 +7,12 @@ on:
|
|||||||
- v**
|
- v**
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
setup:
|
bump-version:
|
||||||
name: "Setup"
|
name: Bump Mobile Version
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
outputs:
|
|
||||||
version_number: ${{ steps.version.outputs.new-version }}
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Branch
|
- name: Checkout Branch
|
||||||
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Calculate bumped version
|
- name: Calculate bumped version
|
||||||
id: version
|
id: version
|
||||||
@@ -29,12 +27,23 @@ jobs:
|
|||||||
NEW_PATCH=$((CURR_PATCH+1))
|
NEW_PATCH=$((CURR_PATCH+1))
|
||||||
NEW_VER=$CURR_MAJOR.$NEW_PATCH
|
NEW_VER=$CURR_MAJOR.$NEW_PATCH
|
||||||
echo "New Version: $NEW_VER"
|
echo "New Version: $NEW_VER"
|
||||||
echo "new-version=$NEW_VER" >> $GITHUB_OUTPUT
|
echo "new_version=$NEW_VER" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
trigger_version_bump:
|
- name: Login to Azure - CI Subscription
|
||||||
name: Bump version to ${{ needs.setup.outputs.version_number }}
|
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||||
needs: setup
|
with:
|
||||||
uses: ./.github/workflows/version-bump.yml
|
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||||
with:
|
|
||||||
version_number: ${{ needs.setup.outputs.version_number }}
|
- name: Retrieve bot secrets
|
||||||
secrets: inherit
|
id: retrieve-bot-secrets
|
||||||
|
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||||
|
with:
|
||||||
|
keyvault: bitwarden-ci
|
||||||
|
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
|
||||||
|
|
||||||
|
- name: "Bump version to ${{ steps.version.outputs.new_version }}"
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ steps.retrieve-bot-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
|
||||||
|
run: |
|
||||||
|
echo '{"cut_rc_branch": "false", "version_number": "${{ steps.version.outputs.new_version }}"}' | \
|
||||||
|
gh workflow run version-bump.yml --json --repo bitwarden/mobile
|
||||||
24
.github/workflows/version-bump.yml
vendored
24
.github/workflows/version-bump.yml
vendored
@@ -72,7 +72,7 @@ jobs:
|
|||||||
CURRENT_VERSION=$(xmllint --xpath '
|
CURRENT_VERSION=$(xmllint --xpath '
|
||||||
string(/manifest/@*[local-name()="versionName"
|
string(/manifest/@*[local-name()="versionName"
|
||||||
and namespace-uri()="http://schemas.android.com/apk/res/android"])
|
and namespace-uri()="http://schemas.android.com/apk/res/android"])
|
||||||
' src/Android/Properties/AndroidManifest.xml)
|
' src/App/Platforms/Android/AndroidManifest.xml)
|
||||||
|
|
||||||
# Error if version has not changed.
|
# Error if version has not changed.
|
||||||
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
|
if [[ "$NEW_VERSION" == "$CURRENT_VERSION" ]]; then
|
||||||
@@ -93,7 +93,7 @@ jobs:
|
|||||||
uses: bitwarden/gh-actions/version-bump@main
|
uses: bitwarden/gh-actions/version-bump@main
|
||||||
with:
|
with:
|
||||||
version: ${{ inputs.version_number }}
|
version: ${{ inputs.version_number }}
|
||||||
file_path: "src/Android/Properties/AndroidManifest.xml"
|
file_path: "src/App/Platforms/Android/AndroidManifest.xml"
|
||||||
|
|
||||||
- name: Bump Version - iOS.Autofill
|
- name: Bump Version - iOS.Autofill
|
||||||
uses: bitwarden/gh-actions/version-bump@main
|
uses: bitwarden/gh-actions/version-bump@main
|
||||||
@@ -117,7 +117,7 @@ jobs:
|
|||||||
uses: bitwarden/gh-actions/version-bump@main
|
uses: bitwarden/gh-actions/version-bump@main
|
||||||
with:
|
with:
|
||||||
version: ${{ inputs.version_number }}
|
version: ${{ inputs.version_number }}
|
||||||
file_path: "src/iOS/Info.plist"
|
file_path: "src/App/Platforms/iOS/Info.plist"
|
||||||
|
|
||||||
- name: Setup git
|
- name: Setup git
|
||||||
run: |
|
run: |
|
||||||
@@ -191,22 +191,26 @@ jobs:
|
|||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
with:
|
with:
|
||||||
ref: main
|
ref: main
|
||||||
|
|
||||||
|
- name: Install xmllint
|
||||||
|
run: sudo apt install -y libxml2-utils
|
||||||
|
|
||||||
- name: Verify version has been updated
|
- name: Verify version has been updated
|
||||||
env:
|
env:
|
||||||
NEW_VERSION: ${{ inputs.version_number }}
|
NEW_VERSION: ${{ inputs.version_number }}
|
||||||
run: |
|
run: |
|
||||||
CURRENT_VERSION=$(xmllint --xpath '
|
# Wait for version to change.
|
||||||
|
while : ; do
|
||||||
|
echo "Waiting for version to be updated..."
|
||||||
|
git pull --force
|
||||||
|
CURRENT_VERSION=$(xmllint --xpath '
|
||||||
string(/manifest/@*[local-name()="versionName"
|
string(/manifest/@*[local-name()="versionName"
|
||||||
and namespace-uri()="http://schemas.android.com/apk/res/android"])
|
and namespace-uri()="http://schemas.android.com/apk/res/android"])
|
||||||
' src/Android/Properties/AndroidManifest.xml)
|
' src/App/Platforms/Android/AndroidManifest.xml)
|
||||||
|
|
||||||
# Wait for version to change.
|
# If the versions don't match we continue the loop, otherwise we break out of the loop.
|
||||||
while [[ "$NEW_VERSION" != "$CURRENT_VERSION" ]]
|
[[ "$NEW_VERSION" != "$CURRENT_VERSION" ]] || break
|
||||||
do
|
|
||||||
echo "Waiting for version to be updated..."
|
|
||||||
sleep 10
|
sleep 10
|
||||||
git pull --force
|
|
||||||
done
|
done
|
||||||
|
|
||||||
- name: Cut RC branch
|
- name: Cut RC branch
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ project_id_env: _CROWDIN_PROJECT_ID
|
|||||||
api_token_env: CROWDIN_API_TOKEN
|
api_token_env: CROWDIN_API_TOKEN
|
||||||
preserve_hierarchy: true
|
preserve_hierarchy: true
|
||||||
files:
|
files:
|
||||||
- source: /src/App/Resources/AppResources.resx
|
- source: /src/Core/Resources/Localization/AppResources.resx
|
||||||
dest: /src/App/Resources/%original_file_name%
|
dest: /src/Core/Resources/Localization/%original_file_name%
|
||||||
translation: /src/App/Resources/AppResources.%two_letters_code%.resx
|
translation: /src/Core/Resources/Localization/AppResources.%two_letters_code%.resx
|
||||||
update_option: update_as_unapproved
|
update_option: update_as_unapproved
|
||||||
languages_mapping:
|
languages_mapping:
|
||||||
two_letters_code:
|
two_letters_code:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?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.1" 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.2.2" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.NFC" />
|
<uses-permission android:name="android.permission.NFC" />
|
||||||
|
|||||||
@@ -79,24 +79,29 @@ namespace Bit.Droid.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
var context = Android.App.Application.Context;
|
var context = Android.App.Application.Context;
|
||||||
var intent = new Intent(context, typeof(MainActivity));
|
var intent = context.PackageManager?.GetLaunchIntentForPackage(context.PackageName ?? string.Empty);
|
||||||
intent.PutExtra(Bit.Core.Constants.NotificationData, JsonConvert.SerializeObject(data));
|
|
||||||
var pendingIntentFlags = AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.UpdateCurrent, true);
|
|
||||||
var pendingIntent = PendingIntent.GetActivity(context, 20220801, intent, pendingIntentFlags);
|
|
||||||
|
|
||||||
var deleteIntent = new Intent(context, typeof(NotificationDismissReceiver));
|
var builder = new NotificationCompat.Builder(context, Bit.Core.Constants.AndroidNotificationChannelId);
|
||||||
deleteIntent.PutExtra(Bit.Core.Constants.NotificationData, JsonConvert.SerializeObject(data));
|
if(intent != null && context.PackageManager != null && !string.IsNullOrEmpty(context.PackageName))
|
||||||
var deletePendingIntent = PendingIntent.GetBroadcast(context, 20220802, deleteIntent, pendingIntentFlags);
|
{
|
||||||
|
intent.PutExtra(Bit.Core.Constants.NotificationData, JsonConvert.SerializeObject(data));
|
||||||
|
var pendingIntentFlags = AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.UpdateCurrent, true);
|
||||||
|
var pendingIntent = PendingIntent.GetActivity(context, 20220801, intent, pendingIntentFlags);
|
||||||
|
|
||||||
var builder = new NotificationCompat.Builder(context, Bit.Core.Constants.AndroidNotificationChannelId)
|
var deleteIntent = new Intent(context, typeof(NotificationDismissReceiver));
|
||||||
.SetContentIntent(pendingIntent)
|
deleteIntent.PutExtra(Bit.Core.Constants.NotificationData, JsonConvert.SerializeObject(data));
|
||||||
.SetContentTitle(title)
|
var deletePendingIntent = PendingIntent.GetBroadcast(context, 20220802, deleteIntent, pendingIntentFlags);
|
||||||
|
|
||||||
|
builder.SetContentIntent(pendingIntent)
|
||||||
|
.SetDeleteIntent(deletePendingIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.SetContentTitle(title)
|
||||||
.SetContentText(message)
|
.SetContentText(message)
|
||||||
.SetSmallIcon(Bit.Core.Resource.Drawable.ic_notification)
|
.SetSmallIcon(Bit.Core.Resource.Drawable.ic_notification)
|
||||||
.SetColor((int)Android.Graphics.Color.White)
|
.SetColor((int)Android.Graphics.Color.White)
|
||||||
.SetDeleteIntent(deletePendingIntent)
|
|
||||||
.SetAutoCancel(true);
|
.SetAutoCancel(true);
|
||||||
|
|
||||||
if (data is PasswordlessNotificationData passwordlessNotificationData && passwordlessNotificationData.TimeoutInMinutes > 0)
|
if (data is PasswordlessNotificationData passwordlessNotificationData && passwordlessNotificationData.TimeoutInMinutes > 0)
|
||||||
{
|
{
|
||||||
builder.SetTimeoutAfter(passwordlessNotificationData.TimeoutInMinutes * 60000);
|
builder.SetTimeoutAfter(passwordlessNotificationData.TimeoutInMinutes * 60000);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>com.8bit.bitwarden</string>
|
<string>com.8bit.bitwarden</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2024.2.1</string>
|
<string>2024.2.2</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>CFBundleIconName</key>
|
<key>CFBundleIconName</key>
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ using Bit.Core.Utilities;
|
|||||||
using Microsoft.Maui.ApplicationModel;
|
using Microsoft.Maui.ApplicationModel;
|
||||||
using Microsoft.Maui.Controls;
|
using Microsoft.Maui.Controls;
|
||||||
using Microsoft.Maui;
|
using Microsoft.Maui;
|
||||||
|
#if IOS
|
||||||
|
using Foundation;
|
||||||
|
using UIKit;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Bit.App.Utilities
|
namespace Bit.App.Utilities
|
||||||
{
|
{
|
||||||
@@ -65,12 +69,11 @@ namespace Bit.App.Utilities
|
|||||||
resources.MergedDictionaries.Add(new ControlTemplates());
|
resources.MergedDictionaries.Add(new ControlTemplates());
|
||||||
|
|
||||||
// Platform styles
|
// Platform styles
|
||||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
if (DeviceInfo.Platform == DevicePlatform.Android)
|
||||||
if (Device.RuntimePlatform == Device.Android)
|
|
||||||
{
|
{
|
||||||
resources.MergedDictionaries.Add(new Styles.Android());
|
resources.MergedDictionaries.Add(new Styles.Android());
|
||||||
}
|
}
|
||||||
else if (Device.RuntimePlatform == Device.iOS)
|
else if (DeviceInfo.Platform == DevicePlatform.iOS)
|
||||||
{
|
{
|
||||||
resources.MergedDictionaries.Add(new iOS());
|
resources.MergedDictionaries.Add(new iOS());
|
||||||
}
|
}
|
||||||
@@ -147,17 +150,47 @@ namespace Bit.App.Utilities
|
|||||||
return stateService.GetAutoDarkThemeAsync().GetAwaiter().GetResult();
|
return stateService.GetAutoDarkThemeAsync().GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//HACK: OsDarkModeEnabled() is divided into Android and iOS implementations due to a MAUI bug.
|
||||||
|
// Currently on iOS when resuming the app after showing a System "Share/Sheet" (or other similar UI)
|
||||||
|
// MAUI reports the incorrect Theme. To avoid this we are fetching the current OS Theme directly on iOS from the iOS API.
|
||||||
|
// MAUI Issue: https://github.com/dotnet/maui/issues/19614
|
||||||
public static bool OsDarkModeEnabled()
|
public static bool OsDarkModeEnabled()
|
||||||
{
|
{
|
||||||
if (Application.Current == null)
|
#if UT
|
||||||
{
|
return false;
|
||||||
// called from iOS extension
|
#else
|
||||||
var app = new App(new AppOptions { IosExtension = true });
|
|
||||||
return app.RequestedTheme == AppTheme.Dark;
|
#if ANDROID
|
||||||
}
|
|
||||||
return Application.Current.RequestedTheme == AppTheme.Dark;
|
return Application.Current.RequestedTheme == AppTheme.Dark;
|
||||||
|
#else
|
||||||
|
var requestedTheme = AppTheme.Unspecified;
|
||||||
|
if (!OperatingSystem.IsIOSVersionAtLeast(13, 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var traits = InvokeOnMainThread(() => WindowStateManager.Default.GetCurrentUIViewController()?.TraitCollection) ?? UITraitCollection.CurrentTraitCollection;
|
||||||
|
var uiStyle = traits.UserInterfaceStyle;
|
||||||
|
|
||||||
|
requestedTheme = uiStyle switch
|
||||||
|
{
|
||||||
|
UIUserInterfaceStyle.Light => AppTheme.Light,
|
||||||
|
UIUserInterfaceStyle.Dark => AppTheme.Dark,
|
||||||
|
_ => AppTheme.Unspecified
|
||||||
|
};
|
||||||
|
return requestedTheme == AppTheme.Dark;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IOS
|
||||||
|
private static T InvokeOnMainThread<T>(Func<T> factory)
|
||||||
|
{
|
||||||
|
T value = default;
|
||||||
|
NSRunLoop.Main.InvokeOnMainThread(() => value = factory());
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public static void ApplyResourcesTo(VisualElement element)
|
public static void ApplyResourcesTo(VisualElement element)
|
||||||
{
|
{
|
||||||
foreach (var resourceDict in Resources().MergedDictionaries)
|
foreach (var resourceDict in Resources().MergedDictionaries)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using AuthenticationServices;
|
using AuthenticationServices;
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>com.8bit.bitwarden.autofill</string>
|
<string>com.8bit.bitwarden.autofill</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2024.2.1</string>
|
<string>2024.2.2</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>CFBundleLocalizations</key>
|
<key>CFBundleLocalizations</key>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>com.8bit.bitwarden.find-login-action-extension</string>
|
<string>com.8bit.bitwarden.find-login-action-extension</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2024.2.1</string>
|
<string>2024.2.2</string>
|
||||||
<key>CFBundleLocalizations</key>
|
<key>CFBundleLocalizations</key>
|
||||||
<array>
|
<array>
|
||||||
<string>en</string>
|
<string>en</string>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>XPC!</string>
|
<string>XPC!</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>2024.2.1</string>
|
<string>2024.2.2</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>MinimumOSVersion</key>
|
<key>MinimumOSVersion</key>
|
||||||
|
|||||||
Reference in New Issue
Block a user