mirror of
https://github.com/bitwarden/mobile
synced 2026-01-06 02:23:57 +00:00
Merge branch 'master' into feature/maui-migration
Fixed conflicts and added null check on ForwardEmailDomainName # Conflicts: # src/Core/Pages/Vault/CipherAddEditPage.xaml # src/Core/Pages/Vault/CipherDetailsPage.xaml # src/iOS.Core/Renderers/CollectionView/ExtendedGroupableItemsViewController.cs
This commit is contained in:
@@ -18,15 +18,16 @@
|
||||
<StackLayout HorizontalOptions="FillAndExpand">
|
||||
<Label
|
||||
StyleClass="text-md"
|
||||
Text="{u:I18n RememberThisDevice}"/>
|
||||
Text="{u:I18n RememberThisDevice}" />
|
||||
<Label
|
||||
StyleClass="box-sub-label"
|
||||
Text="{u:I18n TurnOffUsingPublicDevice}"/>
|
||||
Text="{u:I18n TurnOffUsingPublicDevice}" />
|
||||
</StackLayout>
|
||||
<Switch
|
||||
Scale="0.8"
|
||||
IsToggled="{Binding RememberThisDevice}"
|
||||
VerticalOptions="Center"/>
|
||||
AutomationId="RememberThisDeviceSwitch"
|
||||
VerticalOptions="Center" />
|
||||
</StackLayout>
|
||||
<StackLayout Margin="0, 20, 0, 0">
|
||||
<Button
|
||||
@@ -34,31 +35,34 @@
|
||||
Text="{u:I18n Continue}"
|
||||
StyleClass="btn-primary"
|
||||
Command="{Binding ContinueCommand}"
|
||||
IsVisible="{Binding IsNewUser}"/>
|
||||
IsVisible="{Binding IsNewUser}"
|
||||
AutomationId="ContinueButton" />
|
||||
<Button
|
||||
x:Name="_approveWithMyOtherDevice"
|
||||
Text="{u:I18n ApproveWithMyOtherDevice}"
|
||||
StyleClass="btn-primary"
|
||||
Command="{Binding ApproveWithMyOtherDeviceCommand}"
|
||||
IsVisible="{Binding ApproveWithMyOtherDeviceEnabled}"/>
|
||||
IsVisible="{Binding ApproveWithMyOtherDeviceEnabled}"
|
||||
AutomationId="ApproveWithMyOtherDeviceButton" />
|
||||
<Button
|
||||
x:Name="_requestAdminApproval"
|
||||
Text="{u:I18n RequestAdminApproval}"
|
||||
StyleClass="box-button-row"
|
||||
Command="{Binding RequestAdminApprovalCommand}"
|
||||
IsVisible="{Binding RequestAdminApprovalEnabled}"/>
|
||||
IsVisible="{Binding RequestAdminApprovalEnabled}"
|
||||
AutomationId="RequestAdminApprovalButton" />
|
||||
<Button
|
||||
x:Name="_approveWithMasterPassword"
|
||||
Text="{u:I18n ApproveWithMasterPassword}"
|
||||
StyleClass="box-button-row"
|
||||
Command="{Binding ApproveWithMasterPasswordCommand}"
|
||||
IsVisible="{Binding ApproveWithMasterPasswordEnabled}"/>
|
||||
IsVisible="{Binding ApproveWithMasterPasswordEnabled}"
|
||||
AutomationId="ApproveWithMasterPasswordButton" />
|
||||
<Label
|
||||
Text="{Binding LoggingInAsText}"
|
||||
StyleClass="text-sm"
|
||||
Margin="0,40,0,0"
|
||||
AutomationId="LoggingInAsLabel"
|
||||
/>
|
||||
AutomationId="LoggingInAsLabel" />
|
||||
<Label
|
||||
Text="{u:I18n NotYou}"
|
||||
StyleClass="text-md"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="{u:I18n Close}" Command="{Binding CloseCommand}" Order="Primary" Priority="-1" x:Name="_closeItem"/>
|
||||
<ToolbarItem Text="{u:I18n Close}" Command="{Binding CloseCommand}" Order="Primary" Priority="-1" x:Name="_closeItem" />
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ScrollView>
|
||||
@@ -29,15 +29,17 @@
|
||||
<Label
|
||||
Text="{Binding SubTitle}"
|
||||
FontSize="Small"
|
||||
Margin="0,0,0,10"/>
|
||||
Margin="0,0,0,10"
|
||||
AutomationId="SubTitleLabel" />
|
||||
<Label
|
||||
Text="{Binding Description}"
|
||||
FontSize="Small"
|
||||
Margin="0,0,0,24"/>
|
||||
Margin="0,0,0,24"
|
||||
AutomationId="DescriptionLabel" />
|
||||
<Label
|
||||
Text="{u:I18n FingerprintPhrase}"
|
||||
FontSize="Small"
|
||||
FontAttributes="Bold"/>
|
||||
FontAttributes="Bold" />
|
||||
<controls:MonoLabel
|
||||
FormattedText="{Binding FingerprintPhrase}"
|
||||
FontSize="Small"
|
||||
@@ -62,7 +64,7 @@
|
||||
Color="{DynamicResource DisabledIconColor}" />
|
||||
<Label
|
||||
Text="{Binding OtherOptions}"
|
||||
FontSize="Small"/>
|
||||
FontSize="Small" />
|
||||
<Label
|
||||
Text="{u:I18n ViewAllLoginOptions}"
|
||||
StyleClass="text-sm"
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<StackLayout StyleClass="box">
|
||||
<Label Text="{u:I18n LogInSsoSummary}"
|
||||
StyleClass="text-md"
|
||||
HorizontalTextAlignment="Start"></Label>
|
||||
HorizontalTextAlignment="Start" />
|
||||
<StackLayout StyleClass="box-row">
|
||||
<Label
|
||||
Text="{u:I18n OrgIdentifier}"
|
||||
@@ -33,13 +33,15 @@
|
||||
Keyboard="Default"
|
||||
StyleClass="box-value"
|
||||
ReturnType="Go"
|
||||
ReturnCommand="{Binding LogInCommand}" />
|
||||
ReturnCommand="{Binding LogInCommand}"
|
||||
AutomationId="OrgIdentifierEntry" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<StackLayout Padding="10, 0">
|
||||
<Button Text="{u:I18n LogIn}"
|
||||
StyleClass="btn-primary"
|
||||
Clicked="LogIn_Clicked"></Button>
|
||||
Clicked="LogIn_Clicked"
|
||||
AutomationId="LogInButton" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
|
||||
@@ -279,6 +279,15 @@
|
||||
Text="{Binding AddyIoDomainName}"
|
||||
StyleClass="box-value"
|
||||
AutomationId="AnonAddyDomainNameEntry" />
|
||||
<Label IsVisible="{Binding ForwardedEmailServiceSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:ForwardedEmailServiceType.ForwardEmail}}"
|
||||
Text="{u:I18n DomainNameRequiredParenthesis}"
|
||||
StyleClass="box-label"
|
||||
Margin="0,10,0,0"/>
|
||||
<Entry IsVisible="{Binding ForwardedEmailServiceSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:ForwardedEmailServiceType.ForwardEmail}}"
|
||||
x:Name="_forwardEmailDomainNameEntry"
|
||||
Text="{Binding ForwardEmailDomainName}"
|
||||
StyleClass="box-value"
|
||||
AutomationId="ForwardEmailDomainNameEntry" />
|
||||
</StackLayout>
|
||||
<!--RANDOM WORD OPTIONS-->
|
||||
<Grid IsVisible="{Binding UsernameTypeSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:UsernameType.RandomWord}}">
|
||||
|
||||
@@ -78,6 +78,7 @@ namespace Bit.App.Pages
|
||||
ForwardedEmailServiceType.DuckDuckGo,
|
||||
ForwardedEmailServiceType.Fastmail,
|
||||
ForwardedEmailServiceType.FirefoxRelay,
|
||||
ForwardedEmailServiceType.ForwardEmail,
|
||||
ForwardedEmailServiceType.SimpleLogin
|
||||
};
|
||||
|
||||
@@ -464,6 +465,8 @@ namespace Bit.App.Pages
|
||||
return _usernameOptions.FirefoxRelayApiAccessToken;
|
||||
case ForwardedEmailServiceType.SimpleLogin:
|
||||
return _usernameOptions.SimpleLoginApiKey;
|
||||
case ForwardedEmailServiceType.ForwardEmail:
|
||||
return _usernameOptions.ForwardEmailApiAccessToken;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -513,6 +516,14 @@ namespace Bit.App.Pages
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ForwardedEmailServiceType.ForwardEmail:
|
||||
if (_usernameOptions.ForwardEmailApiAccessToken != value)
|
||||
{
|
||||
_usernameOptions.ForwardEmailApiAccessToken = value;
|
||||
changed = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -537,6 +548,7 @@ namespace Bit.App.Pages
|
||||
case ForwardedEmailServiceType.DuckDuckGo:
|
||||
case ForwardedEmailServiceType.Fastmail:
|
||||
case ForwardedEmailServiceType.SimpleLogin:
|
||||
case ForwardedEmailServiceType.ForwardEmail:
|
||||
return AppResources.APIKeyRequiredParenthesis;
|
||||
default:
|
||||
return null;
|
||||
@@ -567,6 +579,20 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
public string ForwardEmailDomainName
|
||||
{
|
||||
get => _usernameOptions?.ForwardEmailDomainName;
|
||||
set
|
||||
{
|
||||
if (_usernameOptions != null && _usernameOptions.ForwardEmailDomainName != value)
|
||||
{
|
||||
_usernameOptions.ForwardEmailDomainName = value;
|
||||
TriggerPropertyChanged(nameof(ForwardEmailDomainName));
|
||||
SaveUsernameOptionsAsync(false).FireAndForget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CapitalizeRandomWordUsername
|
||||
{
|
||||
get => _usernameOptions?.CapitalizeRandomWordUsername == true;
|
||||
@@ -811,6 +837,7 @@ namespace Bit.App.Pages
|
||||
TriggerPropertyChanged(nameof(GeneratorTypeSelected));
|
||||
TriggerPropertyChanged(nameof(UsernameTypeDescriptionLabel));
|
||||
TriggerPropertyChanged(nameof(EmailWebsite));
|
||||
TriggerPropertyChanged(nameof(ForwardEmailDomainName));
|
||||
}
|
||||
|
||||
private void SetOptions()
|
||||
|
||||
@@ -23,19 +23,21 @@
|
||||
Title="{u:I18n EnableSyncOnRefresh}"
|
||||
IsToggled="{Binding EnableSyncOnRefresh}"
|
||||
Subtitle="{u:I18n EnableSyncOnRefreshDescription}"
|
||||
AutomationId="SubmitCrashLogsSwitch"
|
||||
AutomationId="SyncOnRefreshSwitch"
|
||||
StyleClass="settings-item-view"
|
||||
HorizontalOptions="FillAndExpand" />
|
||||
|
||||
<StackLayout StyleClass="box" Margin="0,12,0,0">
|
||||
<Button
|
||||
Text="{u:I18n SyncNow}"
|
||||
Command="{Binding SyncCommand}"></Button>
|
||||
Command="{Binding SyncCommand}"
|
||||
AutomationId="SyncNowButton"></Button>
|
||||
<Label
|
||||
Text="{Binding LastSyncDisplay}"
|
||||
StyleClass="text-muted, text-sm"
|
||||
HorizontalTextAlignment="Start"
|
||||
Margin="0,10" />
|
||||
Margin="0,10"
|
||||
AutomationId="LastSyncLabel" />
|
||||
</StackLayout>
|
||||
|
||||
<controls:SettingChooserItemView
|
||||
@@ -51,7 +53,7 @@
|
||||
Title="{u:I18n AllowScreenCapture}"
|
||||
IsToggled="{Binding IsScreenCaptureAllowed}"
|
||||
IsEnabled="{Binding CanToggleeScreenCaptureAllowed}"
|
||||
AutomationId="SubmitCrashLogsSwitch"
|
||||
AutomationId="AllowScreenCaptureSwitch"
|
||||
StyleClass="settings-item-view"
|
||||
HorizontalOptions="FillAndExpand" />
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
xmlns:dts="clr-namespace:Bit.App.Lists.DataTemplateSelectors"
|
||||
xmlns:il="clr-namespace:Bit.App.Lists.ItemLayouts.CustomFields"
|
||||
HideSoftInputOnTapped="True"
|
||||
xmlns:core="clr-namespace:Bit.Core"
|
||||
xmlns:core="clr-namespace:Bit.Core"
|
||||
xmlns:appResources="clr-namespace:Bit.Core.Resources.Localization"
|
||||
x:DataType="pages:CipherAddEditPageViewModel"
|
||||
x:Name="_page"
|
||||
Title="{Binding PageTitle}">
|
||||
@@ -29,6 +30,8 @@
|
||||
<u:InverseBoolConverter x:Key="inverseBool" />
|
||||
<u:StringHasValueConverter x:Key="stringHasValue" />
|
||||
<u:IsNotNullConverter x:Key="notNull" />
|
||||
<u:DateTimeConverter x:Key="dateTime" Format="{x:Static appResources:AppResources.CreatedXY}" />
|
||||
|
||||
<ToolbarItem Text="{u:I18n Cancel}" Clicked="Close_Clicked" Order="Primary" Priority="-1"
|
||||
x:Key="closeItem" x:Name="_closeItem" />
|
||||
<ToolbarItem Text="{u:I18n Collections}"
|
||||
@@ -230,7 +233,7 @@
|
||||
Margin="0,10,0,0"
|
||||
IsVisible="{Binding ShowPasskeyInfo}"/>
|
||||
<Entry
|
||||
Text="{Binding CreationDate}"
|
||||
Text="{Binding Cipher.Login.MainFido2Credential.CreationDate, Mode=OneWay, Converter={StaticResource dateTime}, FallbackValue=''}"
|
||||
IsEnabled="False"
|
||||
StyleClass="box-value,text-muted"
|
||||
IsVisible="{Binding ShowPasskeyInfo}" />
|
||||
|
||||
@@ -312,7 +312,7 @@ namespace Bit.App.Pages
|
||||
public string PasswordVisibilityAccessibilityText => ShowPassword ? AppResources.PasswordIsVisibleTapToHide : AppResources.PasswordIsNotVisibleTapToShow;
|
||||
public bool HasTotpValue => IsLogin && !string.IsNullOrEmpty(Cipher?.Login?.Totp);
|
||||
public string SetupTotpText => $"{BitwardenIcons.Camera} {AppResources.SetupTotp}";
|
||||
public bool ShowPasskeyInfo => Cipher?.HasFido2Key == true && !CloneMode;
|
||||
public bool ShowPasskeyInfo => Cipher?.HasFido2Credential == true && !CloneMode;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
@@ -374,7 +374,7 @@ namespace Bit.App.Pages
|
||||
if (Cipher.Type == CipherType.Login)
|
||||
{
|
||||
// passkeys can't be cloned
|
||||
Cipher.Login.Fido2Keys = null;
|
||||
Cipher.Login.Fido2Credentials = null;
|
||||
}
|
||||
}
|
||||
if (appOptions?.OtpData != null && Cipher.Type == CipherType.Login)
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
xmlns:pages="clr-namespace:Bit.App.Pages"
|
||||
xmlns:u="clr-namespace:Bit.App.Utilities"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
xmlns:effects="clr-namespace:Bit.App.Effects"
|
||||
xmlns:views="clr-namespace:Bit.Core.Models.View"
|
||||
xmlns:dts="clr-namespace:Bit.App.Lists.DataTemplateSelectors"
|
||||
xmlns:il="clr-namespace:Bit.App.Lists.ItemLayouts.CustomFields"
|
||||
xmlns:core="clr-namespace:Bit.Core"
|
||||
xmlns:core="clr-namespace:Bit.Core"
|
||||
xmlns:localization="clr-namespace:Bit.Core.Resources.Localization"
|
||||
x:DataType="pages:CipherDetailsPageViewModel"
|
||||
HideSoftInputOnTapped="True"
|
||||
x:Name="_page"
|
||||
@@ -24,6 +24,7 @@
|
||||
<u:InverseBoolConverter x:Key="inverseBool" />
|
||||
<u:StringHasValueConverter x:Key="stringHasValue" />
|
||||
<u:IsNotNullConverter x:Key="notNull" />
|
||||
<u:DateTimeConverter x:Key="dateTime" Format="{x:Static localization:AppResources.CreatedXY}" />
|
||||
<ToolbarItem Text="{u:I18n Collections}"
|
||||
x:Key="collectionsItem"
|
||||
x:Name="_collectionsItem"
|
||||
@@ -200,12 +201,12 @@
|
||||
Text="{u:I18n Passkey}"
|
||||
StyleClass="box-label"
|
||||
Margin="0,10,0,0"
|
||||
IsVisible="{Binding Cipher.Login.MainFido2Key, Converter={StaticResource notNull}}"/>
|
||||
IsVisible="{Binding Cipher.Login.MainFido2Credential, Converter={StaticResource notNull}}"/>
|
||||
<Entry
|
||||
Text="{Binding CreationDate}"
|
||||
Text="{Binding Cipher.Login.MainFido2Credential.CreationDate, Mode=OneWay, Converter={StaticResource dateTime}, FallbackValue=''}"
|
||||
IsEnabled="False"
|
||||
StyleClass="box-value,text-muted"
|
||||
IsVisible="{Binding Cipher.Login.MainFido2Key, Converter={StaticResource notNull}}" />
|
||||
IsVisible="{Binding Cipher.Login.MainFido2Credential, Converter={StaticResource notNull}, FallbackValue=False}" />
|
||||
<Grid StyleClass="box-row"
|
||||
IsVisible="{Binding ShowTotp}"
|
||||
AutomationId="ItemRow">
|
||||
|
||||
@@ -708,7 +708,7 @@ namespace Bit.App.Pages
|
||||
|
||||
private async Task<bool> CanCloneAsync()
|
||||
{
|
||||
if (!Cipher.HasFido2Key)
|
||||
if (!Cipher.HasFido2Credential)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -126,24 +126,27 @@ namespace Bit.App.Pages
|
||||
|
||||
await LoadOnAppearedAsync(_mainLayout, false, async () =>
|
||||
{
|
||||
if (!_syncService.SyncInProgress || (await _cipherService.GetAllAsync()).Any())
|
||||
if (_previousPage == null)
|
||||
{
|
||||
try
|
||||
if (!_syncService.SyncInProgress || (await _cipherService.GetAllAsync()).Any())
|
||||
{
|
||||
await _vm.LoadAsync();
|
||||
try
|
||||
{
|
||||
await _vm.LoadAsync();
|
||||
}
|
||||
catch (Exception e) when (e.Message.Contains("No key."))
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
await _vm.LoadAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception e) when (e.Message.Contains("No key."))
|
||||
else
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
await _vm.LoadAsync();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.Delay(5000);
|
||||
if (!_vm.Loaded)
|
||||
{
|
||||
await _vm.LoadAsync();
|
||||
await Task.Delay(5000);
|
||||
if (!_vm.Loaded)
|
||||
{
|
||||
await _vm.LoadAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
await ShowPreviousPageAsync();
|
||||
|
||||
@@ -113,15 +113,9 @@ namespace Bit.App.Pages
|
||||
try
|
||||
{
|
||||
await _deviceActionService.ShowLoadingAsync(AppResources.Saving);
|
||||
var error = await _cipherService.ShareWithServerAsync(cipherView, OrganizationId, checkedCollectionIds);
|
||||
await _cipherService.ShareWithServerAsync(cipherView, OrganizationId, checkedCollectionIds);
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
|
||||
if (error == ICipherService.ShareWithServerError.DuplicatedPasskeyInOrg)
|
||||
{
|
||||
_platformUtilsService.ShowToast(null, null, AppResources.ThisItemCannotBeSharedWithTheOrganizationBecauseThereIsOneAlreadyWithTheSamePasskey);
|
||||
return false;
|
||||
}
|
||||
|
||||
var movedItemToOrgText = string.Format(AppResources.MovedItemToOrg, cipherView.Name,
|
||||
(await _organizationService.GetAsync(OrganizationId)).Name);
|
||||
_platformUtilsService.ShowToast("success", null, movedItemToOrgText);
|
||||
|
||||
Reference in New Issue
Block a user