mirror of
https://github.com/ngoduykhanh/wireguard-ui.git
synced 2025-04-27 21:09:43 +03:00
Compare commits
7 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2fdafd34ca | ||
![]() |
92f5b5c8b1 | ||
![]() |
8f3433b714 | ||
![]() |
7856ce9555 | ||
![]() |
84032d1e06 | ||
![]() |
ecea82d172 | ||
![]() |
73108f7f21 |
11 changed files with 60 additions and 16 deletions
|
@ -71,6 +71,7 @@ RUN mkdir -p db
|
|||
COPY --from=builder --chown=wgui:wgui /build/wg-ui .
|
||||
RUN chmod +x wg-ui
|
||||
COPY init.sh .
|
||||
RUN chmod +x init.sh
|
||||
|
||||
EXPOSE 5000/tcp
|
||||
ENTRYPOINT ["./init.sh"]
|
||||
|
|
|
@ -38,13 +38,18 @@ function renderClientList(data) {
|
|||
subnetRangesString = obj.Client.subnet_ranges.join(',')
|
||||
}
|
||||
|
||||
let additionalNotesHtml = "";
|
||||
if (obj.Client.additional_notes && obj.Client.additional_notes.length > 0) {
|
||||
additionalNotesHtml = `<span class="info-box-text" style="display: none"><i class="fas fa-additional_notes"></i>${obj.Client.additional_notes.toUpperCase()}</span>`
|
||||
}
|
||||
|
||||
// render client html content
|
||||
let html = `<div class="col-sm-6 col-md-6 col-lg-4" id="client_${obj.Client.id}">
|
||||
<div class="info-box">
|
||||
<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>
|
||||
<div class="info-box-content">
|
||||
<div class="info-box-content" style="overflow: hidden">
|
||||
<div class="btn-group">
|
||||
<a href="download?clientid=${obj.Client.id}" class="btn btn-outline-primary btn-sm">Download</a>
|
||||
</div>
|
||||
|
@ -81,6 +86,7 @@ function renderClientList(data) {
|
|||
<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}
|
||||
${additionalNotesHtml}
|
||||
<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>
|
||||
|
@ -88,6 +94,8 @@ function renderClientList(data) {
|
|||
${prettyDateTime(obj.Client.updated_at)}</span>
|
||||
<span class="info-box-text"><i class="fas fa-server" style="${obj.Client.use_server_dns ? "opacity: 1.0" : "opacity: 0.5"}"></i>
|
||||
${obj.Client.use_server_dns ? 'DNS enabled' : 'DNS disabled'}</span>
|
||||
<span class="info-box-text"><i class="fas fa-file"></i>
|
||||
${obj.Client.additional_notes}</span>
|
||||
<span class="info-box-text"><strong>IP Allocation</strong></span>`
|
||||
+ allocatedIpsHtml
|
||||
+ `<span class="info-box-text"><strong>Allowed IPs</strong></span>`
|
||||
|
|
2
go.mod
2
go.mod
|
@ -47,6 +47,6 @@ require (
|
|||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20210427022245-097af6e1351b // indirect
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
||||
)
|
||||
|
|
5
go.sum
5
go.sum
|
@ -174,13 +174,10 @@ golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
|||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20210427022245-097af6e1351b h1:XDLXhn7ryprJVo+Lpkiib6CIuXE2031GDwtfEm7vLjI=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20210427022245-097af6e1351b/go.mod h1:a057zjmoc00UN7gVkaJt2sXVK523kMJcogDTEvPIasg=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c h1:ADNrRDI5NR23/TUCnEmlLZLt4u9DnZ2nwRkPrAcFvto=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c/go.mod h1:+1XihzyZUBJcSc5WO9SwNA7v26puQwOEDwanaxfNXPQ=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
|
|
|
@ -720,6 +720,7 @@ func UpdateClient(db store.IStore) echo.HandlerFunc {
|
|||
client.PublicKey = _client.PublicKey
|
||||
client.PresharedKey = _client.PresharedKey
|
||||
client.UpdatedAt = time.Now().UTC()
|
||||
client.AdditionalNotes = strings.ReplaceAll(strings.Trim(_client.AdditionalNotes, "\r\n"), "\r\n", "\n")
|
||||
|
||||
// write to the database
|
||||
if err := db.SaveClient(client); err != nil {
|
||||
|
@ -978,10 +979,13 @@ func Status(db store.IStore) echo.HandlerFunc {
|
|||
LastHandshakeTime: devices[i].Peers[j].LastHandshakeTime,
|
||||
LastHandshakeRel: time.Since(devices[i].Peers[j].LastHandshakeTime),
|
||||
AllocatedIP: allocatedIPs,
|
||||
Endpoint: devices[i].Peers[j].Endpoint.String(),
|
||||
}
|
||||
pVm.Connected = pVm.LastHandshakeRel.Minutes() < 3.
|
||||
|
||||
if isAdmin(c) {
|
||||
pVm.Endpoint = devices[i].Peers[j].Endpoint.String()
|
||||
}
|
||||
|
||||
if _client, ok := m[pVm.PublicKey]; ok {
|
||||
pVm.Name = _client.Name
|
||||
pVm.Email = _client.Email
|
||||
|
|
|
@ -18,6 +18,7 @@ type Client struct {
|
|||
AllowedIPs []string `json:"allowed_ips"`
|
||||
ExtraAllowedIPs []string `json:"extra_allowed_ips"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
AdditionalNotes string `json:"additional_notes"`
|
||||
UseServerDNS bool `json:"use_server_dns"`
|
||||
Enabled bool `json:"enabled"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
|
|
|
@ -154,6 +154,7 @@ func (o *JsonDB) Init() error {
|
|||
}
|
||||
|
||||
o.conn.Write("users", user.Username, user)
|
||||
results, _ = o.conn.ReadAll("users")
|
||||
err = util.ManagePerms(path.Join(path.Join(o.dbPath, "users"), user.Username+".json"))
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -288,6 +288,10 @@
|
|||
<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>
|
||||
<div class="form-group">
|
||||
<label for="additional_notes" class="control-label">Notes</label>
|
||||
<textarea class="form-control" style="min-height: 6rem;" id="additional_notes" name="additional_notes" placeholder="Additional notes about this client"></textarea>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
<div class="modal-footer justify-content-between">
|
||||
|
@ -396,8 +400,6 @@
|
|||
toastr.options.positionClass = 'toast-top-right-fix';
|
||||
|
||||
updateApplyConfigVisibility()
|
||||
// from clients.html
|
||||
updateSearchList()
|
||||
|
||||
});
|
||||
|
||||
|
@ -435,7 +437,6 @@
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// populateClient function for render new client info
|
||||
// on the client page.
|
||||
|
@ -483,10 +484,12 @@
|
|||
}
|
||||
const public_key = $("#client_public_key").val();
|
||||
const preshared_key = $("#client_preshared_key").val();
|
||||
|
||||
const additional_notes = $("#additional_notes").val();
|
||||
|
||||
const data = {"name": name, "email": email, "telegram_userid": telegram_userid, "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};
|
||||
"public_key": public_key, "preshared_key": preshared_key, "additional_notes": additional_notes};
|
||||
|
||||
$.ajax({
|
||||
cache: false,
|
||||
|
@ -627,6 +630,7 @@
|
|||
$("#client_extra_allowed_ips").importTags('');
|
||||
$("#client_endpoint").val('');
|
||||
$("#client_telegram_userid").val('');
|
||||
$("#additional_notes").val('');
|
||||
updateSubnetRangesList("#subnet_ranges");
|
||||
updateIPAllocationSuggestion(true);
|
||||
});
|
||||
|
|
|
@ -195,6 +195,10 @@ Wireguard Clients
|
|||
<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>
|
||||
<div class="form-group">
|
||||
<label for="_additional_notes" class="control-label">Notes</label>
|
||||
<textarea class="form-control" style="min-height: 6rem;" id="_additional_notes" name="_additional_notes" placeholder="Additional notes about this client"></textarea>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
<div class="modal-footer justify-content-between">
|
||||
|
@ -391,11 +395,12 @@ Wireguard Clients
|
|||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
// load client list
|
||||
$(document).ready(function () {
|
||||
updateSearchList();
|
||||
populateClientList();
|
||||
})
|
||||
|
||||
|
@ -411,7 +416,7 @@ Wireguard Clients
|
|||
// hide all clients and display only the ones that meet the search criteria (name, email, IP)
|
||||
$('#search-input').keyup(function () {
|
||||
$("#status-selector").val("All");
|
||||
var query = $(this).val();
|
||||
let query = $(this).val().trim();
|
||||
$('.col-lg-4').hide();
|
||||
$(".info-box-text").each(function() {
|
||||
if($(this).children('i.fa-user').length > 0 || $(this).children('i.fa-envelope').length > 0)
|
||||
|
@ -421,7 +426,13 @@ Wireguard Clients
|
|||
})
|
||||
$(".badge-secondary").filter(':contains("' + query + '")').parent().parent().parent().show();
|
||||
$(".fa-tguserid").each(function () {
|
||||
if ($(this).parent().text().trim().indexOf(query.trim()) != -1) {
|
||||
if ($(this).parent().text().trim().indexOf(query) != -1) {
|
||||
$(this).closest('.col-lg-4').show();
|
||||
}
|
||||
})
|
||||
let upperQuery = query.toUpperCase()
|
||||
$(".fa-additional_notes").each(function () {
|
||||
if ($(this).parent().text().trim().indexOf(upperQuery) != -1) {
|
||||
$(this).closest('.col-lg-4').show();
|
||||
}
|
||||
})
|
||||
|
@ -648,6 +659,8 @@ Wireguard Clients
|
|||
|
||||
modal.find("#_client_public_key").val(client.public_key);
|
||||
modal.find("#_client_preshared_key").val(client.preshared_key);
|
||||
|
||||
modal.find("#_additional_notes").val(client.additional_notes);
|
||||
|
||||
// handle subnet range select
|
||||
$('#_subnet_ranges').on('select2:select', function (e) {
|
||||
|
@ -769,9 +782,11 @@ Wireguard Clients
|
|||
enabled = true;
|
||||
}
|
||||
|
||||
const additional_notes = $("#_additional_notes").val();
|
||||
|
||||
const data = {"id": client_id, "name": name, "email": email, "telegram_userid": telegram_userid, "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};
|
||||
"use_server_dns": use_server_dns, "enabled": enabled, "public_key": public_key, "preshared_key": preshared_key, "additional_notes": additional_notes};
|
||||
|
||||
$.ajax({
|
||||
cache: false,
|
||||
|
|
|
@ -20,6 +20,10 @@ Table = {{ .globalSettings.Table }}
|
|||
# Telegram: {{ .Client.TgUserid }}
|
||||
# Created at: {{ .Client.CreatedAt }}
|
||||
# Update at: {{ .Client.UpdatedAt }}
|
||||
{{- if .Client.AdditionalNotes}}
|
||||
|
||||
# Notes:
|
||||
# {{ .Client.AdditionalNotes }}{{end}}
|
||||
[Peer]
|
||||
PublicKey = {{ .Client.PublicKey }}
|
||||
{{if .Client.PresharedKey}}PresharedKey = {{ .Client.PresharedKey }}{{end}}
|
||||
|
|
11
util/util.go
11
util/util.go
|
@ -560,6 +560,15 @@ func WriteWireGuardServerConfig(tmplDir fs.FS, serverConfig model.Server, client
|
|||
tmplWireguardConf = fileContent
|
||||
}
|
||||
|
||||
// escape multiline notes
|
||||
escapedClientDataList := []model.ClientData{}
|
||||
for _, cd := range clientDataList {
|
||||
if cd.Client.AdditionalNotes != "" {
|
||||
cd.Client.AdditionalNotes = strings.ReplaceAll(cd.Client.AdditionalNotes, "\n", "\n# ")
|
||||
}
|
||||
escapedClientDataList = append(escapedClientDataList, cd)
|
||||
}
|
||||
|
||||
// parse the template
|
||||
t, err := template.New("wg_config").Parse(tmplWireguardConf)
|
||||
if err != nil {
|
||||
|
@ -574,7 +583,7 @@ func WriteWireGuardServerConfig(tmplDir fs.FS, serverConfig model.Server, client
|
|||
|
||||
config := map[string]interface{}{
|
||||
"serverConfig": serverConfig,
|
||||
"clientDataList": clientDataList,
|
||||
"clientDataList": escapedClientDataList,
|
||||
"globalSettings": globalSettings,
|
||||
"usersList": usersList,
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue