gosora/common/email.go

125 lines
3.1 KiB
Go
Raw Normal View History

package common
import (
2019-03-03 04:00:04 +00:00
"crypto/tls"
2019-03-03 05:31:13 +00:00
"fmt"
"net/mail"
"net/smtp"
"strings"
p "github.com/Azareal/Gosora/common/phrases"
)
func SendActivationEmail(username, email, token string) error {
schema := "http"
if Config.SslSchema {
schema += "s"
}
// TODO: Move these to the phrase system
subject := "Account Activation - " + Site.Name
Added support for password resets. Sha256 hashes are now stored in the SFile structures, this will come of use later. Rows should be properly closed in DefaultTopicStore.BulkGetMap. All errors should be properly reported now in DefaultTopicStore.BulkGetMap. Rows should be properly closed in DefaultUserStore.BulkGetMap. All errors should be properly reported now in DefaultUserStore.BulkGetMap. Don't have an account on the login page should now be linkified. Renamed tempra-simple to tempra_simple to avoid breaking the template transpiler. Fixed up bits and pieces of login.html on every theme. Removed an old commented code chunk from template_init.go widget_wol widgets should now get minified. bindToAlerts() should now unbind the alert items before attempting to bind to them. Tweaked the SendValidationEmail phrase. Removed a layer of indentation from DefaultAuth.ValidateMFAToken and added the ErrNoMFAToken error for when MFA isn't setup on the specified account. Email validation now uses a constant time compare to mitigate certain classes of timing attacks. Added the /accounts/password-reset/ route. Added the /accounts/password-reset/submit/ route. Added the /accounts/password-reset/token/ route. Added the /accounts/password-reset/token/submit/ route. Added the password_resets table. Added the password_reset_email_fail phrase. Added the password_reset phrase. Added the password_reset_token phrase. Added the password_reset_email_sent phrase. Added the password_reset_token_token_verified phrase. Added the login_forgot_password phrase. Added the password_reset_head phrase. Added the password_reset_username phrase. Added the password_reset_button phrase. Added the password_reset_subject phrase. Added the password_reset_body phrase. Added the password_reset_token_head phrase. Added the password_reset_token_password phrase. Added the password_reset_token_confirm_password phrase. Added the password_reset_mfa_token phrase. Added the password_reset_token_button phrase. You will need to run the updater or patcher for this commit.
2019-03-11 08:47:45 +00:00
msg := "Dear " + username + ", to complete your registration on our forums, we need you to validate your email, so that we can confirm that this email actually belongs to you.\n\nClick on the following link to do so. " + schema + "://" + Site.URL + "/user/edit/token/" + token + "\n\nIf you haven't created an account here, then please feel free to ignore this email.\nWe're sorry for the inconvenience this may have caused."
return SendEmail(email, subject, msg)
}
func SendValidationEmail(username, email, token string) error {
schema := "http"
if Config.SslSchema {
schema += "s"
}
r := func(body *string) func(name, val string) {
return func(name, val string) {
*body = strings.Replace(*body, "{{"+name+"}}", val, -1)
}
}
subject := p.GetAccountPhrase("ValidateEmailSubject")
r1 := r(&subject)
r1("name", Site.Name)
body := p.GetAccountPhrase("ValidateEmailBody")
r2 := r(&body)
r2("username", username)
r2("schema", schema)
r2("url", Site.URL)
r2("token", token)
return SendEmail(email, subject, body)
}
// TODO: Refactor this
func SendEmail(email, subject, msg string) (err error) {
// This hook is useful for plugin_sendmail or for testing tools. Possibly to hook it into some sort of mail server?
ret, hasHook := GetHookTable().VhookNeedHook("email_send_intercept", email, subject, msg)
if hasHook {
return ret.(error)
}
2019-03-03 05:31:13 +00:00
from := mail.Address{"", Site.Email}
to := mail.Address{"", email}
headers := make(map[string]string)
headers["From"] = from.String()
headers["To"] = to.String()
headers["Subject"] = subject
body := ""
for k, v := range headers {
body += fmt.Sprintf("%s: %s\r\n", k, v)
}
body += "\r\n" + msg
2019-03-03 04:00:04 +00:00
var c *smtp.Client
if Config.SMTPEnableTLS {
tlsconfig := &tls.Config{
InsecureSkipVerify: true,
ServerName: Config.SMTPServer,
}
conn, err := tls.Dial("tcp", Config.SMTPServer+":"+Config.SMTPPort, tlsconfig)
if err != nil {
2019-03-03 04:49:03 +00:00
LogWarning(err)
2019-03-03 04:00:04 +00:00
return err
}
c, err = smtp.NewClient(conn, Config.SMTPServer)
} else {
c, err = smtp.Dial(Config.SMTPServer + ":" + Config.SMTPPort)
}
if err != nil {
LogWarning(err)
return err
}
if Config.SMTPUsername != "" {
auth := smtp.PlainAuth("", Config.SMTPUsername, Config.SMTPPassword, Config.SMTPServer)
2019-03-03 04:00:04 +00:00
err = c.Auth(auth)
if err != nil {
2019-03-03 04:49:03 +00:00
LogWarning(err)
return err
}
}
if err = c.Mail(from.Address); err != nil {
2019-03-03 04:49:03 +00:00
LogWarning(err)
return err
}
if err = c.Rcpt(to.Address); err != nil {
2019-03-03 04:49:03 +00:00
LogWarning(err)
return err
}
2019-03-03 04:00:04 +00:00
w, err := c.Data()
if err != nil {
2019-03-03 04:49:03 +00:00
LogWarning(err)
return err
}
2019-03-03 04:00:04 +00:00
_, err = w.Write([]byte(body))
if err != nil {
2019-03-03 04:49:03 +00:00
LogWarning(err)
return err
}
if err = w.Close(); err != nil {
2019-03-03 04:49:03 +00:00
LogWarning(err)
return err
}
if err = c.Quit(); err != nil {
2019-03-03 04:49:03 +00:00
LogWarning(err)
return err
}
return nil
}