Merge remote-tracking branch 'origin/master' into clients-patch

This commit is contained in:
kevin 2022-12-04 21:05:33 +08:00
commit 4608ced961
10 changed files with 98 additions and 38 deletions

View file

@ -7,7 +7,7 @@ on:
jobs: jobs:
releases-matrix: releases-matrix:
name: Release Go Binary name: Release Go Binary
runs-on: ubuntu-latest runs-on: ubuntu-20.04
strategy: strategy:
matrix: matrix:
# build and publish in parallel: linux/386, linux/amd64, darwin/386, darwin/amd64 # build and publish in parallel: linux/386, linux/amd64, darwin/386, darwin/amd64

View file

@ -97,6 +97,7 @@ SMTP_PORT: the SMTP port
SMTP_USERNAME: the SMTP username to authenticate SMTP_USERNAME: the SMTP username to authenticate
SMTP_PASSWORD: the SMTP user password SMTP_PASSWORD: the SMTP user password
SMTP_AUTH_TYPE: the authentication type. Possible values: PLAIN, LOGIN, NONE SMTP_AUTH_TYPE: the authentication type. Possible values: PLAIN, LOGIN, NONE
SMTP_ENCRYPTION: the encryption method. Possible values: SSL, SSLTLS, TLS or STARTTLS (default)
EMAIL_FROM_ADDRESS: the sender's email address EMAIL_FROM_ADDRESS: the sender's email address
EMAIL_FROM_NAME: the sender's name EMAIL_FROM_NAME: the sender's name
``` ```

View file

@ -138,7 +138,15 @@ func GetClient(db store.IStore) echo.HandlerFunc {
return func(c echo.Context) error { return func(c echo.Context) error {
clientID := c.Param("id") clientID := c.Param("id")
clientData, err := db.GetClientByID(clientID, true) qrCodeIncludeFwMark := c.QueryParam("qrCodeIncludeFwMark")
qrCodeSettings := model.QRCodeSettings{
Enabled: true,
IncludeDNS: true,
IncludeFwMark: qrCodeIncludeFwMark == "true",
IncludeMTU: true,
}
clientData, err := db.GetClientByID(clientID, qrCodeSettings)
if err != nil { if err != nil {
return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Client not found"}) return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Client not found"})
} }
@ -257,7 +265,13 @@ func EmailClient(db store.IStore, mailer emailer.Emailer, emailSubject, emailCon
c.Bind(&payload) c.Bind(&payload)
// TODO validate email // TODO validate email
clientData, err := db.GetClientByID(payload.ID, true) qrCodeSettings := model.QRCodeSettings{
Enabled: true,
IncludeDNS: true,
IncludeFwMark: true,
IncludeMTU: true,
}
clientData, err := db.GetClientByID(payload.ID, qrCodeSettings)
if err != nil { if err != nil {
log.Errorf("Cannot generate client id %s config file for downloading: %v", payload.ID, err) 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"}) return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Client not found"})
@ -304,7 +318,7 @@ func UpdateClient(db store.IStore) echo.HandlerFunc {
c.Bind(&_client) c.Bind(&_client)
// validate client existence // validate client existence
clientData, err := db.GetClientByID(_client.ID, false) clientData, err := db.GetClientByID(_client.ID, model.QRCodeSettings{Enabled: false})
if err != nil { if err != nil {
return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Client not found"}) return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Client not found"})
} }
@ -370,7 +384,7 @@ func SetClientStatus(db store.IStore) echo.HandlerFunc {
clientID := data["id"].(string) clientID := data["id"].(string)
status := data["status"].(bool) status := data["status"].(bool)
clientdata, err := db.GetClientByID(clientID, false) clientdata, err := db.GetClientByID(clientID, model.QRCodeSettings{Enabled: false})
if err != nil { if err != nil {
return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, err.Error()}) return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, err.Error()})
} }
@ -395,7 +409,7 @@ func DownloadClient(db store.IStore) echo.HandlerFunc {
return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Missing clientid parameter"}) return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Missing clientid parameter"})
} }
clientData, err := db.GetClientByID(clientID, false) clientData, err := db.GetClientByID(clientID, model.QRCodeSettings{Enabled: false})
if err != nil { if err != nil {
log.Errorf("Cannot generate client id %s config file for downloading: %v", clientID, err) log.Errorf("Cannot generate client id %s config file for downloading: %v", clientID, err)
return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Client not found"}) return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Client not found"})

View file

