1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-14 15:00:49 -05:00

Implement handlebar logic

This commit is contained in:
Hinton 2025-06-05 09:44:57 +02:00
parent 159d4cc32d
commit bcb8b41311
No known key found for this signature in database
GPG Key ID: 5F7295599C5D965C
5 changed files with 95 additions and 9 deletions

View File

@ -1,9 +1,24 @@
using Bit.Core.Platform.Services;
using System.Net;
using Bit.Core.Platform.Services;
namespace Bit.Core.Auth.UserFeatures.Registration.VerifyEmail;
public class VerifyEmail(string url) : BaseMailModel2
public class VerifyEmail() : BaseMailModel2
{
public override string Subject { get; set; } = "Verify Your Email";
public string Url { get; } = url;
public required string Token { get; init; }
public required string Email { get; init; }
public required string WebVaultUrl { get; init; }
public string Url
{
get => string.Format(
"{0}/redirect-connector.html#finish-signup?token={1}&email={2}&fromEmail=true",
WebVaultUrl,
WebUtility.UrlEncode(Token),
WebUtility.UrlEncode(Email)
);
}
}

View File

@ -16,7 +16,9 @@
<ItemGroup>
<EmbeddedResource Include="licensing.cer" />
<EmbeddedResource Include="licensing_dev.cer" />
<EmbeddedResource Include="MailTemplates\Handlebars\**\*.hbs" />
<!-- Email templates uses .hbs extension, they must be included for emails to work -->
<EmbeddedResource Include="**\*.hbs" />
</ItemGroup>
<ItemGroup>
@ -70,7 +72,7 @@
<PackageReference Include="System.Text.Json" Version="8.0.5" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\" />
<Folder Include="Properties\" />

View File

@ -12,7 +12,7 @@ public interface IMailer
/// </summary>
/// <param name="message"></param>
/// <param name="recipient">Recipient email</param>
public void SendEmail(BaseMailModel2 message, string recipient);
public Task SendEmail(BaseMailModel2 message, string recipient);
/// <summary>
/// Sends multiple emails message to the specified recipients.

View File

@ -1,11 +1,57 @@
namespace Bit.Core.Platform.Services;
using System.Reflection;
using HandlebarsDotNet;
namespace Bit.Core.Platform.Services;
#nullable enable
public class Mailer : IMailer
{
public void SendEmail(BaseMailModel2 message, string recipient) => throw new NotImplementedException();
public IHandlebars H { get; set; }
public Mailer()
{
H = Handlebars.Create();
}
public async Task SendEmail(BaseMailModel2 message, string recipient)
{
var htmlTemplate = await ReadTemplateAsync(message, "html");
var textTemplate = await ReadTemplateAsync(message, "txt");
var assembly = typeof(Mailer).Assembly;
var basicHtmlLayoutSource = await ReadSourceAsync(assembly, "Bit.Core.MailTemplates.Handlebars.Layouts.Full.html.hbs");
H.RegisterTemplate("FullHtmlLayout", basicHtmlLayoutSource);
var t = H.Compile(htmlTemplate);
var tmp = t(message);
Console.WriteLine(tmp);
}
public void SendEmails(BaseMailModel2 message, string[] recipients) => throw new NotImplementedException();
private static async Task<string?> ReadTemplateAsync(BaseMailModel2 message, string suffix)
{
var assembly = message.GetType().Assembly;
var qualifiedName = message.GetType().FullName;
var template = $"{qualifiedName}.{suffix}.hbs";
return await ReadSourceAsync(assembly, template);
}
private static async Task<string?> ReadSourceAsync(Assembly assembly, string template)
{
if (assembly.GetManifestResourceNames().All(f => f != template))
{
return null;
}
await using var s = assembly.GetManifestResourceStream(template)!;
using var sr = new StreamReader(s);
return await sr.ReadToEndAsync();
}
}

View File

@ -0,0 +1,23 @@
using Bit.Core.Auth.UserFeatures.Registration.VerifyEmail;
using Bit.Core.Platform.Services;
using Xunit;
namespace Bit.Core.Test.Platform;
public class MailerTest
{
[Fact]
public async Task SendEmailAsync()
{
var mailer = new Mailer();
var mail = new VerifyEmail
{
Token = "test-token",
Email = "test@bitwarden.com",
WebVaultUrl = "https://vault.bitwarden.com"
};
await mailer.SendEmail(mail, "test@bitwarden.com");
}
}