package email
import (
"context"
"fmt"
"html/template"
"net/url"
"strings"
"github.com/cloudreve/Cloudreve/v4/ent"
"github.com/cloudreve/Cloudreve/v4/pkg/setting"
)
type CommonContext struct {
SiteBasic *setting.SiteBasic
Logo *setting.Logo
SiteUrl string
}
// ResetContext used for variables in reset email
type ResetContext struct {
*CommonContext
User *ent.User
Url string
}
// NewResetEmail generates reset email from template
func NewResetEmail(ctx context.Context, settings setting.Provider, user *ent.User, url string) (string, string, error) {
templates := settings.ResetEmailTemplate(ctx)
if len(templates) == 0 {
return "", "", fmt.Errorf("reset email template not configured")
}
selected := selectTemplate(templates, user)
resetCtx := ResetContext{
CommonContext: commonContext(ctx, settings),
User: user,
Url: url,
}
tmpl, err := template.New("reset").Parse(selected.Body)
if err != nil {
return "", "", fmt.Errorf("failed to parse email template: %w", err)
}
var res strings.Builder
err = tmpl.Execute(&res, resetCtx)
if err != nil {
return "", "", fmt.Errorf("failed to execute email template: %w", err)
}
return fmt.Sprintf("[%s] %s", resetCtx.SiteBasic.Name, selected.Title), res.String(), nil
}
// ActivationContext used for variables in activation email
type ActivationContext struct {
*CommonContext
User *ent.User
Url string
}
// NewActivationEmail generates activation email from template
func NewActivationEmail(ctx context.Context, settings setting.Provider, user *ent.User, url string) (string, string, error) {
templates := settings.ActivationEmailTemplate(ctx)
if len(templates) == 0 {
return "", "", fmt.Errorf("activation email template not configured")
}
selected := selectTemplate(templates, user)
activationCtx := ActivationContext{
CommonContext: commonContext(ctx, settings),
User: user,
Url: url,
}
tmpl, err := template.New("activation").Parse(selected.Body)
if err != nil {
return "", "", fmt.Errorf("failed to parse email template: %w", err)
}
var res strings.Builder
err = tmpl.Execute(&res, activationCtx)
if err != nil {
return "", "", fmt.Errorf("failed to execute email template: %w", err)
}
return fmt.Sprintf("[%s] %s", activationCtx.SiteBasic.Name, selected.Title), res.String(), nil
}
func commonContext(ctx context.Context, settings setting.Provider) *CommonContext {
logo := settings.Logo(ctx)
siteUrl := settings.SiteURL(ctx)
res := &CommonContext{
SiteBasic: settings.SiteBasic(ctx),
Logo: settings.Logo(ctx),
SiteUrl: siteUrl.String(),
}
// Add site url if logo is not an url
if !strings.HasPrefix(logo.Light, "http") {
logoPath, _ := url.Parse(logo.Light)
res.Logo.Light = siteUrl.ResolveReference(logoPath).String()
}
if !strings.HasPrefix(logo.Normal, "http") {
logoPath, _ := url.Parse(logo.Normal)
res.Logo.Normal = siteUrl.ResolveReference(logoPath).String()
}
return res
}
func selectTemplate(templates []setting.EmailTemplate, u *ent.User) setting.EmailTemplate {
selected := templates[0]
if u != nil {
for _, t := range templates {
if strings.EqualFold(t.Language, u.Settings.Language) {
selected = t
break
}
}
}
return selected
}