mirror of
https://github.com/ngoduykhanh/wireguard-ui
synced 2024-05-07 08:16:34 +02:00
Telegram support, send config button
This commit is contained in:
parent
c691f0733d
commit
4c6080b3fa
|
@ -1,5 +1,15 @@
|
|||
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>`
|
||||
}
|
||||
|
||||
// render client status css tag style
|
||||
let clientStatusHtml = '>'
|
||||
if (obj.Client.enabled) {
|
||||
|
@ -43,7 +53,7 @@ function renderClientList(data) {
|
|||
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"
|
||||
|
|
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module github.com/ngoduykhanh/wireguard-ui
|
|||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/NicoNex/echotron/v3 v3.27.0
|
||||
github.com/glendc/go-external-ip v0.0.0-20170425150139-139229dcdddd
|
||||
github.com/go-playground/universal-translator v0.17.0 // indirect
|
||||
github.com/gorilla/sessions v1.2.0
|
||||
|
|
2
go.sum
2
go.sum
|
@ -1,4 +1,6 @@
|
|||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
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/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw=
|
||||
|
|
|
@ -19,12 +19,14 @@ 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"
|
||||
)
|
||||
|
||||
|
@ -569,6 +571,56 @@ 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)
|
||||
|
||||
qrCodeSettings := model.QRCodeSettings{
|
||||
Enabled: true,
|
||||
IncludeDNS: true,
|
||||
IncludeMTU: true,
|
||||
}
|
||||
clientData, err := db.GetClientByID(payload.ID, qrCodeSettings)
|
||||
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)
|
||||
|
||||
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 {
|
||||
|
|
62
main.go
62
main.go
|
@ -15,6 +15,7 @@ import (
|
|||
"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"
|
||||
|
@ -30,22 +31,25 @@ var (
|
|||
gitRef = "N/A"
|
||||
buildTime = fmt.Sprintf(time.Now().UTC().Format("01-02-2006 15:04:05"))
|
||||
// configuration variables
|
||||
flagDisableLogin bool = false
|
||||
flagBindAddress string = "0.0.0.0:5000"
|
||||
flagSmtpHostname string = "127.0.0.1"
|
||||
flagSmtpPort int = 25
|
||||
flagSmtpUsername string
|
||||
flagSmtpPassword string
|
||||
flagSmtpAuthType string = "NONE"
|
||||
flagSmtpNoTLSCheck bool = false
|
||||
flagSmtpEncryption string = "STARTTLS"
|
||||
flagSendgridApiKey string
|
||||
flagEmailFrom string
|
||||
flagEmailFromName string = "WireGuard UI"
|
||||
flagSessionSecret string = util.RandomString(32)
|
||||
flagWgConfTemplate string
|
||||
flagBasePath string
|
||||
flagSubnetRanges string
|
||||
flagDisableLogin bool = false
|
||||
flagBindAddress string = "0.0.0.0:5000"
|
||||
flagSmtpHostname string = "127.0.0.1"
|
||||
flagSmtpPort int = 25
|
||||
flagSmtpUsername string
|
||||
flagSmtpPassword string
|
||||
flagSmtpAuthType string = "NONE"
|
||||
flagSmtpNoTLSCheck bool = false
|
||||
flagSmtpEncryption string = "STARTTLS"
|
||||
flagSendgridApiKey string
|
||||
flagEmailFrom string
|
||||
flagEmailFromName string = "WireGuard UI"
|
||||
flagTelegramToken string
|
||||
flagTelegramAllowConfRequest bool = false
|
||||
flagTelegramFloodWait int = 60
|
||||
flagSessionSecret string = util.RandomString(32)
|
||||
flagWgConfTemplate string
|
||||
flagBasePath string
|
||||
flagSubnetRanges string
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -80,6 +84,9 @@ 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.")
|
||||
|
@ -131,8 +138,15 @@ func init() {
|
|||
util.BasePath = util.ParseBasePath(flagBasePath)
|
||||
util.SubnetRanges = util.ParseSubnetRanges(flagSubnetRanges)
|
||||
|
||||
lvl, _ := util.ParseLogLevel(util.LookupEnvOrString(util.LogLevel, "INFO"))
|
||||
|
||||
telegram.TelegramToken = flagTelegramToken
|
||||
telegram.TelegramAllowConfRequest = flagTelegramAllowConfRequest
|
||||
telegram.TelegramFloodWait = flagTelegramFloodWait
|
||||
telegram.LogLevel = lvl
|
||||
|
||||
// print only if log level is INFO or lower
|
||||
if lvl, _ := util.ParseLogLevel(util.LookupEnvOrString(util.LogLevel, "INFO")); lvl <= log.INFO {
|
||||
if lvl <= log.INFO {
|
||||
// print app information
|
||||
fmt.Println("Wireguard UI")
|
||||
fmt.Println("App Version\t:", appVersion)
|
||||
|
@ -221,6 +235,7 @@ 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)
|
||||
|
@ -248,6 +263,8 @@ func main() {
|
|||
// serves other static files
|
||||
app.GET(util.BasePath+"/static/*", echo.WrapHandler(http.StripPrefix(util.BasePath+"/static/", assetHandler)))
|
||||
|
||||
initTelegram(db, util.BuildClientConfig)
|
||||
|
||||
if strings.HasPrefix(util.BindAddress, "unix://") {
|
||||
// Listen on unix domain socket.
|
||||
// https://github.com/labstack/echo/issues/830
|
||||
|
@ -296,3 +313,14 @@ func initServerConfig(db store.IStore, tmplDir fs.FS) {
|
|||
log.Fatalf("Cannot create server config: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func initTelegram(db store.IStore, buildClientConfig telegram.BuildClientConfig) {
|
||||
go func() {
|
||||
for {
|
||||
err := telegram.Start(db, buildClientConfig)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
|
116
telegram/bot.go
Normal file
116
telegram/bot.go
Normal file
|
@ -0,0 +1,116 @@
|
|||
package telegram
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/NicoNex/echotron/v3"
|
||||
"github.com/labstack/gommon/log"
|
||||
"github.com/ngoduykhanh/wireguard-ui/model"
|
||||
"github.com/ngoduykhanh/wireguard-ui/store"
|
||||
)
|
||||
|
||||
type BuildClientConfig func(client model.Client, server model.Server, setting model.GlobalSetting) string
|
||||
|
||||
var (
|
||||
TelegramToken string
|
||||
TelegramAllowConfRequest bool
|
||||
TelegramFloodWait int
|
||||
LogLevel log.Lvl
|
||||
|
||||
TgBot *echotron.API
|
||||
TgBotMutex sync.RWMutex
|
||||
|
||||
floodWait = make(map[int64]int64, 0)
|
||||
)
|
||||
|
||||
func Start(db store.IStore, buildClientConfig BuildClientConfig) (err error) {
|
||||
defer func() {
|
||||
TgBotMutex.Lock()
|
||||
TgBot = nil
|
||||
TgBotMutex.Unlock()
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("[PANIC] recovered from panic: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
token := TelegramToken
|
||||
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
|
||||
}
|
||||
|
||||
TgBotMutex.Lock()
|
||||
TgBot = &bot
|
||||
TgBotMutex.Unlock()
|
||||
|
||||
if LogLevel <= log.INFO {
|
||||
fmt.Printf("[Telegram] Authorized as %s\n", res.Result.Username)
|
||||
}
|
||||
|
||||
if !TelegramAllowConfRequest {
|
||||
return
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(time.Minute)
|
||||
go func() {
|
||||
for range ticker.C {
|
||||
updateFloodWait()
|
||||
}
|
||||
}()
|
||||
|
||||
updatesChan := echotron.PollingUpdatesOptions(token, false, echotron.UpdateOptions{AllowedUpdates: []echotron.UpdateType{echotron.MessageUpdate}})
|
||||
for update := range updatesChan {
|
||||
if update.Message != nil {
|
||||
floodWait[update.Message.Chat.ID] = time.Now().Unix()
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func SendConfig(userid int64, clientName string, confData, qrData []byte) error {
|
||||
TgBotMutex.RLock()
|
||||
defer TgBotMutex.RUnlock()
|
||||
|
||||
if TgBot == nil {
|
||||
return fmt.Errorf("telegram bot is not configured or not available")
|
||||
}
|
||||
|
||||
if _, wait := floodWait[userid]; wait {
|
||||
return fmt.Errorf("this client already got their config less than %d minutes ago", TelegramFloodWait)
|
||||
}
|
||||
|
||||
qrAttachment := echotron.NewInputFileBytes("qr.png", qrData)
|
||||
_, err := TgBot.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 = TgBot.SendDocument(confAttachment, userid, nil)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return fmt.Errorf("unable to send conf file")
|
||||
}
|
||||
|
||||
floodWait[userid] = time.Now().Unix()
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateFloodWait() {
|
||||
thresholdTS := time.Now().Unix() - 60000*int64(TelegramFloodWait)
|
||||
for userid, ts := range floodWait {
|
||||
if ts < thresholdTS {
|
||||
delete(floodWait, userid)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -80,6 +80,35 @@ 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">
|
||||
|
@ -683,6 +712,31 @@ 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');
|
||||
// Refresh the home page (clients page) after sending email successfully
|
||||
location.reload();
|
||||
},
|
||||
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,6 +799,8 @@ Wireguard Clients
|
|||
submitEditClient();
|
||||
} else if (formId === "frm_email_client") {
|
||||
submitEmailClient();
|
||||
} else if (formId === "frm_telegram_client") {
|
||||
submitTelegramClient();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -781,6 +837,30 @@ 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) {
|
||||
|
@ -836,6 +916,32 @@ 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>
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/ngoduykhanh/wireguard-ui/store"
|
||||
"github.com/ngoduykhanh/wireguard-ui/telegram"
|
||||
"golang.org/x/mod/sumdb/dirhash"
|
||||
|
||||
externalip "github.com/glendc/go-external-ip"
|
||||
|
@ -28,7 +29,7 @@ import (
|
|||
)
|
||||
|
||||
// BuildClientConfig to create wireguard client config string
|
||||
func BuildClientConfig(client model.Client, server model.Server, setting model.GlobalSetting) string {
|
||||
var BuildClientConfig telegram.BuildClientConfig = func(client model.Client, server model.Server, setting model.GlobalSetting) string {
|
||||
// Interface section
|
||||
clientAddress := fmt.Sprintf("Address = %s\n", strings.Join(client.AllocatedIPs, ","))
|
||||
clientPrivateKey := fmt.Sprintf("PrivateKey = %s\n", client.PrivateKey)
|
||||
|
|
Loading…
Reference in a new issue