mirror of
https://github.com/hugmouse/maddy-password-reset.git
synced 2025-04-19 04:50:25 +00:00
Attempt at the suggested way
This commit is contained in:
parent
754578f885
commit
d70831744a
1 changed files with 70 additions and 54 deletions
56
main.go
56
main.go
|
@ -3,22 +3,23 @@ package main
|
|||
import (
|
||||
cryptorand "crypto/rand"
|
||||
"database/sql"
|
||||
"github.com/akyoto/cache"
|
||||
"github.com/hugmouse/maddy-password-reset/templates"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"log"
|
||||
"math/big"
|
||||
_ "modernc.org/sqlite"
|
||||
"net/http"
|
||||
"net/mail"
|
||||
"net/smtp"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"regexp"
|
||||
_ "modernc.org/sqlite"
|
||||
"github.com/akyoto/cache"
|
||||
"github.com/hugmouse/maddy-password-reset/templates"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -99,6 +100,22 @@ func (t *Template) Render(w io.Writer, name string, data interface{}, _ echo.Con
|
|||
return t.templates.ExecuteTemplate(w, name, data)
|
||||
}
|
||||
|
||||
func isValidEmailAddress(email string) error {
|
||||
// Parse the email address using addressparser
|
||||
mail, err := mail.ParseAddress(email)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if the parsed address is not nil and has a valid email format
|
||||
if mail == nil || mail.Address == "" {
|
||||
log.Fatalln("Invalid Email Address!")
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
var auth smtp.Auth
|
||||
if !DebugBypassMailSending {
|
||||
|
@ -161,24 +178,21 @@ func main() {
|
|||
|
||||
e.POST("/reset", func(c echo.Context) error {
|
||||
mail := c.FormValue("email")
|
||||
// Define a regular expression to match any non-alphanumeric characters
|
||||
re := regexp.MustCompile("[^a-zA-Z0-9]+")
|
||||
|
||||
// Replace any non-alphanumeric characters with an empty string
|
||||
sanitizedMail := re.ReplaceAllString(mail, "")
|
||||
|
||||
if err := isValidEmailAddress(mail); err != nil {
|
||||
fmt.Println("Invalid email address:", err)
|
||||
} else {
|
||||
go func() {
|
||||
// Check if there is already a password reset
|
||||
_, exists := passwordResetCache.Get(sanitizedMail)
|
||||
_, exists := passwordResetCache.Get(mail)
|
||||
if exists {
|
||||
log.Printf("[Cache] Mail %q already exists in cache, ignoring\n", sanitizedMail)
|
||||
log.Printf("[Cache] Mail %q already exists in cache, ignoring\n", mail)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if it's exists in Maddy db
|
||||
// It will return an error is there is no user found
|
||||
var password string
|
||||
err = db.QueryRow("SELECT value FROM passwords WHERE key = ?", sanitizedMail).Scan(&password)
|
||||
err = db.QueryRow("SELECT value FROM passwords WHERE key = ?", mail).Scan(&password)
|
||||
if err != nil {
|
||||
log.Println("[Sqlite] An error occurred while trying to get password from Maddy database:", err)
|
||||
return
|
||||
|
@ -186,14 +200,14 @@ func main() {
|
|||
|
||||
// Generating an unique key
|
||||
random := randomString(10)
|
||||
passwordResetCache.Set(random, sanitizedMail, CacheTime)
|
||||
passwordResetCache.Set(random, mail, CacheTime)
|
||||
|
||||
// Connect to the server, authenticate, set the sender and recipient,
|
||||
// and send the email all in one step.
|
||||
to := []string{sanitizedMail}
|
||||
to := []string{mail}
|
||||
|
||||
if !DebugBypassMailSending {
|
||||
msg := strings.ReplaceAll(EmailTemplate, "$TO", sanitizedMail)
|
||||
msg := strings.ReplaceAll(EmailTemplate, "$TO", mail)
|
||||
msg = strings.ReplaceAll(msg, "$FROM", EmailFrom)
|
||||
msg = strings.ReplaceAll(msg, "$SUBJECT", EmailSubject)
|
||||
msg = strings.ReplaceAll(msg, "$MESSAGE", EmailMessage)
|
||||
|
@ -209,6 +223,7 @@ func main() {
|
|||
log.Println("[SMTP] Reset link:", HostingURL+"reset/"+random)
|
||||
}
|
||||
}()
|
||||
}
|
||||
return c.Render(http.StatusOK, "reset.gohtml", map[string]any{
|
||||
"Sent": true,
|
||||
})
|
||||
|
@ -228,12 +243,12 @@ func main() {
|
|||
e.POST("/reset/:key", func(c echo.Context) error {
|
||||
key := c.Param("key")
|
||||
password := c.FormValue("password")
|
||||
sanitizedMail, exists := passwordResetCache.Get(key)
|
||||
mail, exists := passwordResetCache.Get(key)
|
||||
if exists {
|
||||
passwordResetCache.Delete(key)
|
||||
}
|
||||
|
||||
maddyExecCommand := exec.Command("maddy", "creds", "password", "-p", password, sanitizedMail.(string))
|
||||
maddyExecCommand := exec.Command("maddy", "creds", "password", "-p", password, mail.(string))
|
||||
err = maddyExecCommand.Run()
|
||||
if err != nil {
|
||||
log.Println("[maddyExecCommand] Failed to execute Maddy's password reset command - ", err)
|
||||
|
@ -242,6 +257,7 @@ func main() {
|
|||
|
||||
return c.String(http.StatusOK, "All good! Your password is now changed.")
|
||||
})
|
||||
|
||||
log.Println("[echo] Starting Echo web server")
|
||||
e.Logger.Fatal(e.Start(":" + strconv.Itoa(HTTPServerPort)))
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue