feat: mail service

This commit is contained in:
Ilia Denisov
2026-04-17 18:39:16 +02:00
committed by GitHub
parent 23ffcb7535
commit 5b7593e6f6
183 changed files with 31215 additions and 248 deletions
@@ -20,6 +20,11 @@ type Input struct {
// Email is the user-supplied e-mail address that should receive the login
// code.
Email string
// AcceptLanguage stores the optional public Accept-Language header forwarded
// by gateway for auth-mail localization and create-only registration
// context.
AcceptLanguage string
}
// Result describes one public send-email-code response.
@@ -160,6 +165,7 @@ func (s *Service) Execute(ctx context.Context, input Input) (result Result, err
if err != nil {
return Result{}, err
}
preferredLanguage := shared.ResolvePreferredLanguage(input.AcceptLanguage)
now := s.clock.Now().UTC()
abuseResult, err := s.abuseProtector.CheckAndReserve(ctx, ports.SendEmailCodeAbuseInput{
@@ -191,13 +197,14 @@ func (s *Service) Execute(ctx context.Context, input Input) (result Result, err
return Result{}, shared.InternalError(err)
}
pending := challenge.Challenge{
ID: challengeID,
Email: email,
CodeHash: codeHash,
Status: pendingStatus,
DeliveryState: pendingDeliveryState,
CreatedAt: now,
ExpiresAt: now.Add(challenge.InitialTTL),
ID: challengeID,
Email: email,
CodeHash: codeHash,
PreferredLanguage: preferredLanguage,
Status: pendingStatus,
DeliveryState: pendingDeliveryState,
CreatedAt: now,
ExpiresAt: now.Add(challenge.InitialTTL),
}
if err := pending.Validate(); err != nil {
return Result{}, shared.InternalError(err)
@@ -240,8 +247,10 @@ func (s *Service) Execute(ctx context.Context, input Input) (result Result, err
return result, err
default:
deliveryResult, err := s.mailSender.SendLoginCode(ctx, ports.SendLoginCodeInput{
Email: email,
Code: code,
Email: email,
IdempotencyKey: challengeID.String(),
Code: code,
Locale: preferredLanguage,
})
if err != nil {
final.Status = challenge.StatusFailed