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:
sysops
2026-07-10 18:34:44 +02:00
co-authored by Claude Sonnet 5
parent 6eeea65ede
commit 867dc7740a
79 changed files with 11951 additions and 2548 deletions
+10
View File
@@ -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
}
+54
View File
@@ -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
View File
@@ -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
}