Replace from-scratch rewrite with real ngoduykhanh/wireguard-ui fork
The from-scratch Go rewrite had unresolved bugs (missing go.sum, UI 404s, path issues) from being built without a working local Go toolchain to verify against. Switching strategy: use the actual upstream wireguard-ui codebase (proven, battle-tested single-server manager) as the base, and extend it for multi-server support instead of re-deriving everything from zero. Kept our own installers (bootstrap.sh, update.sh, scripts/install.sh, scripts/proxmox-install.sh) - these still apply, just need updating to build/install the upstream module layout instead of the old cmd/wireguard-ui-multi structure. Module path intentionally left as upstream's own (github.com/ngoduykhanh/wireguard-ui) for now to avoid touching every internal import; revisit if this needs to be fully rebranded. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
6eeea65ede
commit
867dc7740a
@@ -0,0 +1,10 @@
|
||||
package emailer
|
||||
|
||||
type Attachment struct {
|
||||
Name string
|
||||
Data []byte
|
||||
}
|
||||
|
||||
type Emailer interface {
|
||||
Send(toName string, to string, subject string, content string, attachments []Attachment) error
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package emailer
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/sendgrid/sendgrid-go"
|
||||
"github.com/sendgrid/sendgrid-go/helpers/mail"
|
||||
)
|
||||
|
||||
type SendgridApiMail struct {
|
||||
apiKey string
|
||||
fromName string
|
||||
from string
|
||||
}
|
||||
|
||||
func NewSendgridApiMail(apiKey, fromName, from string) *SendgridApiMail {
|
||||
ans := SendgridApiMail{apiKey: apiKey, fromName: fromName, from: from}
|
||||
return &ans
|
||||
}
|
||||
|
||||
func (o *SendgridApiMail) Send(toName string, to string, subject string, content string, attachments []Attachment) error {
|
||||
m := mail.NewV3Mail()
|
||||
|
||||
mailFrom := mail.NewEmail(o.fromName, o.from)
|
||||
mailContent := mail.NewContent("text/html", content)
|
||||
mailTo := mail.NewEmail(toName, to)
|
||||
|
||||
m.SetFrom(mailFrom)
|
||||
m.AddContent(mailContent)
|
||||
|
||||
personalization := mail.NewPersonalization()
|
||||
personalization.AddTos(mailTo)
|
||||
personalization.Subject = subject
|
||||
|
||||
m.AddPersonalizations(personalization)
|
||||
|
||||
toAdd := make([]*mail.Attachment, 0, len(attachments))
|
||||
for i := range attachments {
|
||||
var att mail.Attachment
|
||||
encoded := base64.StdEncoding.EncodeToString(attachments[i].Data)
|
||||
att.SetContent(encoded)
|
||||
att.SetType("text/plain")
|
||||
att.SetFilename(attachments[i].Name)
|
||||
att.SetDisposition("attachment")
|
||||
toAdd = append(toAdd, &att)
|
||||
}
|
||||
|
||||
m.AddAttachment(toAdd...)
|
||||
request := sendgrid.GetRequest(o.apiKey, "/v3/mail/send", "https://api.sendgrid.com")
|
||||
request.Method = "POST"
|
||||
request.Body = mail.GetRequestBody(m)
|
||||
_, err := sendgrid.API(request)
|
||||
return err
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
package emailer
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
mail "github.com/xhit/go-simple-mail/v2"
|
||||
)
|
||||
|
||||
type SmtpMail struct {
|
||||
hostname string
|
||||
port int
|
||||
username string
|
||||
password string
|
||||
smtpHelo string
|
||||
authType mail.AuthType
|
||||
encryption mail.Encryption
|
||||
noTLSCheck bool
|
||||
fromName string
|
||||
from string
|
||||
}
|
||||
|
||||
func authType(authType string) mail.AuthType {
|
||||
switch strings.ToUpper(authType) {
|
||||
case "PLAIN":
|
||||
return mail.AuthPlain
|
||||
case "LOGIN":
|
||||
return mail.AuthLogin
|
||||
default:
|
||||
return mail.AuthNone
|
||||
}
|
||||
}
|
||||
|
||||
func encryptionType(encryptionType string) mail.Encryption {
|
||||
switch strings.ToUpper(encryptionType) {
|
||||
case "NONE":
|
||||
return mail.EncryptionNone
|
||||
case "SSL":
|
||||
return mail.EncryptionSSL
|
||||
case "SSLTLS":
|
||||
return mail.EncryptionSSLTLS
|
||||
case "TLS":
|
||||
return mail.EncryptionTLS
|
||||
default:
|
||||
return mail.EncryptionSTARTTLS
|
||||
}
|
||||
}
|
||||
|
||||
func NewSmtpMail(hostname string, port int, username string, password string, SmtpHelo string, noTLSCheck bool, auth string, fromName, from string, encryption string) *SmtpMail {
|
||||
ans := SmtpMail{hostname: hostname, port: port, username: username, password: password, smtpHelo: SmtpHelo, noTLSCheck: noTLSCheck, fromName: fromName, from: from, authType: authType(auth), encryption: encryptionType(encryption)}
|
||||
return &ans
|
||||
}
|
||||
|
||||
func addressField(address string, name string) string {
|
||||
if name == "" {
|
||||
return address
|
||||
}
|
||||
return fmt.Sprintf("%s <%s>", name, address)
|
||||
}
|
||||
|
||||
func (o *SmtpMail) Send(toName string, to string, subject string, content string, attachments []Attachment) error {
|
||||
server := mail.NewSMTPClient()
|
||||
|
||||
server.Host = o.hostname
|
||||
server.Port = o.port
|
||||
server.Authentication = o.authType
|
||||
server.Username = o.username
|
||||
server.Password = o.password
|
||||
server.Helo = o.smtpHelo
|
||||
server.Encryption = o.encryption
|
||||
server.KeepAlive = false
|
||||
server.ConnectTimeout = 10 * time.Second
|
||||
server.SendTimeout = 10 * time.Second
|
||||
|
||||
if o.noTLSCheck {
|
||||
server.TLSConfig = &tls.Config{InsecureSkipVerify: true}
|
||||
}
|
||||
|
||||
smtpClient, err := server.Connect()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
email := mail.NewMSG()
|
||||
email.SetFrom(addressField(o.from, o.fromName)).
|
||||
AddTo(addressField(to, toName)).
|
||||
SetSubject(subject).
|
||||
SetBody(mail.TextHTML, content)
|
||||
|
||||
for _, v := range attachments {
|
||||
email.Attach(&mail.File{Name: v.Name, Data: v.Data})
|
||||
}
|
||||
|
||||
err = email.Send(smtpClient)
|
||||
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user