mirror of
https://github.com/bitwarden/android.git
synced 2024-12-25 02:18:27 +03:00
Hide email address in Sends (#1340)
* Add HideEmail model properties and locale strings * Fix UI strings * Add HideEmail to SendService * Add HideEmail option to UI * Tidy up declarations * Add Bitwarden Send translation warning
This commit is contained in:
parent
13ffbe911a
commit
04aeddc5de
12 changed files with 96 additions and 0 deletions
|
@ -89,6 +89,18 @@
|
||||||
StyleClass="text-muted, text-sm, text-bold"
|
StyleClass="text-muted, text-sm, text-bold"
|
||||||
HorizontalTextAlignment="Center" />
|
HorizontalTextAlignment="Center" />
|
||||||
</Frame>
|
</Frame>
|
||||||
|
<Frame
|
||||||
|
IsVisible="{Binding SendOptionsPolicyInEffect}"
|
||||||
|
Padding="10"
|
||||||
|
Margin="0, 12, 0, 0"
|
||||||
|
HasShadow="False"
|
||||||
|
BackgroundColor="Transparent"
|
||||||
|
BorderColor="Accent">
|
||||||
|
<Label
|
||||||
|
Text="{u:I18n SendOptionsPolicyInEffect}"
|
||||||
|
StyleClass="text-muted, text-sm, text-bold"
|
||||||
|
HorizontalTextAlignment="Center" />
|
||||||
|
</Frame>
|
||||||
<StackLayout StyleClass="box-row">
|
<StackLayout StyleClass="box-row">
|
||||||
<Label
|
<Label
|
||||||
Text="{u:I18n Name}"
|
Text="{u:I18n Name}"
|
||||||
|
@ -490,6 +502,20 @@
|
||||||
StyleClass="box-footer-label"
|
StyleClass="box-footer-label"
|
||||||
Margin="0,5,0,0" />
|
Margin="0,5,0,0" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
<StackLayout
|
||||||
|
StyleClass="box-row, box-row-switch"
|
||||||
|
Margin="0,5,0,0">
|
||||||
|
<Label
|
||||||
|
Text="{u:I18n HideEmail}"
|
||||||
|
StyleClass="box-label-regular"
|
||||||
|
VerticalOptions="Center"
|
||||||
|
HorizontalOptions="StartAndExpand" />
|
||||||
|
<Switch
|
||||||
|
IsToggled="{Binding Send.HideEmail}"
|
||||||
|
IsEnabled="{Binding DisableHideEmailControl, Converter={StaticResource inverseBool}}"
|
||||||
|
HorizontalOptions="End"
|
||||||
|
Margin="10,0,0,0" />
|
||||||
|
</StackLayout>
|
||||||
<StackLayout
|
<StackLayout
|
||||||
StyleClass="box-row, box-row-switch"
|
StyleClass="box-row, box-row-switch"
|
||||||
Margin="0,5,0,0">
|
Margin="0,5,0,0">
|
||||||
|
|
|
@ -42,6 +42,9 @@ namespace Bit.App.Pages
|
||||||
nameof(IsText),
|
nameof(IsText),
|
||||||
nameof(IsFile),
|
nameof(IsFile),
|
||||||
};
|
};
|
||||||
|
private bool _disableHideEmail;
|
||||||
|
private bool _sendOptionsPolicyInEffect;
|
||||||
|
private bool _disableHideEmailControl;
|
||||||
|
|
||||||
public SendAddEditPageViewModel()
|
public SendAddEditPageViewModel()
|
||||||
{
|
{
|
||||||
|
@ -91,6 +94,7 @@ namespace Bit.App.Pages
|
||||||
public byte[] FileData { get; set; }
|
public byte[] FileData { get; set; }
|
||||||
public string NewPassword { get; set; }
|
public string NewPassword { get; set; }
|
||||||
public bool ShareOnSave { get; set; }
|
public bool ShareOnSave { get; set; }
|
||||||
|
public bool DisableHideEmailControl { get; set; }
|
||||||
public List<KeyValuePair<string, SendType>> TypeOptions { get; }
|
public List<KeyValuePair<string, SendType>> TypeOptions { get; }
|
||||||
public List<KeyValuePair<string, string>> DeletionTypeOptions { get; }
|
public List<KeyValuePair<string, string>> DeletionTypeOptions { get; }
|
||||||
public List<KeyValuePair<string, string>> ExpirationTypeOptions { get; }
|
public List<KeyValuePair<string, string>> ExpirationTypeOptions { get; }
|
||||||
|
@ -194,6 +198,16 @@ namespace Bit.App.Pages
|
||||||
nameof(ShowPasswordIcon)
|
nameof(ShowPasswordIcon)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
public bool DisableHideEmail
|
||||||
|
{
|
||||||
|
get => _disableHideEmail;
|
||||||
|
set => SetProperty(ref _disableHideEmail, value);
|
||||||
|
}
|
||||||
|
public bool SendOptionsPolicyInEffect
|
||||||
|
{
|
||||||
|
get => _sendOptionsPolicyInEffect;
|
||||||
|
set => SetProperty(ref _sendOptionsPolicyInEffect, value);
|
||||||
|
}
|
||||||
public bool EditMode => !string.IsNullOrWhiteSpace(SendId);
|
public bool EditMode => !string.IsNullOrWhiteSpace(SendId);
|
||||||
public bool IsText => Send?.Type == SendType.Text;
|
public bool IsText => Send?.Type == SendType.Text;
|
||||||
public bool IsFile => Send?.Type == SendType.File;
|
public bool IsFile => Send?.Type == SendType.File;
|
||||||
|
@ -206,6 +220,8 @@ namespace Bit.App.Pages
|
||||||
PageTitle = EditMode ? AppResources.EditSend : AppResources.AddSend;
|
PageTitle = EditMode ? AppResources.EditSend : AppResources.AddSend;
|
||||||
_canAccessPremium = await _userService.CanAccessPremiumAsync();
|
_canAccessPremium = await _userService.CanAccessPremiumAsync();
|
||||||
SendEnabled = ! await AppHelpers.IsSendDisabledByPolicyAsync();
|
SendEnabled = ! await AppHelpers.IsSendDisabledByPolicyAsync();
|
||||||
|
DisableHideEmail = await AppHelpers.IsHideEmailDisabledByPolicyAsync();
|
||||||
|
SendOptionsPolicyInEffect = SendEnabled && DisableHideEmail;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> LoadAsync()
|
public async Task<bool> LoadAsync()
|
||||||
|
@ -243,6 +259,10 @@ namespace Bit.App.Pages
|
||||||
_isOverridingPickers = false;
|
_isOverridingPickers = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DisableHideEmailControl = !SendEnabled ||
|
||||||
|
(!EditMode && DisableHideEmail) ||
|
||||||
|
(EditMode && DisableHideEmail && !Send.HideEmail);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
src/App/Resources/AppResources.Designer.cs
generated
12
src/App/Resources/AppResources.Designer.cs
generated
|
@ -3484,5 +3484,17 @@ namespace Bit.App.Resources {
|
||||||
return ResourceManager.GetString("AboutSend", resourceCulture);
|
return ResourceManager.GetString("AboutSend", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string HideEmail {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("HideEmail", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string SendOptionsPolicyInEffect {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("SendOptionsPolicyInEffect", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1975,4 +1975,11 @@
|
||||||
<value>About Send</value>
|
<value>About Send</value>
|
||||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="HideEmail" xml:space="preserve">
|
||||||
|
<value>Hide my email address from recipients.</value>
|
||||||
|
</data>
|
||||||
|
<data name="SendOptionsPolicyInEffect" xml:space="preserve">
|
||||||
|
<value>One or more organization policies are affecting your Send options.</value>
|
||||||
|
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
|
@ -311,6 +311,26 @@ namespace Bit.App.Utilities
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<bool> IsHideEmailDisabledByPolicyAsync()
|
||||||
|
{
|
||||||
|
var policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
|
||||||
|
var userService = ServiceContainer.Resolve<IUserService>("userService");
|
||||||
|
|
||||||
|
var policies = await policyService.GetAll(PolicyType.SendOptions);
|
||||||
|
var organizations = await userService.GetAllOrganizationAsync();
|
||||||
|
return organizations.Any(o =>
|
||||||
|
{
|
||||||
|
return o.Enabled &&
|
||||||
|
o.Status == OrganizationUserStatusType.Confirmed &&
|
||||||
|
o.UsePolicies &&
|
||||||
|
!o.canManagePolicies &&
|
||||||
|
policies.Any(p => p.OrganizationId == o.Id &&
|
||||||
|
p.Enabled &&
|
||||||
|
p.Data.ContainsKey("disableHideEmail") &&
|
||||||
|
(bool)p.Data["disableHideEmail"]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task<bool> PerformUpdateTasksAsync(ISyncService syncService,
|
public static async Task<bool> PerformUpdateTasksAsync(ISyncService syncService,
|
||||||
IDeviceActionService deviceActionService, IStorageService storageService)
|
IDeviceActionService deviceActionService, IStorageService storageService)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,5 +9,6 @@
|
||||||
RequireSso = 4, // Requires users to authenticate with SSO
|
RequireSso = 4, // Requires users to authenticate with SSO
|
||||||
PersonalOwnership = 5, // Disables personal vault ownership for adding/cloning items
|
PersonalOwnership = 5, // Disables personal vault ownership for adding/cloning items
|
||||||
DisableSend = 6, // Disables the ability to create and edit Sends
|
DisableSend = 6, // Disables the ability to create and edit Sends
|
||||||
|
SendOptions = 7, // Sets restrictions or defaults for Bitwarden Sends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace Bit.Core.Models.Data
|
||||||
DeletionDate = response.DeletionDate;
|
DeletionDate = response.DeletionDate;
|
||||||
Password = response.Password;
|
Password = response.Password;
|
||||||
Disabled = response.Disabled;
|
Disabled = response.Disabled;
|
||||||
|
HideEmail = response.HideEmail.GetValueOrDefault();
|
||||||
|
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
|
@ -54,5 +55,6 @@ namespace Bit.Core.Models.Data
|
||||||
public DateTime DeletionDate { get; set; }
|
public DateTime DeletionDate { get; set; }
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
public bool Disabled { get; set; }
|
public bool Disabled { get; set; }
|
||||||
|
public bool HideEmail { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace Bit.Core.Models.Domain
|
||||||
public DateTime DeletionDate { get; set; }
|
public DateTime DeletionDate { get; set; }
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
public bool Disabled { get; set; }
|
public bool Disabled { get; set; }
|
||||||
|
public bool HideEmail { get; set; }
|
||||||
|
|
||||||
public Send() : base() { }
|
public Send() : base() { }
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ namespace Bit.Core.Models.Domain
|
||||||
RevisionDate = data.RevisionDate;
|
RevisionDate = data.RevisionDate;
|
||||||
DeletionDate = data.DeletionDate;
|
DeletionDate = data.DeletionDate;
|
||||||
ExpirationDate = data.ExpirationDate;
|
ExpirationDate = data.ExpirationDate;
|
||||||
|
HideEmail = data.HideEmail;
|
||||||
|
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace Bit.Core.Models.Request
|
||||||
public SendFileApi File { get; set; }
|
public SendFileApi File { get; set; }
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
public bool Disabled { get; set; }
|
public bool Disabled { get; set; }
|
||||||
|
public bool HideEmail { get; set; }
|
||||||
|
|
||||||
public SendRequest(Send send, long? fileLength)
|
public SendRequest(Send send, long? fileLength)
|
||||||
{
|
{
|
||||||
|
@ -32,6 +33,7 @@ namespace Bit.Core.Models.Request
|
||||||
Key = send.Key?.EncryptedString;
|
Key = send.Key?.EncryptedString;
|
||||||
Password = send.Password;
|
Password = send.Password;
|
||||||
Disabled = send.Disabled;
|
Disabled = send.Disabled;
|
||||||
|
HideEmail = send.HideEmail;
|
||||||
|
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,5 +21,6 @@ namespace Bit.Core.Models.Response
|
||||||
public DateTime DeletionDate { get; set; }
|
public DateTime DeletionDate { get; set; }
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
public bool Disabled { get; set; }
|
public bool Disabled { get; set; }
|
||||||
|
public bool? HideEmail { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace Bit.Core.Models.View
|
||||||
ExpirationDate = send.ExpirationDate;
|
ExpirationDate = send.ExpirationDate;
|
||||||
Disabled = send.Disabled;
|
Disabled = send.Disabled;
|
||||||
Password = send.Password;
|
Password = send.Password;
|
||||||
|
HideEmail = send.HideEmail;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
@ -45,5 +46,6 @@ namespace Bit.Core.Models.View
|
||||||
public bool Expired => ExpirationDate.HasValue && ExpirationDate.Value <= DateTime.UtcNow;
|
public bool Expired => ExpirationDate.HasValue && ExpirationDate.Value <= DateTime.UtcNow;
|
||||||
public bool PendingDelete => DeletionDate <= DateTime.UtcNow;
|
public bool PendingDelete => DeletionDate <= DateTime.UtcNow;
|
||||||
public string DisplayDate => DeletionDate.ToLocalTime().ToString("MMM d, yyyy, h:mm tt");
|
public string DisplayDate => DeletionDate.ToLocalTime().ToString("MMM d, yyyy, h:mm tt");
|
||||||
|
public bool HideEmail { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,7 @@ namespace Bit.Core.Services
|
||||||
Key = await _cryptoService.EncryptAsync(model.Key, key),
|
Key = await _cryptoService.EncryptAsync(model.Key, key),
|
||||||
Name = await _cryptoService.EncryptAsync(model.Name, model.CryptoKey),
|
Name = await _cryptoService.EncryptAsync(model.Name, model.CryptoKey),
|
||||||
Notes = await _cryptoService.EncryptAsync(model.Notes, model.CryptoKey),
|
Notes = await _cryptoService.EncryptAsync(model.Notes, model.CryptoKey),
|
||||||
|
HideEmail = model.HideEmail
|
||||||
};
|
};
|
||||||
byte[] encryptedFileData = null;
|
byte[] encryptedFileData = null;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue