mirror of
https://github.com/bitwarden/mobile
synced 2025-12-05 23:53:33 +00:00
Compare commits
11 Commits
vault/pm-2
...
v2024.7.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5569b13b7 | ||
|
|
5e98954c9e | ||
|
|
1294cd5c69 | ||
|
|
463d837fa8 | ||
|
|
ad6ffad5d1 | ||
|
|
9edcc8b4f7 | ||
|
|
cf5c5aa114 | ||
|
|
36c7beb1e6 | ||
|
|
f6d798af94 | ||
|
|
08ed70d5b1 | ||
|
|
33e0187460 |
16
.github/workflows/build.yml
vendored
16
.github/workflows/build.yml
vendored
@@ -85,11 +85,6 @@ jobs:
|
|||||||
- name: Set up MSBuild
|
- name: Set up MSBuild
|
||||||
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2.0.0
|
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2.0.0
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
- name: Setup Windows builder
|
- name: Setup Windows builder
|
||||||
run: choco install checksum --no-progress
|
run: choco install checksum --no-progress
|
||||||
|
|
||||||
@@ -145,7 +140,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Increment version
|
- name: Increment version
|
||||||
run: |
|
run: |
|
||||||
BUILD_NUMBER=$((3000 + $GITHUB_RUN_NUMBER))
|
BUILD_NUMBER=$((11000 + $GITHUB_RUN_NUMBER))
|
||||||
echo "##### Setting Android Version Code to $BUILD_NUMBER" | tee -a $GITHUB_STEP_SUMMARY
|
echo "##### Setting Android Version Code to $BUILD_NUMBER" | tee -a $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
sed -i "s/android:versionCode=\"1\"/android:versionCode=\"$BUILD_NUMBER\"/" \
|
sed -i "s/android:versionCode=\"1\"/android:versionCode=\"$BUILD_NUMBER\"/" \
|
||||||
@@ -312,11 +307,6 @@ jobs:
|
|||||||
- name: Set up MSBuild
|
- name: Set up MSBuild
|
||||||
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2.0.0
|
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2.0.0
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
- name: Setup Windows builder
|
- name: Setup Windows builder
|
||||||
run: choco install checksum --no-progress
|
run: choco install checksum --no-progress
|
||||||
|
|
||||||
@@ -354,7 +344,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Increment version
|
- name: Increment version
|
||||||
run: |
|
run: |
|
||||||
BUILD_NUMBER=$((3000 + $GITHUB_RUN_NUMBER))
|
BUILD_NUMBER=$((11000 + $GITHUB_RUN_NUMBER))
|
||||||
echo "##### Setting F-Droid Version Code to $BUILD_NUMBER" | tee -a $GITHUB_STEP_SUMMARY
|
echo "##### Setting F-Droid Version Code to $BUILD_NUMBER" | tee -a $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
sed -i "s/android:versionCode=\"1\"/android:versionCode=\"$BUILD_NUMBER\"/" \
|
sed -i "s/android:versionCode=\"1\"/android:versionCode=\"$BUILD_NUMBER\"/" \
|
||||||
@@ -519,7 +509,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Increment version
|
- name: Increment version
|
||||||
run: |
|
run: |
|
||||||
BUILD_NUMBER=$((100 + $GITHUB_RUN_NUMBER))
|
BUILD_NUMBER=$((8000 + $GITHUB_RUN_NUMBER))
|
||||||
echo "##### Setting iOS CFBundleVersion to $BUILD_NUMBER" | tee -a $GITHUB_STEP_SUMMARY
|
echo "##### Setting iOS CFBundleVersion to $BUILD_NUMBER" | tee -a $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
|
||||||
|
|||||||
11
.github/workflows/release.yml
vendored
11
.github/workflows/release.yml
vendored
@@ -72,6 +72,7 @@ jobs:
|
|||||||
workflow: build.yml
|
workflow: build.yml
|
||||||
workflow_conclusion: success
|
workflow_conclusion: success
|
||||||
branch: ${{ steps.branch.outputs.branch-name }}
|
branch: ${{ steps.branch.outputs.branch-name }}
|
||||||
|
skip_unpack: true
|
||||||
|
|
||||||
- name: Dry Run - Download all artifacts
|
- name: Dry Run - Download all artifacts
|
||||||
if: ${{ inputs.release_type == 'Dry Run' }}
|
if: ${{ inputs.release_type == 'Dry Run' }}
|
||||||
@@ -80,9 +81,15 @@ jobs:
|
|||||||
workflow: build.yml
|
workflow: build.yml
|
||||||
workflow_conclusion: success
|
workflow_conclusion: success
|
||||||
branch: main
|
branch: main
|
||||||
|
skip_unpack: true
|
||||||
|
|
||||||
- name: Prep Bitwarden iOS release asset
|
- name: Unzip release assets
|
||||||
run: zip -r Bitwarden\ iOS.zip Bitwarden\ iOS
|
run: |
|
||||||
|
unzip bw-android-apk-sha256.txt.zip -d bw-android-apk-sha256.txt
|
||||||
|
unzip bw-fdroid-apk-sha256.txt.zip -d bw-fdroid-apk-sha256.txt
|
||||||
|
unzip com.x8bit.bitwarden-fdroid.apk.zip -d com.x8bit.bitwarden-fdroid.apk
|
||||||
|
unzip com.x8bit.bitwarden.aab.zip -d com.x8bit.bitwarden.aab
|
||||||
|
unzip com.x8bit.bitwarden.apk.zip -d com.x8bit.bitwarden.apk
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
if: ${{ inputs.release_type != 'Dry Run' }}
|
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||||
|
|||||||
@@ -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.6.0" 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.7.0" 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" />
|
||||||
|
|||||||
@@ -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.6.0</string>
|
<string>2024.7.0</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>CFBundleIconName</key>
|
<key>CFBundleIconName</key>
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ namespace Bit.Core.Abstractions
|
|||||||
Task<CipherResponse> PutShareCipherAsync(string id, CipherShareRequest request);
|
Task<CipherResponse> PutShareCipherAsync(string id, CipherShareRequest request);
|
||||||
Task PutDeleteCipherAsync(string id);
|
Task PutDeleteCipherAsync(string id);
|
||||||
Task<CipherResponse> PutRestoreCipherAsync(string id);
|
Task<CipherResponse> PutRestoreCipherAsync(string id);
|
||||||
Task<bool> HasUnassignedCiphersAsync();
|
|
||||||
Task RefreshIdentityTokenAsync();
|
Task RefreshIdentityTokenAsync();
|
||||||
Task<SsoPrevalidateResponse> PreValidateSsoAsync(string identifier);
|
Task<SsoPrevalidateResponse> PreValidateSsoAsync(string identifier);
|
||||||
Task<TResponse> SendAsync<TRequest, TResponse>(HttpMethod method, string path,
|
Task<TResponse> SendAsync<TRequest, TResponse>(HttpMethod method, string path,
|
||||||
|
|||||||
@@ -36,6 +36,5 @@ namespace Bit.Core.Abstractions
|
|||||||
Task RestoreWithServerAsync(string id);
|
Task RestoreWithServerAsync(string id);
|
||||||
Task<string> CreateNewLoginForPasskeyAsync(Fido2ConfirmNewCredentialParams newPasskeyParams);
|
Task<string> CreateNewLoginForPasskeyAsync(Fido2ConfirmNewCredentialParams newPasskeyParams);
|
||||||
Task CopyTotpCodeIfNeededAsync(CipherView cipher);
|
Task CopyTotpCodeIfNeededAsync(CipherView cipher);
|
||||||
Task<bool> VerifyOrganizationHasUnassignedItemsAsync();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,8 +187,6 @@ namespace Bit.Core.Abstractions
|
|||||||
Task<BwRegion?> GetPreAuthRegionAsync();
|
Task<BwRegion?> GetPreAuthRegionAsync();
|
||||||
Task SetPreAuthRegionAsync(BwRegion value);
|
Task SetPreAuthRegionAsync(BwRegion value);
|
||||||
Task ReloadStateAsync();
|
Task ReloadStateAsync();
|
||||||
Task<bool> GetShouldCheckOrganizationUnassignedItemsAsync(string userId = null);
|
|
||||||
Task SetShouldCheckOrganizationUnassignedItemsAsync(bool shouldCheck, string userId = null);
|
|
||||||
[Obsolete("Use GetPinKeyEncryptedUserKeyAsync instead, left for migration purposes")]
|
[Obsolete("Use GetPinKeyEncryptedUserKeyAsync instead, left for migration purposes")]
|
||||||
Task<string> GetPinProtectedAsync(string userId = null);
|
Task<string> GetPinProtectedAsync(string userId = null);
|
||||||
[Obsolete("Use SetPinKeyEncryptedUserKeyAsync instead, left for migration purposes")]
|
[Obsolete("Use SetPinKeyEncryptedUserKeyAsync instead, left for migration purposes")]
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ namespace Bit.Core
|
|||||||
public const string PasswordlessLoginRequestKey = "passwordlessLoginRequest";
|
public const string PasswordlessLoginRequestKey = "passwordlessLoginRequest";
|
||||||
public const string PreLoginEmailKey = "preLoginEmailKey";
|
public const string PreLoginEmailKey = "preLoginEmailKey";
|
||||||
public const string ConfigsKey = "configsKey";
|
public const string ConfigsKey = "configsKey";
|
||||||
public const string DisplayEuEnvironmentFlag = "display-eu-environment";
|
|
||||||
public const string UnassignedItemsBannerFlag = "unassigned-items-banner";
|
|
||||||
public const string RegionEnvironment = "regionEnvironment";
|
public const string RegionEnvironment = "regionEnvironment";
|
||||||
public const string DuoCallback = "bitwarden://duo-callback";
|
public const string DuoCallback = "bitwarden://duo-callback";
|
||||||
public const string NavigateToMessageCommand = "navigateTo";
|
public const string NavigateToMessageCommand = "navigateTo";
|
||||||
@@ -139,7 +137,6 @@ namespace Bit.Core
|
|||||||
public static string ShouldConnectToWatchKey(string userId) => $"shouldConnectToWatch_{userId}";
|
public static string ShouldConnectToWatchKey(string userId) => $"shouldConnectToWatch_{userId}";
|
||||||
public static string ScreenCaptureAllowedKey(string userId) => $"screenCaptureAllowed_{userId}";
|
public static string ScreenCaptureAllowedKey(string userId) => $"screenCaptureAllowed_{userId}";
|
||||||
public static string PendingAdminAuthRequest(string userId) => $"pendingAdminAuthRequest_{userId}";
|
public static string PendingAdminAuthRequest(string userId) => $"pendingAdminAuthRequest_{userId}";
|
||||||
public static string ShouldCheckOrganizationUnassignedItemsKey(string userId) => $"shouldCheckOrganizationUnassignedItems_{userId}";
|
|
||||||
[Obsolete]
|
[Obsolete]
|
||||||
public static string KeyKey(string userId) => $"key_{userId}";
|
public static string KeyKey(string userId) => $"key_{userId}";
|
||||||
[Obsolete]
|
[Obsolete]
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ namespace Bit.App.Models
|
|||||||
public bool HideAccountSwitcher { get; set; }
|
public bool HideAccountSwitcher { get; set; }
|
||||||
public OtpData? OtpData { get; set; }
|
public OtpData? OtpData { get; set; }
|
||||||
public bool HasUnlockedInThisTransaction { get; set; }
|
public bool HasUnlockedInThisTransaction { get; set; }
|
||||||
public bool HasJustLoggedInOrUnlocked { get; set; }
|
|
||||||
|
|
||||||
public void SetAllFrom(AppOptions o)
|
public void SetAllFrom(AppOptions o)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ namespace Bit.App.Pages
|
|||||||
private bool _rememberEmail;
|
private bool _rememberEmail;
|
||||||
private string _email;
|
private string _email;
|
||||||
private string _selectedEnvironmentName;
|
private string _selectedEnvironmentName;
|
||||||
private bool _displayEuEnvironment;
|
|
||||||
|
|
||||||
public HomeViewModel()
|
public HomeViewModel()
|
||||||
{
|
{
|
||||||
@@ -116,7 +115,6 @@ namespace Bit.App.Pages
|
|||||||
{
|
{
|
||||||
Email = await _stateService.GetRememberedEmailAsync();
|
Email = await _stateService.GetRememberedEmailAsync();
|
||||||
RememberEmail = !string.IsNullOrEmpty(Email);
|
RememberEmail = !string.IsNullOrEmpty(Email);
|
||||||
_displayEuEnvironment = await _configService.GetFeatureFlagBoolAsync(Constants.DisplayEuEnvironmentFlag, forceRefresh: true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ContinueToLoginStepAsync()
|
public async Task ContinueToLoginStepAsync()
|
||||||
@@ -158,11 +156,7 @@ namespace Bit.App.Pages
|
|||||||
|
|
||||||
public async Task ShowEnvironmentPickerAsync()
|
public async Task ShowEnvironmentPickerAsync()
|
||||||
{
|
{
|
||||||
_displayEuEnvironment = await _configService.GetFeatureFlagBoolAsync(Constants.DisplayEuEnvironmentFlag);
|
var options = new string[] { BwRegion.US.Domain(), BwRegion.EU.Domain(), AppResources.SelfHosted };
|
||||||
var options = _displayEuEnvironment
|
|
||||||
? new string[] { BwRegion.US.Domain(), BwRegion.EU.Domain(), AppResources.SelfHosted }
|
|
||||||
: new string[] { BwRegion.US.Domain(), AppResources.SelfHosted };
|
|
||||||
|
|
||||||
await MainThread.InvokeOnMainThreadAsync(async () =>
|
await MainThread.InvokeOnMainThreadAsync(async () =>
|
||||||
{
|
{
|
||||||
var result = await _deviceActionService.Value.DisplayActionSheetAsync(AppResources.LoggingInOn, AppResources.Cancel, null, options);
|
var result = await _deviceActionService.Value.DisplayActionSheetAsync(AppResources.LoggingInOn, AppResources.Cancel, null, options);
|
||||||
|
|||||||
@@ -232,11 +232,6 @@ namespace Bit.App.Pages
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||||
|
|
||||||
if (_appOptions != null)
|
|
||||||
{
|
|
||||||
_appOptions.HasJustLoggedInOrUnlocked = true;
|
|
||||||
}
|
|
||||||
App.MainPage = new TabsPage(_appOptions, previousPage);
|
App.MainPage = new TabsPage(_appOptions, previousPage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,11 +35,6 @@ namespace Bit.App.Pages
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_appOptions != null)
|
|
||||||
{
|
|
||||||
_appOptions.HasJustLoggedInOrUnlocked = true;
|
|
||||||
}
|
|
||||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||||
App.MainPage = new TabsPage(_appOptions, previousPage);
|
App.MainPage = new TabsPage(_appOptions, previousPage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,11 +196,6 @@ namespace Bit.App.Pages
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_appOptions != null)
|
|
||||||
{
|
|
||||||
_appOptions.HasJustLoggedInOrUnlocked = true;
|
|
||||||
}
|
|
||||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||||
App.MainPage = new TabsPage(_appOptions, previousPage);
|
App.MainPage = new TabsPage(_appOptions, previousPage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,11 +56,6 @@ namespace Bit.App.Pages
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_appOptions != null)
|
|
||||||
{
|
|
||||||
_appOptions.HasJustLoggedInOrUnlocked = true;
|
|
||||||
}
|
|
||||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||||
App.MainPage = new TabsPage(_appOptions, previousPage);
|
App.MainPage = new TabsPage(_appOptions, previousPage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,11 +71,6 @@ namespace Bit.App.Pages
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_appOptions != null)
|
|
||||||
{
|
|
||||||
_appOptions.HasJustLoggedInOrUnlocked = true;
|
|
||||||
}
|
|
||||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||||
App.MainPage = new TabsPage(_appOptions, previousPage);
|
App.MainPage = new TabsPage(_appOptions, previousPage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -207,11 +207,6 @@ namespace Bit.App.Pages
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_appOptions != null)
|
|
||||||
{
|
|
||||||
_appOptions.HasJustLoggedInOrUnlocked = true;
|
|
||||||
}
|
|
||||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||||
App.MainPage = new TabsPage(_appOptions, previousPage);
|
App.MainPage = new TabsPage(_appOptions, previousPage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace Bit.App.Pages
|
|||||||
_keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService");
|
_keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService");
|
||||||
_stateService = ServiceContainer.Resolve<IStateService>();
|
_stateService = ServiceContainer.Resolve<IStateService>();
|
||||||
|
|
||||||
_groupingsPage = new NavigationPage(new GroupingsPage(true, previousPage: previousPage, appOptions: appOptions))
|
_groupingsPage = new NavigationPage(new GroupingsPage(true, previousPage: previousPage))
|
||||||
{
|
{
|
||||||
Title = AppResources.MyVault,
|
Title = AppResources.MyVault,
|
||||||
IconImageSource = "lock.png"
|
IconImageSource = "lock.png"
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace Bit.App.Pages
|
|||||||
|
|
||||||
public GroupingsPage(bool mainPage, CipherType? type = null, string folderId = null,
|
public GroupingsPage(bool mainPage, CipherType? type = null, string folderId = null,
|
||||||
string collectionId = null, string pageTitle = null, string vaultFilterSelection = null,
|
string collectionId = null, string pageTitle = null, string vaultFilterSelection = null,
|
||||||
PreviousPageInfo previousPage = null, bool deleted = false, bool showTotp = false, AppOptions appOptions = null)
|
PreviousPageInfo previousPage = null, bool deleted = false, bool showTotp = false)
|
||||||
{
|
{
|
||||||
_pageName = string.Concat(nameof(GroupingsPage), "_", DateTime.UtcNow.Ticks);
|
_pageName = string.Concat(nameof(GroupingsPage), "_", DateTime.UtcNow.Ticks);
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@@ -51,7 +51,6 @@ namespace Bit.App.Pages
|
|||||||
_vm.CollectionId = collectionId;
|
_vm.CollectionId = collectionId;
|
||||||
_vm.Deleted = deleted;
|
_vm.Deleted = deleted;
|
||||||
_vm.ShowTotp = showTotp;
|
_vm.ShowTotp = showTotp;
|
||||||
_vm.AppOptions = appOptions;
|
|
||||||
_previousPage = previousPage;
|
_previousPage = previousPage;
|
||||||
if (pageTitle != null)
|
if (pageTitle != null)
|
||||||
{
|
{
|
||||||
@@ -162,8 +161,6 @@ namespace Bit.App.Pages
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _vm.CheckOrganizationUnassignedItemsAsync();
|
|
||||||
|
|
||||||
// Push registration
|
// Push registration
|
||||||
var lastPushRegistration = await _stateService.GetPushLastRegistrationDateAsync();
|
var lastPushRegistration = await _stateService.GetPushLastRegistrationDateAsync();
|
||||||
lastPushRegistration = lastPushRegistration.GetValueOrDefault(DateTime.MinValue);
|
lastPushRegistration = lastPushRegistration.GetValueOrDefault(DateTime.MinValue);
|
||||||
|
|||||||
@@ -46,8 +46,6 @@ namespace Bit.App.Pages
|
|||||||
private readonly IPasswordRepromptService _passwordRepromptService;
|
private readonly IPasswordRepromptService _passwordRepromptService;
|
||||||
private readonly IOrganizationService _organizationService;
|
private readonly IOrganizationService _organizationService;
|
||||||
private readonly IPolicyService _policyService;
|
private readonly IPolicyService _policyService;
|
||||||
private readonly IConfigService _configService;
|
|
||||||
private readonly IEnvironmentService _environmentService;
|
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
public GroupingsPageViewModel()
|
public GroupingsPageViewModel()
|
||||||
@@ -64,8 +62,6 @@ namespace Bit.App.Pages
|
|||||||
_passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService");
|
_passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService");
|
||||||
_organizationService = ServiceContainer.Resolve<IOrganizationService>("organizationService");
|
_organizationService = ServiceContainer.Resolve<IOrganizationService>("organizationService");
|
||||||
_policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
|
_policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
|
||||||
_configService = ServiceContainer.Resolve<IConfigService>();
|
|
||||||
_environmentService = ServiceContainer.Resolve<IEnvironmentService>();
|
|
||||||
_logger = ServiceContainer.Resolve<ILogger>("logger");
|
_logger = ServiceContainer.Resolve<ILogger>("logger");
|
||||||
|
|
||||||
Loading = true;
|
Loading = true;
|
||||||
@@ -109,7 +105,6 @@ namespace Bit.App.Pages
|
|||||||
public List<Core.Models.View.CollectionView> Collections { get; set; }
|
public List<Core.Models.View.CollectionView> Collections { get; set; }
|
||||||
public List<TreeNode<Core.Models.View.CollectionView>> NestedCollections { get; set; }
|
public List<TreeNode<Core.Models.View.CollectionView>> NestedCollections { get; set; }
|
||||||
|
|
||||||
public AppOptions AppOptions { get; internal set; }
|
|
||||||
protected override ICipherService cipherService => _cipherService;
|
protected override ICipherService cipherService => _cipherService;
|
||||||
protected override IPolicyService policyService => _policyService;
|
protected override IPolicyService policyService => _policyService;
|
||||||
protected override IOrganizationService organizationService => _organizationService;
|
protected override IOrganizationService organizationService => _organizationService;
|
||||||
@@ -705,59 +700,5 @@ namespace Bit.App.Pages
|
|||||||
var folders = decFolders.Where(f => _allCiphers.Any(c => c.FolderId == f.Id)).ToList();
|
var folders = decFolders.Where(f => _allCiphers.Any(c => c.FolderId == f.Id)).ToList();
|
||||||
return folders.Any() ? folders : null;
|
return folders.Any() ? folders : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task CheckOrganizationUnassignedItemsAsync()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (AppOptions?.HasJustLoggedInOrUnlocked != true)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppOptions.HasJustLoggedInOrUnlocked = false;
|
|
||||||
|
|
||||||
if (!await _configService.GetFeatureFlagBoolAsync(Core.Constants.UnassignedItemsBannerFlag)
|
|
||||||
||
|
|
||||||
!await _stateService.GetShouldCheckOrganizationUnassignedItemsAsync())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var waitSyncTask = Task.Run(async () =>
|
|
||||||
{
|
|
||||||
while (_syncService.SyncInProgress)
|
|
||||||
{
|
|
||||||
await Task.Delay(100);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
await waitSyncTask.WaitAsync(TimeSpan.FromMinutes(5));
|
|
||||||
|
|
||||||
if (!await _cipherService.VerifyOrganizationHasUnassignedItemsAsync())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var message = _environmentService.SelectedRegion == Core.Enums.Region.SelfHosted
|
|
||||||
? AppResources.OrganizationUnassignedItemsMessageSelfHost041624DescriptionLong
|
|
||||||
: AppResources.OrganizationUnassignedItemsMessageUSEUDescriptionLong;
|
|
||||||
|
|
||||||
var response = await _deviceActionService.DisplayAlertAsync(AppResources.Notice,
|
|
||||||
message,
|
|
||||||
null,
|
|
||||||
AppResources.RemindMeLater,
|
|
||||||
AppResources.Ok);
|
|
||||||
|
|
||||||
if (response == AppResources.Ok)
|
|
||||||
{
|
|
||||||
await _stateService.SetShouldCheckOrganizationUnassignedItemsAsync(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (TimeoutException) { }
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.Exception(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1328,7 +1328,7 @@ namespace Bit.Core.Resources.Localization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Bitwarden Help Center.
|
/// Looks up a localized string similar to Bitwarden help center.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string BitwardenHelpCenter {
|
public static string BitwardenHelpCenter {
|
||||||
get {
|
get {
|
||||||
@@ -4929,15 +4929,6 @@ namespace Bit.Core.Resources.Localization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Looks up a localized string similar to Notice.
|
|
||||||
/// </summary>
|
|
||||||
public static string Notice {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("Notice", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to This account has two-step login set up, however, none of the configured two-step providers are supported on this device. Please use a supported device and/or add additional providers that are better supported across devices (such as an authenticator app)..
|
/// Looks up a localized string similar to This account has two-step login set up, however, none of the configured two-step providers are supported on this device. Please use a supported device and/or add additional providers that are better supported across devices (such as an authenticator app)..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -5173,24 +5164,6 @@ namespace Bit.Core.Resources.Localization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Looks up a localized string similar to On May 16, 2024, unassigned organization items will no longer be visible in the All Vaults view and only accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible..
|
|
||||||
/// </summary>
|
|
||||||
public static string OrganizationUnassignedItemsMessageSelfHost041624DescriptionLong {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("OrganizationUnassignedItemsMessageSelfHost041624DescriptionLong", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Looks up a localized string similar to Unassigned organization items are no longer visible in the All Vaults view and only accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible..
|
|
||||||
/// </summary>
|
|
||||||
public static string OrganizationUnassignedItemsMessageUSEUDescriptionLong {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("OrganizationUnassignedItemsMessageUSEUDescriptionLong", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Organization identifier.
|
/// Looks up a localized string similar to Organization identifier.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -5876,15 +5849,6 @@ namespace Bit.Core.Resources.Localization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Looks up a localized string similar to Remind me later.
|
|
||||||
/// </summary>
|
|
||||||
public static string RemindMeLater {
|
|
||||||
get {
|
|
||||||
return ResourceManager.GetString("RemindMeLater", resourceCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Remove.
|
/// Looks up a localized string similar to Remove.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -2818,7 +2818,7 @@ Haluatko vaihtaa tähän tiliin?</value>
|
|||||||
<value>Tekstinsisäistä automattitäyttöä käytetään, jos aktiivinen näppäimistö tukee sitä. Muussa tapauksessa käytetään ponnahdusvalintaa.</value>
|
<value>Tekstinsisäistä automattitäyttöä käytetään, jos aktiivinen näppäimistö tukee sitä. Muussa tapauksessa käytetään ponnahdusvalintaa.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AdditionalOptions" xml:space="preserve">
|
<data name="AdditionalOptions" xml:space="preserve">
|
||||||
<value>Lisäasetukset</value>
|
<value>Lisävalinnat</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ContinueToWebApp" xml:space="preserve">
|
<data name="ContinueToWebApp" xml:space="preserve">
|
||||||
<value>Avataanko verkkosovellus?</value>
|
<value>Avataanko verkkosovellus?</value>
|
||||||
|
|||||||
@@ -2769,7 +2769,7 @@ Do you want to switch to this account?</value>
|
|||||||
<value>Account security</value>
|
<value>Account security</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="BitwardenHelpCenter" xml:space="preserve">
|
<data name="BitwardenHelpCenter" xml:space="preserve">
|
||||||
<value>Bitwarden Help Center</value>
|
<value>Bitwarden help center</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ContactBitwardenSupport" xml:space="preserve">
|
<data name="ContactBitwardenSupport" xml:space="preserve">
|
||||||
<value>Contact Bitwarden support</value>
|
<value>Contact Bitwarden support</value>
|
||||||
@@ -2975,18 +2975,6 @@ Do you want to switch to this account?</value>
|
|||||||
<data name="YourPasskeyWillBeSavedToYourBitwardenVaultForX" xml:space="preserve">
|
<data name="YourPasskeyWillBeSavedToYourBitwardenVaultForX" xml:space="preserve">
|
||||||
<value>Your passkey will be saved to your Bitwarden vault for {0}</value>
|
<value>Your passkey will be saved to your Bitwarden vault for {0}</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="OrganizationUnassignedItemsMessageUSEUDescriptionLong" xml:space="preserve">
|
|
||||||
<value>Unassigned organization items are no longer visible in the All Vaults view and only accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible.</value>
|
|
||||||
</data>
|
|
||||||
<data name="OrganizationUnassignedItemsMessageSelfHost041624DescriptionLong" xml:space="preserve">
|
|
||||||
<value>On May 16, 2024, unassigned organization items will no longer be visible in the All Vaults view and only accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible.</value>
|
|
||||||
</data>
|
|
||||||
<data name="RemindMeLater" xml:space="preserve">
|
|
||||||
<value>Remind me later</value>
|
|
||||||
</data>
|
|
||||||
<data name="Notice" xml:space="preserve">
|
|
||||||
<value>Notice</value>
|
|
||||||
</data>
|
|
||||||
<data name="PasskeysNotSupportedForThisApp" xml:space="preserve">
|
<data name="PasskeysNotSupportedForThisApp" xml:space="preserve">
|
||||||
<value>Passkeys not supported for this app</value>
|
<value>Passkeys not supported for this app</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -2838,7 +2838,7 @@ Bu hesaba geçmek ister misiniz?</value>
|
|||||||
<value>App Store'a gitmek ister misiniz?</value>
|
<value>App Store'a gitmek ister misiniz?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ContinueToDeviceSettings" xml:space="preserve">
|
<data name="ContinueToDeviceSettings" xml:space="preserve">
|
||||||
<value>Continue to device Settings?</value>
|
<value>Cihaz ayarlarına gidilsin mi?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TwoStepLoginDescriptionLong" xml:space="preserve">
|
<data name="TwoStepLoginDescriptionLong" xml:space="preserve">
|
||||||
<value>Bitwarden web uygulamasında iki aşamalı girişi ayarlayarak hesabınızın güvenliğini artırabilirsiniz.</value>
|
<value>Bitwarden web uygulamasında iki aşamalı girişi ayarlayarak hesabınızın güvenliğini artırabilirsiniz.</value>
|
||||||
@@ -2933,11 +2933,11 @@ Bu hesaba geçmek ister misiniz?</value>
|
|||||||
<value>Geçiş anahtarı okuma hatası</value>
|
<value>Geçiş anahtarı okuma hatası</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ThereWasAProblemCreatingAPasskeyForXTryAgainLater" xml:space="preserve">
|
<data name="ThereWasAProblemCreatingAPasskeyForXTryAgainLater" xml:space="preserve">
|
||||||
<value>There was a problem creating a passkey for {0}. Try again later.</value>
|
<value>{0} için geçiş anahtarı oluşturulamadı. Daha sonra tekrar deneyin.</value>
|
||||||
<comment>The parameter is the RpId</comment>
|
<comment>The parameter is the RpId</comment>
|
||||||
</data>
|
</data>
|
||||||
<data name="ThereWasAProblemReadingAPasskeyForXTryAgainLater" xml:space="preserve">
|
<data name="ThereWasAProblemReadingAPasskeyForXTryAgainLater" xml:space="preserve">
|
||||||
<value>There was a problem reading your passkey for {0}. Try again later.</value>
|
<value>{0} için geçiş anahtarı okunamadı. Daha sonra tekrar deneyin.</value>
|
||||||
<comment>The parameter is the RpId</comment>
|
<comment>The parameter is the RpId</comment>
|
||||||
</data>
|
</data>
|
||||||
<data name="VerifyingIdentityEllipsis" xml:space="preserve">
|
<data name="VerifyingIdentityEllipsis" xml:space="preserve">
|
||||||
@@ -2962,16 +2962,16 @@ Bu hesaba geçmek ister misiniz?</value>
|
|||||||
<value>1. Go to your device's Settings > Passwords > Password Options</value>
|
<value>1. Go to your device's Settings > Passwords > Password Options</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="SecondDotTurnOnAutoFill" xml:space="preserve">
|
<data name="SecondDotTurnOnAutoFill" xml:space="preserve">
|
||||||
<value>2. Turn on AutoFill</value>
|
<value>Oto-Doldurma'yı Etkinleştir</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ThirdDotSelectBitwardenToUseForPasswordsAndPasskeys" xml:space="preserve">
|
<data name="ThirdDotSelectBitwardenToUseForPasswordsAndPasskeys" xml:space="preserve">
|
||||||
<value>3. Select "Bitwarden" to use for passwords and passkeys</value>
|
<value>Parolalarınızı ve geçiş anahtarlarını kullanmak için "Bitwarden" seçin</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="YourPasskeyWillBeSavedToYourBitwardenVault" xml:space="preserve">
|
<data name="YourPasskeyWillBeSavedToYourBitwardenVault" xml:space="preserve">
|
||||||
<value>Your passkey will be saved to your Bitwarden vault</value>
|
<value>Geçiş anahtarınız Bitwarden kasasına kaydedilecektir</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="YourPasskeyWillBeSavedToYourBitwardenVaultForX" xml:space="preserve">
|
<data name="YourPasskeyWillBeSavedToYourBitwardenVaultForX" xml:space="preserve">
|
||||||
<value>Your passkey will be saved to your Bitwarden vault for {0}</value>
|
<value>{0} için geçiş anahtarınız Bitwarden kasasına kaydedilecektir</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="OrganizationUnassignedItemsMessageUSEUDescriptionLong" xml:space="preserve">
|
<data name="OrganizationUnassignedItemsMessageUSEUDescriptionLong" xml:space="preserve">
|
||||||
<value>Unassigned organization items are no longer visible in the All Vaults view and only accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible.</value>
|
<value>Unassigned organization items are no longer visible in the All Vaults view and only accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible.</value>
|
||||||
@@ -2989,18 +2989,18 @@ Bu hesaba geçmek ister misiniz?</value>
|
|||||||
<value>Bu uygulamada geçiş anahtarları desteklenmiyor</value>
|
<value>Bu uygulamada geçiş anahtarları desteklenmiyor</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PasskeyOperationFailedBecauseBrowserIsNotPrivileged" xml:space="preserve">
|
<data name="PasskeyOperationFailedBecauseBrowserIsNotPrivileged" xml:space="preserve">
|
||||||
<value>Passkey operation failed because browser is not privileged</value>
|
<value>Geçiş anahtarı eylemi başarısız oldu çünkü tarayıcı ayrıcalıklı değil</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PasskeyOperationFailedBecauseBrowserSignatureDoesNotMatch" xml:space="preserve">
|
<data name="PasskeyOperationFailedBecauseBrowserSignatureDoesNotMatch" xml:space="preserve">
|
||||||
<value>Passkey operation failed because browser signature does not match</value>
|
<value>Geçiş anahtarı eylemi başarısız oldu çünkü tarayıcı imzası uyumsuz</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PasskeyOperationFailedBecauseOfMissingAssetLinks" xml:space="preserve">
|
<data name="PasskeyOperationFailedBecauseOfMissingAssetLinks" xml:space="preserve">
|
||||||
<value>Passkey operation failed because of missing asset links</value>
|
<value>Geçiş anahtarı eylemi başarısız oldu çünkü varlık bağlantıları eksik</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PasskeyOperationFailedBecauseAppNotFoundInAssetLinks" xml:space="preserve">
|
<data name="PasskeyOperationFailedBecauseAppNotFoundInAssetLinks" xml:space="preserve">
|
||||||
<value>Passkey operation failed because app not found in asset links</value>
|
<value>Geçiş anahtarı eylemi başarısız oldu çünkü uygulama varlık bağlantılarında bulunamadı</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PasskeyOperationFailedBecauseAppCouldNotBeVerified" xml:space="preserve">
|
<data name="PasskeyOperationFailedBecauseAppCouldNotBeVerified" xml:space="preserve">
|
||||||
<value>Passkey operation failed because app could not be verified</value>
|
<value>Geçiş anahtarı eylemi başarısız oldu çünkü uygulama doğrulanamadı</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
@@ -2695,7 +2695,7 @@
|
|||||||
<value>批准后,您将收到通知。 </value>
|
<value>批准后,您将收到通知。 </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="TroubleLoggingIn" xml:space="preserve">
|
<data name="TroubleLoggingIn" xml:space="preserve">
|
||||||
<value>登录遇到问题?</value>
|
<value>登录遇到问题吗?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LoggingInAsX" xml:space="preserve">
|
<data name="LoggingInAsX" xml:space="preserve">
|
||||||
<value>正登录为 {0}</value>
|
<value>正登录为 {0}</value>
|
||||||
|
|||||||
@@ -334,11 +334,6 @@ namespace Bit.Core.Services
|
|||||||
return SendAsync<object, CipherResponse>(HttpMethod.Put, string.Concat("/ciphers/", id, "/restore"), null, true, true);
|
return SendAsync<object, CipherResponse>(HttpMethod.Put, string.Concat("/ciphers/", id, "/restore"), null, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<bool> HasUnassignedCiphersAsync()
|
|
||||||
{
|
|
||||||
return SendAsync<object, bool>(HttpMethod.Get, "/ciphers/has-unassigned-ciphers", null, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Attachments APIs
|
#region Attachments APIs
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//#define ENABLE_NEW_CIPHER_KEY_ENCRYPTION_ON_CREATION
|
#define ENABLE_NEW_CIPHER_KEY_ENCRYPTION_ON_CREATION
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -114,7 +114,7 @@ namespace Bit.Core.Services
|
|||||||
public async Task<Cipher> EncryptAsync(CipherView model, SymmetricCryptoKey key = null,
|
public async Task<Cipher> EncryptAsync(CipherView model, SymmetricCryptoKey key = null,
|
||||||
Cipher originalCipher = null)
|
Cipher originalCipher = null)
|
||||||
{
|
{
|
||||||
// Adjust password history
|
// Adjust password history and attachments
|
||||||
if (model.Id != null)
|
if (model.Id != null)
|
||||||
{
|
{
|
||||||
if (originalCipher == null)
|
if (originalCipher == null)
|
||||||
@@ -169,6 +169,9 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//adjust attachments
|
||||||
|
model.Attachments = existingCipher.Attachments;
|
||||||
}
|
}
|
||||||
if (!model.PasswordHistory?.Any() ?? false)
|
if (!model.PasswordHistory?.Any() ?? false)
|
||||||
{
|
{
|
||||||
@@ -571,39 +574,28 @@ namespace Bit.Core.Services
|
|||||||
await UpsertAsync(data);
|
await UpsertAsync(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ShareWithServerAsync(CipherView cipherView, string organizationId, HashSet<string> collectionIds)
|
public async Task ShareWithServerAsync(CipherView cipher, string organizationId, HashSet<string> collectionIds)
|
||||||
{
|
{
|
||||||
var attachmentTasks = new List<Task>();
|
var attachmentTasks = new List<Task>();
|
||||||
Cipher cipher = null;
|
if (cipher.Attachments != null)
|
||||||
//If the cipher doesn't have a key, we update it
|
|
||||||
if(cipherView.Key == null && await ShouldUseCipherKeyEncryptionAsync())
|
|
||||||
{
|
{
|
||||||
await UpdateAndUpsertAsync(cipherView, cipher => _apiService.PutCipherAsync(cipherView.Id, new CipherRequest(cipher)));
|
foreach (var attachment in cipher.Attachments)
|
||||||
cipher = await GetAsync(cipherView.Id);
|
|
||||||
cipherView = await cipher.DecryptAsync();
|
|
||||||
}
|
|
||||||
if (cipherView.Attachments != null)
|
|
||||||
{
|
|
||||||
foreach (var attachment in cipherView.Attachments)
|
|
||||||
{
|
{
|
||||||
if (attachment.Key == null)
|
if (attachment.Key == null)
|
||||||
{
|
{
|
||||||
attachmentTasks.Add(ShareAttachmentWithServerAsync(attachment, cipherView.Id, organizationId));
|
attachmentTasks.Add(ShareAttachmentWithServerAsync(attachment, cipher.Id, organizationId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await Task.WhenAll(attachmentTasks);
|
await Task.WhenAll(attachmentTasks);
|
||||||
cipherView.OrganizationId = organizationId;
|
cipher.OrganizationId = organizationId;
|
||||||
cipherView.CollectionIds = collectionIds;
|
cipher.CollectionIds = collectionIds;
|
||||||
await UpdateAndUpsertAsync(cipherView, cipher => _apiService.PutShareCipherAsync(cipherView.Id, new CipherShareRequest(cipher)), collectionIds);
|
var encCipher = await EncryptAsync(cipher);
|
||||||
|
var request = new CipherShareRequest(encCipher);
|
||||||
async Task UpdateAndUpsertAsync(CipherView cipherView, Func<Cipher,Task<CipherResponse>> callPutCipherApi, HashSet<string> collectionIds = null)
|
var response = await _apiService.PutShareCipherAsync(cipher.Id, request);
|
||||||
{
|
var userId = await _stateService.GetActiveUserIdAsync();
|
||||||
var cipher = await EncryptAsync(cipherView);
|
var data = new CipherData(response, userId, collectionIds);
|
||||||
var response = await callPutCipherApi(cipher);
|
await UpsertAsync(data);
|
||||||
var data = new CipherData(response, await _stateService.GetActiveUserIdAsync(), collectionIds);
|
|
||||||
await UpsertAsync(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Cipher> SaveAttachmentRawWithServerAsync(Cipher cipher, CipherView cipherView, string filename, byte[] data)
|
public async Task<Cipher> SaveAttachmentRawWithServerAsync(Cipher cipher, CipherView cipherView, string filename, byte[] data)
|
||||||
@@ -846,24 +838,6 @@ namespace Bit.Core.Services
|
|||||||
await ClearCacheAsync();
|
await ClearCacheAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> VerifyOrganizationHasUnassignedItemsAsync()
|
|
||||||
{
|
|
||||||
var organizations = await _stateService.GetOrganizationsAsync();
|
|
||||||
if (organizations?.Any() != true)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return await _apiService.HasUnassignedCiphersAsync();
|
|
||||||
}
|
|
||||||
catch (ApiException ex) when (ex.Error?.StatusCode == System.Net.HttpStatusCode.BadRequest)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
private async Task<Tuple<SymmetricCryptoKey, EncString, SymmetricCryptoKey>> MakeAttachmentKeyAsync(string organizationId, Cipher cipher = null, CipherView cipherView = null)
|
private async Task<Tuple<SymmetricCryptoKey, EncString, SymmetricCryptoKey>> MakeAttachmentKeyAsync(string organizationId, Cipher cipher = null, CipherView cipherView = null)
|
||||||
|
|||||||
@@ -1384,16 +1384,6 @@ namespace Bit.Core.Services
|
|||||||
await _storageMediatorService.SaveAsync(Constants.RegionEnvironment, value);
|
await _storageMediatorService.SaveAsync(Constants.RegionEnvironment, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> GetShouldCheckOrganizationUnassignedItemsAsync(string userId = null)
|
|
||||||
{
|
|
||||||
return await _storageMediatorService.GetAsync<bool?>(await ComposeKeyAsync(Constants.ShouldCheckOrganizationUnassignedItemsKey, userId)) ?? true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SetShouldCheckOrganizationUnassignedItemsAsync(bool shouldCheck, string userId = null)
|
|
||||||
{
|
|
||||||
await _storageMediatorService.SaveAsync<bool?>(await ComposeKeyAsync(Constants.ShouldCheckOrganizationUnassignedItemsKey, userId), shouldCheck);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
[Obsolete("Use IStorageMediatorService instead")]
|
[Obsolete("Use IStorageMediatorService instead")]
|
||||||
|
|||||||
@@ -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.6.0</string>
|
<string>2024.7.0</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.6.0</string>
|
<string>2024.7.0</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.6.0</string>
|
<string>2024.7.0</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