Basic but complete authentication flow
This commit is contained in:
104
internal/command/send_confirmation_email.go
Normal file
104
internal/command/send_confirmation_email.go
Normal file
@ -0,0 +1,104 @@
|
||||
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
|
||||
}
|
Reference in New Issue
Block a user