hydra-passwordless/internal/command/send_confirmation_email.go

105 lines
2.5 KiB
Go

package command
import (
"bytes"
"context"
"fmt"
"log"
"forge.cadoles.com/wpetit/hydra-passwordless/internal/config"
"forge.cadoles.com/wpetit/hydra-passwordless/internal/hydra"
"forge.cadoles.com/wpetit/hydra-passwordless/internal/mail"
"forge.cadoles.com/wpetit/hydra-passwordless/internal/token"
"github.com/aymerick/douceur/inliner"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/cqrs"
"gitlab.com/wpetit/goweb/middleware/container"
"gitlab.com/wpetit/goweb/service/build"
"gitlab.com/wpetit/goweb/service/template"
)
type SendConfirmationEmailRequest struct {
Email string
Challenge string
DefaultScheme string
DefaultAddress string
}
func HandleSendConfirmationEmailRequest(ctx context.Context, cmd cqrs.Command) error {
req, ok := cmd.Request().(*SendConfirmationEmailRequest)
if !ok {
return cqrs.ErrUnexpectedRequest
}
ctn := container.Must(ctx)
tmpl := template.Must(ctn)
hydr := hydra.Must(ctn)
info := build.Must(ctn)
ml := mail.Must(ctn)
conf := config.Must(ctn)
_, err := hydr.LoginRequest(req.Challenge)
if err != nil {
return errors.Wrap(err, "could not retrieve hydra login response")
}
token, err := token.Generate(
conf.HTTP.TokenSigningKey,
conf.HTTP.TokenEncryptionKey,
req.Email,
req.Challenge,
)
if err != nil {
return errors.Wrap(err, "could not generate jwt")
}
address := req.DefaultAddress
if conf.HTTP.PublicAddress != "" {
address = conf.HTTP.PublicAddress
}
scheme := req.DefaultScheme
if scheme == "" {
scheme = "http:"
}
if conf.HTTP.PublicScheme != "" {
scheme = conf.HTTP.PublicScheme
}
log.Println(req, scheme)
verificationLink := fmt.Sprintf("%s//%s/verify?token=%s", scheme, address, token)
log.Println(verificationLink)
data := template.Data{
"BuildInfo": info,
"VerificationLink": verificationLink,
}
var buf bytes.Buffer
if err := tmpl.Render(&buf, "verification_email.html.tmpl", data); err != nil {
return errors.Wrap(err, "could not render email template")
}
// Inline CSS for mail clients
html, err := inliner.Inline(buf.String())
if err != nil {
return errors.Wrap(err, "could not inline css")
}
err = ml.Send(
mail.WithSender(conf.SMTP.SenderAddress, conf.SMTP.SenderName),
mail.WithRecipients(req.Email),
mail.WithSubject(fmt.Sprintf("[Authentification]")),
mail.WithBody(mail.ContentTypeHTML, html, nil),
mail.WithAlternativeBody(mail.ContentTypeText, "", nil),
)
if err != nil {
return errors.Wrap(err, "could not send email")
}
return nil
}