1153 lines
47 KiB
Diff
1153 lines
47 KiB
Diff
diff --git a/README.md b/README.md
|
|
index 74c446e..67c5718 100644
|
|
--- a/README.md
|
|
+++ b/README.md
|
|
@@ -9,7 +9,7 @@ A web user interface to manage your WireGuard setup.
|
|
- Friendly UI
|
|
- Authentication
|
|
- Manage extra client information (name, email, etc.)
|
|
-- Retrieve client config using QR code / file / email / Telegram
|
|
+- Retrieve client config using QR code / file / email
|
|
|
|

|
|
|
|
@@ -39,7 +39,6 @@ docker-compose up
|
|
| Variable | Description | Default |
|
|
|-------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------|
|
|
| `BASE_PATH` | Set this variable if you run wireguard-ui under a subpath of your reverse proxy virtual host (e.g. /wireguard) | N/A |
|
|
-| `BIND_ADDRESS` | The addresses that can access to the web interface and the port, use unix:///abspath/to/file.socket for unix domain socket. | 0.0.0.0:80 |
|
|
| `SESSION_SECRET` | The secret key used to encrypt the session cookies. Set this to a random value | N/A |
|
|
| `SESSION_SECRET_FILE` | Optional filepath for the secret key used to encrypt the session cookies. Leave `SESSION_SECRET` blank to take effect | N/A |
|
|
| `SESSION_MAX_DURATION` | Max time in days a remembered session is refreshed and valid. Non-refreshed session is valid for 7 days max, regardless of this setting. | 90 |
|
|
@@ -71,9 +70,6 @@ docker-compose up
|
|
| `SMTP_AUTH_TYPE` | The SMTP authentication type. Possible values: `PLAIN`, `LOGIN`, `NONE` | `NONE` |
|
|
| `SMTP_ENCRYPTION` | The encryption method. Possible values: `NONE`, `SSL`, `SSLTLS`, `TLS`, `STARTTLS` | `STARTTLS` |
|
|
| `SMTP_HELO` | Hostname to use for the HELO message. smtp-relay.gmail.com needs this set to anything but `localhost` | `localhost` |
|
|
-| `TELEGRAM_TOKEN` | Telegram bot token for distributing configs to clients | N/A |
|
|
-| `TELEGRAM_ALLOW_CONF_REQUEST` | Allow users to get configs from the bot by sending a message | `false` |
|
|
-| `TELEGRAM_FLOOD_WAIT` | Time in minutes before the next conf request is processed | `60` |
|
|
|
|
### Defaults for server configuration
|
|
|
|
diff --git a/custom/js/helper.js b/custom/js/helper.js
|
|
index d98eacb..931320a 100644
|
|
--- a/custom/js/helper.js
|
|
+++ b/custom/js/helper.js
|
|
@@ -1,20 +1,5 @@
|
|
function renderClientList(data) {
|
|
$.each(data, function(index, obj) {
|
|
- // render telegram button
|
|
- let telegramButton = ''
|
|
- if (obj.Client.telegram_userid) {
|
|
- telegramButton = `<div class="btn-group">
|
|
- <button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal"
|
|
- data-target="#modal_telegram_client" data-clientid="${obj.Client.id}"
|
|
- data-clientname="${obj.Client.name}">Telegram</button>
|
|
- </div>`
|
|
- }
|
|
-
|
|
- let telegramHtml = "";
|
|
- if (obj.Client.telegram_userid && obj.Client.telegram_userid.length > 0) {
|
|
- telegramHtml = `<span class="info-box-text" style="display: none"><i class="fas fa-tguserid"></i>${obj.Client.telegram_userid}</span>`
|
|
- }
|
|
-
|
|
// render client status css tag style
|
|
let clientStatusHtml = '>'
|
|
if (obj.Client.enabled) {
|
|
@@ -48,20 +33,19 @@ function renderClientList(data) {
|
|
<div class="btn-group">
|
|
<a href="download?clientid=${obj.Client.id}" class="btn btn-outline-primary btn-sm">Download</a>
|
|
</div>
|
|
- <div class="btn-group">
|
|
+ <div class="btn-group">
|
|
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal"
|
|
data-target="#modal_qr_client" data-clientid="${obj.Client.id}"
|
|
data-clientname="${obj.Client.name}" ${obj.QRCode != "" ? '' : ' disabled'}>QR code</button>
|
|
</div>
|
|
- <div class="btn-group">
|
|
+ <div class="btn-group">
|
|
<button type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal"
|
|
data-target="#modal_email_client" data-clientid="${obj.Client.id}"
|
|
data-clientname="${obj.Client.name}">Email</button>
|
|
</div>
|
|
- ${telegramButton}
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-outline-danger btn-sm">More</button>
|
|
- <button type="button" class="btn btn-outline-danger btn-sm dropdown-toggle dropdown-icon"
|
|
+ <button type="button" class="btn btn-outline-danger btn-sm dropdown-toggle dropdown-icon"
|
|
data-toggle="dropdown">
|
|
</button>
|
|
<div class="dropdown-menu" role="menu">
|
|
@@ -80,7 +64,6 @@ function renderClientList(data) {
|
|
<span class="info-box-text"><i class="fas fa-user"></i> ${obj.Client.name}</span>
|
|
<span class="info-box-text" style="display: none"><i class="fas fa-key"></i> ${obj.Client.public_key}</span>
|
|
<span class="info-box-text" style="display: none"><i class="fas fa-subnetrange"></i>${subnetRangesString}</span>
|
|
- ${telegramHtml}
|
|
<span class="info-box-text"><i class="fas fa-envelope"></i> ${obj.Client.email}</span>
|
|
<span class="info-box-text"><i class="fas fa-clock"></i>
|
|
${prettyDateTime(obj.Client.created_at)}</span>
|
|
diff --git a/go.mod b/go.mod
|
|
index 6255955..d3ce2b4 100644
|
|
--- a/go.mod
|
|
+++ b/go.mod
|
|
@@ -20,6 +20,7 @@ require (
|
|
//golang.zx2c4.com/wireguard v0.0.20200121 // indirect
|
|
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c
|
|
gopkg.in/go-playground/validator.v9 v9.31.0
|
|
+ github.com/coreos/go-systemd/v22 v22.5.0
|
|
)
|
|
|
|
require (
|
|
diff --git a/go.sum b/go.sum
|
|
index 16f05fe..61f0c7c 100644
|
|
--- a/go.sum
|
|
+++ b/go.sum
|
|
@@ -1,6 +1,8 @@
|
|
github.com/NicoNex/echotron/v3 v3.27.0 h1:iq4BLPO+Dz1JHjh2HPk0D0NldAZSYcAjaOicgYEhUzw=
|
|
github.com/NicoNex/echotron/v3 v3.27.0/go.mod h1:LpP5IyHw0y+DZUZMBgXEDAF9O8feXrQu7w7nlJzzoZI=
|
|
github.com/coreos/bbolt v1.3.1-coreos.6.0.20180223184059-4f5275f4ebbf/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
|
+github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
|
+github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
@@ -12,6 +14,7 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
|
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
|
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
|
|
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
|
+github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
|
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
|
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
|
diff --git a/handler/routes.go b/handler/routes.go
|
|
index ef01d08..1aa86ef 100644
|
|
--- a/handler/routes.go
|
|
+++ b/handler/routes.go
|
|
@@ -10,7 +10,6 @@ import (
|
|
"os"
|
|
"regexp"
|
|
"sort"
|
|
- "strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
@@ -19,14 +18,12 @@ import (
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/labstack/gommon/log"
|
|
"github.com/rs/xid"
|
|
- "github.com/skip2/go-qrcode"
|
|
"golang.zx2c4.com/wireguard/wgctrl"
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
|
|
"github.com/ngoduykhanh/wireguard-ui/emailer"
|
|
"github.com/ngoduykhanh/wireguard-ui/model"
|
|
"github.com/ngoduykhanh/wireguard-ui/store"
|
|
- "github.com/ngoduykhanh/wireguard-ui/telegram"
|
|
"github.com/ngoduykhanh/wireguard-ui/util"
|
|
)
|
|
|
|
@@ -414,14 +411,6 @@ func NewClient(db store.IStore) echo.HandlerFunc {
|
|
var client model.Client
|
|
c.Bind(&client)
|
|
|
|
- // Validate Telegram userid if provided
|
|
- if client.TgUserid != "" {
|
|
- idNum, err := strconv.ParseInt(client.TgUserid, 10, 64)
|
|
- if err != nil || idNum == 0 {
|
|
- return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Telegram userid must be a non-zero number"})
|
|
- }
|
|
- }
|
|
-
|
|
// read server information
|
|
server, err := db.GetServer()
|
|
if err != nil {
|
|
@@ -575,51 +564,6 @@ func EmailClient(db store.IStore, mailer emailer.Emailer, emailSubject, emailCon
|
|
}
|
|
}
|
|
|
|
-// SendTelegramClient handler to send the configuration via Telegram
|
|
-func SendTelegramClient(db store.IStore) echo.HandlerFunc {
|
|
- type clientIdUseridPayload struct {
|
|
- ID string `json:"id"`
|
|
- Userid string `json:"userid"`
|
|
- }
|
|
- return func(c echo.Context) error {
|
|
- var payload clientIdUseridPayload
|
|
- c.Bind(&payload)
|
|
-
|
|
- clientData, err := db.GetClientByID(payload.ID, model.QRCodeSettings{Enabled: false})
|
|
- if err != nil {
|
|
- log.Errorf("Cannot generate client id %s config file for downloading: %v", payload.ID, err)
|
|
- return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Client not found"})
|
|
- }
|
|
-
|
|
- // build config
|
|
- server, _ := db.GetServer()
|
|
- globalSettings, _ := db.GetGlobalSettings()
|
|
- config := util.BuildClientConfig(*clientData.Client, server, globalSettings)
|
|
- configData := []byte(config)
|
|
- var qrData []byte
|
|
-
|
|
- if clientData.Client.PrivateKey != "" {
|
|
- qrData, err = qrcode.Encode(config, qrcode.Medium, 512)
|
|
- if err != nil {
|
|
- return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "qr gen: " + err.Error()})
|
|
- }
|
|
- }
|
|
-
|
|
- userid, err := strconv.ParseInt(clientData.Client.TgUserid, 10, 64)
|
|
- if err != nil {
|
|
- return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "userid: " + err.Error()})
|
|
- }
|
|
-
|
|
- err = telegram.SendConfig(userid, clientData.Client.Name, configData, qrData, false)
|
|
-
|
|
- if err != nil {
|
|
- return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, err.Error()})
|
|
- }
|
|
-
|
|
- return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Telegram message sent successfully"})
|
|
- }
|
|
-}
|
|
-
|
|
// UpdateClient handler to update client information
|
|
func UpdateClient(db store.IStore) echo.HandlerFunc {
|
|
return func(c echo.Context) error {
|
|
@@ -636,14 +580,6 @@ func UpdateClient(db store.IStore) echo.HandlerFunc {
|
|
return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Client not found"})
|
|
}
|
|
|
|
- // Validate Telegram userid if provided
|
|
- if _client.TgUserid != "" {
|
|
- idNum, err := strconv.ParseInt(_client.TgUserid, 10, 64)
|
|
- if err != nil || idNum == 0 {
|
|
- return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Telegram userid must be a non-zero number"})
|
|
- }
|
|
- }
|
|
-
|
|
server, err := db.GetServer()
|
|
if err != nil {
|
|
return c.JSON(http.StatusBadRequest, jsonHTTPResponse{
|
|
@@ -710,7 +646,6 @@ func UpdateClient(db store.IStore) echo.HandlerFunc {
|
|
// map new data
|
|
client.Name = _client.Name
|
|
client.Email = _client.Email
|
|
- client.TgUserid = _client.TgUserid
|
|
client.Enabled = _client.Enabled
|
|
client.UseServerDNS = _client.UseServerDNS
|
|
client.AllocatedIPs = _client.AllocatedIPs
|
|
diff --git a/main.go b/main.go
|
|
index 1125746..bca8534 100644
|
|
--- a/main.go
|
|
+++ b/main.go
|
|
@@ -1,22 +1,23 @@
|
|
package main
|
|
|
|
import (
|
|
+ "context"
|
|
"crypto/sha512"
|
|
"embed"
|
|
"flag"
|
|
"fmt"
|
|
"io/fs"
|
|
- "net"
|
|
"net/http"
|
|
"os"
|
|
- "strings"
|
|
+ "os/exec"
|
|
+ "os/signal"
|
|
"syscall"
|
|
"time"
|
|
|
|
+ "github.com/coreos/go-systemd/v22/activation"
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/labstack/gommon/log"
|
|
"github.com/ngoduykhanh/wireguard-ui/store"
|
|
- "github.com/ngoduykhanh/wireguard-ui/telegram"
|
|
|
|
"github.com/ngoduykhanh/wireguard-ui/emailer"
|
|
"github.com/ngoduykhanh/wireguard-ui/handler"
|
|
@@ -32,35 +33,31 @@ var (
|
|
gitRef = "N/A"
|
|
buildTime = fmt.Sprintf(time.Now().UTC().Format("01-02-2006 15:04:05"))
|
|
// configuration variables
|
|
- flagDisableLogin = false
|
|
- flagBindAddress = "0.0.0.0:5000"
|
|
- flagSmtpHostname = "127.0.0.1"
|
|
- flagSmtpPort = 25
|
|
- flagSmtpUsername string
|
|
- flagSmtpPassword string
|
|
- flagSmtpAuthType = "NONE"
|
|
- flagSmtpNoTLSCheck = false
|
|
- flagSmtpEncryption = "STARTTLS"
|
|
- flagSmtpHelo = "localhost"
|
|
- flagSendgridApiKey string
|
|
- flagEmailFrom string
|
|
- flagEmailFromName = "WireGuard UI"
|
|
- flagTelegramToken string
|
|
- flagTelegramAllowConfRequest = false
|
|
- flagTelegramFloodWait = 60
|
|
- flagSessionSecret = util.RandomString(32)
|
|
- flagSessionMaxDuration = 90
|
|
- flagWgConfTemplate string
|
|
- flagBasePath string
|
|
- flagSubnetRanges string
|
|
+ flagDisableLogin = false
|
|
+ flagSmtpHostname = "127.0.0.1"
|
|
+ flagSmtpPort = 25
|
|
+ flagSmtpUsername string
|
|
+ flagSmtpPassword string
|
|
+ flagSmtpAuthType = "NONE"
|
|
+ flagSmtpNoTLSCheck = false
|
|
+ flagSmtpEncryption = "STARTTLS"
|
|
+ flagSmtpHelo = "localhost"
|
|
+ flagSendgridApiKey string
|
|
+ flagEmailFrom string
|
|
+ flagEmailFromName = "WireGuard UI"
|
|
+ flagSessionSecret = util.RandomString(32)
|
|
+ flagSessionMaxDuration = 90
|
|
+ flagWgConfTemplate string
|
|
+ flagBasePath string
|
|
+ flagSubnetRanges string
|
|
)
|
|
|
|
const (
|
|
- defaultEmailSubject = "Your wireguard configuration"
|
|
- defaultEmailContent = `Hi,</br>
|
|
-<p>In this email you can find your personal configuration for our wireguard server.</p>
|
|
+ defaultEmailSubject = "Your WireGuard configuration"
|
|
+ defaultEmailContent = `Hey there,</br>
|
|
+<p>Please find attached your configuration for the WireGuard server.</p>
|
|
|
|
-<p>Best</p>
|
|
+<p>Thanks!</p>
|
|
`
|
|
)
|
|
|
|
@@ -77,7 +74,6 @@ var embeddedAssets embed.FS
|
|
func init() {
|
|
// command-line flags and env variables
|
|
flag.BoolVar(&flagDisableLogin, "disable-login", util.LookupEnvOrBool("DISABLE_LOGIN", flagDisableLogin), "Disable authentication on the app. This is potentially dangerous.")
|
|
- flag.StringVar(&flagBindAddress, "bind-address", util.LookupEnvOrString("BIND_ADDRESS", flagBindAddress), "Address:Port to which the app will be bound.")
|
|
flag.StringVar(&flagSmtpHostname, "smtp-hostname", util.LookupEnvOrString("SMTP_HOSTNAME", flagSmtpHostname), "SMTP Hostname")
|
|
flag.IntVar(&flagSmtpPort, "smtp-port", util.LookupEnvOrInt("SMTP_PORT", flagSmtpPort), "SMTP Port")
|
|
flag.StringVar(&flagSmtpHelo, "smtp-helo", util.LookupEnvOrString("SMTP_HELO", flagSmtpHelo), "SMTP HELO Hostname")
|
|
@@ -87,9 +83,6 @@ func init() {
|
|
flag.StringVar(&flagSmtpAuthType, "smtp-auth-type", util.LookupEnvOrString("SMTP_AUTH_TYPE", flagSmtpAuthType), "SMTP Auth Type : PLAIN, LOGIN or NONE.")
|
|
flag.StringVar(&flagEmailFrom, "email-from", util.LookupEnvOrString("EMAIL_FROM_ADDRESS", flagEmailFrom), "'From' email address.")
|
|
flag.StringVar(&flagEmailFromName, "email-from-name", util.LookupEnvOrString("EMAIL_FROM_NAME", flagEmailFromName), "'From' email name.")
|
|
- flag.StringVar(&flagTelegramToken, "telegram-token", util.LookupEnvOrString("TELEGRAM_TOKEN", flagTelegramToken), "Telegram bot token for distributing configs to clients.")
|
|
- flag.BoolVar(&flagTelegramAllowConfRequest, "telegram-allow-conf-request", util.LookupEnvOrBool("TELEGRAM_ALLOW_CONF_REQUEST", flagTelegramAllowConfRequest), "Allow users to get configs from the bot by sending a message.")
|
|
- flag.IntVar(&flagTelegramFloodWait, "telegram-flood-wait", util.LookupEnvOrInt("TELEGRAM_FLOOD_WAIT", flagTelegramFloodWait), "Time in minutes before the next conf request is processed.")
|
|
flag.StringVar(&flagWgConfTemplate, "wg-conf-template", util.LookupEnvOrString("WG_CONF_TEMPLATE", flagWgConfTemplate), "Path to custom wg.conf template.")
|
|
flag.StringVar(&flagBasePath, "base-path", util.LookupEnvOrString("BASE_PATH", flagBasePath), "The base path of the URL")
|
|
flag.StringVar(&flagSubnetRanges, "subnet-ranges", util.LookupEnvOrString("SUBNET_RANGES", flagSubnetRanges), "IP ranges to choose from when assigning an IP for a client.")
|
|
@@ -126,7 +119,6 @@ func init() {
|
|
|
|
// update runtime config
|
|
util.DisableLogin = flagDisableLogin
|
|
- util.BindAddress = flagBindAddress
|
|
util.SmtpHostname = flagSmtpHostname
|
|
util.SmtpPort = flagSmtpPort
|
|
util.SmtpHelo = flagSmtpHelo
|
|
@@ -146,11 +138,6 @@ func init() {
|
|
|
|
lvl, _ := util.ParseLogLevel(util.LookupEnvOrString(util.LogLevel, "INFO"))
|
|
|
|
- telegram.Token = flagTelegramToken
|
|
- telegram.AllowConfRequest = flagTelegramAllowConfRequest
|
|
- telegram.FloodWait = flagTelegramFloodWait
|
|
- telegram.LogLevel = lvl
|
|
-
|
|
// print only if log level is INFO or lower
|
|
if lvl <= log.INFO {
|
|
// print app information
|
|
@@ -161,7 +148,6 @@ func init() {
|
|
fmt.Println("Build Time\t:", buildTime)
|
|
fmt.Println("Git Repo\t:", "https://github.com/ngoduykhanh/wireguard-ui")
|
|
fmt.Println("Authentication\t:", !util.DisableLogin)
|
|
- fmt.Println("Bind address\t:", util.BindAddress)
|
|
//fmt.Println("Sendgrid key\t:", util.SendgridApiKey)
|
|
fmt.Println("Email from\t:", util.EmailFrom)
|
|
fmt.Println("Email from name\t:", util.EmailFromName)
|
|
@@ -241,7 +227,6 @@ func main() {
|
|
app.POST(util.BasePath+"/new-client", handler.NewClient(db), handler.ValidSession, handler.ContentTypeJson)
|
|
app.POST(util.BasePath+"/update-client", handler.UpdateClient(db), handler.ValidSession, handler.ContentTypeJson)
|
|
app.POST(util.BasePath+"/email-client", handler.EmailClient(db, sendmail, defaultEmailSubject, defaultEmailContent), handler.ValidSession, handler.ContentTypeJson)
|
|
- app.POST(util.BasePath+"/send-telegram-client", handler.SendTelegramClient(db), handler.ValidSession, handler.ContentTypeJson)
|
|
app.POST(util.BasePath+"/client/set-status", handler.SetClientStatus(db), handler.ValidSession, handler.ContentTypeJson)
|
|
app.POST(util.BasePath+"/remove-client", handler.RemoveClient(db), handler.ValidSession, handler.ContentTypeJson)
|
|
app.GET(util.BasePath+"/download", handler.DownloadClient(db), handler.ValidSession)
|
|
@@ -269,29 +254,28 @@ func main() {
|
|
// serves other static files
|
|
app.GET(util.BasePath+"/static/*", echo.WrapHandler(http.StripPrefix(util.BasePath+"/static/", assetHandler)))
|
|
|
|
- initDeps := telegram.TgBotInitDependencies{
|
|
- DB: db,
|
|
- SendRequestedConfigsToTelegram: util.SendRequestedConfigsToTelegram,
|
|
+ listeners, _ := activation.Listeners()
|
|
+ if len(listeners) == 0 {
|
|
+ app.Logger.Fatal("no activated socket found; aborting")
|
|
}
|
|
|
|
- initTelegram(initDeps)
|
|
-
|
|
- if strings.HasPrefix(util.BindAddress, "unix://") {
|
|
- // Listen on unix domain socket.
|
|
- // https://github.com/labstack/echo/issues/830
|
|
- err := syscall.Unlink(util.BindAddress[6:])
|
|
- if err != nil {
|
|
- app.Logger.Fatalf("Cannot unlink unix socket: Error: %v", err)
|
|
- }
|
|
- l, err := net.Listen("unix", util.BindAddress[6:])
|
|
- if err != nil {
|
|
- app.Logger.Fatalf("Cannot create unix socket. Error: %v", err)
|
|
- }
|
|
- app.Listener = l
|
|
- app.Logger.Fatal(app.Start(""))
|
|
- } else {
|
|
- // Listen on TCP socket
|
|
- app.Logger.Fatal(app.Start(util.BindAddress))
|
|
+ app.Listener = listeners[0]
|
|
+
|
|
+ globalSettings, _ := db.GetGlobalSettings()
|
|
+ defer cleanup(globalSettings.ConfigFilePath)
|
|
+
|
|
+ ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
|
+ defer stop()
|
|
+
|
|
+ go func() {
|
|
+ <-ctx.Done()
|
|
+ cleanup(globalSettings.ConfigFilePath)
|
|
+ os.Exit(0)
|
|
+ }()
|
|
+
|
|
+ if err := app.Start(""); err != nil {
|
|
+ cleanup(globalSettings.ConfigFilePath)
|
|
+ app.Logger.Fatal(err)
|
|
}
|
|
}
|
|
|
|
@@ -301,11 +285,6 @@ func initServerConfig(db store.IStore, tmplDir fs.FS) {
|
|
log.Fatalf("Cannot get global settings: %v", err)
|
|
}
|
|
|
|
- if _, err := os.Stat(settings.ConfigFilePath); err == nil {
|
|
- // file exists, don't overwrite it implicitly
|
|
- return
|
|
- }
|
|
-
|
|
server, err := db.GetServer()
|
|
if err != nil {
|
|
log.Fatalf("Cannot get server config: %v", err)
|
|
@@ -328,13 +307,9 @@ func initServerConfig(db store.IStore, tmplDir fs.FS) {
|
|
}
|
|
}
|
|
|
|
-func initTelegram(initDeps telegram.TgBotInitDependencies) {
|
|
- go func() {
|
|
- for {
|
|
- err := telegram.Start(initDeps)
|
|
- if err == nil {
|
|
- break
|
|
- }
|
|
- }
|
|
- }()
|
|
+func cleanup(cfgPath string) {
|
|
+ cmd := exec.Command("wg-quick", "down", cfgPath)
|
|
+ cmd.Stdout = os.Stdout
|
|
+ cmd.Stderr = os.Stdout
|
|
+ cmd.Run()
|
|
}
|
|
diff --git a/model/client.go b/model/client.go
|
|
index cb00016..6199123 100644
|
|
--- a/model/client.go
|
|
+++ b/model/client.go
|
|
@@ -11,7 +11,6 @@ type Client struct {
|
|
PublicKey string `json:"public_key"`
|
|
PresharedKey string `json:"preshared_key"`
|
|
Name string `json:"name"`
|
|
- TgUserid string `json:"telegram_userid"`
|
|
Email string `json:"email"`
|
|
SubnetRanges []string `json:"subnet_ranges,omitempty"`
|
|
AllocatedIPs []string `json:"allocated_ips"`
|
|
diff --git a/store/jsondb/jsondb.go b/store/jsondb/jsondb.go
|
|
index 1401b2c..70537ab 100644
|
|
--- a/store/jsondb/jsondb.go
|
|
+++ b/store/jsondb/jsondb.go
|
|
@@ -6,7 +6,6 @@ import (
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
- "strconv"
|
|
"time"
|
|
|
|
"github.com/sdomino/scribble"
|
|
@@ -169,19 +168,6 @@ func (o *JsonDB) Init() error {
|
|
}
|
|
}
|
|
|
|
- clients, err := o.GetClients(false)
|
|
- if err != nil {
|
|
- return nil
|
|
- }
|
|
- for _, cl := range clients {
|
|
- client := cl.Client
|
|
- if client.Enabled && len(client.TgUserid) > 0 {
|
|
- if userid, err := strconv.ParseInt(client.TgUserid, 10, 64); err == nil {
|
|
- util.UpdateTgToClientID(userid, client.ID)
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
return nil
|
|
}
|
|
|
|
@@ -336,17 +322,6 @@ func (o *JsonDB) GetClientByID(clientID string, qrCodeSettings model.QRCodeSetti
|
|
func (o *JsonDB) SaveClient(client model.Client) error {
|
|
clientPath := path.Join(path.Join(o.dbPath, "clients"), client.ID+".json")
|
|
output := o.conn.Write("clients", client.ID, client)
|
|
- if output == nil {
|
|
- if client.Enabled && len(client.TgUserid) > 0 {
|
|
- if userid, err := strconv.ParseInt(client.TgUserid, 10, 64); err == nil {
|
|
- util.UpdateTgToClientID(userid, client.ID)
|
|
- }
|
|
- } else {
|
|
- util.RemoveTgToClientID(client.ID)
|
|
- }
|
|
- } else {
|
|
- util.RemoveTgToClientID(client.ID)
|
|
- }
|
|
err := util.ManagePerms(clientPath)
|
|
if err != nil {
|
|
return err
|
|
@@ -355,7 +330,6 @@ func (o *JsonDB) SaveClient(client model.Client) error {
|
|
}
|
|
|
|
func (o *JsonDB) DeleteClient(clientID string) error {
|
|
- util.RemoveTgToClientID(clientID)
|
|
return o.conn.Delete("clients", clientID)
|
|
}
|
|
|
|
diff --git a/telegram/bot.go b/telegram/bot.go
|
|
deleted file mode 100644
|
|
index 7842f63..0000000
|
|
--- a/telegram/bot.go
|
|
+++ /dev/null
|
|
@@ -1,161 +0,0 @@
|
|
-package telegram
|
|
-
|
|
-import (
|
|
- "fmt"
|
|
- "sync"
|
|
- "time"
|
|
-
|
|
- "github.com/NicoNex/echotron/v3"
|
|
- "github.com/labstack/gommon/log"
|
|
- "github.com/ngoduykhanh/wireguard-ui/store"
|
|
-)
|
|
-
|
|
-type SendRequestedConfigsToTelegram func(db store.IStore, userid int64) []string
|
|
-
|
|
-type TgBotInitDependencies struct {
|
|
- DB store.IStore
|
|
- SendRequestedConfigsToTelegram SendRequestedConfigsToTelegram
|
|
-}
|
|
-
|
|
-var (
|
|
- Token string
|
|
- AllowConfRequest bool
|
|
- FloodWait int
|
|
- LogLevel log.Lvl
|
|
-
|
|
- Bot *echotron.API
|
|
- BotMutex sync.RWMutex
|
|
-
|
|
- floodWait = make(map[int64]int64)
|
|
- floodMessageSent = make(map[int64]struct{})
|
|
-)
|
|
-
|
|
-func Start(initDeps TgBotInitDependencies) (err error) {
|
|
- ticker := time.NewTicker(time.Minute)
|
|
- defer func() {
|
|
- if err != nil {
|
|
- BotMutex.Lock()
|
|
- Bot = nil
|
|
- BotMutex.Unlock()
|
|
- ticker.Stop()
|
|
- }
|
|
- if r := recover(); r != nil {
|
|
- err = fmt.Errorf("[PANIC] recovered from panic: %v", r)
|
|
- }
|
|
- }()
|
|
-
|
|
- token := Token
|
|
- if token == "" || len(token) < 30 {
|
|
- return
|
|
- }
|
|
-
|
|
- bot := echotron.NewAPI(token)
|
|
-
|
|
- res, err := bot.GetMe()
|
|
- if !res.Ok || err != nil {
|
|
- log.Warnf("[Telegram] Unable to connect to bot.\n%v\n%v", res.Description, err)
|
|
- return
|
|
- }
|
|
-
|
|
- BotMutex.Lock()
|
|
- Bot = &bot
|
|
- BotMutex.Unlock()
|
|
-
|
|
- if LogLevel <= log.INFO {
|
|
- fmt.Printf("[Telegram] Authorized as %s\n", res.Result.Username)
|
|
- }
|
|
-
|
|
- go func() {
|
|
- for range ticker.C {
|
|
- updateFloodWait()
|
|
- }
|
|
- }()
|
|
-
|
|
- if !AllowConfRequest {
|
|
- return
|
|
- }
|
|
-
|
|
- updatesChan := echotron.PollingUpdatesOptions(token, false, echotron.UpdateOptions{AllowedUpdates: []echotron.UpdateType{echotron.MessageUpdate}})
|
|
- for update := range updatesChan {
|
|
- if update.Message != nil {
|
|
- userid := update.Message.Chat.ID
|
|
- if _, wait := floodWait[userid]; wait {
|
|
- if _, notified := floodMessageSent[userid]; notified {
|
|
- continue
|
|
- }
|
|
- floodMessageSent[userid] = struct{}{}
|
|
- _, err := bot.SendMessage(
|
|
- fmt.Sprintf("You can only request your configs once per %d minutes", FloodWait),
|
|
- userid,
|
|
- &echotron.MessageOptions{
|
|
- ReplyToMessageID: update.Message.ID,
|
|
- })
|
|
- if err != nil {
|
|
- log.Errorf("Failed to send telegram message. Error %v", err)
|
|
- }
|
|
- continue
|
|
- }
|
|
- floodWait[userid] = time.Now().Unix()
|
|
-
|
|
- failed := initDeps.SendRequestedConfigsToTelegram(initDeps.DB, userid)
|
|
- if len(failed) > 0 {
|
|
- messageText := "Failed to send configs:\n"
|
|
- for _, f := range failed {
|
|
- messageText += f + "\n"
|
|
- }
|
|
- _, err := bot.SendMessage(
|
|
- messageText,
|
|
- userid,
|
|
- &echotron.MessageOptions{
|
|
- ReplyToMessageID: update.Message.ID,
|
|
- })
|
|
- if err != nil {
|
|
- log.Errorf("Failed to send telegram message. Error %v", err)
|
|
- }
|
|
- }
|
|
- }
|
|
- }
|
|
- return err
|
|
-}
|
|
-
|
|
-func SendConfig(userid int64, clientName string, confData, qrData []byte, ignoreFloodWait bool) error {
|
|
- BotMutex.RLock()
|
|
- defer BotMutex.RUnlock()
|
|
-
|
|
- if Bot == nil {
|
|
- return fmt.Errorf("telegram bot is not configured or not available")
|
|
- }
|
|
-
|
|
- if _, wait := floodWait[userid]; wait && !ignoreFloodWait {
|
|
- return fmt.Errorf("this client already got their config less than %d minutes ago", FloodWait)
|
|
- }
|
|
-
|
|
- if !ignoreFloodWait {
|
|
- floodWait[userid] = time.Now().Unix()
|
|
- }
|
|
-
|
|
- qrAttachment := echotron.NewInputFileBytes("qr.png", qrData)
|
|
- _, err := Bot.SendPhoto(qrAttachment, userid, &echotron.PhotoOptions{Caption: clientName})
|
|
- if err != nil {
|
|
- log.Error(err)
|
|
- return fmt.Errorf("unable to send qr picture")
|
|
- }
|
|
-
|
|
- confAttachment := echotron.NewInputFileBytes(clientName+".conf", confData)
|
|
- _, err = Bot.SendDocument(confAttachment, userid, nil)
|
|
- if err != nil {
|
|
- log.Error(err)
|
|
- return fmt.Errorf("unable to send conf file")
|
|
- }
|
|
- return nil
|
|
-}
|
|
-
|
|
-func updateFloodWait() {
|
|
- thresholdTS := time.Now().Unix() - 60*int64(FloodWait)
|
|
- for userid, ts := range floodWait {
|
|
- if ts < thresholdTS {
|
|
- delete(floodWait, userid)
|
|
- delete(floodMessageSent, userid)
|
|
- }
|
|
- }
|
|
-}
|
|
diff --git a/templates/base.html b/templates/base.html
|
|
index ab086e1..99e2b18 100644
|
|
--- a/templates/base.html
|
|
+++ b/templates/base.html
|
|
@@ -281,14 +281,6 @@
|
|
<input type="text" class="form-control" id="client_preshared_key" name="client_preshared_key" placeholder="Autogenerated - enter "-" to skip generation">
|
|
</div>
|
|
</details>
|
|
- <details style="margin-top: 0.5rem;">
|
|
- <summary><strong>Additional configuration</strong>
|
|
- </summary>
|
|
- <div class="form-group" style="margin-top: 0.5rem;">
|
|
- <label for="client_telegram_userid" class="control-label">Telegram userid</label>
|
|
- <input type="text" class="form-control" id="client_telegram_userid" name="client_telegram_userid">
|
|
- </div>
|
|
- </details>
|
|
</div>
|
|
<div class="modal-footer justify-content-between">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
|
@@ -436,7 +428,7 @@
|
|
});
|
|
}
|
|
|
|
-
|
|
+
|
|
// populateClient function for render new client info
|
|
// on the client page.
|
|
function populateClient(client_id) {
|
|
@@ -460,7 +452,6 @@
|
|
function submitNewClient() {
|
|
const name = $("#client_name").val();
|
|
const email = $("#client_email").val();
|
|
- const telegram_userid = $("#client_telegram_userid").val();
|
|
const allocated_ips = $("#client_allocated_ips").val().split(",");
|
|
const allowed_ips = $("#client_allowed_ips").val().split(",");
|
|
const endpoint = $("#client_endpoint").val();
|
|
@@ -484,7 +475,7 @@
|
|
const public_key = $("#client_public_key").val();
|
|
const preshared_key = $("#client_preshared_key").val();
|
|
|
|
- const data = {"name": name, "email": email, "telegram_userid": telegram_userid, "allocated_ips": allocated_ips, "allowed_ips": allowed_ips,
|
|
+ const data = {"name": name, "email": email, "allocated_ips": allocated_ips, "allowed_ips": allowed_ips,
|
|
"extra_allowed_ips": extra_allowed_ips, "endpoint": endpoint, "use_server_dns": use_server_dns, "enabled": enabled,
|
|
"public_key": public_key, "preshared_key": preshared_key};
|
|
|
|
@@ -626,7 +617,6 @@
|
|
$("#client_allocated_ips").importTags('');
|
|
$("#client_extra_allowed_ips").importTags('');
|
|
$("#client_endpoint").val('');
|
|
- $("#client_telegram_userid").val('');
|
|
updateSubnetRangesList("#subnet_ranges");
|
|
updateIPAllocationSuggestion(true);
|
|
});
|
|
diff --git a/templates/clients.html b/templates/clients.html
|
|
index cf11e0a..992d65c 100644
|
|
--- a/templates/clients.html
|
|
+++ b/templates/clients.html
|
|
@@ -80,35 +80,6 @@ Wireguard Clients
|
|
</div>
|
|
<!-- /.modal -->
|
|
|
|
-<div class="modal fade" id="modal_telegram_client">
|
|
- <div class="modal-dialog">
|
|
- <div class="modal-content">
|
|
- <div class="modal-header">
|
|
- <h4 class="modal-title">Telegram Configuration</h4>
|
|
- <button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
- <span aria-hidden="true">×</span>
|
|
- </button>
|
|
- </div>
|
|
- <form name="frm_telegram_client" id="frm_telegram_client">
|
|
- <div class="modal-body">
|
|
- <input type="hidden" id="tg_client_id" name="tg_client_id">
|
|
- <div class="form-group">
|
|
- <label for="tg_client_userid" class="control-label">Telegram userid</label>
|
|
- <input type="text" class="form-control" id="tg_client_userid" name="tg_client_userid">
|
|
- </div>
|
|
- </div>
|
|
- <div class="modal-footer justify-content-between">
|
|
- <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
|
- <button type="submit" class="btn btn-success">Send</button>
|
|
- </div>
|
|
- </form>
|
|
- </div>
|
|
- <!-- /.modal-content -->
|
|
- </div>
|
|
- <!-- /.modal-dialog -->
|
|
-</div>
|
|
-<!-- /.modal -->
|
|
-
|
|
<div class="modal fade" id="modal_edit_client">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
@@ -188,14 +159,6 @@ Wireguard Clients
|
|
<input type="text" class="form-control" id="_client_preshared_key" name="_client_preshared_key">
|
|
</div>
|
|
</details>
|
|
- <details style="margin-top: 0.5rem;">
|
|
- <summary><strong>Additional configuration</strong>
|
|
- </summary>
|
|
- <div class="form-group" style="margin-top: 0.5rem;">
|
|
- <label for="_client_telegram_userid" class="control-label">Telegram userid</label>
|
|
- <input type="text" class="form-control" id="_client_telegram_userid" name="_client_telegram_userid">
|
|
- </div>
|
|
- </details>
|
|
</div>
|
|
<div class="modal-footer justify-content-between">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
|
@@ -420,11 +383,6 @@ Wireguard Clients
|
|
}
|
|
})
|
|
$(".badge-secondary").filter(':contains("' + query + '")').parent().parent().parent().show();
|
|
- $(".fa-tguserid").each(function () {
|
|
- if ($(this).parent().text().trim().indexOf(query.trim()) != -1) {
|
|
- $(this).closest('.col-lg-4').show();
|
|
- }
|
|
- })
|
|
})
|
|
|
|
$("#status-selector").on('change', function () {
|
|
@@ -494,7 +452,7 @@ Wireguard Clients
|
|
if (sr === selectedSR) {
|
|
$(this).closest('.col-lg-4').show();
|
|
break
|
|
- }
|
|
+ }
|
|
}
|
|
})
|
|
// $('.col-lg-4').show();
|
|
@@ -615,7 +573,6 @@ Wireguard Clients
|
|
|
|
modal.find(".modal-title").text("Edit Client " + client.name);
|
|
modal.find("#_client_id").val(client.id);
|
|
- modal.find("#_client_telegram_userid").val(client.telegram_userid);
|
|
modal.find("#_client_name").val(client.name);
|
|
modal.find("#_client_email").val(client.email);
|
|
|
|
@@ -715,29 +672,6 @@ Wireguard Clients
|
|
});
|
|
}
|
|
|
|
- // submitTelegramClient function for sending a telegram message with the configuration to the client
|
|
- function submitTelegramClient() {
|
|
- const client_id = $("#tg_client_id").val();
|
|
- const userid = $("#tg_client_userid").val();
|
|
- const data = {"id": client_id, "userid": userid};
|
|
- $.ajax({
|
|
- cache: false,
|
|
- method: 'POST',
|
|
- url: '{{.basePath}}/send-telegram-client',
|
|
- dataType: 'json',
|
|
- contentType: "application/json",
|
|
- data: JSON.stringify(data),
|
|
- success: function(resp) {
|
|
- $("#modal_telegram_client").modal('hide');
|
|
- toastr.success('Sent config via telegram to client successfully');
|
|
- },
|
|
- error: function(jqXHR, exception) {
|
|
- const responseJson = jQuery.parseJSON(jqXHR.responseText);
|
|
- toastr.error(responseJson['message']);
|
|
- }
|
|
- });
|
|
- }
|
|
-
|
|
// submitEditClient function for updating an existing client
|
|
// This sends dialogue data to the back-end when user presses "Save"
|
|
// See e.g. routes.go:UpdateClient for where data is processed/verified.
|
|
@@ -745,7 +679,6 @@ Wireguard Clients
|
|
const client_id = $("#_client_id").val();
|
|
const name = $("#_client_name").val();
|
|
const email = $("#_client_email").val();
|
|
- const telegram_userid = $("#_client_telegram_userid").val();
|
|
const allocated_ips = $("#_client_allocated_ips").val().split(",");
|
|
const allowed_ips = $("#_client_allowed_ips").val().split(",");
|
|
let use_server_dns = false;
|
|
@@ -769,7 +702,7 @@ Wireguard Clients
|
|
enabled = true;
|
|
}
|
|
|
|
- const data = {"id": client_id, "name": name, "email": email, "telegram_userid": telegram_userid, "allocated_ips": allocated_ips,
|
|
+ const data = {"id": client_id, "name": name, "email": email, "allocated_ips": allocated_ips,
|
|
"allowed_ips": allowed_ips, "extra_allowed_ips": extra_allowed_ips, "endpoint": endpoint,
|
|
"use_server_dns": use_server_dns, "enabled": enabled, "public_key": public_key, "preshared_key": preshared_key};
|
|
|
|
@@ -800,8 +733,6 @@ Wireguard Clients
|
|
submitEditClient();
|
|
} else if (formId === "frm_email_client") {
|
|
submitEmailClient();
|
|
- } else if (formId === "frm_telegram_client") {
|
|
- submitTelegramClient();
|
|
}
|
|
}
|
|
|
|
@@ -838,30 +769,6 @@ Wireguard Clients
|
|
regenerateQRCode();
|
|
});
|
|
|
|
- $("#modal_telegram_client").on('show.bs.modal', function (event) {
|
|
- let modal = $(this);
|
|
- const button = $(event.relatedTarget);
|
|
- const client_id = button.data('clientid');
|
|
- $.ajax({
|
|
- cache: false,
|
|
- method: 'GET',
|
|
- url: '{{.basePath}}/api/client/' + client_id,
|
|
- dataType: 'json',
|
|
- contentType: "application/json",
|
|
- success: function (resp) {
|
|
- const client = resp.Client;
|
|
-
|
|
- modal.find(".modal-title").text("Send config to client " + client.name);
|
|
- modal.find("#tg_client_id").val(client.id);
|
|
- modal.find("#tg_client_userid").val(client.telegram_userid);
|
|
- },
|
|
- error: function (jqXHR, exception) {
|
|
- const responseJson = jQuery.parseJSON(jqXHR.responseText);
|
|
- toastr.error(responseJson['message']);
|
|
- }
|
|
- });
|
|
- });
|
|
-
|
|
$(document).ready(function () {
|
|
$.validator.setDefaults({
|
|
submitHandler: function (form) {
|
|
@@ -917,33 +824,7 @@ Wireguard Clients
|
|
$(element).removeClass('is-invalid');
|
|
}
|
|
});
|
|
- // Telegram client form validation
|
|
- $("#frm_telegram_client").validate({
|
|
- rules: {
|
|
- tg_client_userid: {
|
|
- required: true,
|
|
- number: true,
|
|
- },
|
|
- },
|
|
- messages: {
|
|
- tg_client_userid: {
|
|
- required: "Please enter a telegram userid",
|
|
- number: "Please enter a valid telegram userid"
|
|
- },
|
|
- },
|
|
- errorElement: 'span',
|
|
- errorPlacement: function (error, element) {
|
|
- error.addClass('invalid-feedback');
|
|
- element.closest('.form-group').append(error);
|
|
- },
|
|
- highlight: function (element, errorClass, validClass) {
|
|
- $(element).addClass('is-invalid');
|
|
- },
|
|
- unhighlight: function (element, errorClass, validClass) {
|
|
- $(element).removeClass('is-invalid');
|
|
- }
|
|
- });
|
|
- //
|
|
+ //
|
|
});
|
|
</script>
|
|
{{end}}
|
|
diff --git a/templates/wg.conf b/templates/wg.conf
|
|
index a8389cf..c715362 100644
|
|
--- a/templates/wg.conf
|
|
+++ b/templates/wg.conf
|
|
@@ -17,7 +17,6 @@ Table = {{ .globalSettings.Table }}
|
|
# ID: {{ .Client.ID }}
|
|
# Name: {{ .Client.Name }}
|
|
# Email: {{ .Client.Email }}
|
|
-# Telegram: {{ .Client.TgUserid }}
|
|
# Created at: {{ .Client.CreatedAt }}
|
|
# Update at: {{ .Client.UpdatedAt }}
|
|
[Peer]
|
|
diff --git a/util/cache.go b/util/cache.go
|
|
index 48b37ea..fcb5e28 100644
|
|
--- a/util/cache.go
|
|
+++ b/util/cache.go
|
|
@@ -1,8 +1,4 @@
|
|
package util
|
|
|
|
-import "sync"
|
|
-
|
|
var IPToSubnetRange = map[string]uint16{}
|
|
-var TgUseridToClientID = map[int64][]string{}
|
|
-var TgUseridToClientIDMutex sync.RWMutex
|
|
var DBUsersToCRC32 = map[string]uint32{}
|
|
diff --git a/util/config.go b/util/config.go
|
|
index 4af6bd2..613ac27 100644
|
|
--- a/util/config.go
|
|
+++ b/util/config.go
|
|
@@ -10,7 +10,6 @@ import (
|
|
// Runtime config
|
|
var (
|
|
DisableLogin bool
|
|
- BindAddress string
|
|
SmtpHostname string
|
|
SmtpPort int
|
|
SmtpUsername string
|
|
diff --git a/util/util.go b/util/util.go
|
|
index 06b87c3..3898cda 100644
|
|
--- a/util/util.go
|
|
+++ b/util/util.go
|
|
@@ -13,6 +13,7 @@ import (
|
|
"math/rand"
|
|
"net"
|
|
"os"
|
|
+ "os/exec"
|
|
"path"
|
|
"path/filepath"
|
|
"strconv"
|
|
@@ -21,8 +22,6 @@ import (
|
|
"time"
|
|
|
|
"github.com/ngoduykhanh/wireguard-ui/store"
|
|
- "github.com/ngoduykhanh/wireguard-ui/telegram"
|
|
- "github.com/skip2/go-qrcode"
|
|
"golang.org/x/mod/sumdb/dirhash"
|
|
|
|
externalip "github.com/glendc/go-external-ip"
|
|
@@ -585,58 +584,17 @@ func WriteWireGuardServerConfig(tmplDir fs.FS, serverConfig model.Server, client
|
|
}
|
|
f.Close()
|
|
|
|
- return nil
|
|
-}
|
|
-
|
|
-// SendRequestedConfigsToTelegram to send client all their configs. Returns failed configs list.
|
|
-func SendRequestedConfigsToTelegram(db store.IStore, userid int64) []string {
|
|
- failedList := make([]string, 0)
|
|
- TgUseridToClientIDMutex.RLock()
|
|
- if clids, found := TgUseridToClientID[userid]; found && len(clids) > 0 {
|
|
- TgUseridToClientIDMutex.RUnlock()
|
|
-
|
|
- for _, clid := range clids {
|
|
- clientData, err := db.GetClientByID(clid, qrCodeSettings)
|
|
- if err != nil {
|
|
- // return fmt.Errorf("unable to get client")
|
|
- failedList = append(failedList, clid)
|
|
- continue
|
|
- }
|
|
+ cmdDown := exec.Command("wg-quick", "down", globalSettings.ConfigFilePath)
|
|
+ cmdDown.Stdout = os.Stdout
|
|
+ cmdDown.Stderr = os.Stdout
|
|
+ cmdDown.Run()
|
|
|
|
- // build config
|
|
- server, _ := db.GetServer()
|
|
- globalSettings, _ := db.GetGlobalSettings()
|
|
- config := BuildClientConfig(*clientData.Client, server, globalSettings)
|
|
- configData := []byte(config)
|
|
- var qrData []byte
|
|
+ cmdUp := exec.Command("wg-quick", "up", globalSettings.ConfigFilePath)
|
|
+ cmdUp.Stdout = os.Stdout
|
|
+ cmdUp.Stderr = os.Stdout
|
|
+ cmdUp.Run()
|
|
|
|
- if clientData.Client.PrivateKey != "" {
|
|
- qrData, err = qrcode.Encode(config, qrcode.Medium, 512)
|
|
- if err != nil {
|
|
- // return fmt.Errorf("unable to encode qr")
|
|
- failedList = append(failedList, clientData.Client.Name)
|
|
- continue
|
|
- }
|
|
- }
|
|
-
|
|
- userid, err := strconv.ParseInt(clientData.Client.TgUserid, 10, 64)
|
|
- if err != nil {
|
|
- // return fmt.Errorf("tg usrid is unreadable")
|
|
- failedList = append(failedList, clientData.Client.Name)
|
|
- continue
|
|
- }
|
|
-
|
|
- err = telegram.SendConfig(userid, clientData.Client.Name, configData, qrData, true)
|
|
- if err != nil {
|
|
- failedList = append(failedList, clientData.Client.Name)
|
|
- continue
|
|
- }
|
|
- time.Sleep(2 * time.Second)
|
|
- }
|
|
- } else {
|
|
- TgUseridToClientIDMutex.RUnlock()
|
|
- }
|
|
- return failedList
|
|
+ return nil
|
|
}
|
|
|
|
func LookupEnvOrString(key string, defaultVal string) string {
|
|
@@ -769,68 +727,6 @@ func ManagePerms(path string) error {
|
|
return err
|
|
}
|
|
|
|
-func AddTgToClientID(userid int64, clientID string) {
|
|
- TgUseridToClientIDMutex.Lock()
|
|
- defer TgUseridToClientIDMutex.Unlock()
|
|
-
|
|
- if _, ok := TgUseridToClientID[userid]; ok && TgUseridToClientID[userid] != nil {
|
|
- TgUseridToClientID[userid] = append(TgUseridToClientID[userid], clientID)
|
|
- } else {
|
|
- TgUseridToClientID[userid] = []string{clientID}
|
|
- }
|
|
-}
|
|
-
|
|
-func UpdateTgToClientID(userid int64, clientID string) {
|
|
- TgUseridToClientIDMutex.Lock()
|
|
- defer TgUseridToClientIDMutex.Unlock()
|
|
-
|
|
- // Detach clientID from any existing userid
|
|
- for uid, cls := range TgUseridToClientID {
|
|
- if cls != nil {
|
|
- filtered := filterStringSlice(cls, clientID)
|
|
- if len(filtered) > 0 {
|
|
- TgUseridToClientID[uid] = filtered
|
|
- } else {
|
|
- delete(TgUseridToClientID, uid)
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- // Attach it to the new one
|
|
- if _, ok := TgUseridToClientID[userid]; ok && TgUseridToClientID[userid] != nil {
|
|
- TgUseridToClientID[userid] = append(TgUseridToClientID[userid], clientID)
|
|
- } else {
|
|
- TgUseridToClientID[userid] = []string{clientID}
|
|
- }
|
|
-}
|
|
-
|
|
-func RemoveTgToClientID(clientID string) {
|
|
- TgUseridToClientIDMutex.Lock()
|
|
- defer TgUseridToClientIDMutex.Unlock()
|
|
-
|
|
- // Detach clientID from any existing userid
|
|
- for uid, cls := range TgUseridToClientID {
|
|
- if cls != nil {
|
|
- filtered := filterStringSlice(cls, clientID)
|
|
- if len(filtered) > 0 {
|
|
- TgUseridToClientID[uid] = filtered
|
|
- } else {
|
|
- delete(TgUseridToClientID, uid)
|
|
- }
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-func filterStringSlice(s []string, excludedStr string) []string {
|
|
- filtered := s[:0]
|
|
- for _, v := range s {
|
|
- if v != excludedStr {
|
|
- filtered = append(filtered, v)
|
|
- }
|
|
- }
|
|
- return filtered
|
|
-}
|
|
-
|
|
func GetDBUserCRC32(dbuser model.User) uint32 {
|
|
buf := new(bytes.Buffer)
|
|
enc := gob.NewEncoder(buf)
|