diff --git a/.drone.yml b/.drone.yml index 386db23..662c398 100644 --- a/.drone.yml +++ b/.drone.yml @@ -13,10 +13,10 @@ steps: commands: - apk --no-cache add python2 build-base tar - yarn config set network-timeout 100000 - - yarn --cwd htdocs install - - tar --transform="s@.@./happydns-${DRONE_COMMIT}@" --exclude-vcs --exclude=./htdocs/node_modules/.cache -czf /dev/shm/happydns-src.tar.gz . + - yarn --cwd ui install + - tar --transform="s@.@./happydns-${DRONE_COMMIT}@" --exclude-vcs --exclude=./ui/node_modules/.cache -czf /dev/shm/happydns-src.tar.gz . - mv /dev/shm/happydns-src.tar.gz . - - yarn --cwd htdocs --offline build + - yarn --cwd ui --offline build - name: deploy sources image: appleboy/drone-scp @@ -55,8 +55,7 @@ steps: - name: backend image: golang:alpine commands: - - apk --no-cache add go-bindata - - sed -i '/yarn --cwd htdocs --offline build/d' static.go + - sed -i '/yarn --offline build/d' ui/assets.go - go generate -v - go build -v -tags netgo -ldflags '-w' -o happydns-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} environment: @@ -173,14 +172,13 @@ steps: commands: - apk --no-cache add python2 build-base - yarn config set network-timeout 100000 - - yarn --cwd htdocs install - - yarn --cwd htdocs --offline build + - yarn --cwd ui install + - yarn --cwd ui --offline build - name: backend image: golang:alpine commands: - - apk --no-cache add go-bindata - - sed -i '/yarn --cwd htdocs --offline build/d' static.go + - sed -i '/yarn --offline build/d' ui/assets.go - go generate -v - go build -v -tags netgo -ldflags '-w' -o happydns-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} - ln happydns-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH} happydns @@ -291,14 +289,14 @@ steps: commands: - apk --no-cache add python2 build-base - yarn config set network-timeout 100000 - - yarn --cwd htdocs install - - yarn --cwd htdocs --offline build + - yarn --cwd ui install + - yarn --cwd ui --offline build - name: backend armel image: golang:alpine commands: - - apk --no-cache add go-bindata build-base - - sed -i '/yarn --cwd htdocs --offline build/d' static.go + - apk --no-cache add build-base + - sed -i '/yarn --offline build/d' ui/assets.go - go generate -v - go build -v -tags netgo -ldflags '-w' -o happydns-${DRONE_STAGE_OS}-${DRONE_STAGE_ARCH}el environment: diff --git a/api/routes.go b/api/routes.go new file mode 100644 index 0000000..2f2a463 --- /dev/null +++ b/api/routes.go @@ -0,0 +1,52 @@ +// Copyright or © or Copr. happyDNS (2021) +// +// contact@happydns.org +// +// This software is a computer program whose purpose is to provide a modern +// interface to interact with DNS systems. +// +// This software is governed by the CeCILL license under French law and abiding +// by the rules of distribution of free software. You can use, modify and/or +// redistribute the software under the terms of the CeCILL license as +// circulated by CEA, CNRS and INRIA at the following URL +// "http://www.cecill.info". +// +// As a counterpart to the access to the source code and rights to copy, modify +// and redistribute granted by the license, users are provided only with a +// limited warranty and the software's author, the holder of the economic +// rights, and the successive licensors have only limited liability. +// +// In this respect, the user's attention is drawn to the risks associated with +// loading, using, modifying and/or developing or reproducing the software by +// the user in light of its specific status of free software, that may mean +// that it is complicated to manipulate, and that also therefore means that it +// is reserved for developers and experienced professionals having in-depth +// computer knowledge. Users are therefore encouraged to load and test the +// software's suitability as regards their requirements in conditions enabling +// the security of their systems and/or data to be ensured and, more generally, +// to use and operate it in the same conditions as regards security. +// +// The fact that you are presently reading this means that you have had +// knowledge of the CeCILL license and that you accept its terms. + +package api + +import ( + "github.com/gin-gonic/gin" + + "git.happydns.org/happydns/config" +) + +var routes []func(*config.Options, *gin.RouterGroup) + +func AddRoutes(f func(*config.Options, *gin.RouterGroup)) { + routes = append(routes, f) +} + +func DeclareRoutes(cfg *config.Options, router *gin.Engine) { + apiRoutes := router.Group("/api") + + for _, r := range routes { + r(cfg, apiRoutes) + } +} diff --git a/go.mod b/go.mod index 9fc4eb2..55bc0d1 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module git.happydns.org/happydns -go 1.14 +go 1.16 require ( + github.com/gin-gonic/gin v1.7.1 github.com/go-mail/mail v2.3.1+incompatible - github.com/go-sql-driver/mysql v1.5.0 - github.com/golang/snappy v0.0.3 // indirect + github.com/go-sql-driver/mysql v1.6.0 github.com/julienschmidt/httprouter v1.3.0 github.com/miekg/dns v1.1.42 github.com/ovh/go-ovh v1.1.0 @@ -13,9 +13,6 @@ require ( github.com/syndtr/goleveldb v1.0.0 github.com/yuin/goldmark v1.3.7 golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a - golang.org/x/net v0.0.0-20210510120150-4163338589ed // indirect - golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect - gopkg.in/ini.v1 v1.62.0 // indirect gopkg.in/mail.v2 v2.3.1 // indirect ) diff --git a/go.sum b/go.sum index 4d007dc..c6329bd 100644 --- a/go.sum +++ b/go.sum @@ -1,24 +1,49 @@ -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.7.1 h1:qC89GU3p8TvKWMAVhEpmpB2CIb1hnqt2UdKZaP93mS8= +github.com/gin-gonic/gin v1.7.1/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/go-mail/mail v2.3.1+incompatible h1:UzNOn0k5lpfVtO31cK3hn6I4VEVGhe3lX8AJBAxXExM= github.com/go-mail/mail v2.3.1+incompatible/go.mod h1:VPWjmmNyRsWXQZHVHT3g0YbIINUkSmuKOiLIDkWbL6M= -github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/miekg/dns v1.1.42 h1:gWGe42RGaIqXQZ+r3WUGEKBEtvPHY2SXo4dqixDNxuY= github.com/miekg/dns v1.1.42/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -28,12 +53,22 @@ github.com/ovh/go-ovh v1.1.0 h1:bHXZmw8nTgZin4Nv7JuaLs0KG5x54EQR7migYTd1zrk= github.com/ovh/go-ovh v1.1.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA= github.com/oze4/godaddygo v1.3.19 h1:pOyN6+MEfyS32cz2LU3uPyMQiZSBCJI+WQRjFggVjYU= github.com/oze4/godaddygo v1.3.19/go.mod h1:W5+UTEo7rLLDhXFjPox6Us9fBI26rR8DI1YmqwMOb/E= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.7 h1:NSaHgaeJFCtWXCBkBKXw0rhgMuJ0VoE9FB5mWldcrQ4= github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -50,9 +85,8 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I= -golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -61,17 +95,16 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04 h1:cEhElsAv9LUt9ZUUocxzWe05oFLVd+AA2nstydTeI8g= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -86,12 +119,13 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww= gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= -gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk= gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/main.go b/main.go index 511edb3..817bf74 100644 --- a/main.go +++ b/main.go @@ -38,7 +38,6 @@ import ( "math/rand" "net" "net/http" - "net/url" "os" "os/signal" "strings" @@ -48,6 +47,7 @@ import ( "git.happydns.org/happydns/admin" "git.happydns.org/happydns/api" "git.happydns.org/happydns/config" + "git.happydns.org/happydns/internal/app" "git.happydns.org/happydns/model" "git.happydns.org/happydns/storage" @@ -62,48 +62,6 @@ import ( _ "git.happydns.org/happydns/storage/leveldb" ) -type ResponseWriterPrefix struct { - real http.ResponseWriter - prefix string -} - -func (r ResponseWriterPrefix) Header() http.Header { - return r.real.Header() -} - -func (r ResponseWriterPrefix) WriteHeader(s int) { - if v, exists := r.real.Header()["Location"]; exists { - r.real.Header().Set("Location", r.prefix+v[0]) - } - r.real.WriteHeader(s) -} - -func (r ResponseWriterPrefix) Write(z []byte) (int, error) { - return r.real.Write(z) -} - -func StripPrefix(opts *config.Options, h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Add in the context's request options - ctx := r.Context() - ctx = context.WithValue(ctx, "opts", opts) - r = r.WithContext(ctx) - - if opts.BaseURL != "" && r.URL.Path == "/" { - http.Redirect(w, r, opts.BaseURL+"/", http.StatusFound) - } else if p := strings.TrimPrefix(r.URL.Path, opts.BaseURL); len(p) < len(r.URL.Path) { - r2 := new(http.Request) - *r2 = *r - r2.URL = new(url.URL) - *r2.URL = *r.URL - r2.URL.Path = p - h.ServeHTTP(ResponseWriterPrefix{w, opts.BaseURL}, r2) - } else { - h.ServeHTTP(w, r) - } - }) -} - func main() { var err error @@ -154,10 +112,11 @@ func main() { interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM) + var adminSrv *http.Server if opts.AdminBind != "" { - adminSrv := &http.Server{ + adminSrv = &http.Server{ Addr: opts.AdminBind, - Handler: StripPrefix(opts, admin.Router()), + Handler: admin.Router(), } go func() { @@ -180,21 +139,16 @@ func main() { log.Println(fmt.Sprintf("Admin listening on %s", opts.AdminBind)) } - srv := &http.Server{ - Addr: opts.Bind, - Handler: StripPrefix(opts, api.Router()), - } - - // Serve content - go func() { - log.Fatal(srv.ListenAndServe()) - }() - log.Println(fmt.Sprintf("Ready, listening on %s", opts.Bind)) + a := app.NewApp(opts) + go a.Start() // Wait shutdown signal <-interrupt - log.Print("The service is shutting down...") - srv.Shutdown(context.Background()) - log.Println("done") + log.Println("Stopping the service...") + a.Stop() + if adminSrv != nil { + adminSrv.Shutdown(context.Background()) + } + log.Println("Stopped") } diff --git a/htdocs/.editorconfig b/ui/.editorconfig similarity index 100% rename from htdocs/.editorconfig rename to ui/.editorconfig diff --git a/ui/.env b/ui/.env new file mode 100644 index 0000000..f256c63 --- /dev/null +++ b/ui/.env @@ -0,0 +1,2 @@ +VUE_APP_I18N_LOCALE=en +VUE_APP_I18N_FALLBACK_LOCALE=en diff --git a/htdocs/.gitignore b/ui/.gitignore similarity index 100% rename from htdocs/.gitignore rename to ui/.gitignore diff --git a/htdocs/README.md b/ui/README.md similarity index 100% rename from htdocs/README.md rename to ui/README.md diff --git a/ui/assets.go b/ui/assets.go new file mode 100644 index 0000000..1c9b390 --- /dev/null +++ b/ui/assets.go @@ -0,0 +1,23 @@ +package ui + +import ( + "embed" + "io/fs" + "log" + "net/http" +) + +//go:generate yarn --offline build +//go:embed dist + +var _assets embed.FS + +var Assets http.FileSystem + +func init() { + sub, err := fs.Sub(_assets, "dist") + if err != nil { + log.Fatal("Unable to cd to dist/ directory:", err) + } + Assets = http.FS(sub) +} diff --git a/htdocs/package.json b/ui/package.json similarity index 100% rename from htdocs/package.json rename to ui/package.json diff --git a/htdocs/public/favicon.ico b/ui/public/favicon.ico similarity index 100% rename from htdocs/public/favicon.ico rename to ui/public/favicon.ico diff --git a/htdocs/public/fonts/FantasqueSansMono-Bold.woff b/ui/public/fonts/FantasqueSansMono-Bold.woff similarity index 100% rename from htdocs/public/fonts/FantasqueSansMono-Bold.woff rename to ui/public/fonts/FantasqueSansMono-Bold.woff diff --git a/htdocs/public/fonts/FantasqueSansMono-Bold.woff2 b/ui/public/fonts/FantasqueSansMono-Bold.woff2 similarity index 100% rename from htdocs/public/fonts/FantasqueSansMono-Bold.woff2 rename to ui/public/fonts/FantasqueSansMono-Bold.woff2 diff --git a/htdocs/public/fonts/FantasqueSansMono-BoldItalic.woff b/ui/public/fonts/FantasqueSansMono-BoldItalic.woff similarity index 100% rename from htdocs/public/fonts/FantasqueSansMono-BoldItalic.woff rename to ui/public/fonts/FantasqueSansMono-BoldItalic.woff diff --git a/htdocs/public/fonts/FantasqueSansMono-BoldItalic.woff2 b/ui/public/fonts/FantasqueSansMono-BoldItalic.woff2 similarity index 100% rename from htdocs/public/fonts/FantasqueSansMono-BoldItalic.woff2 rename to ui/public/fonts/FantasqueSansMono-BoldItalic.woff2 diff --git a/htdocs/public/fonts/FantasqueSansMono-Italic.woff b/ui/public/fonts/FantasqueSansMono-Italic.woff similarity index 100% rename from htdocs/public/fonts/FantasqueSansMono-Italic.woff rename to ui/public/fonts/FantasqueSansMono-Italic.woff diff --git a/htdocs/public/fonts/FantasqueSansMono-Italic.woff2 b/ui/public/fonts/FantasqueSansMono-Italic.woff2 similarity index 100% rename from htdocs/public/fonts/FantasqueSansMono-Italic.woff2 rename to ui/public/fonts/FantasqueSansMono-Italic.woff2 diff --git a/htdocs/public/fonts/FantasqueSansMono-Regular.woff b/ui/public/fonts/FantasqueSansMono-Regular.woff similarity index 100% rename from htdocs/public/fonts/FantasqueSansMono-Regular.woff rename to ui/public/fonts/FantasqueSansMono-Regular.woff diff --git a/htdocs/public/fonts/FantasqueSansMono-Regular.woff2 b/ui/public/fonts/FantasqueSansMono-Regular.woff2 similarity index 100% rename from htdocs/public/fonts/FantasqueSansMono-Regular.woff2 rename to ui/public/fonts/FantasqueSansMono-Regular.woff2 diff --git a/htdocs/public/fonts/Montserrat.woff2 b/ui/public/fonts/Montserrat.woff2 similarity index 100% rename from htdocs/public/fonts/Montserrat.woff2 rename to ui/public/fonts/Montserrat.woff2 diff --git a/htdocs/public/img/happyDNS.svg b/ui/public/img/happyDNS.svg similarity index 100% rename from htdocs/public/img/happyDNS.svg rename to ui/public/img/happyDNS.svg diff --git a/htdocs/public/img/happydns.png b/ui/public/img/happydns.png similarity index 100% rename from htdocs/public/img/happydns.png rename to ui/public/img/happydns.png diff --git a/htdocs/public/img/icons/android-chrome-192x192.png b/ui/public/img/icons/android-chrome-192x192.png similarity index 100% rename from htdocs/public/img/icons/android-chrome-192x192.png rename to ui/public/img/icons/android-chrome-192x192.png diff --git a/htdocs/public/img/icons/android-chrome-512x512.png b/ui/public/img/icons/android-chrome-512x512.png similarity index 100% rename from htdocs/public/img/icons/android-chrome-512x512.png rename to ui/public/img/icons/android-chrome-512x512.png diff --git a/htdocs/public/img/icons/apple-touch-icon-120x120.png b/ui/public/img/icons/apple-touch-icon-120x120.png similarity index 100% rename from htdocs/public/img/icons/apple-touch-icon-120x120.png rename to ui/public/img/icons/apple-touch-icon-120x120.png diff --git a/htdocs/public/img/icons/apple-touch-icon-152x152.png b/ui/public/img/icons/apple-touch-icon-152x152.png similarity index 100% rename from htdocs/public/img/icons/apple-touch-icon-152x152.png rename to ui/public/img/icons/apple-touch-icon-152x152.png diff --git a/htdocs/public/img/icons/apple-touch-icon-180x180.png b/ui/public/img/icons/apple-touch-icon-180x180.png similarity index 100% rename from htdocs/public/img/icons/apple-touch-icon-180x180.png rename to ui/public/img/icons/apple-touch-icon-180x180.png diff --git a/htdocs/public/img/icons/apple-touch-icon-60x60.png b/ui/public/img/icons/apple-touch-icon-60x60.png similarity index 100% rename from htdocs/public/img/icons/apple-touch-icon-60x60.png rename to ui/public/img/icons/apple-touch-icon-60x60.png diff --git a/htdocs/public/img/icons/apple-touch-icon-76x76.png b/ui/public/img/icons/apple-touch-icon-76x76.png similarity index 100% rename from htdocs/public/img/icons/apple-touch-icon-76x76.png rename to ui/public/img/icons/apple-touch-icon-76x76.png diff --git a/htdocs/public/img/icons/apple-touch-icon.png b/ui/public/img/icons/apple-touch-icon.png similarity index 100% rename from htdocs/public/img/icons/apple-touch-icon.png rename to ui/public/img/icons/apple-touch-icon.png diff --git a/htdocs/public/img/icons/favicon-16x16.png b/ui/public/img/icons/favicon-16x16.png similarity index 100% rename from htdocs/public/img/icons/favicon-16x16.png rename to ui/public/img/icons/favicon-16x16.png diff --git a/htdocs/public/img/icons/favicon-32x32.png b/ui/public/img/icons/favicon-32x32.png similarity index 100% rename from htdocs/public/img/icons/favicon-32x32.png rename to ui/public/img/icons/favicon-32x32.png diff --git a/ui/public/img/icons/icon-rounded.svg b/ui/public/img/icons/icon-rounded.svg new file mode 100644 index 0000000..2b961aa --- /dev/null +++ b/ui/public/img/icons/icon-rounded.svg @@ -0,0 +1,115 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + h + + + + diff --git a/htdocs/public/img/icons/msapplication-icon-144x144.png b/ui/public/img/icons/msapplication-icon-144x144.png similarity index 100% rename from htdocs/public/img/icons/msapplication-icon-144x144.png rename to ui/public/img/icons/msapplication-icon-144x144.png diff --git a/htdocs/public/img/icons/mstile-150x150.png b/ui/public/img/icons/mstile-150x150.png similarity index 100% rename from htdocs/public/img/icons/mstile-150x150.png rename to ui/public/img/icons/mstile-150x150.png diff --git a/htdocs/public/img/icons/safari-pinned-tab.svg b/ui/public/img/icons/safari-pinned-tab.svg similarity index 100% rename from htdocs/public/img/icons/safari-pinned-tab.svg rename to ui/public/img/icons/safari-pinned-tab.svg diff --git a/htdocs/public/img/screenshot.png b/ui/public/img/screenshot.png similarity index 100% rename from htdocs/public/img/screenshot.png rename to ui/public/img/screenshot.png diff --git a/htdocs/public/index.html b/ui/public/index.html similarity index 100% rename from htdocs/public/index.html rename to ui/public/index.html diff --git a/htdocs/public/manifest.json b/ui/public/manifest.json similarity index 100% rename from htdocs/public/manifest.json rename to ui/public/manifest.json diff --git a/htdocs/public/robots.txt b/ui/public/robots.txt similarity index 100% rename from htdocs/public/robots.txt rename to ui/public/robots.txt diff --git a/ui/routes.go b/ui/routes.go new file mode 100644 index 0000000..563ca77 --- /dev/null +++ b/ui/routes.go @@ -0,0 +1,83 @@ +package ui + +import ( + "io" + "net/http" + "net/url" + "path" + + "github.com/gin-gonic/gin" + + "git.happydns.org/happydns/config" +) + +func DeclareRoutes(cfg *config.Options, router *gin.Engine) { + router.GET("/", serveOrReverse("/", cfg)) + + // Routes handled by the showcase + router.GET("/en/*_", serveOrReverse("/", cfg)) + router.GET("/fr/*_", serveOrReverse("/", cfg)) + + // Routes for real existings files + router.GET("/css/*path", serveOrReverse("", cfg)) + router.GET("/fonts/*path", serveOrReverse("", cfg)) + router.GET("/img/*path", serveOrReverse("", cfg)) + router.GET("/js/*path", serveOrReverse("", cfg)) + router.GET("/favicon.ico", serveOrReverse("", cfg)) + router.GET("/manifest.json", serveOrReverse("", cfg)) + router.GET("/robots.txt", serveOrReverse("", cfg)) + router.GET("/service-worker.js", serveOrReverse("", cfg)) + + // Routes to virtual content + router.GET("/domains/*_", serveOrReverse("/", cfg)) + router.GET("/email-validation", serveOrReverse("/", cfg)) + router.GET("/forgotten-password", serveOrReverse("/", cfg)) + router.GET("/join", serveOrReverse("/", cfg)) + router.GET("/login", serveOrReverse("/", cfg)) + router.GET("/me", serveOrReverse("/", cfg)) + router.GET("/onboarding/*_", serveOrReverse("/", cfg)) + router.GET("/services/*_", serveOrReverse("/", cfg)) + router.GET("/sources/*_", serveOrReverse("/", cfg)) + router.GET("/tools/*_", serveOrReverse("/", cfg)) + router.GET("/resolver/*_", serveOrReverse("/", cfg)) + router.GET("/zones/*_", serveOrReverse("/", cfg)) +} + +func serveOrReverse(forced_url string, cfg *config.Options) gin.HandlerFunc { + if cfg.DevProxy != "" { + return func(c *gin.Context) { + if u, err := url.Parse(cfg.DevProxy); err != nil { + http.Error(c.Writer, err.Error(), http.StatusInternalServerError) + } else { + if forced_url != "" { + u.Path = path.Join(u.Path, forced_url) + } else { + u.Path = path.Join(u.Path, c.Request.URL.Path) + } + + if r, err := http.NewRequest(c.Request.Method, u.String(), c.Request.Body); err != nil { + http.Error(c.Writer, err.Error(), http.StatusInternalServerError) + } else if resp, err := http.DefaultClient.Do(r); err != nil { + http.Error(c.Writer, err.Error(), http.StatusBadGateway) + } else { + defer resp.Body.Close() + + for key := range resp.Header { + c.Writer.Header().Add(key, resp.Header.Get(key)) + } + c.Writer.WriteHeader(resp.StatusCode) + + io.Copy(c.Writer, resp.Body) + } + } + } + } else if forced_url != "" { + return func(c *gin.Context) { + c.FileFromFS(forced_url, Assets) + } + } else { + return func(c *gin.Context) { + c.FileFromFS(c.Request.URL.Path, Assets) + } + } +} diff --git a/htdocs/src/App.vue b/ui/src/App.vue similarity index 100% rename from htdocs/src/App.vue rename to ui/src/App.vue diff --git a/htdocs/src/api/api.js b/ui/src/api/api.js similarity index 100% rename from htdocs/src/api/api.js rename to ui/src/api/api.js diff --git a/htdocs/src/api/domains.js b/ui/src/api/domains.js similarity index 100% rename from htdocs/src/api/domains.js rename to ui/src/api/domains.js diff --git a/htdocs/src/api/sourceSpecs.js b/ui/src/api/sourceSpecs.js similarity index 100% rename from htdocs/src/api/sourceSpecs.js rename to ui/src/api/sourceSpecs.js diff --git a/htdocs/src/api/sources.js b/ui/src/api/sources.js similarity index 100% rename from htdocs/src/api/sources.js rename to ui/src/api/sources.js diff --git a/htdocs/src/api/user.js b/ui/src/api/user.js similarity index 100% rename from htdocs/src/api/user.js rename to ui/src/api/user.js diff --git a/htdocs/src/api/zones.js b/ui/src/api/zones.js similarity index 100% rename from htdocs/src/api/zones.js rename to ui/src/api/zones.js diff --git a/htdocs/src/app.scss b/ui/src/app.scss similarity index 100% rename from htdocs/src/app.scss rename to ui/src/app.scss diff --git a/htdocs/src/assets/css/glyphicon.css b/ui/src/assets/css/glyphicon.css similarity index 100% rename from htdocs/src/assets/css/glyphicon.css rename to ui/src/assets/css/glyphicon.css diff --git a/htdocs/src/assets/fonts/glyphicons-halflings-regular.eot b/ui/src/assets/fonts/glyphicons-halflings-regular.eot similarity index 100% rename from htdocs/src/assets/fonts/glyphicons-halflings-regular.eot rename to ui/src/assets/fonts/glyphicons-halflings-regular.eot diff --git a/htdocs/src/assets/fonts/glyphicons-halflings-regular.svg b/ui/src/assets/fonts/glyphicons-halflings-regular.svg similarity index 100% rename from htdocs/src/assets/fonts/glyphicons-halflings-regular.svg rename to ui/src/assets/fonts/glyphicons-halflings-regular.svg diff --git a/htdocs/src/assets/fonts/glyphicons-halflings-regular.ttf b/ui/src/assets/fonts/glyphicons-halflings-regular.ttf similarity index 100% rename from htdocs/src/assets/fonts/glyphicons-halflings-regular.ttf rename to ui/src/assets/fonts/glyphicons-halflings-regular.ttf diff --git a/htdocs/src/assets/fonts/glyphicons-halflings-regular.woff b/ui/src/assets/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from htdocs/src/assets/fonts/glyphicons-halflings-regular.woff rename to ui/src/assets/fonts/glyphicons-halflings-regular.woff diff --git a/htdocs/src/assets/fonts/glyphicons-halflings-regular.woff2 b/ui/src/assets/fonts/glyphicons-halflings-regular.woff2 similarity index 100% rename from htdocs/src/assets/fonts/glyphicons-halflings-regular.woff2 rename to ui/src/assets/fonts/glyphicons-halflings-regular.woff2 diff --git a/htdocs/src/assets/logo.png b/ui/src/assets/logo.png similarity index 100% rename from htdocs/src/assets/logo.png rename to ui/src/assets/logo.png diff --git a/htdocs/src/components/ZoneList.vue b/ui/src/components/ZoneList.vue similarity index 100% rename from htdocs/src/components/ZoneList.vue rename to ui/src/components/ZoneList.vue diff --git a/htdocs/src/components/hCustomForm.vue b/ui/src/components/hCustomForm.vue similarity index 100% rename from htdocs/src/components/hCustomForm.vue rename to ui/src/components/hCustomForm.vue diff --git a/htdocs/src/components/hDomainService.vue b/ui/src/components/hDomainService.vue similarity index 100% rename from htdocs/src/components/hDomainService.vue rename to ui/src/components/hDomainService.vue diff --git a/ui/src/components/hDomainServiceNew.vue b/ui/src/components/hDomainServiceNew.vue new file mode 100644 index 0000000..b99c511 --- /dev/null +++ b/ui/src/components/hDomainServiceNew.vue @@ -0,0 +1,153 @@ + + + + + diff --git a/htdocs/src/components/hEditableService.vue b/ui/src/components/hEditableService.vue similarity index 100% rename from htdocs/src/components/hEditableService.vue rename to ui/src/components/hEditableService.vue diff --git a/htdocs/src/components/hFamilyTabs.vue b/ui/src/components/hFamilyTabs.vue similarity index 100% rename from htdocs/src/components/hFamilyTabs.vue rename to ui/src/components/hFamilyTabs.vue diff --git a/htdocs/src/components/hFields.vue b/ui/src/components/hFields.vue similarity index 100% rename from htdocs/src/components/hFields.vue rename to ui/src/components/hFields.vue diff --git a/htdocs/src/components/hHelp.vue b/ui/src/components/hHelp.vue similarity index 100% rename from htdocs/src/components/hHelp.vue rename to ui/src/components/hHelp.vue diff --git a/htdocs/src/components/hLinedRecord.vue b/ui/src/components/hLinedRecord.vue similarity index 100% rename from htdocs/src/components/hLinedRecord.vue rename to ui/src/components/hLinedRecord.vue diff --git a/htdocs/src/components/hListGroupInput.vue b/ui/src/components/hListGroupInput.vue similarity index 100% rename from htdocs/src/components/hListGroupInput.vue rename to ui/src/components/hListGroupInput.vue diff --git a/htdocs/src/components/hListGroupInputNewDomain.vue b/ui/src/components/hListGroupInputNewDomain.vue similarity index 100% rename from htdocs/src/components/hListGroupInputNewDomain.vue rename to ui/src/components/hListGroupInputNewDomain.vue diff --git a/htdocs/src/components/hModalAddSource.vue b/ui/src/components/hModalAddSource.vue similarity index 100% rename from htdocs/src/components/hModalAddSource.vue rename to ui/src/components/hModalAddSource.vue diff --git a/htdocs/src/components/hModalService.vue b/ui/src/components/hModalService.vue similarity index 100% rename from htdocs/src/components/hModalService.vue rename to ui/src/components/hModalService.vue diff --git a/htdocs/src/components/hNewSourceSelector.vue b/ui/src/components/hNewSourceSelector.vue similarity index 100% rename from htdocs/src/components/hNewSourceSelector.vue rename to ui/src/components/hNewSourceSelector.vue diff --git a/htdocs/src/components/hRecord.vue b/ui/src/components/hRecord.vue similarity index 100% rename from htdocs/src/components/hRecord.vue rename to ui/src/components/hRecord.vue diff --git a/htdocs/src/components/hRecordHead.vue b/ui/src/components/hRecordHead.vue similarity index 100% rename from htdocs/src/components/hRecordHead.vue rename to ui/src/components/hRecordHead.vue diff --git a/htdocs/src/components/hResourceValue.vue b/ui/src/components/hResourceValue.vue similarity index 100% rename from htdocs/src/components/hResourceValue.vue rename to ui/src/components/hResourceValue.vue diff --git a/htdocs/src/components/hResourceValueInput.vue b/ui/src/components/hResourceValueInput.vue similarity index 100% rename from htdocs/src/components/hResourceValueInput.vue rename to ui/src/components/hResourceValueInput.vue diff --git a/htdocs/src/components/hResourceValueInputRaw.vue b/ui/src/components/hResourceValueInputRaw.vue similarity index 100% rename from htdocs/src/components/hResourceValueInputRaw.vue rename to ui/src/components/hResourceValueInputRaw.vue diff --git a/htdocs/src/components/hResourceValueMap.vue b/ui/src/components/hResourceValueMap.vue similarity index 100% rename from htdocs/src/components/hResourceValueMap.vue rename to ui/src/components/hResourceValueMap.vue diff --git a/htdocs/src/components/hResourceValueObject.vue b/ui/src/components/hResourceValueObject.vue similarity index 100% rename from htdocs/src/components/hResourceValueObject.vue rename to ui/src/components/hResourceValueObject.vue diff --git a/htdocs/src/components/hResourceValueSimpleInput.vue b/ui/src/components/hResourceValueSimpleInput.vue similarity index 100% rename from htdocs/src/components/hResourceValueSimpleInput.vue rename to ui/src/components/hResourceValueSimpleInput.vue diff --git a/htdocs/src/components/hResourceValueTable.vue b/ui/src/components/hResourceValueTable.vue similarity index 100% rename from htdocs/src/components/hResourceValueTable.vue rename to ui/src/components/hResourceValueTable.vue diff --git a/htdocs/src/components/hSourceListDomains.vue b/ui/src/components/hSourceListDomains.vue similarity index 100% rename from htdocs/src/components/hSourceListDomains.vue rename to ui/src/components/hSourceListDomains.vue diff --git a/htdocs/src/components/hSourceState.vue b/ui/src/components/hSourceState.vue similarity index 100% rename from htdocs/src/components/hSourceState.vue rename to ui/src/components/hSourceState.vue diff --git a/htdocs/src/components/hSourceStateButtons.vue b/ui/src/components/hSourceStateButtons.vue similarity index 100% rename from htdocs/src/components/hSourceStateButtons.vue rename to ui/src/components/hSourceStateButtons.vue diff --git a/htdocs/src/components/hSubdomainItem.vue b/ui/src/components/hSubdomainItem.vue similarity index 100% rename from htdocs/src/components/hSubdomainItem.vue rename to ui/src/components/hSubdomainItem.vue diff --git a/htdocs/src/components/hSubdomainList.vue b/ui/src/components/hSubdomainList.vue similarity index 100% rename from htdocs/src/components/hSubdomainList.vue rename to ui/src/components/hSubdomainList.vue diff --git a/htdocs/src/components/hUserSourceSelector.vue b/ui/src/components/hUserSourceSelector.vue similarity index 100% rename from htdocs/src/components/hUserSourceSelector.vue rename to ui/src/components/hUserSourceSelector.vue diff --git a/htdocs/src/components/logo.vue b/ui/src/components/logo.vue similarity index 100% rename from htdocs/src/components/logo.vue rename to ui/src/components/logo.vue diff --git a/htdocs/src/components/sourceList.vue b/ui/src/components/sourceList.vue similarity index 100% rename from htdocs/src/components/sourceList.vue rename to ui/src/components/sourceList.vue diff --git a/htdocs/src/i18n.js b/ui/src/i18n.js similarity index 100% rename from htdocs/src/i18n.js rename to ui/src/i18n.js diff --git a/htdocs/src/locales/en.json b/ui/src/locales/en.json similarity index 100% rename from htdocs/src/locales/en.json rename to ui/src/locales/en.json diff --git a/htdocs/src/locales/fr.json b/ui/src/locales/fr.json similarity index 100% rename from htdocs/src/locales/fr.json rename to ui/src/locales/fr.json diff --git a/htdocs/src/main.js b/ui/src/main.js similarity index 100% rename from htdocs/src/main.js rename to ui/src/main.js diff --git a/htdocs/src/mixins/addDomainToSource.js b/ui/src/mixins/addDomainToSource.js similarity index 100% rename from htdocs/src/mixins/addDomainToSource.js rename to ui/src/mixins/addDomainToSource.js diff --git a/htdocs/src/mixins/customForm.js b/ui/src/mixins/customForm.js similarity index 100% rename from htdocs/src/mixins/customForm.js rename to ui/src/mixins/customForm.js diff --git a/htdocs/src/mixins/fieldsDescription.js b/ui/src/mixins/fieldsDescription.js similarity index 100% rename from htdocs/src/mixins/fieldsDescription.js rename to ui/src/mixins/fieldsDescription.js diff --git a/htdocs/src/mixins/languages.js b/ui/src/mixins/languages.js similarity index 100% rename from htdocs/src/mixins/languages.js rename to ui/src/mixins/languages.js diff --git a/htdocs/src/mixins/passwordChecks.js b/ui/src/mixins/passwordChecks.js similarity index 100% rename from htdocs/src/mixins/passwordChecks.js rename to ui/src/mixins/passwordChecks.js diff --git a/htdocs/src/mixins/sourceSpecs.js b/ui/src/mixins/sourceSpecs.js similarity index 100% rename from htdocs/src/mixins/sourceSpecs.js rename to ui/src/mixins/sourceSpecs.js diff --git a/htdocs/src/mixins/sourceState.js b/ui/src/mixins/sourceState.js similarity index 100% rename from htdocs/src/mixins/sourceState.js rename to ui/src/mixins/sourceState.js diff --git a/htdocs/src/mixins/validateDomain.js b/ui/src/mixins/validateDomain.js similarity index 100% rename from htdocs/src/mixins/validateDomain.js rename to ui/src/mixins/validateDomain.js diff --git a/htdocs/src/registerServiceWorker.js b/ui/src/registerServiceWorker.js similarity index 100% rename from htdocs/src/registerServiceWorker.js rename to ui/src/registerServiceWorker.js diff --git a/htdocs/src/router/index.js b/ui/src/router/index.js similarity index 100% rename from htdocs/src/router/index.js rename to ui/src/router/index.js diff --git a/htdocs/src/service-worker.js b/ui/src/service-worker.js similarity index 100% rename from htdocs/src/service-worker.js rename to ui/src/service-worker.js diff --git a/htdocs/src/services/Api.js b/ui/src/services/Api.js similarity index 100% rename from htdocs/src/services/Api.js rename to ui/src/services/Api.js diff --git a/htdocs/src/services/ServiceSpecsApi.js b/ui/src/services/ServiceSpecsApi.js similarity index 100% rename from htdocs/src/services/ServiceSpecsApi.js rename to ui/src/services/ServiceSpecsApi.js diff --git a/htdocs/src/services/ServicesApi.js b/ui/src/services/ServicesApi.js similarity index 100% rename from htdocs/src/services/ServicesApi.js rename to ui/src/services/ServicesApi.js diff --git a/htdocs/src/services/SourceSettingsApi.js b/ui/src/services/SourceSettingsApi.js similarity index 100% rename from htdocs/src/services/SourceSettingsApi.js rename to ui/src/services/SourceSettingsApi.js diff --git a/htdocs/src/services/SourceSpecsApi.js b/ui/src/services/SourceSpecsApi.js similarity index 100% rename from htdocs/src/services/SourceSpecsApi.js rename to ui/src/services/SourceSpecsApi.js diff --git a/htdocs/src/services/SourcesApi.js b/ui/src/services/SourcesApi.js similarity index 100% rename from htdocs/src/services/SourcesApi.js rename to ui/src/services/SourcesApi.js diff --git a/htdocs/src/store/index.js b/ui/src/store/index.js similarity index 100% rename from htdocs/src/store/index.js rename to ui/src/store/index.js diff --git a/htdocs/src/store/module/domains.js b/ui/src/store/module/domains.js similarity index 100% rename from htdocs/src/store/module/domains.js rename to ui/src/store/module/domains.js diff --git a/htdocs/src/store/module/sourceSpecs.js b/ui/src/store/module/sourceSpecs.js similarity index 100% rename from htdocs/src/store/module/sourceSpecs.js rename to ui/src/store/module/sourceSpecs.js diff --git a/htdocs/src/store/module/sources.js b/ui/src/store/module/sources.js similarity index 100% rename from htdocs/src/store/module/sources.js rename to ui/src/store/module/sources.js diff --git a/htdocs/src/store/module/user.js b/ui/src/store/module/user.js similarity index 100% rename from htdocs/src/store/module/user.js rename to ui/src/store/module/user.js diff --git a/htdocs/src/utils/domainCompare.js b/ui/src/utils/domainCompare.js similarity index 100% rename from htdocs/src/utils/domainCompare.js rename to ui/src/utils/domainCompare.js diff --git a/htdocs/src/utils/recordsFields.js b/ui/src/utils/recordsFields.js similarity index 100% rename from htdocs/src/utils/recordsFields.js rename to ui/src/utils/recordsFields.js diff --git a/htdocs/src/views/404.vue b/ui/src/views/404.vue similarity index 100% rename from htdocs/src/views/404.vue rename to ui/src/views/404.vue diff --git a/htdocs/src/views/Index.vue b/ui/src/views/Index.vue similarity index 100% rename from htdocs/src/views/Index.vue rename to ui/src/views/Index.vue diff --git a/htdocs/src/views/domain-new.vue b/ui/src/views/domain-new.vue similarity index 100% rename from htdocs/src/views/domain-new.vue rename to ui/src/views/domain-new.vue diff --git a/htdocs/src/views/domain-source.vue b/ui/src/views/domain-source.vue similarity index 100% rename from htdocs/src/views/domain-source.vue rename to ui/src/views/domain-source.vue diff --git a/htdocs/src/views/domain.vue b/ui/src/views/domain.vue similarity index 100% rename from htdocs/src/views/domain.vue rename to ui/src/views/domain.vue diff --git a/htdocs/src/views/email-validation.vue b/ui/src/views/email-validation.vue similarity index 100% rename from htdocs/src/views/email-validation.vue rename to ui/src/views/email-validation.vue diff --git a/htdocs/src/views/forgotten-password.vue b/ui/src/views/forgotten-password.vue similarity index 100% rename from htdocs/src/views/forgotten-password.vue rename to ui/src/views/forgotten-password.vue diff --git a/htdocs/src/views/home.vue b/ui/src/views/home.vue similarity index 100% rename from htdocs/src/views/home.vue rename to ui/src/views/home.vue diff --git a/htdocs/src/views/loading.vue b/ui/src/views/loading.vue similarity index 100% rename from htdocs/src/views/loading.vue rename to ui/src/views/loading.vue diff --git a/htdocs/src/views/login.vue b/ui/src/views/login.vue similarity index 100% rename from htdocs/src/views/login.vue rename to ui/src/views/login.vue diff --git a/htdocs/src/views/me.vue b/ui/src/views/me.vue similarity index 100% rename from htdocs/src/views/me.vue rename to ui/src/views/me.vue diff --git a/htdocs/src/views/onboarding.vue b/ui/src/views/onboarding.vue similarity index 100% rename from htdocs/src/views/onboarding.vue rename to ui/src/views/onboarding.vue diff --git a/htdocs/src/views/signup.vue b/ui/src/views/signup.vue similarity index 100% rename from htdocs/src/views/signup.vue rename to ui/src/views/signup.vue diff --git a/htdocs/src/views/source-list.vue b/ui/src/views/source-list.vue similarity index 100% rename from htdocs/src/views/source-list.vue rename to ui/src/views/source-list.vue diff --git a/htdocs/src/views/source-new-choice.vue b/ui/src/views/source-new-choice.vue similarity index 100% rename from htdocs/src/views/source-new-choice.vue rename to ui/src/views/source-new-choice.vue diff --git a/htdocs/src/views/source-new-state.vue b/ui/src/views/source-new-state.vue similarity index 100% rename from htdocs/src/views/source-new-state.vue rename to ui/src/views/source-new-state.vue diff --git a/htdocs/src/views/source-new.vue b/ui/src/views/source-new.vue similarity index 100% rename from htdocs/src/views/source-new.vue rename to ui/src/views/source-new.vue diff --git a/htdocs/src/views/source.vue b/ui/src/views/source.vue similarity index 100% rename from htdocs/src/views/source.vue rename to ui/src/views/source.vue diff --git a/htdocs/src/views/tools-client.vue b/ui/src/views/tools-client.vue similarity index 100% rename from htdocs/src/views/tools-client.vue rename to ui/src/views/tools-client.vue diff --git a/htdocs/src/views/zone-records.vue b/ui/src/views/zone-records.vue similarity index 100% rename from htdocs/src/views/zone-records.vue rename to ui/src/views/zone-records.vue diff --git a/htdocs/vue.config.js b/ui/vue.config.js similarity index 100% rename from htdocs/vue.config.js rename to ui/vue.config.js diff --git a/htdocs/yarn.lock b/ui/yarn.lock similarity index 100% rename from htdocs/yarn.lock rename to ui/yarn.lock