diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a17c0c5..4865708 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,29 @@ stages: + - build artifacts - build docker image - push docker hub +build-back: + stage: build artifacts + image: golang:latest + script: + - GOOS=linux GOARCH=amd64 go build -o ${CI_PROJECT_NAME}-linux-amd64 + artifacts: + paths: + - ${CI_PROJECT_NAME}-linux-amd64 + +build-front: + stage: build artifacts + image: node:10-alpine + script: + - cd ./ui + - npm install + - npm run build + - cd .. + artifacts: + paths: + - ui/dist + build: stage: build docker image image: docker:latest diff --git a/README.md b/README.md index af50f9c..0123076 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ The goal is to run Wg Gen Web in a container and WireGuard on host system. * Self-hosted and web based * Automatically select IP from the netowrk pool assigned to client * QR-Code for convenient mobile client configuration + * Sent email to client with QR-code and client config * Enable / Disable client * Generation of `wg0.conf` after any modification * Dockerized diff --git a/core/client.go b/core/client.go index e2839fc..2a6ddec 100644 --- a/core/client.go +++ b/core/client.go @@ -16,7 +16,6 @@ import ( "path/filepath" "sort" "strconv" - "strings" "time" ) @@ -49,8 +48,8 @@ func CreateClient(client *model.Client) (*model.Client, error) { } ips := make([]string, 0) - for _, network := range strings.Split(client.Address, ",") { - ip, err := util.GetAvailableIp(strings.TrimSpace(network), reserverIps) + for _, network := range client.Address { + ip, err := util.GetAvailableIp(network, reserverIps) if err != nil { return nil, err } @@ -61,7 +60,7 @@ func CreateClient(client *model.Client) (*model.Client, error) { } ips = append(ips, ip) } - client.Address = strings.Join(ips, ",") + client.Address = ips client.Created = time.Now().UTC() client.Updated = client.Created diff --git a/core/migrate.go b/core/migrate.go new file mode 100644 index 0000000..e8e1137 --- /dev/null +++ b/core/migrate.go @@ -0,0 +1,189 @@ +package core + +import ( + "encoding/json" + uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" + "gitlab.127-0-0-1.fr/vx3r/wg-gen-web/model" + "gitlab.127-0-0-1.fr/vx3r/wg-gen-web/storage" + "gitlab.127-0-0-1.fr/vx3r/wg-gen-web/util" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +// Migrate all changes, current struct fields change +func Migrate() error { + clients, err := readClients() + if err != nil { + return err + } + + s, err := deserialize("server.json") + if err != nil { + return err + } + + for _, client := range clients { + switch v := client["allowedIPs"].(type) { + case []interface{}: + log.Infof("client %s has been already migrated", client["id"]) + continue + default: + log.Infof("unexpected type %T, mus be migrated", v) + } + + c := &model.Client{} + c.Id = client["id"].(string) + c.Name = client["name"].(string) + c.Email = client["email"].(string) + c.Enable = client["enable"].(bool) + c.AllowedIPs = make([]string, 0) + for _, address := range strings.Split(client["allowedIPs"].(string), ",") { + if util.IsValidCidr(strings.TrimSpace(address)) { + c.AllowedIPs = append(c.AllowedIPs, strings.TrimSpace(address)) + } + } + c.Address = make([]string, 0) + for _, address := range strings.Split(client["address"].(string), ",") { + if util.IsValidCidr(strings.TrimSpace(address)) { + c.Address = append(c.Address, strings.TrimSpace(address)) + } + } + c.PrivateKey = client["privateKey"].(string) + c.PublicKey = client["publicKey"].(string) + created, err := time.Parse(time.RFC3339, client["created"].(string)) + if err != nil { + log.WithFields(log.Fields{ + "err": err, + }).Errorf("failed to parse time") + continue + } + c.Created = created + updated, err := time.Parse(time.RFC3339, client["updated"].(string)) + if err != nil { + log.WithFields(log.Fields{ + "err": err, + }).Errorf("failed to parse time") + continue + } + c.Updated = updated + + err = storage.Serialize(c.Id, c) + if err != nil { + log.WithFields(log.Fields{ + "err": err, + }).Errorf("failed to Serialize client") + } + } + + switch v := s["address"].(type) { + case []interface{}: + log.Info("server has been already migrated") + return nil + default: + log.Infof("unexpected type %T, mus be migrated", v) + } + + server := &model.Server{} + + server.Address = make([]string, 0) + for _, address := range strings.Split(s["address"].(string), ",") { + if util.IsValidCidr(strings.TrimSpace(address)) { + server.Address = append(server.Address, strings.TrimSpace(address)) + } + } + server.ListenPort = int(s["listenPort"].(float64)) + server.PrivateKey = s["privateKey"].(string) + server.PublicKey = s["publicKey"].(string) + server.PresharedKey = s["presharedKey"].(string) + server.Endpoint = s["endpoint"].(string) + server.PersistentKeepalive = int(s["persistentKeepalive"].(float64)) + server.Dns = make([]string, 0) + for _, address := range strings.Split(s["dns"].(string), ",") { + if util.IsValidIp(strings.TrimSpace(address)) { + server.Dns = append(server.Dns, strings.TrimSpace(address)) + } + } + if val, ok := s["preUp"]; ok { + server.PreUp = val.(string) + } + if val, ok := s["postUp"]; ok { + server.PostUp = val.(string) + } + if val, ok := s["preDown"]; ok { + server.PreDown = val.(string) + } + if val, ok := s["postDown"]; ok { + server.PostDown = val.(string) + } + created, err := time.Parse(time.RFC3339, s["created"].(string)) + if err != nil { + log.WithFields(log.Fields{ + "err": err, + }).Errorf("failed to parse time") + } + server.Created = created + updated, err := time.Parse(time.RFC3339, s["updated"].(string)) + if err != nil { + log.WithFields(log.Fields{ + "err": err, + }).Errorf("failed to parse time") + } + server.Updated = updated + + err = storage.Serialize("server.json", server) + if err != nil { + log.WithFields(log.Fields{ + "err": err, + }).Errorf("failed to Serialize server") + } + + return nil +} + +func readClients() ([]map[string]interface{}, error) { + clients := make([]map[string]interface{}, 0) + + files, err := ioutil.ReadDir(filepath.Join(os.Getenv("WG_CONF_DIR"))) + if err != nil { + return nil, err + } + + for _, f := range files { + // clients file name is an uuid + _, err := uuid.FromString(f.Name()) + if err == nil { + c, err := deserialize(f.Name()) + if err != nil { + log.WithFields(log.Fields{ + "err": err, + "path": f.Name(), + }).Error("failed to deserialize client") + } else { + clients = append(clients, c) + } + } + } + + return clients, nil +} + +func deserialize(id string) (map[string]interface{}, error) { + path := filepath.Join(os.Getenv("WG_CONF_DIR"), id) + + data, err := util.ReadFile(path) + if err != nil { + return nil, err + } + + var d map[string]interface{} + err = json.Unmarshal(data, &d) + if err != nil { + return nil, err + } + + return d, nil +} diff --git a/core/server.go b/core/server.go index a4535d7..6a94f33 100644 --- a/core/server.go +++ b/core/server.go @@ -10,7 +10,6 @@ import ( "golang.zx2c4.com/wireguard/wgctrl/wgtypes" "os" "path/filepath" - "strings" "time" ) @@ -32,12 +31,19 @@ func ReadServer() (*model.Server, error) { } server.PresharedKey = presharedKey.String() - server.Name = "Created with default values" server.Endpoint = "wireguard.example.com:123" server.ListenPort = 51820 - server.Address = "fd9f:6666::10:6:6:1/112, 10.6.6.1/24" - server.Dns = "fd9f::10:0:0:2, 10.0.0.2" + + server.Address = make([]string, 0) + server.Address = append(server.Address, "fd9f:6666::10:6:6:1/64") + server.Address = append(server.Address, "10.6.6.1/24") + + server.Dns = make([]string, 0) + server.Dns = append(server.Dns, "fd9f::10:0:0:2") + server.Dns = append(server.Dns, "10.0.0.2") + server.PersistentKeepalive = 16 + server.Mtu = 0 server.PreUp = "echo WireGuard PreUp" server.PostUp = "echo WireGuard PostUp" server.PreDown = "echo WireGuard PreDown" @@ -131,12 +137,12 @@ func GetAllReservedIps() ([]string, error) { reserverIps := make([]string, 0) for _, client := range clients { - for _, cidr := range strings.Split(client.Address, ",") { - ip, err := util.GetIpFromCidr(strings.TrimSpace(cidr)) + for _, cidr := range client.Address { + ip, err := util.GetIpFromCidr(cidr) if err != nil { log.WithFields(log.Fields{ "err": err, - "cidr": err, + "cidr": cidr, }).Error("failed to ip from cidr") } else { reserverIps = append(reserverIps, ip) @@ -144,8 +150,8 @@ func GetAllReservedIps() ([]string, error) { } } - for _, cidr := range strings.Split(server.Address, ",") { - ip, err := util.GetIpFromCidr(strings.TrimSpace(cidr)) + for _, cidr := range server.Address { + ip, err := util.GetIpFromCidr(cidr) if err != nil { log.WithFields(log.Fields{ "err": err, diff --git a/main.go b/main.go index a5cdd96..737256a 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,7 @@ import ( "github.com/joho/godotenv" log "github.com/sirupsen/logrus" "gitlab.127-0-0-1.fr/vx3r/wg-gen-web/api" + "gitlab.127-0-0-1.fr/vx3r/wg-gen-web/core" "gitlab.127-0-0-1.fr/vx3r/wg-gen-web/util" "os" "path/filepath" @@ -40,6 +41,14 @@ func main() { } } + // check server.json or create it + _, err = core.ReadServer() + if err != nil { + log.WithFields(log.Fields{ + "err": err, + }).Fatal("failed to ensure server.json exists") + } + if os.Getenv("GIN_MODE") == "debug" { // set gin release debug gin.SetMode(gin.DebugMode) @@ -50,6 +59,14 @@ func main() { gin.DisableConsoleColor() } + // migrate + err = core.Migrate() + if err != nil { + log.WithFields(log.Fields{ + "err": err, + }).Fatal("failed to migrate") + } + // creates a gin router with default middleware: logger and recovery (crash-free) middleware app := gin.Default() diff --git a/model/client.go b/model/client.go index 3ff5dcb..eb0eb77 100644 --- a/model/client.go +++ b/model/client.go @@ -3,7 +3,6 @@ package model import ( "fmt" "gitlab.127-0-0-1.fr/vx3r/wg-gen-web/util" - "strings" "time" ) @@ -13,8 +12,8 @@ type Client struct { Name string `json:"name"` Email string `json:"email"` Enable bool `json:"enable"` - AllowedIPs string `json:"allowedIPs"` - Address string `json:"address"` + AllowedIPs []string `json:"allowedIPs"` + Address []string `json:"address"` PrivateKey string `json:"privateKey"` PublicKey string `json:"publicKey"` Created time.Time `json:"created"` @@ -41,22 +40,22 @@ func (a Client) IsValid() []error { errs = append(errs, fmt.Errorf("email %s is invalid", a.Email)) } // check if the allowedIPs empty - if a.AllowedIPs == "" { + if len(a.AllowedIPs) == 0 { errs = append(errs, fmt.Errorf("allowedIPs field is required")) } // check if the allowedIPs are valid - for _, allowedIP := range strings.Split(a.AllowedIPs, ",") { - if !util.IsValidCidr(strings.TrimSpace(allowedIP)) { + for _, allowedIP := range a.AllowedIPs { + if !util.IsValidCidr(allowedIP) { errs = append(errs, fmt.Errorf("allowedIP %s is invalid", allowedIP)) } } // check if the address empty - if a.Address == "" { + if len(a.Address) == 0 { errs = append(errs, fmt.Errorf("address field is required")) } // check if the address are valid - for _, address := range strings.Split(a.Address, ",") { - if !util.IsValidCidr(strings.TrimSpace(address)) { + for _, address := range a.Address { + if !util.IsValidCidr(address) { errs = append(errs, fmt.Errorf("address %s is invalid", address)) } } diff --git a/model/server.go b/model/server.go index cb52ce0..1007a66 100644 --- a/model/server.go +++ b/model/server.go @@ -3,21 +3,20 @@ package model import ( "fmt" "gitlab.127-0-0-1.fr/vx3r/wg-gen-web/util" - "strings" "time" ) // Server structure type Server struct { - Name string `json:"name"` - Address string `json:"address"` + Address []string `json:"address"` ListenPort int `json:"listenPort"` + Mtu int `json:"mtu"` PrivateKey string `json:"privateKey"` PublicKey string `json:"publicKey"` PresharedKey string `json:"presharedKey"` Endpoint string `json:"endpoint"` PersistentKeepalive int `json:"persistentKeepalive"` - Dns string `json:"dns"` + Dns []string `json:"dns"` PreUp string `json:"preUp"` PostUp string `json:"postUp"` PreDown string `json:"preDown"` @@ -29,21 +28,13 @@ type Server struct { func (a Server) IsValid() []error { errs := make([]error, 0) - // check if the name empty - if a.Name == "" { - errs = append(errs, fmt.Errorf("name is required")) - } - // check the name field is between 3 to 40 chars - if len(a.Name) < 2 || len(a.Name) > 40 { - errs = append(errs, fmt.Errorf("name must be between 2-40 chars")) - } // check if the address empty - if a.Address == "" { + if len(a.Address) == 0 { errs = append(errs, fmt.Errorf("address is required")) } // check if the address are valid - for _, address := range strings.Split(a.Address, ",") { - if !util.IsValidCidr(strings.TrimSpace(address)) { + for _, address := range a.Address { + if !util.IsValidCidr(address) { errs = append(errs, fmt.Errorf("address %s is invalid", address)) } } @@ -59,13 +50,13 @@ func (a Server) IsValid() []error { if a.PersistentKeepalive < 0 { errs = append(errs, fmt.Errorf("persistentKeepalive %d is invalid", a.PersistentKeepalive)) } - // check if the dns empty - if a.Dns == "" { - errs = append(errs, fmt.Errorf("dns is required")) + // check if the mtu is valid + if a.Mtu < 0 { + errs = append(errs, fmt.Errorf("MTU %d is invalid", a.PersistentKeepalive)) } // check if the address are valid - for _, dns := range strings.Split(a.Dns, ",") { - if !util.IsValidIp(strings.TrimSpace(dns)) { + for _, dns := range a.Dns { + if !util.IsValidIp(dns) { errs = append(errs, fmt.Errorf("dns %s is invalid", dns)) } } diff --git a/template/template.go b/template/template.go index ea6a720..007a083 100644 --- a/template/template.go +++ b/template/template.go @@ -197,45 +197,54 @@ var ( ` - clientTpl = ` -[Interface] -Address = {{.Client.Address}} -PrivateKey = {{.Client.PrivateKey}} -DNS = {{.Server.Dns}} + clientTpl = `[Interface] +Address = {{ StringsJoin .Client.Address ", " }} +PrivateKey = {{ .Client.PrivateKey }} +{{ if ne (len .Server.Dns) 0 -}} +DNS = {{ StringsJoin .Server.Dns ", " }} +{{- end }} +{{ if ne .Server.Mtu 0 -}} +MTU = {{.Server.Mtu}} +{{- end}} [Peer] -PublicKey = {{.Server.PublicKey}} -PresharedKey = {{.Server.PresharedKey}} -AllowedIPs = {{.Client.AllowedIPs}} -Endpoint = {{.Server.Endpoint}} -PersistentKeepalive = {{.Server.PersistentKeepalive}}` +PublicKey = {{ .Server.PublicKey }} +PresharedKey = {{ .Server.PresharedKey }} +AllowedIPs = {{ StringsJoin .Client.AllowedIPs ", " }} +Endpoint = {{ .Server.Endpoint }} +{{ if ne .Server.PersistentKeepalive 0 -}} +PersistentKeepalive = {{.Server.PersistentKeepalive}} +{{- end}} +` - wgTpl = ` -# {{.Server.Name}} / Updated: {{.Server.Updated}} / Created: {{.Server.Created}} + wgTpl = `# Updated: {{ .Server.Updated }} / Created: {{ .Server.Created }} [Interface] - {{range .ServerAdresses}} -Address = {{.}} - {{end}} -ListenPort = {{.Server.ListenPort}} -PrivateKey = {{.Server.PrivateKey}} -PreUp = {{.Server.PreUp}} -PostUp = {{.Server.PostUp}} -PreDown = {{.Server.PreDown}} -PostDown = {{.Server.PostDown}} - {{$server := .Server}} - {{range .Clients}} - {{if .Enable}} +{{- range .Server.Address }} +Address = {{ . }} +{{- end }} +ListenPort = {{ .Server.ListenPort }} +PrivateKey = {{ .Server.PrivateKey }} +{{ if ne .Server.Mtu 0 -}} +MTU = {{.Server.Mtu}} +{{- end}} +PreUp = {{ .Server.PreUp }} +PostUp = {{ .Server.PostUp }} +PreDown = {{ .Server.PreDown }} +PostDown = {{ .Server.PostDown }} +{{ $server := .Server }} +{{- range .Clients }} +{{ if .Enable -}} # {{.Name}} / {{.Email}} / Updated: {{.Updated}} / Created: {{.Created}} [Peer] -PublicKey = {{.PublicKey}} -PresharedKey = {{$server.PresharedKey}} -AllowedIPs = {{.Address}} - {{end}} - {{end}}` +PublicKey = {{ .PublicKey }} +PresharedKey = {{ $server.PresharedKey }} +AllowedIPs = {{ StringsJoin .Address ", " }} +{{- end }} +{{ end }}` ) // DumpClientWg dump client wg config with go template func DumpClientWg(client *model.Client, server *model.Server) ([]byte, error) { - t, err := template.New("client").Parse(clientTpl) + t, err := template.New("client").Funcs(template.FuncMap{"StringsJoin": strings.Join}).Parse(clientTpl) if err != nil { return nil, err } @@ -251,19 +260,17 @@ func DumpClientWg(client *model.Client, server *model.Server) ([]byte, error) { // DumpServerWg dump server wg config with go template, write it to file and return bytes func DumpServerWg(clients []*model.Client, server *model.Server) ([]byte, error) { - t, err := template.New("server").Parse(wgTpl) + t, err := template.New("server").Funcs(template.FuncMap{"StringsJoin": strings.Join}).Parse(wgTpl) if err != nil { return nil, err } configDataWg, err := dump(t, struct { - Clients []*model.Client - Server *model.Server - ServerAdresses []string + Clients []*model.Client + Server *model.Server }{ - ServerAdresses: strings.Split(server.Address, ","), - Clients: clients, - Server: server, + Clients: clients, + Server: server, }) if err != nil { return nil, err diff --git a/ui/package-lock.json b/ui/package-lock.json index 6a3bf90..5a594d8 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -3561,12 +3561,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3581,17 +3583,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3708,7 +3713,8 @@ "inherits": { "version": "2.0.4", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3720,6 +3726,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3734,6 +3741,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3741,12 +3749,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.9.0", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3765,6 +3775,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3854,7 +3865,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3866,6 +3878,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3987,6 +4000,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -8920,11 +8934,6 @@ "moment": "^2.19.2" } }, - "vue-plugin-axios": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/vue-plugin-axios/-/vue-plugin-axios-1.0.14.tgz", - "integrity": "sha512-hpFdi17XsSdYQnrlHrml4BnmH9ceJSkpCoMGbPCz5vfDoY7okWuzKgeKK44NgRlZzlUCrq7ug3fGLZ2nv/qNNA==" - }, "vue-router": { "version": "3.1.5", "resolved": "https://registry.npm.taobao.org/vue-router/download/vue-router-3.1.5.tgz", diff --git a/ui/package.json b/ui/package.json index 82eb328..64aff46 100644 --- a/ui/package.json +++ b/ui/package.json @@ -12,7 +12,6 @@ "moment": "^2.24.0", "vue": "^2.6.10", "vue-moment": "^4.1.0", - "vue-plugin-axios": "^1.0.14", "vue-router": "^3.1.3", "vuetify": "^2.1.0" }, diff --git a/ui/src/components/Clients.vue b/ui/src/components/Clients.vue new file mode 100644 index 0000000..71f71f9 --- /dev/null +++ b/ui/src/components/Clients.vue @@ -0,0 +1,449 @@ + + diff --git a/ui/src/components/Notification.vue b/ui/src/components/Notification.vue new file mode 100644 index 0000000..a898aa6 --- /dev/null +++ b/ui/src/components/Notification.vue @@ -0,0 +1,25 @@ + + diff --git a/ui/src/components/Server.vue b/ui/src/components/Server.vue new file mode 100644 index 0000000..01e9106 --- /dev/null +++ b/ui/src/components/Server.vue @@ -0,0 +1,230 @@ + + diff --git a/ui/src/main.js b/ui/src/main.js index 6ba4187..bfb2c50 100644 --- a/ui/src/main.js +++ b/ui/src/main.js @@ -2,7 +2,6 @@ import Vue from 'vue' import App from './App.vue' import router from './router' import vuetify from './plugins/vuetify'; -import './plugins/axios'; import './plugins/moment'; import './plugins/cidr' diff --git a/ui/src/plugins/axios.js b/ui/src/plugins/axios.js deleted file mode 100644 index 11c1ce5..0000000 --- a/ui/src/plugins/axios.js +++ /dev/null @@ -1,13 +0,0 @@ -import Vue from 'vue' -import VueAxios from 'vue-plugin-axios' -import axios from 'axios' - -export const myVar = 'This is my variable' - -// https://www.npmjs.com/package/vue-cli-plugin-vuetify -Vue.use(VueAxios, { - axios, - config: { - baseURL: process.env.VUE_APP_API_BASE_URL || '/api/v1.0', - }, -}); diff --git a/ui/src/plugins/moment.js b/ui/src/plugins/moment.js index b03fce7..5e8ebb0 100644 --- a/ui/src/plugins/moment.js +++ b/ui/src/plugins/moment.js @@ -2,7 +2,7 @@ import Vue from 'vue' import moment from 'moment'; import VueMoment from 'vue-moment' -moment.locale('es'); +moment.locale('en'); Vue.use(VueMoment, { moment diff --git a/ui/src/services/ApiService.js b/ui/src/services/ApiService.js new file mode 100644 index 0000000..dc55572 --- /dev/null +++ b/ui/src/services/ApiService.js @@ -0,0 +1,40 @@ +import axios from 'axios' + +let baseUrl = "/api/v1.0"; +if (process.env.NODE_ENV === "development"){ + baseUrl = process.env.VUE_APP_API_BASE_URL +} + +export const API_BASE_URL = baseUrl; + +export class ApiService { + get(resource) { + return axios + .get(`${API_BASE_URL}${resource}`) + .then(response => response.data) + }; + + post(resource, data) { + return axios + .post(`${API_BASE_URL}${resource}`, data) + .then(response => response.data) + }; + + put(resource, data) { + return axios + .put(`${API_BASE_URL}${resource}`, data) + .then(response => response.data) + }; + + patch(resource, data) { + return axios + .patch(`${API_BASE_URL}${resource}`, data) + .then(response => response.data) + }; + + delete(resource) { + return axios + .delete(`${API_BASE_URL}${resource}`) + .then(response => response.data) + }; +} diff --git a/ui/src/views/Home.vue b/ui/src/views/Home.vue index 7a6d2db..6ac0b8a 100644 --- a/ui/src/views/Home.vue +++ b/ui/src/views/Home.vue @@ -1,638 +1,19 @@