[PM-1835] Add ForwardEmail alias to Username Generator (#2803)

* Add ForwardEmail alias to Username Generator

* remove unnecessary initializer

* Corrected order of alias Generators

* PM-4307 - Trigger ForwardEmailDomainName PropertyChanged after initialization
This commit is contained in:
aj-rosado 2023-10-26 13:58:07 +01:00 committed by GitHub
parent 4dda7a6634
commit 2e5fb414b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 118 additions and 0 deletions

View file

@ -278,6 +278,15 @@
Text="{Binding AddyIoDomainName}" Text="{Binding AddyIoDomainName}"
StyleClass="box-value" StyleClass="box-value"
AutomationId="AnonAddyDomainNameEntry" /> 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> </StackLayout>
<!--RANDOM WORD OPTIONS--> <!--RANDOM WORD OPTIONS-->
<Grid IsVisible="{Binding UsernameTypeSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:UsernameType.RandomWord}}"> <Grid IsVisible="{Binding UsernameTypeSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:UsernameType.RandomWord}}">

View file

@ -81,6 +81,7 @@ namespace Bit.App.Pages
ForwardedEmailServiceType.DuckDuckGo, ForwardedEmailServiceType.DuckDuckGo,
ForwardedEmailServiceType.Fastmail, ForwardedEmailServiceType.Fastmail,
ForwardedEmailServiceType.FirefoxRelay, ForwardedEmailServiceType.FirefoxRelay,
ForwardedEmailServiceType.ForwardEmail,
ForwardedEmailServiceType.SimpleLogin ForwardedEmailServiceType.SimpleLogin
}; };
@ -461,6 +462,8 @@ namespace Bit.App.Pages
return _usernameOptions.FirefoxRelayApiAccessToken; return _usernameOptions.FirefoxRelayApiAccessToken;
case ForwardedEmailServiceType.SimpleLogin: case ForwardedEmailServiceType.SimpleLogin:
return _usernameOptions.SimpleLoginApiKey; return _usernameOptions.SimpleLoginApiKey;
case ForwardedEmailServiceType.ForwardEmail:
return _usernameOptions.ForwardEmailApiAccessToken;
default: default:
return null; return null;
} }
@ -505,6 +508,14 @@ namespace Bit.App.Pages
changed = true; changed = true;
} }
break; break;
case ForwardedEmailServiceType.ForwardEmail:
if (_usernameOptions.ForwardEmailApiAccessToken != value)
{
_usernameOptions.ForwardEmailApiAccessToken = value;
changed = true;
}
break;
default: default:
break; break;
} }
@ -529,6 +540,7 @@ namespace Bit.App.Pages
case ForwardedEmailServiceType.DuckDuckGo: case ForwardedEmailServiceType.DuckDuckGo:
case ForwardedEmailServiceType.Fastmail: case ForwardedEmailServiceType.Fastmail:
case ForwardedEmailServiceType.SimpleLogin: case ForwardedEmailServiceType.SimpleLogin:
case ForwardedEmailServiceType.ForwardEmail:
return AppResources.APIKeyRequiredParenthesis; return AppResources.APIKeyRequiredParenthesis;
default: default:
return null; return null;
@ -559,6 +571,20 @@ namespace Bit.App.Pages
} }
} }
public string ForwardEmailDomainName
{
get => _usernameOptions.ForwardEmailDomainName;
set
{
if (_usernameOptions.ForwardEmailDomainName != value)
{
_usernameOptions.ForwardEmailDomainName = value;
TriggerPropertyChanged(nameof(ForwardEmailDomainName));
SaveUsernameOptionsAsync(false).FireAndForget();
}
}
}
public bool CapitalizeRandomWordUsername public bool CapitalizeRandomWordUsername
{ {
get => _usernameOptions.CapitalizeRandomWordUsername; get => _usernameOptions.CapitalizeRandomWordUsername;
@ -803,6 +829,7 @@ namespace Bit.App.Pages
TriggerPropertyChanged(nameof(GeneratorTypeSelected)); TriggerPropertyChanged(nameof(GeneratorTypeSelected));
TriggerPropertyChanged(nameof(UsernameTypeDescriptionLabel)); TriggerPropertyChanged(nameof(UsernameTypeDescriptionLabel));
TriggerPropertyChanged(nameof(EmailWebsite)); TriggerPropertyChanged(nameof(EmailWebsite));
TriggerPropertyChanged(nameof(ForwardEmailDomainName));
} }
private void SetOptions() private void SetOptions()

View file

