• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DigitalTolk / wireguard-ui / 24835132478

23 Apr 2026 12:26PM UTC coverage: 82.607% (+1.5%) from 81.067%
24835132478

Pull #11

github

web-flow
Merge 68b85fd12 into 74711d7b9
Pull Request #11: Fixes

437 of 554 branches covered (78.88%)

Branch coverage included in aggregate %.

431 of 547 new or added lines in 19 files covered. (78.79%)

8 existing lines in 1 file now uncovered.

2878 of 3459 relevant lines covered (83.2%)

13.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.27
/handler/api_v1_server.go
1
package handler
2

3
import (
4
        "net/http"
5
        "strings"
6
        "time"
7

8
        "github.com/labstack/echo/v4"
9
        "github.com/labstack/gommon/log"
10
        "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
11

12
        "github.com/DigitalTolk/wireguard-ui/model"
13
        "github.com/DigitalTolk/wireguard-ui/store"
14
        "github.com/DigitalTolk/wireguard-ui/util"
15
)
16

17
// APIGetServer returns server config (interface + keypair)
18
func APIGetServer(db store.IStore) echo.HandlerFunc {
1✔
19
        return func(c echo.Context) error {
2✔
20
                server, err := db.GetServer()
1✔
21
                if err != nil {
1✔
22
                        return apiInternalError(c, "Cannot get server config")
×
23
                }
×
24
                return c.JSON(http.StatusOK, server)
1✔
25
        }
26
}
27

28
// APIUpdateServerInterface updates server interface settings
29
func APIUpdateServerInterface(db store.IStore) echo.HandlerFunc {
4✔
30
        return func(c echo.Context) error {
8✔
31
                var serverInterface model.ServerInterface
4✔
32
                if err := c.Bind(&serverInterface); err != nil {
5✔
33
                        return apiBadRequest(c, "Invalid request body")
1✔
34
                }
1✔
35

36
                if !util.ValidateServerAddresses(serverInterface.Addresses) {
4✔
37
                        return apiBadRequest(c, "Interface IP address must be in CIDR format")
1✔
38
                }
1✔
39

40
                if serverInterface.ListenPort < 1 || serverInterface.ListenPort > 65535 {
2✔
NEW
41
                        return apiBadRequest(c, "Listen port must be between 1 and 65535")
×
NEW
42
                }
×
43

44
                // capture before state
45
                oldServer, _ := db.GetServer()
2✔
46

2✔
47
                serverInterface.UpdatedAt = time.Now().UTC()
2✔
48

2✔
49
                if err := db.SaveServerInterface(serverInterface); err != nil {
2✔
50
                        return apiInternalError(c, "Cannot save server interface")
×
51
                }
×
52

53
                log.Infof("Updated server interfaces: %v", serverInterface)
2✔
54
                auditLogEvent(c, "server.interface.update", "server", "interface", map[string]interface{}{
2✔
55
                        "before": oldServer.Interface,
2✔
56
                        "after":  serverInterface,
2✔
57
                })
2✔
58
                return c.JSON(http.StatusOK, serverInterface)
2✔
59
        }
60
}
61

62
// APIRegenerateServerKeypair generates a new server keypair
63
func APIRegenerateServerKeypair(db store.IStore) echo.HandlerFunc {
1✔
64
        return func(c echo.Context) error {
2✔
65
                key, err := wgtypes.GeneratePrivateKey()
1✔
66
                if err != nil {
1✔
67
                        return apiInternalError(c, "Cannot generate WireGuard key pair")
×
68
                }
×
69

70
                kp := model.ServerKeypair{
1✔
71
                        PrivateKey: key.String(),
1✔
72
                        PublicKey:  key.PublicKey().String(),
1✔
73
                        UpdatedAt:  time.Now().UTC(),
1✔
74
                }
1✔
75

1✔
76
                if err := db.SaveServerKeyPair(kp); err != nil {
1✔
77
                        return apiInternalError(c, "Cannot save server keypair")
×
78
                }
×
79

80
                log.Infof("Regenerated server keypair")
1✔
81
                auditLogEvent(c, "server.keypair.regenerate", "server", "keypair", nil)
1✔
82
                return c.JSON(http.StatusOK, kp)
1✔
83
        }
84
}
85

86
// APIGetSettings returns global settings
87
func APIGetSettings(db store.IStore) echo.HandlerFunc {
1✔
88
        return func(c echo.Context) error {
2✔
89
                settings, err := db.GetGlobalSettings()
1✔
90
                if err != nil {
1✔
91
                        return apiInternalError(c, "Cannot get global settings")
×
92
                }
×
93
                return c.JSON(http.StatusOK, settings)
1✔
94
        }
95
}
96

97
// APIUpdateSettings updates global settings
98
func APIUpdateSettings(db store.IStore) echo.HandlerFunc {
4✔
99
        return func(c echo.Context) error {
8✔
100
                var settings model.GlobalSetting
4✔
101
                if err := c.Bind(&settings); err != nil {
5✔
102
                        return apiBadRequest(c, "Invalid request body")
1✔
103
                }
1✔
104

105
                if !util.ValidateIPAddressList(settings.DNSServers) {
4✔
106
                        return apiBadRequest(c, "Invalid DNS server address")
1✔
107
                }
1✔
108

109
                if settings.MTU != 0 && (settings.MTU < 1280 || settings.MTU > 9000) {
2✔
NEW
110
                        return apiBadRequest(c, "MTU must be 0 (to omit) or between 1280 and 9000")
×
NEW
111
                }
×
112

113
                if settings.PersistentKeepalive < 0 || settings.PersistentKeepalive > 65535 {
2✔
NEW
114
                        return apiBadRequest(c, "Persistent keepalive must be between 0 and 65535")
×
NEW
115
                }
×
116

117
                if settings.ConfigFilePath != "" && !strings.HasPrefix(settings.ConfigFilePath, "/") {
2✔
NEW
118
                        return apiBadRequest(c, "Config file path must be an absolute path starting with /")
×
NEW
119
                }
×
120

121
                // capture before state
122
                oldSettings, _ := db.GetGlobalSettings()
2✔
123

2✔
124
                settings.UpdatedAt = time.Now().UTC()
2✔
125

2✔
126
                if err := db.SaveGlobalSettings(settings); err != nil {
2✔
127
                        return apiInternalError(c, "Cannot save global settings")
×
128
                }
×
129

130
                log.Infof("Updated global settings")
2✔
131
                auditLogEvent(c, "settings.update", "settings", "global", map[string]interface{}{
2✔
132
                        "before": oldSettings,
2✔
133
                        "after":  settings,
2✔
134
                })
2✔
135
                return c.JSON(http.StatusOK, settings)
2✔
136
        }
137
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc