mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-29 12:30:11 +00:00
Compare commits
No commits in common. "b8dfb5d6a3058c47869e6f4253cab905fc30c73a" and "831296a3e88e0772f6cc4c68788a15f037b7694d" have entirely different histories.
b8dfb5d6a3
...
831296a3e8
34
api.go
34
api.go
@ -92,13 +92,10 @@ func (app *appContext) checkInvites() {
|
|||||||
for address, settings := range notify {
|
for address, settings := range notify {
|
||||||
if settings["notify-expiry"] {
|
if settings["notify-expiry"] {
|
||||||
go func() {
|
go func() {
|
||||||
msg, err := app.email.constructExpiry(code, data, app)
|
if app.email.constructExpiry(code, data, app) != nil {
|
||||||
if err != nil {
|
|
||||||
app.err.Printf("%s: Failed to construct expiry notification", code)
|
app.err.Printf("%s: Failed to construct expiry notification", code)
|
||||||
app.debug.Printf("Error: %s", err)
|
} else if app.email.send(address, app) != nil {
|
||||||
} else if err := app.email.send(address, msg); err != nil {
|
|
||||||
app.err.Printf("%s: Failed to send expiry notification", code)
|
app.err.Printf("%s: Failed to send expiry notification", code)
|
||||||
app.debug.Printf("Error: %s", err)
|
|
||||||
} else {
|
} else {
|
||||||
app.info.Printf("Sent expiry notification to %s", address)
|
app.info.Printf("Sent expiry notification to %s", address)
|
||||||
}
|
}
|
||||||
@ -129,13 +126,10 @@ func (app *appContext) checkInvite(code string, used bool, username string) bool
|
|||||||
for address, settings := range notify {
|
for address, settings := range notify {
|
||||||
if settings["notify-expiry"] {
|
if settings["notify-expiry"] {
|
||||||
go func() {
|
go func() {
|
||||||
msg, err := app.email.constructExpiry(code, inv, app)
|
if app.email.constructExpiry(code, inv, app) != nil {
|
||||||
if err != nil {
|
|
||||||
app.err.Printf("%s: Failed to construct expiry notification", code)
|
app.err.Printf("%s: Failed to construct expiry notification", code)
|
||||||
app.debug.Printf("Error: %s", err)
|
} else if app.email.send(address, app) != nil {
|
||||||
} else if err := app.email.send(address, msg); err != nil {
|
|
||||||
app.err.Printf("%s: Failed to send expiry notification", code)
|
app.err.Printf("%s: Failed to send expiry notification", code)
|
||||||
app.debug.Printf("Error: %s", err)
|
|
||||||
} else {
|
} else {
|
||||||
app.info.Printf("Sent expiry notification to %s", address)
|
app.info.Printf("Sent expiry notification to %s", address)
|
||||||
}
|
}
|
||||||
@ -222,11 +216,10 @@ func (app *appContext) NewUser(gc *gin.Context) {
|
|||||||
for address, settings := range invite.Notify {
|
for address, settings := range invite.Notify {
|
||||||
if settings["notify-creation"] {
|
if settings["notify-creation"] {
|
||||||
go func() {
|
go func() {
|
||||||
msg, err := app.email.constructCreated(req.Code, req.Username, req.Email, invite, app)
|
if app.email.constructCreated(req.Code, req.Username, req.Email, invite, app) != nil {
|
||||||
if err != nil {
|
|
||||||
app.err.Printf("%s: Failed to construct user creation notification", req.Code)
|
app.err.Printf("%s: Failed to construct user creation notification", req.Code)
|
||||||
app.debug.Printf("%s: Error: %s", req.Code, err)
|
app.debug.Printf("%s: Error: %s", req.Code, err)
|
||||||
} else if err := app.email.send(address, msg); err != nil {
|
} else if app.email.send(address, app) != nil {
|
||||||
app.err.Printf("%s: Failed to send user creation notification", req.Code)
|
app.err.Printf("%s: Failed to send user creation notification", req.Code)
|
||||||
app.debug.Printf("%s: Error: %s", req.Code, err)
|
app.debug.Printf("%s: Error: %s", req.Code, err)
|
||||||
} else {
|
} else {
|
||||||
@ -307,12 +300,11 @@ func (app *appContext) GenerateInvite(gc *gin.Context) {
|
|||||||
if req.Email != "" && app.config.Section("invite_emails").Key("enabled").MustBool(false) {
|
if req.Email != "" && app.config.Section("invite_emails").Key("enabled").MustBool(false) {
|
||||||
app.debug.Printf("%s: Sending invite email", invite_code)
|
app.debug.Printf("%s: Sending invite email", invite_code)
|
||||||
invite.Email = req.Email
|
invite.Email = req.Email
|
||||||
msg, err := app.email.constructInvite(invite_code, invite, app)
|
if err := app.email.constructInvite(invite_code, invite, app); err != nil {
|
||||||
if err != nil {
|
|
||||||
invite.Email = fmt.Sprintf("Failed to send to %s", req.Email)
|
invite.Email = fmt.Sprintf("Failed to send to %s", req.Email)
|
||||||
app.err.Printf("%s: Failed to construct invite email", invite_code)
|
app.err.Printf("%s: Failed to construct invite email", invite_code)
|
||||||
app.debug.Printf("%s: Error: %s", invite_code, err)
|
app.debug.Printf("%s: Error: %s", invite_code, err)
|
||||||
} else if err := app.email.send(req.Email, msg); err != nil {
|
} else if err := app.email.send(req.Email, app); err != nil {
|
||||||
invite.Email = fmt.Sprintf("Failed to send to %s", req.Email)
|
invite.Email = fmt.Sprintf("Failed to send to %s", req.Email)
|
||||||
app.err.Printf("%s: %s", invite_code, invite.Email)
|
app.err.Printf("%s: %s", invite_code, invite.Email)
|
||||||
app.debug.Printf("%s: Error: %s", invite_code, err)
|
app.debug.Printf("%s: Error: %s", invite_code, err)
|
||||||
@ -361,9 +353,9 @@ func (app *appContext) GetInvites(gc *gin.Context) {
|
|||||||
address = app.config.Section("ui").Key("email").String()
|
address = app.config.Section("ui").Key("email").String()
|
||||||
}
|
}
|
||||||
if _, ok := inv.Notify[address]; ok {
|
if _, ok := inv.Notify[address]; ok {
|
||||||
for _, notifyType := range []string{"notify-expiry", "notify-creation"} {
|
for _, notify_type := range []string{"notify-expiry", "notify-creation"} {
|
||||||
if _, ok = inv.Notify[notifyType]; ok {
|
if _, ok = inv.Notify[notify_type]; ok {
|
||||||
invite[notifyType] = inv.Notify[address][notifyType]
|
invite[notify_type] = inv.Notify[address][notify_type]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -565,7 +557,7 @@ func (app *appContext) SetDefaults(gc *gin.Context) {
|
|||||||
respond(500, "Couldn't get user", gc)
|
respond(500, "Couldn't get user", gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
userID := user["Id"].(string)
|
userId := user["Id"].(string)
|
||||||
policy := user["Policy"].(map[string]interface{})
|
policy := user["Policy"].(map[string]interface{})
|
||||||
app.storage.policy = policy
|
app.storage.policy = policy
|
||||||
app.storage.storePolicy()
|
app.storage.storePolicy()
|
||||||
@ -573,7 +565,7 @@ func (app *appContext) SetDefaults(gc *gin.Context) {
|
|||||||
if req.Homescreen {
|
if req.Homescreen {
|
||||||
configuration := user["Configuration"].(map[string]interface{})
|
configuration := user["Configuration"].(map[string]interface{})
|
||||||
var displayprefs map[string]interface{}
|
var displayprefs map[string]interface{}
|
||||||
displayprefs, status, err = app.jf.getDisplayPreferences(userID)
|
displayprefs, status, err = app.jf.getDisplayPreferences(userId)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if !(status == 200 || status == 204) || err != nil {
|
||||||
app.err.Printf("Failed to get DisplayPrefs: Code %d", status)
|
app.err.Printf("Failed to get DisplayPrefs: Code %d", status)
|
||||||
app.debug.Printf("Error: %s", err)
|
app.debug.Printf("Error: %s", err)
|
||||||
|
@ -69,7 +69,5 @@ func (app *appContext) loadConfig() error {
|
|||||||
app.config.Section("notifications").Key("created_html").SetValue(app.config.Section("notifications").Key("created_html").MustString(filepath.Join(app.local_path, "created.html")))
|
app.config.Section("notifications").Key("created_html").SetValue(app.config.Section("notifications").Key("created_html").MustString(filepath.Join(app.local_path, "created.html")))
|
||||||
app.config.Section("notifications").Key("created_text").SetValue(app.config.Section("notifications").Key("created_text").MustString(filepath.Join(app.local_path, "created.txt")))
|
app.config.Section("notifications").Key("created_text").SetValue(app.config.Section("notifications").Key("created_text").MustString(filepath.Join(app.local_path, "created.txt")))
|
||||||
|
|
||||||
app.email = NewEmailer(app)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
226
email.go
226
email.go
@ -15,64 +15,15 @@ import (
|
|||||||
"github.com/mailgun/mailgun-go/v4"
|
"github.com/mailgun/mailgun-go/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
// implements email sending, right now via smtp or mailgun.
|
|
||||||
type emailClient interface {
|
|
||||||
send(address, fromName, fromAddr string, email *Email) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type Mailgun struct {
|
|
||||||
client *mailgun.MailgunImpl
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mg *Mailgun) send(address, fromName, fromAddr string, email *Email) error {
|
|
||||||
message := mg.client.NewMessage(
|
|
||||||
fmt.Sprintf("%s <%s>", fromName, fromAddr),
|
|
||||||
email.subject,
|
|
||||||
email.text,
|
|
||||||
address,
|
|
||||||
)
|
|
||||||
message.SetHtml(email.html)
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
|
||||||
defer cancel()
|
|
||||||
_, _, err := mg.client.Send(ctx, message)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type Smtp struct {
|
|
||||||
sslTls bool
|
|
||||||
host, server string
|
|
||||||
port int
|
|
||||||
auth smtp.Auth
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sm *Smtp) send(address, fromName, fromAddr string, email *Email) error {
|
|
||||||
e := jEmail.NewEmail()
|
|
||||||
e.Subject = email.subject
|
|
||||||
e.From = fmt.Sprintf("%s <%s>", fromName, fromAddr)
|
|
||||||
e.To = []string{address}
|
|
||||||
e.Text = []byte(email.text)
|
|
||||||
e.HTML = []byte(email.html)
|
|
||||||
tlsConfig := &tls.Config{
|
|
||||||
InsecureSkipVerify: false,
|
|
||||||
ServerName: sm.host,
|
|
||||||
}
|
|
||||||
server := fmt.Sprintf("%s:%d", sm.server, sm.port)
|
|
||||||
var err error
|
|
||||||
if sm.sslTls {
|
|
||||||
err = e.SendWithTLS(server, sm.auth, tlsConfig)
|
|
||||||
} else {
|
|
||||||
err = e.SendWithStartTLS(server, sm.auth, tlsConfig)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emailer contains the email sender, email content, and methods to construct message content.
|
|
||||||
type Emailer struct {
|
type Emailer struct {
|
||||||
fromAddr, fromName string
|
smtpAuth smtp.Auth
|
||||||
sender emailClient
|
sendType, sendMethod, fromAddr, fromName string
|
||||||
|
content Email
|
||||||
|
mg *mailgun.MailgunImpl
|
||||||
|
mime string
|
||||||
|
host string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Email stores content.
|
|
||||||
type Email struct {
|
type Email struct {
|
||||||
subject string
|
subject string
|
||||||
html, text string
|
html, text string
|
||||||
@ -99,53 +50,29 @@ func (email *Emailer) formatExpiry(expiry time.Time, tzaware bool, datePattern,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEmailer(app *appContext) *Emailer {
|
func (email *Emailer) init(app *appContext) {
|
||||||
emailer := &Emailer{
|
email.fromAddr = app.config.Section("email").Key("address").String()
|
||||||
fromAddr: app.config.Section("email").Key("address").String(),
|
email.fromName = app.config.Section("email").Key("from").String()
|
||||||
fromName: app.config.Section("email").Key("from").String(),
|
email.sendMethod = app.config.Section("email").Key("method").String()
|
||||||
}
|
if email.sendMethod == "mailgun" {
|
||||||
method := app.config.Section("email").Key("method").String()
|
email.mg = mailgun.NewMailgun(strings.Split(email.fromAddr, "@")[1], app.config.Section("mailgun").Key("api_key").String())
|
||||||
if method == "smtp" {
|
api_url := app.config.Section("mailgun").Key("api_url").String()
|
||||||
sslTls := false
|
// Mailgun client takes the base url, so we need to trim off the end (e.g 'v3/messages'
|
||||||
if app.config.Section("smtp").Key("encryption").String() == "ssl_tls" {
|
if strings.Contains(api_url, "messages") {
|
||||||
sslTls = true
|
api_url = api_url[0:strings.LastIndex(api_url, "/")]
|
||||||
|
api_url = api_url[0:strings.LastIndex(api_url, "/")]
|
||||||
}
|
}
|
||||||
emailer.NewSMTP(app.config.Section("smtp").Key("server").String(), app.config.Section("smtp").Key("port").MustInt(465), app.config.Section("smtp").Key("password").String(), app.host, sslTls)
|
email.mg.SetAPIBase(api_url)
|
||||||
} else if method == "mailgun" {
|
} else if email.sendMethod == "smtp" {
|
||||||
emailer.NewMailgun(app.config.Section("mailgun").Key("api_url").String(), app.config.Section("mailgun").Key("api_key").String())
|
app.host = app.config.Section("smtp").Key("server").String()
|
||||||
}
|
email.smtpAuth = smtp.PlainAuth("", email.fromAddr, app.config.Section("smtp").Key("password").String(), app.host)
|
||||||
return emailer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (emailer *Emailer) NewMailgun(url, key string) {
|
|
||||||
sender := &Mailgun{
|
|
||||||
client: mailgun.NewMailgun(strings.Split(emailer.fromAddr, "@")[1], key),
|
|
||||||
}
|
|
||||||
// Mailgun client takes the base url, so we need to trim off the end (e.g 'v3/messages'
|
|
||||||
if strings.Contains(url, "messages") {
|
|
||||||
url = url[0:strings.LastIndex(url, "/")]
|
|
||||||
url = url[0:strings.LastIndex(url, "/")]
|
|
||||||
}
|
|
||||||
sender.client.SetAPIBase(url)
|
|
||||||
emailer.sender = sender
|
|
||||||
}
|
|
||||||
|
|
||||||
func (emailer *Emailer) NewSMTP(server string, port int, password, host string, sslTls bool) {
|
|
||||||
emailer.sender = &Smtp{
|
|
||||||
auth: smtp.PlainAuth("", emailer.fromAddr, password, host),
|
|
||||||
server: server,
|
|
||||||
host: host,
|
|
||||||
port: port,
|
|
||||||
sslTls: sslTls,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (emailer *Emailer) constructInvite(code string, invite Invite, app *appContext) (*Email, error) {
|
func (email *Emailer) constructInvite(code string, invite Invite, app *appContext) error {
|
||||||
email := &Email{
|
email.content.subject = app.config.Section("invite_emails").Key("subject").String()
|
||||||
subject: app.config.Section("invite_emails").Key("subject").String(),
|
|
||||||
}
|
|
||||||
expiry := invite.ValidTill
|
expiry := invite.ValidTill
|
||||||
d, t, expires_in := emailer.formatExpiry(expiry, false, app.datePattern, app.timePattern)
|
d, t, expires_in := email.formatExpiry(expiry, false, app.datePattern, app.timePattern)
|
||||||
message := app.config.Section("email").Key("message").String()
|
message := app.config.Section("email").Key("message").String()
|
||||||
invite_link := app.config.Section("invite_emails").Key("url_base").String()
|
invite_link := app.config.Section("invite_emails").Key("url_base").String()
|
||||||
invite_link = fmt.Sprintf("%s/%s", invite_link, code)
|
invite_link = fmt.Sprintf("%s/%s", invite_link, code)
|
||||||
@ -154,7 +81,7 @@ func (emailer *Emailer) constructInvite(code string, invite Invite, app *appCont
|
|||||||
fpath := app.config.Section("invite_emails").Key("email_" + key).String()
|
fpath := app.config.Section("invite_emails").Key("email_" + key).String()
|
||||||
tpl, err := template.ParseFiles(fpath)
|
tpl, err := template.ParseFiles(fpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
var tplData bytes.Buffer
|
var tplData bytes.Buffer
|
||||||
err = tpl.Execute(&tplData, map[string]string{
|
err = tpl.Execute(&tplData, map[string]string{
|
||||||
@ -165,27 +92,26 @@ func (emailer *Emailer) constructInvite(code string, invite Invite, app *appCont
|
|||||||
"message": message,
|
"message": message,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if key == "html" {
|
if key == "html" {
|
||||||
email.html = tplData.String()
|
email.content.html = tplData.String()
|
||||||
} else {
|
} else {
|
||||||
email.text = tplData.String()
|
email.content.text = tplData.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return email, nil
|
email.sendType = "invite"
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (emailer *Emailer) constructExpiry(code string, invite Invite, app *appContext) (*Email, error) {
|
func (email *Emailer) constructExpiry(code string, invite Invite, app *appContext) error {
|
||||||
email := &Email{
|
email.content.subject = "Notice: Invite expired"
|
||||||
subject: "Notice: Invite expired",
|
|
||||||
}
|
|
||||||
expiry := app.formatDatetime(invite.ValidTill)
|
expiry := app.formatDatetime(invite.ValidTill)
|
||||||
for _, key := range []string{"html", "text"} {
|
for _, key := range []string{"html", "text"} {
|
||||||
fpath := app.config.Section("notifications").Key("expiry_" + key).String()
|
fpath := app.config.Section("notifications").Key("expiry_" + key).String()
|
||||||
tpl, err := template.ParseFiles(fpath)
|
tpl, err := template.ParseFiles(fpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
var tplData bytes.Buffer
|
var tplData bytes.Buffer
|
||||||
err = tpl.Execute(&tplData, map[string]string{
|
err = tpl.Execute(&tplData, map[string]string{
|
||||||
@ -193,21 +119,20 @@ func (emailer *Emailer) constructExpiry(code string, invite Invite, app *appCont
|
|||||||
"expiry": expiry,
|
"expiry": expiry,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if key == "html" {
|
if key == "html" {
|
||||||
email.html = tplData.String()
|
email.content.html = tplData.String()
|
||||||
} else {
|
} else {
|
||||||
email.text = tplData.String()
|
email.content.text = tplData.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return email, nil
|
email.sendType = "expiry"
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (emailer *Emailer) constructCreated(code, username, address string, invite Invite, app *appContext) (*Email, error) {
|
func (email *Emailer) constructCreated(code, username, address string, invite Invite, app *appContext) error {
|
||||||
email := &Email{
|
email.content.subject = "Notice: User created"
|
||||||
subject: "Notice: User created",
|
|
||||||
}
|
|
||||||
created := app.formatDatetime(invite.Created)
|
created := app.formatDatetime(invite.Created)
|
||||||
var tplAddress string
|
var tplAddress string
|
||||||
if app.config.Section("email").Key("no_username").MustBool(false) {
|
if app.config.Section("email").Key("no_username").MustBool(false) {
|
||||||
@ -219,7 +144,7 @@ func (emailer *Emailer) constructCreated(code, username, address string, invite
|
|||||||
fpath := app.config.Section("notifications").Key("created_" + key).String()
|
fpath := app.config.Section("notifications").Key("created_" + key).String()
|
||||||
tpl, err := template.ParseFiles(fpath)
|
tpl, err := template.ParseFiles(fpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
var tplData bytes.Buffer
|
var tplData bytes.Buffer
|
||||||
err = tpl.Execute(&tplData, map[string]string{
|
err = tpl.Execute(&tplData, map[string]string{
|
||||||
@ -229,28 +154,27 @@ func (emailer *Emailer) constructCreated(code, username, address string, invite
|
|||||||
"time": created,
|
"time": created,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if key == "html" {
|
if key == "html" {
|
||||||
email.html = tplData.String()
|
email.content.html = tplData.String()
|
||||||
} else {
|
} else {
|
||||||
email.text = tplData.String()
|
email.content.text = tplData.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return email, nil
|
email.sendType = "created"
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (emailer *Emailer) constructReset(pwr Pwr, app *appContext) (*Email, error) {
|
func (email *Emailer) constructReset(pwr Pwr, app *appContext) error {
|
||||||
email := &Email{
|
email.content.subject = app.config.Section("password_resets").Key("subject").MustString("Password reset - Jellyfin")
|
||||||
subject: app.config.Section("password_resets").Key("subject").MustString("Password reset - Jellyfin"),
|
d, t, expires_in := email.formatExpiry(pwr.Expiry, true, app.datePattern, app.timePattern)
|
||||||
}
|
|
||||||
d, t, expires_in := emailer.formatExpiry(pwr.Expiry, true, app.datePattern, app.timePattern)
|
|
||||||
message := app.config.Section("email").Key("message").String()
|
message := app.config.Section("email").Key("message").String()
|
||||||
for _, key := range []string{"html", "text"} {
|
for _, key := range []string{"html", "text"} {
|
||||||
fpath := app.config.Section("password_resets").Key("email_" + key).String()
|
fpath := app.config.Section("password_resets").Key("email_" + key).String()
|
||||||
tpl, err := template.ParseFiles(fpath)
|
tpl, err := template.ParseFiles(fpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
var tplData bytes.Buffer
|
var tplData bytes.Buffer
|
||||||
err = tpl.Execute(&tplData, map[string]string{
|
err = tpl.Execute(&tplData, map[string]string{
|
||||||
@ -262,17 +186,55 @@ func (emailer *Emailer) constructReset(pwr Pwr, app *appContext) (*Email, error)
|
|||||||
"message": message,
|
"message": message,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if key == "html" {
|
if key == "html" {
|
||||||
email.html = tplData.String()
|
email.content.html = tplData.String()
|
||||||
} else {
|
} else {
|
||||||
email.text = tplData.String()
|
email.content.text = tplData.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return email, nil
|
email.sendType = "reset"
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (emailer *Emailer) send(address string, email *Email) error {
|
func (email *Emailer) send(address string, app *appContext) error {
|
||||||
return emailer.sender.send(address, emailer.fromName, emailer.fromAddr, email)
|
if email.sendMethod == "mailgun" {
|
||||||
|
message := email.mg.NewMessage(
|
||||||
|
fmt.Sprintf("%s <%s>", email.fromName, email.fromAddr),
|
||||||
|
email.content.subject,
|
||||||
|
email.content.text,
|
||||||
|
address)
|
||||||
|
message.SetHtml(email.content.html)
|
||||||
|
mgapp, cancel := context.WithTimeout(context.Background(), time.Second*30)
|
||||||
|
defer cancel()
|
||||||
|
_, _, err := email.mg.Send(mgapp, message)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if email.sendMethod == "smtp" {
|
||||||
|
e := jEmail.NewEmail()
|
||||||
|
e.Subject = email.content.subject
|
||||||
|
e.From = fmt.Sprintf("%s <%s>", email.fromName, email.fromAddr)
|
||||||
|
e.To = []string{address}
|
||||||
|
e.Text = []byte(email.content.text)
|
||||||
|
e.HTML = []byte(email.content.html)
|
||||||
|
smtpType := app.config.Section("smtp").Key("encryption").String()
|
||||||
|
tlsConfig := &tls.Config{
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
ServerName: app.host,
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
if smtpType == "ssl_tls" {
|
||||||
|
port := app.config.Section("smtp").Key("port").MustInt(465)
|
||||||
|
server := fmt.Sprintf("%s:%d", app.host, port)
|
||||||
|
err = e.SendWithTLS(server, email.smtpAuth, tlsConfig)
|
||||||
|
} else if smtpType == "starttls" {
|
||||||
|
port := app.config.Section("smtp").Key("port").MustInt(587)
|
||||||
|
server := fmt.Sprintf("%s:%d", app.host, port)
|
||||||
|
e.SendWithStartTLS(server, email.smtpAuth, tlsConfig)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
6
main.go
6
main.go
@ -53,7 +53,7 @@ type appContext struct {
|
|||||||
timePattern string
|
timePattern string
|
||||||
storage Storage
|
storage Storage
|
||||||
validator Validator
|
validator Validator
|
||||||
email *Emailer
|
email Emailer
|
||||||
info, debug, err *log.Logger
|
info, debug, err *log.Logger
|
||||||
host string
|
host string
|
||||||
port int
|
port int
|
||||||
@ -361,6 +361,8 @@ func start(asDaemon, firstCall bool) {
|
|||||||
}
|
}
|
||||||
app.validator.init(validatorConf)
|
app.validator.init(validatorConf)
|
||||||
|
|
||||||
|
app.email.init(app)
|
||||||
|
|
||||||
inviteDaemon := NewRepeater(time.Duration(60*time.Second), app)
|
inviteDaemon := NewRepeater(time.Duration(60*time.Second), app)
|
||||||
go inviteDaemon.Run()
|
go inviteDaemon.Run()
|
||||||
|
|
||||||
@ -474,7 +476,7 @@ func main() {
|
|||||||
folder = os.Getenv("TEMP")
|
folder = os.Getenv("TEMP")
|
||||||
}
|
}
|
||||||
SOCK = filepath.Join(folder, SOCK)
|
SOCK = filepath.Join(folder, SOCK)
|
||||||
fmt.Println("Socket:", SOCK)
|
fmt.Println(SOCK)
|
||||||
if flagPassed("start") {
|
if flagPassed("start") {
|
||||||
args := []string{}
|
args := []string{}
|
||||||
for i, f := range os.Args {
|
for i, f := range os.Args {
|
||||||
|
@ -71,13 +71,10 @@ func pwrMonitor(app *appContext, watcher *fsnotify.Watcher) {
|
|||||||
app.err.Printf("Couldn't find email for user \"%s\". Make sure it's set", pwr.Username)
|
app.err.Printf("Couldn't find email for user \"%s\". Make sure it's set", pwr.Username)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
msg, err := app.email.constructReset(pwr, app)
|
if app.email.constructReset(pwr, app) != nil {
|
||||||
if err != nil {
|
|
||||||
app.err.Printf("Failed to construct password reset email for %s", pwr.Username)
|
app.err.Printf("Failed to construct password reset email for %s", pwr.Username)
|
||||||
app.debug.Printf("%s: Error: %s", pwr.Username, err)
|
} else if app.email.send(address, app) != nil {
|
||||||
} else if err := app.email.send(address, msg); err != nil {
|
|
||||||
app.err.Printf("Failed to send password reset email to \"%s\"", address)
|
app.err.Printf("Failed to send password reset email to \"%s\"", address)
|
||||||
app.debug.Printf("%s: Error: %s", pwr.Username, err)
|
|
||||||
} else {
|
} else {
|
||||||
app.info.Printf("Sent password reset email to \"%s\"", address)
|
app.info.Printf("Sent password reset email to \"%s\"", address)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user