@ -28,3 +28,10 @@ type ClientData struct {
Client *Client Client *Client
QRCode string QRCode string
} }
type QRCodeSettings struct {
Enabled bool
IncludeDNS bool
IncludeFwMark bool
IncludeMTU bool
}

View file

@ -81,14 +81,18 @@ func (o *JsonDB) Init() error {
// global settings // global settings
if _, err := os.Stat(globalSettingPath); os.IsNotExist(err) { if _, err := os.Stat(globalSettingPath); os.IsNotExist(err) {
endpointAddress := util.LookupEnvOrString(util.EndpointAddressEnvVar, "")
if endpointAddress == "" {
// automatically find an external IP address
publicInterface, err := util.GetPublicIP() publicInterface, err := util.GetPublicIP()
if err != nil { if err != nil {
return err return err
} }
endpointAddress = publicInterface.IPAddress
}
globalSetting := new(model.GlobalSetting) globalSetting := new(model.GlobalSetting)
globalSetting.EndpointAddress = util.LookupEnvOrString(util.EndpointAddressEnvVar, publicInterface.IPAddress) globalSetting.EndpointAddress = endpointAddress
globalSetting.DNSServers = util.LookupEnvOrStrings(util.DNSEnvVar, []string{util.DefaultDNS}) globalSetting.DNSServers = util.LookupEnvOrStrings(util.DNSEnvVar, []string{util.DefaultDNS})
globalSetting.MTU = util.LookupEnvOrInt(util.MTUEnvVar, util.DefaultMTU) globalSetting.MTU = util.LookupEnvOrInt(util.MTUEnvVar, util.DefaultMTU)
globalSetting.PersistentKeepalive = util.LookupEnvOrInt(util.PersistentKeepaliveEnvVar, util.DefaultPersistentKeepalive) globalSetting.PersistentKeepalive = util.LookupEnvOrInt(util.PersistentKeepaliveEnvVar, util.DefaultPersistentKeepalive)
@ -190,7 +194,7 @@ func (o *JsonDB) GetClients(hasQRCode bool) ([]model.ClientData, error) {
return clients, nil return clients, nil
} }
func (o *JsonDB) GetClientByID(clientID string, hasQRCode bool) (model.ClientData, error) { func (o *JsonDB) GetClientByID(clientID string, qrCodeSettings model.QRCodeSettings) (model.ClientData, error) {
client := model.Client{} client := model.Client{}
clientData := model.ClientData{} clientData := model.ClientData{}
@ -200,9 +204,17 @@ func (o *JsonDB) GetClientByID(clientID string, hasQRCode bool) (model.ClientDat
} }
// generate client qrcode image in base64 // generate client qrcode image in base64
if hasQRCode && client.PrivateKey != "" { if qrCodeSettings.Enabled && client.PrivateKey != "" {
server, _ := o.GetServer() server, _ := o.GetServer()
globalSettings, _ := o.GetGlobalSettings() globalSettings, _ := o.GetGlobalSettings()
client := client
client.UseServerDNS = qrCodeSettings.IncludeDNS
if !qrCodeSettings.IncludeMTU {
globalSettings.MTU = 0
}
if !qrCodeSettings.IncludeFwMark {
globalSettings.ForwardMark = ""
}
png, err := qrcode.Encode(util.BuildClientConfig(client, server, globalSettings), qrcode.Medium, 256) png, err := qrcode.Encode(util.BuildClientConfig(client, server, globalSettings), qrcode.Medium, 256)
if err == nil { if err == nil {

View file

@ -10,7 +10,7 @@ type IStore interface {
GetGlobalSettings() (model.GlobalSetting, error) GetGlobalSettings() (model.GlobalSetting, error)
GetServer() (model.Server, error) GetServer() (model.Server, error)
GetClients(hasQRCode bool) ([]model.ClientData, error) GetClients(hasQRCode bool) ([]model.ClientData, error)
GetClientByID(clientID string, hasQRCode bool) (model.ClientData, error) GetClientByID(clientID string, qrCode model.QRCodeSettings) (model.ClientData, error)
SaveClient(client model.Client) error SaveClient(client model.Client) error
DeleteClient(clientID string) error DeleteClient(clientID string) error
SaveServerInterface(serverInterface model.ServerInterface) error SaveServerInterface(serverInterface model.ServerInterface) error

View file

@ -386,7 +386,7 @@
$("#modal_new_client").modal('hide'); $("#modal_new_client").modal('hide');
toastr.success('Created new client successfully'); toastr.success('Created new client successfully');
// Update the home page (clients page) after adding successfully // Update the home page (clients page) after adding successfully
if (window.location.pathname === "/") { if (window.location.pathname === "{{.basePath}}/") {
populateClient(resp.id); populateClient(resp.id);
} }
}, },

View file

@ -68,7 +68,18 @@ Wireguard Clients
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
</div> </div>
<div class="modal-body">
<input type="hidden" id="qr_client_id" name="qr_client_id">
<img id="qr_code" class="w-100" style="image-rendering: pixelated;" src="" alt="QR code" /> <img id="qr_code" class="w-100" style="image-rendering: pixelated;" src="" alt="QR code" />
<div class="form-group">
<div class="icheck-primary d-inline">
<input type="checkbox" id="qr_include_fwmark" onchange="regenerateQRCode()">
<label for="qr_include_fwmark">
Include FwMark
</label>
</div>
</div>
</div>
</div> </div>
<!-- /.modal-content --> <!-- /.modal-content -->
</div> </div>
@ -387,6 +398,37 @@ Wireguard Clients
}); });
}); });
// regenerateQRCode function for regenerating QR Code adding/removing some parts of configuration because of compatibility issues with some clients
function regenerateQRCode() {
const client_id = $("#qr_client_id").val();
const QRCodeImg = $("#qr_code");
let include_fwmark = false;
if ($("#qr_include_fwmark").is(':checked')){
include_fwmark = true;
}
QRCodeImg.hide();
$.ajax({
cache: false,
method: 'GET',
url: '{{.basePath}}/api/client/' + client_id,
data: {
qrCodeIncludeFwMark: include_fwmark
},
dataType: 'json',
contentType: "application/json",
success: function (resp) {
const client = resp.Client;
$(".modal-title").text("Scan QR Code for " + client.name + " profile");
QRCodeImg.attr('src', resp.QRCode).show();
},
error: function (jqXHR, exception) {
const responseJson = jQuery.parseJSON(jqXHR.responseText);
toastr.error(responseJson['message']);
}
});
}
// submitEmailClient function for sending an email to the client with the configuration // submitEmailClient function for sending an email to the client with the configuration
function submitEmailClient() { function submitEmailClient() {
const client_id = $("#e_client_id").val(); const client_id = $("#e_client_id").val();
@ -500,31 +542,14 @@ Wireguard Clients
let modal = $(this); let modal = $(this);
const button = $(event.relatedTarget); const button = $(event.relatedTarget);
const client_id = button.data('clientid'); const client_id = button.data('clientid');
const QRCodeImg = modal.find("#qr_code");
QRCodeImg.hide();
$.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("Scan QR Code for " + client.name + " profile"); modal.find("#qr_client_id").val(client_id);
QRCodeImg.attr('src', resp.QRCode).show(); regenerateQRCode();
},
error: function (jqXHR, exception) {
const responseJson = jQuery.parseJSON(jqXHR.responseText);
toastr.error(responseJson['message']);
}
});
}); });
$(document).ready(function () { $(document).ready(function () {
$.validator.setDefaults({ $.validator.setDefaults({
submitHandler: function (form) { submitHandler: function (form) {
//submitEditClient();
submitHandler(form); submitHandler(form);
} }
}); });
@ -577,6 +602,7 @@ Wireguard Clients
$(element).removeClass('is-invalid'); $(element).removeClass('is-invalid');
} }
}); });
//
}); });
</script> </script>
{{end}} {{end}}

View file

@ -172,7 +172,7 @@ Global Settings
} }
function updateEndpointSuggestionIP() { function updateEndpointSuggestionIP() {
$.getJSON("/api/machine-ips", null, function(data) { $.getJSON("{{.basePath}}/api/machine-ips", null, function(data) {
$("#ip_suggestion option").remove(); $("#ip_suggestion option").remove();
$.each(data, function(index, item) { $.each(data, function(index, item) {
$("#ip_suggestion").append( $("#ip_suggestion").append(

View file

@ -70,7 +70,7 @@ func BuildClientConfig(client model.Client, server model.Server, setting model.G
} }
forwardMark := "" forwardMark := ""
if setting.ForwardMark != "" && setting.ForwardMark != DefaultForwardMark { if setting.ForwardMark != "" {
forwardMark = fmt.Sprintf("FwMark = %s\n", setting.ForwardMark) forwardMark = fmt.Sprintf("FwMark = %s\n", setting.ForwardMark)
} }