mirror of
https://github.com/ngoduykhanh/wireguard-ui.git
synced 2025-06-08 00:56:58 +03:00
Merge branch 'master' into preshared-key-optional
This commit is contained in:
commit
bbc8bd341d
13 changed files with 276 additions and 26 deletions
16
README.md
16
README.md
|
@ -33,7 +33,9 @@ wireguard interface stats. See the `cap_add` and `network_mode` options on the d
|
|||
|
||||
Set the `SESSION_SECRET` environment variable to a random value.
|
||||
|
||||
In order to sent the wireguard configuration to clients via email (using sendgrid api) set the following environment variables
|
||||
In order to sent the wireguard configuration to clients via email, set the following environment variables:
|
||||
|
||||
- using SendGrid API
|
||||
|
||||
```
|
||||
SENDGRID_API_KEY: Your sendgrid api key
|
||||
|
@ -41,6 +43,18 @@ EMAIL_FROM_ADDRESS: the email address you registered on sendgrid
|
|||
EMAIL_FROM_NAME: the sender's email address
|
||||
```
|
||||
|
||||
- using SMTP
|
||||
|
||||
```
|
||||
SMTP_HOSTNAME
|
||||
SMTP_PORT
|
||||
SMTP_USERNAME
|
||||
SMTP_PASSWORD
|
||||
SMTP_AUTH_TYPE
|
||||
EMAIL_FROM_ADDRESS: the sender's email address
|
||||
EMAIL_FROM_NAME: the sender's name
|
||||
```
|
||||
|
||||
### Using binary file
|
||||
|
||||
Download the binary file from the release and run it with command:
|
||||
|
|
|
@ -24,11 +24,15 @@ function renderClientList(data) {
|
|||
<div class="overlay" id="paused_${obj.Client.id}"` + clientStatusHtml
|
||||
+ `<i class="paused-client fas fa-3x fa-play" onclick="resumeClient('${obj.Client.id}')"></i>
|
||||
</div>
|
||||
<img src="${obj.QRCode}" />
|
||||
<div class="info-box-content">
|
||||
<div class="btn-group">
|
||||
<a href="/download?clientid=${obj.Client.id}" class="btn btn-outline-success btn-sm">Download</a>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" data-toggle="modal"
|
||||
data-target="#modal_qr_client" data-clientid="${obj.Client.id}"
|
||||
data-clientname="${obj.Client.name}">Scan</button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" data-toggle="modal"
|
||||
data-target="#modal_email_client" data-clientid="${obj.Client.id}"
|
||||
|
|
81
emailer/smtp.go
Normal file
81
emailer/smtp.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package emailer
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
mail "github.com/xhit/go-simple-mail/v2"
|
||||
)
|
||||
|
||||
type SmtpMail struct {
|
||||
hostname string
|
||||
port int
|
||||
username string
|
||||
password string
|
||||
authType mail.AuthType
|
||||
noTLSCheck bool
|
||||
fromName string
|
||||
from string
|
||||
}
|
||||
|
||||
func authType(authType string) mail.AuthType {
|
||||
switch authType {
|
||||
case "PLAIN":
|
||||
return mail.AuthPlain
|
||||
case "LOGIN":
|
||||
return mail.AuthLogin
|
||||
default:
|
||||
return mail.AuthNone
|
||||
}
|
||||
}
|
||||
|
||||
func NewSmtpMail(hostname string, port int, username string, password string, noTLSCheck bool, auth string, fromName, from string) *SmtpMail {
|
||||
ans := SmtpMail{hostname: hostname, port: port, username: username, password: password, noTLSCheck: noTLSCheck, fromName: fromName, from: from, authType: authType(auth)}
|
||||
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.Encryption = mail.EncryptionSTARTTLS
|
||||
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("From "+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
|
||||
}
|
1
go.mod
1
go.mod
|
@ -17,6 +17,7 @@ require (
|
|||
github.com/sendgrid/rest v2.6.4+incompatible // indirect
|
||||
github.com/sendgrid/sendgrid-go v3.10.0+incompatible
|
||||
github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086
|
||||
github.com/xhit/go-simple-mail/v2 v2.10.0
|
||||
golang.zx2c4.com/wireguard v0.0.20200121 // indirect
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -147,6 +147,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
|
|||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
|
||||
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/xhit/go-simple-mail/v2 v2.10.0 h1:nib6RaJ4qVh5HD9UE9QJqnUZyWp3upv+Z6CFxaMj0V8=
|
||||
github.com/xhit/go-simple-mail/v2 v2.10.0/go.mod h1:kA1XbQfCI4JxQ9ccSN6VFyIEkkugOm7YiPkA5hKiQn4=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
|
|
|
@ -160,6 +160,12 @@ func NewClient(db store.IStore) echo.HandlerFunc {
|
|||
return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Allowed IPs must be in CIDR format"})
|
||||
}
|
||||
|
||||
// validate extra AllowedIPs
|
||||
if util.ValidateExtraAllowedIPs(client.ExtraAllowedIPs) == false {
|
||||
log.Warnf("Invalid Extra AllowedIPs input from user: %v", client.ExtraAllowedIPs)
|
||||
return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Extra AllowedIPs must be in CIDR format"})
|
||||
}
|
||||
|
||||
// gen ID
|
||||
guid := xid.New()
|
||||
client.ID = guid.String()
|
||||
|
@ -274,6 +280,11 @@ func UpdateClient(db store.IStore) echo.HandlerFunc {
|
|||
return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Allowed IPs must be in CIDR format"})
|
||||
}
|
||||
|
||||
if util.ValidateExtraAllowedIPs(_client.ExtraAllowedIPs) == false {
|
||||
log.Warnf("Invalid Allowed IPs input from user: %v", _client.ExtraAllowedIPs)
|
||||
return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Extra Allowed IPs must be in CIDR format"})
|
||||
}
|
||||
|
||||
// map new data
|
||||
client.Name = _client.Name
|
||||
client.Email = _client.Email
|
||||
|
@ -281,6 +292,7 @@ func UpdateClient(db store.IStore) echo.HandlerFunc {
|
|||
client.UseServerDNS = _client.UseServerDNS
|
||||
client.AllocatedIPs = _client.AllocatedIPs
|
||||
client.AllowedIPs = _client.AllowedIPs
|
||||
client.ExtraAllowedIPs = _client.ExtraAllowedIPs
|
||||
client.UpdatedAt = time.Now().UTC()
|
||||
|
||||
// write to the database
|
||||
|
@ -628,7 +640,7 @@ func SuggestIPAllocation(db store.IStore) echo.HandlerFunc {
|
|||
fmt.Sprintf("Cannot suggest ip allocation: failed to get available ip from network %s", cidr),
|
||||
})
|
||||
}
|
||||
if (strings.Contains(ip, ":")) {
|
||||
if strings.Contains(ip, ":") {
|
||||
suggestedIPs = append(suggestedIPs, fmt.Sprintf("%s/128", ip))
|
||||
} else {
|
||||
suggestedIPs = append(suggestedIPs, fmt.Sprintf("%s/32", ip))
|
||||
|
|
25
main.go
25
main.go
|
@ -25,6 +25,12 @@ var (
|
|||
// 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
|
||||
flagSendgridApiKey string
|
||||
flagEmailFrom string
|
||||
flagEmailFromName string = "WireGuard UI"
|
||||
|
@ -45,6 +51,12 @@ 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(&flagSmtpUsername, "smtp-username", util.LookupEnvOrString("SMTP_USERNAME", flagSmtpUsername), "SMTP Password")
|
||||
flag.StringVar(&flagSmtpPassword, "smtp-password", util.LookupEnvOrString("SMTP_PASSWORD", flagSmtpPassword), "SMTP Password")
|
||||
flag.BoolVar(&flagSmtpNoTLSCheck, "smtp-no-tls-check", util.LookupEnvOrBool("SMTP_NO_TLS_CHECK", flagSmtpNoTLSCheck), "Disable TLS verification for SMTP. This is potentially dangerous.")
|
||||
flag.StringVar(&flagSmtpAuthType, "smtp-auth-type", util.LookupEnvOrString("SMTP_AUTH_TYPE", flagSmtpAuthType), "SMTP Auth Type : Plain or None.")
|
||||
flag.StringVar(&flagSendgridApiKey, "sendgrid-api-key", util.LookupEnvOrString("SENDGRID_API_KEY", flagSendgridApiKey), "Your sendgrid api key.")
|
||||
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.")
|
||||
|
@ -54,6 +66,12 @@ func init() {
|
|||
// update runtime config
|
||||
util.DisableLogin = flagDisableLogin
|
||||
util.BindAddress = flagBindAddress
|
||||
util.SmtpHostname = flagSmtpHostname
|
||||
util.SmtpPort = flagSmtpPort
|
||||
util.SmtpUsername = flagSmtpUsername
|
||||
util.SmtpPassword = flagSmtpPassword
|
||||
util.SmtpAuthType = flagSmtpAuthType
|
||||
util.SmtpNoTLSCheck = flagSmtpNoTLSCheck
|
||||
util.SendgridApiKey = flagSendgridApiKey
|
||||
util.EmailFrom = flagEmailFrom
|
||||
util.EmailFromName = flagEmailFromName
|
||||
|
@ -103,7 +121,12 @@ func main() {
|
|||
app.POST("/login", handler.Login(db))
|
||||
}
|
||||
|
||||
sendmail := emailer.NewSendgridApiMail(util.SendgridApiKey, util.EmailFromName, util.EmailFrom)
|
||||
var sendmail emailer.Emailer
|
||||
if util.SendgridApiKey != "" {
|
||||
sendmail = emailer.NewSendgridApiMail(util.SendgridApiKey, util.EmailFromName, util.EmailFrom)
|
||||
} else {
|
||||
sendmail = emailer.NewSmtpMail(util.SmtpHostname, util.SmtpPort, util.SmtpUsername, util.SmtpPassword, util.SmtpNoTLSCheck, util.SmtpAuthType, util.EmailFromName, util.EmailFrom)
|
||||
}
|
||||
|
||||
app.GET("/_health", handler.Health())
|
||||
app.GET("/logout", handler.Logout(), handler.ValidSession)
|
||||
|
|
|
@ -6,18 +6,19 @@ import (
|
|||
|
||||
// Client model
|
||||
type Client struct {
|
||||
ID string `json:"id"`
|
||||
PrivateKey string `json:"private_key"`
|
||||
PublicKey string `json:"public_key"`
|
||||
PresharedKey string `json:"preshared_key"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
AllocatedIPs []string `json:"allocated_ips"`
|
||||
AllowedIPs []string `json:"allowed_ips"`
|
||||
UseServerDNS bool `json:"use_server_dns"`
|
||||
Enabled bool `json:"enabled"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
ID string `json:"id"`
|
||||
PrivateKey string `json:"private_key"`
|
||||
PublicKey string `json:"public_key"`
|
||||
PresharedKey string `json:"preshared_key"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
AllocatedIPs []string `json:"allocated_ips"`
|
||||
AllowedIPs []string `json:"allowed_ips"`
|
||||
ExtraAllowedIPs []string `json:"extra_allowed_ips"`
|
||||
UseServerDNS bool `json:"use_server_dns"`
|
||||
Enabled bool `json:"enabled"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ClientData includes the Client and extra data
|
||||
|
|
|
@ -163,6 +163,11 @@
|
|||
<input type="text" data-role="tagsinput" class="form-control" id="client_allowed_ips"
|
||||
value="0.0.0.0/0">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="client_extra_allowed_ips" class="control-label">Extra Allowed IPs</label>
|
||||
<input type="text" data-role="tagsinput" class="form-control"
|
||||
id="client_extra_allowed_ips">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="icheck-primary d-inline">
|
||||
<input type="checkbox" id="use_server_dns" checked>
|
||||
|
@ -293,6 +298,12 @@
|
|||
const allocated_ips = $("#client_allocated_ips").val().split(",");
|
||||
const allowed_ips = $("#client_allowed_ips").val().split(",");
|
||||
let use_server_dns = false;
|
||||
let extra_allowed_ips = [];
|
||||
|
||||
if ($("#client_extra_allowed_ips").val() !== "") {
|
||||
extra_allowed_ips = $("#client_extra_allowed_ips").val().split(",");
|
||||
}
|
||||
|
||||
|
||||
if ($("#use_server_dns").is(':checked')){
|
||||
use_server_dns = true;
|
||||
|
@ -305,7 +316,7 @@
|
|||
}
|
||||
|
||||
const data = {"name": name, "email": email, "allocated_ips": allocated_ips, "allowed_ips": allowed_ips,
|
||||
"use_server_dns": use_server_dns, "enabled": enabled};
|
||||
"extra_allowed_ips": extra_allowed_ips, "use_server_dns": use_server_dns, "enabled": enabled};
|
||||
|
||||
$.ajax({
|
||||
cache: false,
|
||||
|
@ -376,6 +387,16 @@
|
|||
'placeholderColor': '#666666'
|
||||
});
|
||||
|
||||
$("#client_extra_allowed_ips").tagsInput({
|
||||
'width': '100%',
|
||||
'height': '75%',
|
||||
'interactive': true,
|
||||
'defaultText': 'Add More',
|
||||
'removeWithBackspace': true,
|
||||
'minChars': 0,
|
||||
'placeholderColor': '#666666'
|
||||
});
|
||||
|
||||
// New client form validation
|
||||
$(document).ready(function () {
|
||||
$.validator.setDefaults({
|
||||
|
@ -414,6 +435,7 @@
|
|||
$("#client_name").val("");
|
||||
$("#client_email").val("");
|
||||
$("#client_allocated_ips").importTags('');
|
||||
$("#client_extra_allowed_ips").importTags('');
|
||||
updateIPAllocationSuggestion();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -57,6 +57,24 @@ Wireguard Clients
|
|||
</div>
|
||||
<!-- /.modal-dialog -->
|
||||
</div>
|
||||
<!-- /.modal -->
|
||||
|
||||
<div class="modal fade" id="modal_qr_client">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">QR Code</h4>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<img id="qr_code" class="w-100" style="image-rendering: pixelated;" src="" alt="QR code" />
|
||||
</div>
|
||||
<!-- /.modal-content -->
|
||||
</div>
|
||||
<!-- /.modal-dialog -->
|
||||
</div>
|
||||
<!-- /.modal -->
|
||||
|
||||
<div class="modal fade" id="modal_edit_client">
|
||||
<div class="modal-dialog">
|
||||
|
@ -86,6 +104,11 @@ Wireguard Clients
|
|||
<label for="_client_allowed_ips" class="control-label">Allowed IPs</label>
|
||||
<input type="text" data-role="tagsinput" class="form-control" id="_client_allowed_ips">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="_client_extra_allowed_ips" class="control-label">Extra Allowed IPs</label>
|
||||
<input type="text" data-role="tagsinput" class="form-control"
|
||||
id="_client_extra_allowed_ips">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="icheck-primary d-inline">
|
||||
<input type="checkbox" id="_use_server_dns">
|
||||
|
@ -275,7 +298,7 @@ Wireguard Clients
|
|||
|
||||
// Edit client modal event
|
||||
$(document).ready(function () {
|
||||
$("#modal_edit_client").on('shown.bs.modal', function (event) {
|
||||
$("#modal_edit_client").on('show.bs.modal', function (event) {
|
||||
let modal = $(this);
|
||||
const button = $(event.relatedTarget);
|
||||
const client_id = button.data('clientid');
|
||||
|
@ -302,6 +325,16 @@ Wireguard Clients
|
|||
'placeholderColor': '#666666'
|
||||
});
|
||||
|
||||
modal.find("#_client_extra_allowed_ips").tagsInput({
|
||||
'width': '100%',
|
||||
'height': '75%',
|
||||
'interactive': true,
|
||||
'defaultText': 'Add More',
|
||||
'removeWithBackspace' : true,
|
||||
'minChars': 0,
|
||||
'placeholderColor': '#666666'
|
||||
})
|
||||
|
||||
// update client modal data
|
||||
$.ajax({
|
||||
cache: false,
|
||||
|
@ -327,6 +360,11 @@ Wireguard Clients
|
|||
modal.find("#_client_allowed_ips").addTag(obj);
|
||||
});
|
||||
|
||||
modal.find("#_client_extra_allowed_ips").importTags('');
|
||||
client.extra_allowed_ips.forEach(function (obj) {
|
||||
modal.find("#_client_extra_allowed_ips").addTag(obj);
|
||||
});
|
||||
|
||||
modal.find("#_use_server_dns").prop("checked", client.use_server_dns);
|
||||
modal.find("#_enabled").prop("checked", client.enabled);
|
||||
},
|
||||
|
@ -371,6 +409,11 @@ Wireguard Clients
|
|||
const allocated_ips = $("#_client_allocated_ips").val().split(",");
|
||||
const allowed_ips = $("#_client_allowed_ips").val().split(",");
|
||||
let use_server_dns = false;
|
||||
let extra_allowed_ips = [];
|
||||
|
||||
if( $("#_client_extra_allowed_ips").val() !== "" ) {
|
||||
extra_allowed_ips = $("#_client_extra_allowed_ips").val().split(",");
|
||||
}
|
||||
|
||||
if ($("#_use_server_dns").is(':checked')){
|
||||
use_server_dns = true;
|
||||
|
@ -383,7 +426,7 @@ Wireguard Clients
|
|||
}
|
||||
|
||||
const data = {"id": client_id, "name": name, "email": email, "allocated_ips": allocated_ips,
|
||||
"allowed_ips": allowed_ips, "use_server_dns": use_server_dns, "enabled": enabled};
|
||||
"allowed_ips": allowed_ips, "extra_allowed_ips": extra_allowed_ips, "use_server_dns": use_server_dns, "enabled": enabled};
|
||||
|
||||
$.ajax({
|
||||
cache: false,
|
||||
|
@ -415,7 +458,7 @@ Wireguard Clients
|
|||
}
|
||||
}
|
||||
|
||||
$("#modal_email_client").on('shown.bs.modal', function (event) {
|
||||
$("#modal_email_client").on('show.bs.modal', function (event) {
|
||||
let modal = $(this);
|
||||
const button = $(event.relatedTarget);
|
||||
const client_id = button.data('clientid');
|
||||
|
@ -439,6 +482,31 @@ Wireguard Clients
|
|||
});
|
||||
});
|
||||
|
||||
$("#modal_qr_client").on('show.bs.modal', function (event) {
|
||||
let modal = $(this);
|
||||
const button = $(event.relatedTarget);
|
||||
const client_id = button.data('clientid');
|
||||
const QRCodeImg = modal.find("#qr_code");
|
||||
QRCodeImg.hide();
|
||||
$.ajax({
|
||||
cache: false,
|
||||
method: 'GET',
|
||||
url: '/api/client/' + client_id,
|
||||
dataType: 'json',
|
||||
contentType: "application/json",
|
||||
success: function (resp) {
|
||||
const client = resp.Client;
|
||||
|
||||
modal.find(".modal-title").text("QR Code for " + client.name);
|
||||
QRCodeImg.attr('src', resp.QRCode).show();
|
||||
},
|
||||
error: function (jqXHR, exception) {
|
||||
const responseJson = jQuery.parseJSON(jqXHR.responseText);
|
||||
toastr.error(responseJson['message']);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).ready(function () {
|
||||
$.validator.setDefaults({
|
||||
submitHandler: function (form) {
|
||||
|
|
|
@ -20,5 +20,5 @@ PostDown = {{ .serverConfig.Interface.PostDown }}
|
|||
[Peer]
|
||||
PublicKey = {{ .Client.PublicKey }}
|
||||
{{if .Client.PresharedKey }}PresharedKey = {{ .Client.PresharedKey }}
|
||||
{{end}}AllowedIPs = {{$first :=true}}{{range .Client.AllocatedIPs }}{{if $first}}{{$first = false}}{{else}},{{end}}{{.}}{{end}}
|
||||
{{end}}AllowedIPs = {{$first :=true}}{{range .Client.AllocatedIPs }}{{if $first}}{{$first = false}}{{else}},{{end}}{{.}}{{end}}{{range .Client.ExtraAllowedIPs }},{{.}}{{end}}
|
||||
{{end}}{{end}}
|
||||
|
|
|
@ -4,6 +4,12 @@ package util
|
|||
var (
|
||||
DisableLogin bool
|
||||
BindAddress string
|
||||
SmtpHostname string
|
||||
SmtpPort int
|
||||
SmtpUsername string
|
||||
SmtpPassword string
|
||||
SmtpNoTLSCheck bool
|
||||
SmtpAuthType string
|
||||
SendgridApiKey string
|
||||
EmailFrom string
|
||||
EmailFromName string
|
||||
|
|
26
util/util.go
26
util/util.go
|
@ -80,10 +80,18 @@ func ValidateCIDR(cidr string) bool {
|
|||
}
|
||||
|
||||
// ValidateCIDRList to validate a list of network CIDR
|
||||
func ValidateCIDRList(cidrs []string) bool {
|
||||
func ValidateCIDRList(cidrs []string, allowEmpty bool) bool {
|
||||
for _, cidr := range cidrs {
|
||||
if ValidateCIDR(cidr) == false {
|
||||
return false
|
||||
if allowEmpty {
|
||||
if len(cidr) > 0 {
|
||||
if ValidateCIDR(cidr) == false {
|
||||
return false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ValidateCIDR(cidr) == false {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
@ -91,7 +99,15 @@ func ValidateCIDRList(cidrs []string) bool {
|
|||
|
||||
// ValidateAllowedIPs to validate allowed ip addresses in CIDR format
|
||||
func ValidateAllowedIPs(cidrs []string) bool {
|
||||
if ValidateCIDRList(cidrs) == false {
|
||||
if ValidateCIDRList(cidrs, false) == false {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ValidateExtraAllowedIPs to validate extra Allowed ip addresses, allowing empty strings
|
||||
func ValidateExtraAllowedIPs(cidrs []string) bool {
|
||||
if ValidateCIDRList(cidrs, true) == false {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
@ -99,7 +115,7 @@ func ValidateAllowedIPs(cidrs []string) bool {
|
|||
|
||||
// ValidateServerAddresses to validate allowed ip addresses in CIDR format
|
||||
func ValidateServerAddresses(cidrs []string) bool {
|
||||
if ValidateCIDRList(cidrs) == false {
|
||||
if ValidateCIDRList(cidrs, false) == false {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue