mirror of
https://github.com/h44z/wg-portal.git
synced 2025-04-19 08:55:12 +00:00
128 lines
3.4 KiB
Go
128 lines
3.4 KiB
Go
|
package mail
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"github.com/h44z/wg-portal/internal/config"
|
||
|
"github.com/h44z/wg-portal/internal/domain"
|
||
|
"github.com/sirupsen/logrus"
|
||
|
"io"
|
||
|
)
|
||
|
|
||
|
type Manager struct {
|
||
|
cfg *config.Config
|
||
|
tplHandler *TemplateHandler
|
||
|
|
||
|
mailer Mailer
|
||
|
configFiles ConfigFileManager
|
||
|
users UserDatabaseRepo
|
||
|
wg WireguardDatabaseRepo
|
||
|
}
|
||
|
|
||
|
func NewMailManager(cfg *config.Config, mailer Mailer, configFiles ConfigFileManager, users UserDatabaseRepo, wg WireguardDatabaseRepo) (*Manager, error) {
|
||
|
tplHandler, err := newTemplateHandler(cfg.Web.ExternalUrl)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("failed to initialize template handler: %w", err)
|
||
|
}
|
||
|
|
||
|
m := &Manager{
|
||
|
cfg: cfg,
|
||
|
tplHandler: tplHandler,
|
||
|
mailer: mailer,
|
||
|
configFiles: configFiles,
|
||
|
users: users,
|
||
|
wg: wg,
|
||
|
}
|
||
|
|
||
|
return m, nil
|
||
|
}
|
||
|
|
||
|
func (m Manager) SendPeerEmail(ctx context.Context, linkOnly bool, peers ...domain.PeerIdentifier) error {
|
||
|
for _, peerId := range peers {
|
||
|
peer, err := m.wg.GetPeer(ctx, peerId)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("failed to fetch peer %s: %w", peerId, err)
|
||
|
}
|
||
|
|
||
|
if peer.UserIdentifier == "" {
|
||
|
logrus.Debugf("skipping peer email for %s, no user linked", peerId)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
user, err := m.users.GetUser(ctx, peer.UserIdentifier)
|
||
|
if err != nil {
|
||
|
logrus.Debugf("skipping peer email for %s, unable to fetch user: %v", peerId, err)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
if user.Email == "" {
|
||
|
logrus.Debugf("skipping peer email for %s, user has no mail address", peerId)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
err = m.sendPeerEmail(ctx, linkOnly, user, peer)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("failed to send peer email for %s: %w", peerId, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (m Manager) sendPeerEmail(ctx context.Context, linkOnly bool, user *domain.User, peer *domain.Peer) error {
|
||
|
qrName := "WireGuardQRCode.png"
|
||
|
configName := peer.GetConfigFileName()
|
||
|
|
||
|
var (
|
||
|
txtMail, htmlMail io.Reader
|
||
|
err error
|
||
|
mailOptions domain.MailOptions
|
||
|
)
|
||
|
if linkOnly {
|
||
|
txtMail, htmlMail, err = m.tplHandler.GetConfigMail(user, "deep link TBD")
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("failed to get mail body: %w", err)
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
peerConfig, err := m.configFiles.GetPeerConfig(ctx, peer.Identifier)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("failed to fetch peer config for %s: %w", peer.Identifier, err)
|
||
|
}
|
||
|
|
||
|
peerConfigQr, err := m.configFiles.GetPeerConfigQrCode(ctx, peer.Identifier)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("failed to fetch peer config QR code for %s: %w", peer.Identifier, err)
|
||
|
}
|
||
|
|
||
|
txtMail, htmlMail, err = m.tplHandler.GetConfigMailWithAttachment(user, configName, qrName)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("failed to get full mail body: %w", err)
|
||
|
}
|
||
|
|
||
|
mailOptions.Attachments = append(mailOptions.Attachments, domain.MailAttachment{
|
||
|
Name: configName,
|
||
|
ContentType: "text/plain",
|
||
|
Data: peerConfig,
|
||
|
Embedded: false,
|
||
|
})
|
||
|
mailOptions.Attachments = append(mailOptions.Attachments, domain.MailAttachment{
|
||
|
Name: qrName,
|
||
|
ContentType: "image/png",
|
||
|
Data: peerConfigQr,
|
||
|
Embedded: true,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
txtMailStr, _ := io.ReadAll(txtMail)
|
||
|
htmlMailStr, _ := io.ReadAll(htmlMail)
|
||
|
mailOptions.HtmlBody = string(htmlMailStr)
|
||
|
|
||
|
err = m.mailer.Send(ctx, "WireGuard VPN Configuration", string(txtMailStr), []string{user.Email}, &mailOptions)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("failed to send mail: %w", err)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|