diff --git a/.gitignore b/.gitignore index cf8b1ff..d2fe01d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ releases collerd.db !docker/collerd.json collerd.json +node_modules diff --git a/Makefile b/Makefile index cb3b93c..547f06e 100644 --- a/Makefile +++ b/Makefile @@ -55,6 +55,9 @@ releases: build_linux_amd64 build_darwin_arm64 archive_linux_amd64 archive_darwi releases_with_docker: docker run -it -v $(shell pwd):/mnt -w /mnt -e "UID=$(shell id -u)" -e "GID=$(shell id -g)" ${DOCKER_IMAGE} ./docker/build.sh +dependencies: + npm install + test: cd src \ && go test internal/*.go \ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4cf810c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,40 @@ +{ + "name": "coller", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "bootstrap": "^5.3.8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/bootstrap": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz", + "integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..719e5df --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "bootstrap": "^5.3.8" + } +} diff --git a/src/cmd/collerd/README.md b/src/cmd/collerd/README.md index 114604e..5f9a06d 100644 --- a/src/cmd/collerd/README.md +++ b/src/cmd/collerd/README.md @@ -36,6 +36,7 @@ The file format is **JSON**: * **enable_upload_file_button** (bool): Display the upload file button in the UI (default true) * **tls_cert_file** (string): Path to TLS certificate file to enable HTTPS * **tls_key_file** (string): Path to TLS key file to enable HTTPS +* **bootstrap_directory** (string): Serve [Bootstrap](https://getbootstrap.com/) assets from this local directory (ex: "./node_modules/bootstrap/dist"). See **Dependencies** for details. The configuration file is not required but the service might not be exposed to the public. @@ -78,4 +79,35 @@ If the note is encrypted, the encrypted value is returned (application/octet-str Errors return **500 Server Internal Error** with the **JSON** payload: * **message** (string): context of the error -* **error** (string): error message \ No newline at end of file +* **error** (string): error message + +## Dependencies + +The web interface depends on: + +- [Bootstrap](https://getbootstrap.com/) +- [Monaco Editor](https://github.com/microsoft/monaco-editor/) + +By default, those dependencies are fetched from **remote CDN** services by the client. + +If you would like to download them to serve them locally: + +``` +npm install +``` + +or via `make`: + +``` +make dependencies +``` + +Then configure the local directories: + +```json +{ + "bootstrap_directory": "./node_modules/bootstrap/dist" +} +``` + +Downloading Monaco Editor is not supported yet. diff --git a/src/server/config.go b/src/server/config.go index 060f693..f07c9a7 100644 --- a/src/server/config.go +++ b/src/server/config.go @@ -28,6 +28,7 @@ type Config struct { EnableUploadFileButton bool `json:"enable_upload_file_button"` TLSCertFile string `json:"tls_cert_file"` TLSKeyFile string `json:"tls_key_file"` + BootstrapDirectory string `json:"bootstrap_directory"` } func NewConfig() *Config { diff --git a/src/server/server.go b/src/server/server.go index 26f8e75..f8a2d3f 100644 --- a/src/server/server.go +++ b/src/server/server.go @@ -196,6 +196,7 @@ type PageData struct { URL string Note *Note EnableUploadFileButton bool + BootstrapDirectory string } type HomeHandler struct { @@ -430,10 +431,11 @@ func (s *Server) Start() error { "string": func(b []byte) string { return string(b) }, } p := PageData{ - Title: s.config.Title, - Expirations: s.config.Expirations, - Expiration: s.config.Expiration, - Languages: s.config.Languages, + Title: s.config.Title, + Expirations: s.config.Expirations, + Expiration: s.config.Expiration, + Languages: s.config.Languages, + BootstrapDirectory: s.config.BootstrapDirectory, } if s.config.ShowVersion { @@ -470,6 +472,10 @@ func (s *Server) Start() error { } r.Path("/{id:[a-zA-Z0-9]+}.html").Handler(webNoteHandler).Methods("GET") + if s.config.BootstrapDirectory != "" { + r.PathPrefix("/static/bootstrap/").Handler(http.StripPrefix("/static/bootstrap/", http.FileServer(http.Dir(s.config.BootstrapDirectory)))) + } + r.Path("/").Handler(&HomeHandler{Templates: templates, PageData: p}).Methods("GET") addr := fmt.Sprintf("%s:%d", s.config.ListenAddress, s.config.ListenPort) diff --git a/src/server/templates/head.html b/src/server/templates/head.html index bd8edba..e5f3544 100644 --- a/src/server/templates/head.html +++ b/src/server/templates/head.html @@ -4,6 +4,6 @@ {{.Title}} - + {{end}} \ No newline at end of file