105 lines
2.5 KiB
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
|
||
|
}
|