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

Compare commits

..

11 Commits

Author SHA1 Message Date
Vince Grassia
e5569b13b7 Fix build pipeline MAUI version (#3354)
(cherry picked from commit 3262fdc9ec)
2024-07-16 08:52:32 -04:00
Carlos Gonçalves
5e98954c9e pm-9483 Update model attachments (#3344) 2024-07-08 17:08:03 +01:00
Vince Grassia
1294cd5c69 Fix build numbers 2024-07-02 13:30:08 -04:00
Bitwarden DevOps
463d837fa8 Bumped version to 2024.7.0 (#3341) 2024-07-01 17:15:59 +00:00
Matt Czech
ad6ffad5d1 [PM-9043] BIT-2356: Update casing of Bitwarden Help Center string (#3305) 2024-06-19 21:00:59 +00:00
Federico Maccaroni
9edcc8b4f7 [AC-2788] Remove unassigned items feature flag and logic (#3300) 2024-06-19 08:57:04 -03:00
Álison Fernandes
cf5c5aa114 [PM-8392] Enables the Cipher Key Encryption preprocessor define (#3266) 2024-06-18 13:41:49 +01:00
github-actions[bot]
36c7beb1e6 Autosync Crowdin Translations (#3297)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2024-06-14 08:23:03 +00:00
Bitwarden DevOps
f6d798af94 Bump version to 2024.6.1 (#3296) 2024-06-13 15:50:57 +00:00
Michał Chęciński
08ed70d5b1 Fix release (#3294) 2024-06-13 08:40:18 -07:00
André Bispo
33e0187460 [PM-8814] Remove EU feature flag (#3291) 2024-06-12 14:32:04 +01:00
30 changed files with 53 additions and 251 deletions

View File

@@ -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

View File

@@ -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' }}

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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,

View File

@@ -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();
} }
} }

View File

@@ -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")]

View File

@@ -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]

View File

@@ -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)
{ {

View File

@@ -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);

View File

@@ -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);
} }
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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);
} }

View File

@@ -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"

View File

@@ -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);

View File

@@ -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);
}
}
} }
} }

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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 &gt; Passwords &gt; Password Options</value> <value>1. Go to your device's Settings &gt; Passwords &gt; 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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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)

View File

@@ -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")]

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>