Rename term "device" => "client". Add some WIP ui components

This commit is contained in:
Daniel Lundin
2019-07-20 12:26:34 +02:00
parent fea8aad061
commit 49203fb2ea
17 changed files with 244 additions and 119 deletions
+6 -6
View File
@@ -19,10 +19,10 @@ type ServerConfig struct {
type UserConfig struct {
Name string
Devices map[string]*DeviceConfig
Clients map[string]*ClientConfig
}
type DeviceConfig struct {
type ClientConfig struct {
Name string
PrivateKey string
PublicKey string
@@ -74,21 +74,21 @@ func (cfg *ServerConfig) GetUserConfig(user string) *UserConfig {
log.WithField("user", user).Info("No such user. Creating one.")
c = &UserConfig{
Name: user,
Devices: make(map[string]*DeviceConfig),
Clients: make(map[string]*ClientConfig),
}
cfg.Users[user] = c
}
return c
}
func NewDeviceConfig(ip net.IP) *DeviceConfig {
func NewClientConfig(ip net.IP) *ClientConfig {
key, err := wgtypes.GeneratePrivateKey()
if err != nil {
log.Fatal(err)
}
cfg := DeviceConfig{
Name: "Unnamed Device",
cfg := ClientConfig{
Name: "Unnamed Client",
PrivateKey: key.String(),
PublicKey: key.PublicKey().String(),
IP: ip,
+4
View File
@@ -7,14 +7,18 @@ require (
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect
github.com/ddollar/forego v0.16.1 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/dln/luxaforce v0.0.0-20180531194703-db2a6b5fc72d // indirect
github.com/elazarl/go-bindata-assetfs v1.0.0
github.com/futurenda/google-auth-id-token-verifier v0.0.0-20170311140316-2a5b89f28b7e // indirect
github.com/google/nftables v0.0.0-20190430150743-07c974e3643d
github.com/julienschmidt/httprouter v1.2.0
github.com/koneu/natend v0.0.0-20150829182554-ec0926ea948d // indirect
github.com/mattn/goreman v0.2.1 // indirect
github.com/mdlayher/wireguardctrl v0.0.0-20190419142446-a4a944b88a6b
github.com/sirupsen/logrus v1.4.1
github.com/toqueteos/webbrowser v1.1.0 // indirect
github.com/vishvananda/netlink v1.0.0
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc
google.golang.org/grpc v1.22.0 // indirect
gopkg.in/alecthomas/kingpin.v2 v2.2.6
)
+29
View File
@@ -1,15 +1,28 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/EmbarkStudios/src v0.0.0-20190708074312-9ce83ae72fd4 h1:DemX5XAjzL1lvIuLVAMfX2grfxjZo7CQ9JH7FnB+3VQ=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ddollar/forego v0.16.1 h1:HbAl3XyEdU1lw17PvZzqMzcx7b8BKZshEsdb4+1TI3Y=
github.com/ddollar/forego v0.16.1/go.mod h1:moJFK5OqWdZeLVEYHynQRJqoKImixOuxgQBFCtoe0bU=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dln/luxaforce v0.0.0-20180531194703-db2a6b5fc72d h1:0MwrV1xaSUg0I5dzeoRuc6tg0UQACo98/ABwQcOFJg4=
github.com/dln/luxaforce v0.0.0-20180531194703-db2a6b5fc72d/go.mod h1:CahaXJvJI62kC6ikqP63GWz40sAB1igBuQDPlxY3qnk=
github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/futurenda/google-auth-id-token-verifier v0.0.0-20170311140316-2a5b89f28b7e h1:qFV0nTBo/TC3ckN/VvyT0B1/VZb94AvSANfU7XR5lcM=
github.com/futurenda/google-auth-id-token-verifier v0.0.0-20170311140316-2a5b89f28b7e/go.mod h1:EX5Jbcw/PxsrlV7D2o77gpzcJevkXl3DQjkF8a0xNMI=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/nftables v0.0.0-20190430150743-07c974e3643d h1:TC4HtISCtWOTUVPQmq4CAqe0+8R2fvnkJlQn47ep2hI=
@@ -43,6 +56,8 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/toqueteos/webbrowser v1.1.0 h1:Prj1okiysRgHPoe3B1bOIVxcv+UuSt525BDQmR5W0x0=
github.com/toqueteos/webbrowser v1.1.0/go.mod h1:Hqqqmzj8AHn+VlZyVjaRWY20i25hoOZGAABCcg2el4A=
github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM=
github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4=
@@ -50,8 +65,13 @@ github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmF
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 h1:O5YqonU5IWby+w98jVUG9h7zlCWCcH4RHyPVReBmhzk=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190419010253-1f3472d942ba h1:h0zCzEL5UW1mERvwTN6AXcc75PpLkY6OcReia6Dq1BM=
golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180925112736-b09afc3d579e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -59,9 +79,18 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be h1:mI+jhqkn68ybP0ORJqunXn+fq+Eeb4hHKqLQcFICjAc=
golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw=
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+34 -34
View File
@@ -183,7 +183,7 @@ func (s *Server) allocateIP() net.IP {
allocated := make(map[string]bool)
allocated[s.ipAddr.String()] = true
for _, cfg := range s.Config.Users {
for _, dev := range cfg.Devices {
for _, dev := range cfg.Clients {
allocated[dev.IP.String()] = true
}
}
@@ -235,7 +235,7 @@ func (s *Server) configureWireguard() error {
peers := make([]wgtypes.PeerConfig, 0)
for user, cfg := range s.Config.Users {
for id, dev := range cfg.Devices {
for id, dev := range cfg.Clients {
pubKey, err := wgtypes.ParseKey(dev.PublicKey)
if err != nil {
return err
@@ -249,7 +249,7 @@ func (s *Server) configureWireguard() error {
AllowedIPs: allowedIPs,
}
log.WithFields(log.Fields{"user": user, "device": id, "key": dev.PublicKey, "allowedIPs": peer.AllowedIPs}).Debug("Adding wireguard peer")
log.WithFields(log.Fields{"user": user, "client": id, "key": dev.PublicKey, "allowedIPs": peer.AllowedIPs}).Debug("Adding wireguard peer")
peers = append(peers, peer)
}
@@ -278,11 +278,11 @@ func (s *Server) Start() error {
}
router := httprouter.New()
router.GET("/api/v1/users/:user/devices/:device", s.withAuth(s.GetDevice))
router.PUT("/api/v1/users/:user/devices/:device", s.withAuth(s.EditDevice))
router.DELETE("/api/v1/users/:user/devices/:device", s.withAuth(s.DeleteDevice))
router.GET("/api/v1/users/:user/devices", s.withAuth(s.GetDevices))
router.POST("/api/v1/users/:user/devices", s.withAuth(s.CreateDevice))
router.GET("/api/v1/users/:user/clients/:client", s.withAuth(s.GetClient))
router.PUT("/api/v1/users/:user/clients/:client", s.withAuth(s.EditClient))
router.DELETE("/api/v1/users/:user/clients/:client", s.withAuth(s.DeleteClient))
router.GET("/api/v1/users/:user/clients", s.withAuth(s.GetClients))
router.POST("/api/v1/users/:user/clients", s.withAuth(s.CreateClient))
if *devUIServer != "" {
log.Debug("Serving static assets proxying from development server: ", *devUIServer)
@@ -361,17 +361,17 @@ func (s *Server) withAuth(handler httprouter.Handle) httprouter.Handle {
}
}
func (s *Server) GetDevices(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
user := r.Context().Value("user")
func (s *Server) GetClients(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
user := r.Context().Value("user").(string)
log.Debug(user)
err := json.NewEncoder(w).Encode(s.Config)
err := json.NewEncoder(w).Encode(s.Config.Users[user].Clients)
if err != nil {
log.Error(err)
w.WriteHeader(http.StatusInternalServerError)
}
}
func (s *Server) GetDevice(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
func (s *Server) GetClient(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
user := r.Context().Value("user").(string)
usercfg := s.Config.Users[user]
if usercfg == nil {
@@ -379,8 +379,8 @@ func (s *Server) GetDevice(w http.ResponseWriter, r *http.Request, ps httprouter
return
}
device := usercfg.Devices[ps.ByName("device")]
if device == nil {
client := usercfg.Clients[ps.ByName("client")]
if client == nil {
w.WriteHeader(http.StatusNotFound)
return
}
@@ -400,11 +400,11 @@ DNS = %s
PublicKey = %s
AllowedIPs = %s
Endpoint = %s
`, device.IP.String(), device.PrivateKey, "8.8.8.8", s.Config.PublicKey, allowedIPs, *wgEndpoint)
`, client.IP.String(), client.PrivateKey, "8.8.8.8", s.Config.PublicKey, allowedIPs, *wgEndpoint)
return
}
err := json.NewEncoder(w).Encode(device)
err := json.NewEncoder(w).Encode(client)
if err != nil {
log.Error(err)
w.WriteHeader(http.StatusInternalServerError)
@@ -412,7 +412,7 @@ Endpoint = %s
}
}
func (s *Server) EditDevice(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
func (s *Server) EditClient(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
user := r.Context().Value("user").(string)
usercfg := s.Config.Users[user]
if usercfg == nil {
@@ -420,13 +420,13 @@ func (s *Server) EditDevice(w http.ResponseWriter, r *http.Request, ps httproute
return
}
device := usercfg.Devices[ps.ByName("device")]
if device == nil {
client := usercfg.Clients[ps.ByName("client")]
if client == nil {
w.WriteHeader(http.StatusNotFound)
return
}
cfg := DeviceConfig{}
cfg := ClientConfig{}
if err := json.NewDecoder(r.Body).Decode(&cfg); err != nil {
log.Warn("Error parsing request: ", err)
@@ -434,23 +434,23 @@ func (s *Server) EditDevice(w http.ResponseWriter, r *http.Request, ps httproute
return
}
log.Debugf("EditDevice: %#v", cfg)
log.Debugf("EditClient: %#v", cfg)
if cfg.Name != "" {
device.Name = cfg.Name
client.Name = cfg.Name
}
s.reconfigure()
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(device); err != nil {
if err := json.NewEncoder(w).Encode(client); err != nil {
log.Error(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
}
func (s *Server) DeleteDevice(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
func (s *Server) DeleteClient(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
user := r.Context().Value("user").(string)
usercfg := s.Config.Users[user]
if usercfg == nil {
@@ -458,32 +458,32 @@ func (s *Server) DeleteDevice(w http.ResponseWriter, r *http.Request, ps httprou
return
}
device := ps.ByName("device")
if usercfg.Devices[device] == nil {
client := ps.ByName("client")
if usercfg.Clients[client] == nil {
w.WriteHeader(http.StatusNotFound)
return
}
delete(usercfg.Devices, device)
delete(usercfg.Clients, client)
s.reconfigure()
log.WithField("user", user).Debug("Deleted device: ", device)
log.WithField("user", user).Debug("Deleted client: ", client)
w.WriteHeader(http.StatusOK)
}
func (s *Server) CreateDevice(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
func (s *Server) CreateClient(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
s.mutex.Lock()
defer s.mutex.Unlock()
user := r.Context().Value("user").(string)
log.WithField("user", user).Debug("CreateDevice")
log.WithField("user", user).Debug("CreateClient")
c := s.Config.GetUserConfig(user)
log.Debugf("user config: %#v", c)
i := 0
for k := range c.Devices {
for k := range c.Clients {
n, err := strconv.Atoi(k)
if err != nil {
log.Error(err)
@@ -497,12 +497,12 @@ func (s *Server) CreateDevice(w http.ResponseWriter, r *http.Request, ps httprou
i = i + 1
ip := s.allocateIP()
device := NewDeviceConfig(ip)
c.Devices[strconv.Itoa(i)] = device
client := NewClientConfig(ip)
c.Clients[strconv.Itoa(i)] = client
s.reconfigure()
err := json.NewEncoder(w).Encode(device)
err := json.NewEncoder(w).Encode(client)
if err != nil {
log.Error(err)
w.WriteHeader(http.StatusInternalServerError)
+9 -3
View File
@@ -2861,9 +2861,15 @@
}
},
"svelte": {
"version": "3.4.4",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.4.4.tgz",
"integrity": "sha512-O9tzroEWVPOQe1QITW1jP8LAJwXmCfDDGdkOCa9Y6NlJ+gQwn+/rhFbMQ+vu2PWPLZt1gxN8DjTFM4nOBuMLFg==",
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.5.1.tgz",
"integrity": "sha512-iMnuyteFGQ8Yl68G/DHTHY1sLwoAMya1eS0ZOHIm/dqn2etR8WEe8hUAoluLryde4Cft4gvMhtHV3NhE60nBmQ==",
"dev": true
},
"svelte-routing": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/svelte-routing/-/svelte-routing-1.2.0.tgz",
"integrity": "sha512-bOWejHnBor46uvQAz6u3HpN+EXNnNvQFY8Qja4aIbg+BVN0QmrdkCyR35/KVf1Mq/Jjp9juRZfiYcble+TErGg==",
"dev": true
},
"terser": {
+2 -1
View File
@@ -11,7 +11,8 @@
"rollup-plugin-svelte": "^5.0.3",
"rollup-plugin-terser": "^5.0.0",
"sirv-cli": "^0.4.3",
"svelte": "^3.4.4"
"svelte": "^3.5.1",
"svelte-routing": "1.2.0"
},
"scripts": {
"build": "rollup -c",
+1 -58
View File
@@ -1,61 +1,4 @@
html, body {
position: relative;
width: 100%;
height: 100%;
}
body {
color: #333;
margin: 0;
padding: 8px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
padding-top: 5rem;
}
a {
color: rgb(0,100,200);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: rgb(0,80,160);
}
label {
display: block;
}
input, button, select, textarea {
font-family: inherit;
font-size: inherit;
padding: 0.4em;
margin: 0 0 0.5em 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
}
input:disabled {
color: #ccc;
}
input[type="range"] {
height: 0;
}
button {
background-color: #f4f4f4;
outline: none;
}
button:active {
background-color: #ddd;
}
button:focus {
border-color: #666;
}
+9 -3
View File
@@ -1,11 +1,13 @@
<!doctype html>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf8'>
<meta name='viewport' content='width=device-width'>
<title>Svelte app</title>
<title>Wireguard VPN</title>
<link rel="stylesheet" href="https://unpkg.com/bootstrap-material-design@4.1.1/dist/css/bootstrap-material-design.min.css" integrity="sha384-wXznGJNEXNG1NFsbm0ugrLFMQPWswR3lds2VeinahP8N0zJw9VWSopbjv2x7WCvX" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel='icon' type='image/png' href='favicon.png'>
<link rel='stylesheet' href='global.css'>
<link rel='stylesheet' href='bundle.css'>
@@ -13,5 +15,9 @@
<body>
<script src='bundle.js'></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://unpkg.com/popper.js@1.12.6/dist/umd/popper.js" integrity="sha384-fA23ZRQ3G/J53mElWqVJEGJzU0sTs+SvzG8fXVWP+kJQ1lwFAOkcUOysnlKJC33U" crossorigin="anonymous"></script>
<script src="https://unpkg.com/bootstrap-material-design@4.1.1/dist/js/bootstrap-material-design.js" integrity="sha384-CauSuKpEqAFajSpkdjv3z9t8E7RlpJ1UP0lKM/+NdtSarroVKu069AlsRPKkFBz9" crossorigin="anonymous"></script>
<script>$(document).ready(function() { $('body').bootstrapMaterialDesign(); });</script>
</body>
</html>
</html>
+3
View File
@@ -0,0 +1,3 @@
<h1>About</h1>
Wireguard is nice.
+17 -8
View File
@@ -1,11 +1,20 @@
<script>
export let name;
import { Router, Link, Route } from "svelte-routing";
import About from "./About.svelte";
import Clients from "./Clients.svelte";
import EditClient from "./EditClient.svelte";
import Nav from "./Nav.svelte";
export let url = "";
</script>
<style>
h1 {
color: purple;
}
</style>
<h1>Hello {name}!</h1>
<Router url="{url}">
<Nav />
<main role="main" class="container">
<div>
<Route path="client/:clientId" component="{EditClient}" />
<Route path="about" component="{About}" />
<Route path="/"><Clients /></Route>
</div>
</main>
</Router>
+20
View File
@@ -0,0 +1,20 @@
<script>
import { link } from "svelte-routing";
export let client;
let clientId = client[0];
let dev = client[1];
</script>
<div>
<h4>{client.Name}</h4>
<dl>
<dt>IP</dt><dd>{dev.IP}</dd>
<dt>PrivateKey</dt><dd>{dev.PrivateKey}</dd>
<dt>PublicKey</dt><dd>{dev.PublicKey}</dd>
</dl>
<a href="/client/{clientId}" use:link role="button" class="btn btn-primary material-icons">
edit
</a>
</div>
+26
View File
@@ -0,0 +1,26 @@
<script>
import { onMount } from 'svelte';
import Client from './Client.svelte';
let user = "anonymous";
let clients = [];
onMount(async () => {
const res = await fetch(`/api/v1/users/` + user + `/clients`);
clients = Object.entries(await res.json());
});
</script>
<h2>My Clients</h2>
<ul>
{#each clients as dev}
<li><Client client={dev}/></li>
{/each}
</ul>
<button type="button" class="btn btn-primary bmd-btn-fab">
<i class="material-icons">add</i>
</button>
+29
View File
@@ -0,0 +1,29 @@
<script>
import { onMount } from 'svelte';
import { link } from "svelte-routing";
export let clientId;
let user = "anonymous";
let client = {};
onMount(async () => {
const res = await fetch(`/api/v1/users/` + user + `/clients/` + clientId);
client = Object.entries(await res.json());
});
</script>
<h2>Edit Client {client.Name}</h2>
<form>
<div class="form-group">
<label for="name" class="bmd-label-floating">Client Name</label>
<input type="email" class="form-control" id="name" value={client.Name}>
<span class="bmd-help">Friendly name of client.</span>
</div>
</form>
<p>
{client}
</p>
+21
View File
@@ -0,0 +1,21 @@
<script>
import { Router, Link, Route } from "svelte-routing";
import About from "./About.svelte";
import Clients from "./Clients.svelte";
import NavLink from "./NavLink.svelte";
</script>
<header>
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
<a class="navbar-brand" href="/">Wireguard VPN</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav mr-auto">
<li class="nav-item"><NavLink to="/">Clients</NavLink></li>
<li class="nav-item"><NavLink to="about">About</NavLink></li>
</ul>
</div>
</nav>
</header>
+17
View File
@@ -0,0 +1,17 @@
<script>
import { Link } from "svelte-routing";
export let to = "";
function getProps({ location, href, isPartiallyCurrent, isCurrent }) {
const isActive = href === "/" ? isCurrent : isPartiallyCurrent || isCurrent;
// The object returned here is spread on the anchor element's attributes
if (isActive) {
return { class: "nav-link active" };
}
return { class: "nav-link" };
}
</script>
<Link to="{to}" getProps="{getProps}">
<slot />
</Link>
+3 -6
View File
@@ -1,10 +1,7 @@
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
name: 'Wireguard'
}
new App({
target: document.body,
// hydrate: true,
});
export default app;
+14
View File
@@ -0,0 +1,14 @@
const { createServer } = require("http");
const app = require("./dist/App.js");
createServer((req, res) => {
const { html } = app.render({ url: req.url });
res.write(`
<!DOCTYPE html>
<body>${html}</body>
<script src="/dist/bundle.js"></script>
`);
res.end();
}).listen(5000);