Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Outlook's SMTP server support #161

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Runtime settings:
ORANGEFORUM_DSN=postgres://dbuser:dbpass@localhost:5432/testdb
SECRET_KEY=s6JM1e8JTAphtKNR2y27XA8kkAaXOSYB

# SMTP settings:
SMTP_HOST=
SMTP_PORT=
SMTP_USER=
SMTP_PASS=
SMTP_LOGIN= # Empty or none-empty.
# When none-empty, do SMTPAuthLogin instead of SMTPAuthPlain
FROM_EMAIL=
2 changes: 1 addition & 1 deletion e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"strings"
"testing"

"github.com/s-gv/orangeforum/models"
"orangeforum/models"
)

const (
Expand Down
12 changes: 7 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
module github.com/s-gv/orangeforum
module orangeforum

go 1.16
go 1.21

toolchain go1.21.0

require (
github.com/Depado/bfchroma v1.3.0
github.com/alecthomas/chroma v0.9.2
github.com/alexedwards/scs/v2 v2.4.0
github.com/go-chi/chi v1.5.2
github.com/alecthomas/chroma v0.10.0
github.com/alexedwards/scs/v2 v2.6.0
github.com/go-chi/chi v1.5.5
github.com/go-chi/jwtauth v1.2.0
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/google/uuid v1.2.0
Expand Down
362 changes: 53 additions & 309 deletions go.sum

Large diffs are not rendered by default.

12 changes: 10 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import (
"os"
"time"

"orangeforum/models"
"orangeforum/views"

"github.com/golang/glog"
"github.com/s-gv/orangeforum/models"
"github.com/s-gv/orangeforum/views"

_ "github.com/jackc/pgx/v4/stdlib"
"github.com/jmoiron/sqlx"
_ "github.com/joho/godotenv/autoload" // load .env file automatically
)

func main() {
Expand All @@ -36,6 +38,7 @@ func main() {
deleteDomain := flag.Bool("deletedomain", false, "Delete domain")
deleteUser := flag.Bool("deleteuser", false, "Delete user")
setSMTP := flag.Bool("setsmtp", false, "Set SMTP Settings")
envSMTP := flag.Bool("envsmtp", false, "Set SMTP Settings from .env")
disableLogger := flag.Bool("disablelogger", false, "Disable HTTP request logger")

flag.Parse()
Expand Down Expand Up @@ -107,6 +110,11 @@ func main() {
return
}

if *envSMTP {
commandSetupSMTPFromEnv()
return
}

if len(secretKey) != 32 {
glog.Warningf("Secret key in environment variable SECRET_KEY does not have length 32. Using randomly generated key. This will invalidate any active sessions.")

Expand Down
4 changes: 2 additions & 2 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
"testing"

"github.com/jmoiron/sqlx"
"github.com/s-gv/orangeforum/models"
"github.com/s-gv/orangeforum/views"
"orangeforum/models"
"orangeforum/views"
)

var TestServer *httptest.Server
Expand Down
31 changes: 30 additions & 1 deletion management.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ package main

import (
"fmt"
"os"
"strconv"
"strings"
"syscall"

"github.com/s-gv/orangeforum/models"
"orangeforum/models"

"golang.org/x/crypto/ssh/terminal"
)

Expand Down Expand Up @@ -227,3 +230,29 @@ func commandSetupSMTP() {

models.UpdateDomainSMTPByID(domain.DomainID, smtpHost, smtpPort, smtpUser, smtpPass, defaultFromEmail)
}

func commandSetupSMTPFromEnv() {
var domainName string
fmt.Printf("Domain name: ")
fmt.Scanf("%s\n", &domainName)

domain := models.GetDomainByName(domainName)
if domain == nil {
fmt.Printf("[ERROR] Invalid domain\n")
return
}

smtpHost := os.Getenv("SMTP_HOST")
p := os.Getenv("SMTP_PORT")
smtpPort, err := strconv.Atoi(p)
if err != nil {
fmt.Printf("[ERROR] Invalid env SMTP_PORT setting\n")
return
}

smtpUser := os.Getenv("SMTP_USER")
smtpPass := os.Getenv("SMTP_PASS")
defaultFromEmail := smtpUser // os.Getenv("FROM_EMAIL")

models.UpdateDomainSMTPByID(domain.DomainID, smtpHost, smtpPort, smtpUser, smtpPass, defaultFromEmail)
}
2 changes: 1 addition & 1 deletion models_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package main
import (
"testing"

"github.com/s-gv/orangeforum/models"
"orangeforum/models"
)

func TestDomainCreation(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions views/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (

"github.com/go-chi/chi"
"github.com/gorilla/csrf"
"github.com/s-gv/orangeforum/models"
"github.com/s-gv/orangeforum/templates"
"orangeforum/models"
"orangeforum/templates"
)

func adminHandler(w http.ResponseWriter, r *http.Request) {
Expand Down
14 changes: 11 additions & 3 deletions views/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@ import (
"context"
"net/http"
"net/url"
"os"
"regexp"
"strconv"
"strings"
"time"

"orangeforum/models"
"orangeforum/templates"

"github.com/go-chi/chi"
"github.com/go-chi/jwtauth"
"github.com/golang/glog"
"github.com/google/uuid"
"github.com/gorilla/csrf"
"github.com/lestrrat-go/jwx/jwt"
"github.com/s-gv/orangeforum/models"
"github.com/s-gv/orangeforum/templates"
)

const CtxUserKey = contextKey("user")
Expand Down Expand Up @@ -235,7 +237,13 @@ func postAuthOneTimeSignIn(w http.ResponseWriter, r *http.Request) {
subject := forumName + " sign-in link"
body := "Someone (hopefully you) requested a sign-in link for " + forumName + ".\r\n" +
"If you want to sign-in, visit " + link + "\r\n\r\nIf not, just ignore this message."
sendMail(domain.DefaultFromEmail, user.Email, subject, body, domain.ForumName, domain.SMTPHost, domain.SMTPPort, domain.SMTPUser, domain.SMTPPass)
if os.Getenv("SMTP_LOGIN") != "" {
// do SMTPAuthLogin, when SMTP_LOGIN is none-empty
sendMailWithLogin(domain.DefaultFromEmail, user.Email, subject, body, domain.ForumName, domain.SMTPHost, domain.SMTPPort, domain.SMTPUser, domain.SMTPPass)
} else {
// do SMTPAuthPlain
sendMail(domain.DefaultFromEmail, user.Email, subject, body, domain.ForumName, domain.SMTPHost, domain.SMTPPort, domain.SMTPUser, domain.SMTPPass)
}
}

templates.OneTimeSignin.Execute(w, map[string]interface{}{
Expand Down
4 changes: 2 additions & 2 deletions views/comments.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (

"github.com/go-chi/chi"
"github.com/gorilla/csrf"
"github.com/s-gv/orangeforum/models"
"github.com/s-gv/orangeforum/templates"
"orangeforum/models"
"orangeforum/templates"
)

func editComment(w http.ResponseWriter, r *http.Request) {
Expand Down
2 changes: 1 addition & 1 deletion views/domains.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"net/http"

"github.com/go-chi/chi"
"github.com/s-gv/orangeforum/models"
"orangeforum/models"
)

type contextKey string
Expand Down
4 changes: 2 additions & 2 deletions views/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"net/http"

"github.com/gorilla/csrf"
"github.com/s-gv/orangeforum/models"
"github.com/s-gv/orangeforum/templates"
"orangeforum/models"
"orangeforum/templates"
)

func getIndex(w http.ResponseWriter, r *http.Request) {
Expand Down
2 changes: 1 addition & 1 deletion views/static.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package views
import (
"net/http"

"github.com/s-gv/orangeforum/templates"
"orangeforum/templates"
)

func getCSS(w http.ResponseWriter, r *http.Request) {
Expand Down
4 changes: 2 additions & 2 deletions views/topics.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (

"github.com/go-chi/chi"
"github.com/gorilla/csrf"
"github.com/s-gv/orangeforum/models"
"github.com/s-gv/orangeforum/templates"
"orangeforum/models"
"orangeforum/templates"
)

func getTopicList(w http.ResponseWriter, r *http.Request) {
Expand Down
4 changes: 2 additions & 2 deletions views/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (

"github.com/go-chi/chi"
"github.com/gorilla/csrf"
"github.com/s-gv/orangeforum/models"
"github.com/s-gv/orangeforum/templates"
"orangeforum/models"
"orangeforum/templates"
)

const UserField string = "User"
Expand Down
29 changes: 29 additions & 0 deletions views/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
package views

import (
"fmt"
"net/smtp"
"strconv"
"strings"

"github.com/golang/glog"
"github.com/wneessen/go-mail"
)

func sendMail(from string, to string, sub string, body string, forumName string, smtpHost string, smtpPort int, smtpUser string, smtpPass string) {
Expand Down Expand Up @@ -36,3 +39,29 @@ func sendMail(from string, to string, sub string, body string, forumName string,

}(from, to, sub, body, forumName, smtpHost, smtpPort, smtpUser, smtpPass)
}

// For Outlook
func sendMailWithLogin(from string, to string, sub string, body string, forumName string, smtpHost string, smtpPort int, smtpUser string, smtpPass string) error {
// Create a new message
m := mail.NewMsg()
if err := m.From(from); err != nil {
return fmt.Errorf(w, "failed to set From address: %w", err)
}
if err := m.To(strings.Split(to, ",")...); err != nil {
return fmt.Errorf(w, "failed to set To address: %w", err)
}
m.Subject(sub)
m.SetBodyString(mail.TypeTextHTML, body)

// Sending the email
c, err := mail.NewClient(smtpHost, mail.WithPort(smtpPort),
// mail.WithSMTPAuth(mail.SMTPAuthPlain),
mail.WithSMTPAuth(mail.SMTPAuthLogin), // for Outlook
mail.WithUsername(smtpUser), mail.WithPassword(smtpPass))
if err != nil {
return fmt.Errorf(w, "failed to create mail client: %w", err)
}
if err := c.DialAndSend(m); err != nil {
return fmt.Errorf(w, "failed to send mail: %w", err)
}
}