@ -3235,6 +3235,15 @@ namespace Bit.App.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to ForwardEmail.
/// </summary>
public static string ForwardEmail {
get {
return ResourceManager.GetString("ForwardEmail", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to 4 hours. /// Looks up a localized string similar to 4 hours.
/// </summary> /// </summary>

View file

@ -2425,6 +2425,10 @@ select Add TOTP to store the key safely</value>
<value>Fastmail</value> <value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment> <comment>"Fastmail" is the product name and should not be translated.</comment>
</data> </data>
<data name="ForwardEmail" xml:space="preserve">
<value>ForwardEmail</value>
<comment>"ForwardEmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve"> <data name="APIAccessToken" xml:space="preserve">
<value>API access token</value> <value>API access token</value>
</data> </data>

View file

@ -15,5 +15,7 @@ namespace Bit.Core.Enums
DuckDuckGo = 3, DuckDuckGo = 3,
[LocalizableEnum("Fastmail")] [LocalizableEnum("Fastmail")]
Fastmail = 4, Fastmail = 4,
[LocalizableEnum("ForwardEmail")]
ForwardEmail = 5,
} }
} }

View file

@ -24,6 +24,8 @@ namespace Bit.Core.Models.Domain
public string FastMailApiKey { get; set; } public string FastMailApiKey { get; set; }
public string AnonAddyApiAccessToken { get; set; } public string AnonAddyApiAccessToken { get; set; }
public string AnonAddyDomainName { get; set; } public string AnonAddyDomainName { get; set; }
public string ForwardEmailApiAccessToken { get; set; }
public string ForwardEmailDomainName { get; set; }
public string EmailWebsite { get; set; } public string EmailWebsite { get; set; }
public ForwarderOptions GetForwarderOptions() public ForwarderOptions GetForwarderOptions()
@ -49,6 +51,12 @@ namespace Bit.Core.Models.Domain
return new ForwarderOptions { ApiKey = FirefoxRelayApiAccessToken }; return new ForwarderOptions { ApiKey = FirefoxRelayApiAccessToken };
case ForwardedEmailServiceType.SimpleLogin: case ForwardedEmailServiceType.SimpleLogin:
return new ForwarderOptions { ApiKey = SimpleLoginApiKey }; return new ForwarderOptions { ApiKey = SimpleLoginApiKey };
case ForwardedEmailServiceType.ForwardEmail:
return new ForwardEmailForwarderOptions
{
ApiKey = ForwardEmailApiAccessToken,
DomainName = ForwardEmailDomainName
};
default: default:
return null; return null;
} }

View file

@ -0,0 +1,52 @@
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Bit.Core.Abstractions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Bit.Core.Services.EmailForwarders
{
public class ForwardEmailForwarderOptions : ForwarderOptions
{
public string DomainName { get; set; }
}
public class ForwardEmailForwarder : BaseForwarder<ForwardEmailForwarderOptions>
{
private readonly string _domain;
protected override string RequestUri => $"https://api.forwardemail.net/v1/domains/{_domain}/aliases";
public ForwardEmailForwarder(string domain)
{
_domain = domain;
}
protected override bool CanGenerate(ForwardEmailForwarderOptions options)
{
return !string.IsNullOrWhiteSpace(options.ApiKey) && !string.IsNullOrWhiteSpace(options.DomainName);
}
protected override void ConfigureHeaders(HttpRequestHeaders headers, ForwardEmailForwarderOptions options)
{
headers.Add("Authorization", $"Basic {Convert.ToBase64String(Encoding.UTF8.GetBytes(options.ApiKey + ":"))}");
}
protected override Task<HttpContent> GetContentAsync(IApiService apiService, ForwardEmailForwarderOptions options)
{
return Task.FromResult<HttpContent>(new StringContent(
JsonConvert.SerializeObject(
new
{
description = "Generated by Bitwarden."
}), Encoding.UTF8, "application/json"));
}
protected override string HandleResponse(JObject result)
{
return $"{result["name"]}@{result["domain"]?["name"] ?? _domain}";
}
}
}

View file

@ -141,6 +141,13 @@ namespace Bit.Core.Services
.GenerateAsync(_apiService, (AnonAddyForwarderOptions)options.GetForwarderOptions()); .GenerateAsync(_apiService, (AnonAddyForwarderOptions)options.GetForwarderOptions());
} }
if (options.ServiceType == ForwardedEmailServiceType.ForwardEmail)
{
var forwardedEmailOptions = (ForwardEmailForwarderOptions)options.GetForwarderOptions();
return await new ForwardEmailForwarder(forwardedEmailOptions.DomainName)
.GenerateAsync(_apiService, forwardedEmailOptions);
}
BaseForwarder<ForwarderOptions> simpleForwarder = null; BaseForwarder<ForwarderOptions> simpleForwarder = null;
switch (options.ServiceType) switch (options.ServiceType)