Init
This commit is contained in:
commit
9d1eb7ae6a
1
.bin/acorn
Symbolic link
1
.bin/acorn
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/acorn/bin/acorn
|
1
.bin/browserslist
Symbolic link
1
.bin/browserslist
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/browserslist/cli.js
|
1
.bin/browserslist-lint
Symbolic link
1
.bin/browserslist-lint
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/update-browserslist-db/cli.js
|
1
.bin/envinfo
Symbolic link
1
.bin/envinfo
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/envinfo/dist/cli.js
|
1
.bin/esbuild
Symbolic link
1
.bin/esbuild
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/esbuild/bin/esbuild
|
1
.bin/import-local-fixture
Symbolic link
1
.bin/import-local-fixture
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/import-local/fixtures/cli.js
|
1
.bin/jsesc
Symbolic link
1
.bin/jsesc
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/jsesc/bin/jsesc
|
1
.bin/json5
Symbolic link
1
.bin/json5
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/json5/lib/cli.js
|
1
.bin/loose-envify
Symbolic link
1
.bin/loose-envify
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/loose-envify/cli.js
|
1
.bin/nanoid
Symbolic link
1
.bin/nanoid
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/nanoid/bin/nanoid.cjs
|
1
.bin/node-which
Symbolic link
1
.bin/node-which
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/which/bin/node-which
|
1
.bin/resolve
Symbolic link
1
.bin/resolve
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/resolve/bin/resolve
|
1
.bin/rollup
Symbolic link
1
.bin/rollup
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/rollup/dist/bin/rollup
|
1
.bin/semver
Symbolic link
1
.bin/semver
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/semver/bin/semver.js
|
1
.bin/terser
Symbolic link
1
.bin/terser
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/terser/bin/terser
|
1
.bin/tsserver
Symbolic link
1
.bin/tsserver
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/typescript/bin/tsserver
|
1
.bin/webpack
Symbolic link
1
.bin/webpack
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/webpack/bin/webpack.js
|
1
.bin/webpack-cli
Symbolic link
1
.bin/webpack-cli
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../node_modules/webpack-cli/bin/cli.js
|
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
go_modules
|
||||||
|
gupm_modules
|
||||||
|
node_modules
|
||||||
|
build
|
||||||
|
dev.gs
|
||||||
|
localcert.csr
|
||||||
|
localcert.crt
|
||||||
|
localcert.key
|
||||||
|
.vite
|
||||||
|
dev.json
|
7
.gupm_rc.gs
Normal file
7
.gupm_rc.gs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// look up dependencies in local go_modules and gupm_modules directories
|
||||||
|
env("GOPATH", run("go", ["env", "GOROOT"]) + ":" + pwd() + "/go_modules" + ":" + pwd() + "/gupm_modules")
|
||||||
|
|
||||||
|
// dev mode
|
||||||
|
env("MONGODB", readJsonFile("dev.json").MONGODB)
|
||||||
|
env("HTTP_PORT", 8080)
|
||||||
|
env("HTTPS_PORT", 8443)
|
5
build.gs
Normal file
5
build.gs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
removeFiles(["build"]);
|
||||||
|
var goArgs = ["build", "-o", "build/bin"]
|
||||||
|
goArgs = goArgs.concat(dir("src/*.go"))
|
||||||
|
exec("go", goArgs);
|
||||||
|
copyFiles("client/dist/", "build/static/")
|
40
client/dist/assets/index-fb8d864c.js
vendored
Normal file
40
client/dist/assets/index-fb8d864c.js
vendored
Normal file
File diff suppressed because one or more lines are too long
14
client/dist/index.html
vendored
Normal file
14
client/dist/index.html
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite App</title>
|
||||||
|
<script type="module" crossorigin src="/assets/index-fb8d864c.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
13
client/index.html
Normal file
13
client/index.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite App</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
0
client/src/main.css
Normal file
0
client/src/main.css
Normal file
9
client/src/main.tsx
Normal file
9
client/src/main.tsx
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import React from 'react'
|
||||||
|
import ReactDOM from 'react-dom/client'
|
||||||
|
import './main.css'
|
||||||
|
|
||||||
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<div>Hello</div>
|
||||||
|
</React.StrictMode>
|
||||||
|
)
|
11
generate-certificate.sh
Normal file
11
generate-certificate.sh
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/ash
|
||||||
|
FILE_CERT_NAME=localcert
|
||||||
|
if [ -f "certificates/$FILE_CERT_NAME.crt" ] && [ -f "$FILE_CERT_NAME.key" ] ; then
|
||||||
|
echo "Cert and Key already exist"
|
||||||
|
else
|
||||||
|
echo "Cert and Key does not exist, trying to create new ones..."
|
||||||
|
apk update && apk add openssl && rm -rf /var/cache/apk/*
|
||||||
|
openssl req -new -subj "/C=US/ST=California/CN=localhost" \
|
||||||
|
-newkey rsa:2048 -nodes -keyout "$FILE_CERT_NAME.key" -out "$FILE_CERT_NAME.csr"
|
||||||
|
openssl x509 -req -days 365 -in "$FILE_CERT_NAME.csr" -signkey "$FILE_CERT_NAME.key" -out "$FILE_CERT_NAME.crt" -extfile "self-signed-cert.ext"
|
||||||
|
fi
|
32
gupm.json
Normal file
32
gupm.json
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"author": "Yann Stepienik",
|
||||||
|
"cli": {
|
||||||
|
"aliases": {
|
||||||
|
"start": "build/bin",
|
||||||
|
"certificate": "sh generate-certificate.sh"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"default": {
|
||||||
|
"go://github.com/go-playground/validator/v10": "master",
|
||||||
|
"go://github.com/gorilla/mux": "master",
|
||||||
|
"go://github.com/imdario/mergo": "master",
|
||||||
|
"go://github.com/joho/godotenv": "master",
|
||||||
|
"go://github.com/lib/pq": "master",
|
||||||
|
"go://github.com/pquerna/ffjson": "master",
|
||||||
|
"go://go.mongodb.org/mongo-driver": "master",
|
||||||
|
"go://gopkg.in/ffmt.v1": "v1.5.6",
|
||||||
|
"npm://@esbuild/linux-x64": "0.16.17",
|
||||||
|
"npm://@vitejs/plugin-react": "3.1.0",
|
||||||
|
"npm://react": "18.2.0",
|
||||||
|
"npm://react-dom": "18.2.0",
|
||||||
|
"npm://typescript": "4.9.5",
|
||||||
|
"npm://vite": "4.1.1"
|
||||||
|
},
|
||||||
|
"defaultProvider": "go"
|
||||||
|
},
|
||||||
|
"description": "MyData file server",
|
||||||
|
"license": "ISC",
|
||||||
|
"name": "myFileServer",
|
||||||
|
"wrapInstallFolder": "src"
|
||||||
|
}
|
30
readme.md
Normal file
30
readme.md
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# GUCO Server
|
||||||
|
|
||||||
|
blablabla ...
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
blablabala ...
|
||||||
|
|
||||||
|
# Build locally
|
||||||
|
|
||||||
|
You need [GuPM](https://github.com/azukaar/GuPM) with the [provider-go](https://github.com/azukaar/GuPM-official#provider-go) plugin to run this project.
|
||||||
|
|
||||||
|
```
|
||||||
|
g make
|
||||||
|
```
|
||||||
|
|
||||||
|
# Run locally
|
||||||
|
|
||||||
|
First create a file called dev.json with:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"MONGODB": "your mongodb connection string"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
g build
|
||||||
|
g start
|
||||||
|
```
|
4
self-signed-cert.ext
Normal file
4
self-signed-cert.ext
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
subjectAltName = @alt_names
|
||||||
|
[alt_names]
|
||||||
|
DNS.1 = localhost
|
||||||
|
DNS.2 = https-server
|
59
src/file/copy.go
Normal file
59
src/file/copy.go
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"io"
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
"../utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func copyFile(src, dst string) error {
|
||||||
|
in, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer in.Close()
|
||||||
|
|
||||||
|
out, err := os.Create(dst)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(out, in)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return out.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func FileCopy(w http.ResponseWriter, req *http.Request) {
|
||||||
|
utils.SetHeaders(w)
|
||||||
|
|
||||||
|
fullPath := req.URL.Query().Get("path")
|
||||||
|
if fullPath == "" {
|
||||||
|
log.Println("No path specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := utils.GetRealPath(fullPath)
|
||||||
|
|
||||||
|
fullDestination := req.URL.Query().Get("destination")
|
||||||
|
if fullDestination == "" {
|
||||||
|
log.Println("No destination specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
destination := utils.GetRealPath(fullDestination)
|
||||||
|
|
||||||
|
// copy file to destination
|
||||||
|
err := copyFile(filePath, destination)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// return json object
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||||
|
"Status": "OK",
|
||||||
|
})
|
||||||
|
}
|
31
src/file/delete.go
Normal file
31
src/file/delete.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
"../utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FileDelete(w http.ResponseWriter, req *http.Request) {
|
||||||
|
utils.SetHeaders(w)
|
||||||
|
|
||||||
|
fullPath := req.URL.Query().Get("path")
|
||||||
|
if fullPath == "" {
|
||||||
|
log.Println("No path specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := utils.GetRealPath(fullPath)
|
||||||
|
|
||||||
|
// delete file
|
||||||
|
err := os.Remove(filePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// return json object
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||||
|
"Status": "OK",
|
||||||
|
})
|
||||||
|
}
|
112
src/file/get.go
Normal file
112
src/file/get.go
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
package file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
"os"
|
||||||
|
// "bytes"
|
||||||
|
// "mime/multipart"
|
||||||
|
"bufio"
|
||||||
|
"strconv"
|
||||||
|
"../utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getExtension(path string) string {
|
||||||
|
return strings.Split(path, ".")[len(strings.Split(path, ".")) - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func getContentType(path string) string {
|
||||||
|
switch getExtension(path) {
|
||||||
|
case "html":
|
||||||
|
return "text/html"
|
||||||
|
case "css":
|
||||||
|
return "text/css"
|
||||||
|
case "js":
|
||||||
|
return "application/javascript"
|
||||||
|
case "png":
|
||||||
|
return "image/png"
|
||||||
|
case "jpg":
|
||||||
|
return "image/jpeg"
|
||||||
|
case "jpeg":
|
||||||
|
return "image/jpeg"
|
||||||
|
case "gif":
|
||||||
|
return "image/gif"
|
||||||
|
case "svg":
|
||||||
|
return "image/svg+xml"
|
||||||
|
case "mp4":
|
||||||
|
return "video/mp4"
|
||||||
|
case "mkv":
|
||||||
|
return "video/x-matroska"
|
||||||
|
case "webm":
|
||||||
|
return "video/webm"
|
||||||
|
case "mp3":
|
||||||
|
return "audio/mpeg"
|
||||||
|
case "wav":
|
||||||
|
return "audio/wav"
|
||||||
|
case "ogg":
|
||||||
|
return "audio/ogg"
|
||||||
|
default:
|
||||||
|
return "text/plain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func FileGet(w http.ResponseWriter, req *http.Request) {
|
||||||
|
utils.SetHeaders(w)
|
||||||
|
|
||||||
|
fullPath := req.URL.Query().Get("path")
|
||||||
|
if fullPath == "" {
|
||||||
|
log.Println("No path specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := utils.GetRealPath(fullPath)
|
||||||
|
|
||||||
|
file, err := os.Open(filePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
/*fileBytes, err := ioutil.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// set header content type depending on file type
|
||||||
|
w.Header().Set("Content-Type", getContentType(filePath))
|
||||||
|
|
||||||
|
// multipart file send
|
||||||
|
if getExtension(filePath) == "mp4" || getExtension(filePath) == "mkv" || getExtension(filePath) == "webm" {
|
||||||
|
w.Header().Set("Content-Disposition", "attachment; filename=" + filePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// open stat file
|
||||||
|
stat, err := os.Stat(filePath)
|
||||||
|
|
||||||
|
|
||||||
|
buffer := bufio.NewReader(file)
|
||||||
|
|
||||||
|
// set content-length
|
||||||
|
w.Header().Set("Content-Length", strconv.FormatInt(stat.Size(), 10))
|
||||||
|
|
||||||
|
//copy buffer to client
|
||||||
|
io.Copy(w, buffer)
|
||||||
|
|
||||||
|
/*
|
||||||
|
// get file stats
|
||||||
|
fileStats, err := os.Stat(filePath)
|
||||||
|
|
||||||
|
// return json object with metadata FileStat and content
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||||
|
"Metadata": FileStats{
|
||||||
|
Name: fileStats.Name(),
|
||||||
|
Path: filePath,
|
||||||
|
Size: fileStats.Size(),
|
||||||
|
Mode: fileStats.Mode(),
|
||||||
|
ModTime: fileStats.ModTime(),
|
||||||
|
IsDir: fileStats.IsDir(),
|
||||||
|
},
|
||||||
|
"Content": string(file),
|
||||||
|
})*/
|
||||||
|
}
|
55
src/file/list.go
Normal file
55
src/file/list.go
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"encoding/json"
|
||||||
|
"../utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FileList(w http.ResponseWriter, req *http.Request) {
|
||||||
|
utils.SetHeaders(w)
|
||||||
|
|
||||||
|
fullPath := req.URL.Query().Get("path")
|
||||||
|
if fullPath == "" {
|
||||||
|
log.Println("No path specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := utils.GetRealPath(fullPath)
|
||||||
|
|
||||||
|
files, err := ioutil.ReadDir(filePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// get folder stats
|
||||||
|
folderStats, err := os.Stat(filePath)
|
||||||
|
|
||||||
|
// add file FileStats to json object
|
||||||
|
var fileStats [](utils.FileStats)
|
||||||
|
for _, file := range files {
|
||||||
|
fileStats = append(fileStats, utils.FileStats{
|
||||||
|
Name: file.Name(),
|
||||||
|
Path: fullPath + "/" + file.Name(),
|
||||||
|
Size: file.Size(),
|
||||||
|
Mode: file.Mode(),
|
||||||
|
ModTime: file.ModTime(),
|
||||||
|
IsDir: file.IsDir(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// return json object
|
||||||
|
// return json object with metadata FileStat and content
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||||
|
"Metadata": utils.FileStats{
|
||||||
|
Name: folderStats.Name(),
|
||||||
|
Size: folderStats.Size(),
|
||||||
|
Mode: folderStats.Mode(),
|
||||||
|
ModTime: folderStats.ModTime(),
|
||||||
|
IsDir: folderStats.IsDir(),
|
||||||
|
},
|
||||||
|
"Content": fileStats,
|
||||||
|
})
|
||||||
|
}
|
39
src/file/move.go
Normal file
39
src/file/move.go
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
"../utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func FileMove(w http.ResponseWriter, req *http.Request) {
|
||||||
|
utils.SetHeaders(w)
|
||||||
|
|
||||||
|
fullPath := req.URL.Query().Get("path")
|
||||||
|
if fullPath == "" {
|
||||||
|
log.Println("No path specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := utils.GetRealPath(fullPath)
|
||||||
|
|
||||||
|
fullDestination := req.URL.Query().Get("destination")
|
||||||
|
if fullDestination == "" {
|
||||||
|
log.Println("No destination specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
destination := utils.GetRealPath(fullDestination)
|
||||||
|
|
||||||
|
// copy file to destination
|
||||||
|
|
||||||
|
err := os.Rename(filePath, destination)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// return json object
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||||
|
"Status": "OK",
|
||||||
|
})
|
||||||
|
}
|
106
src/index.go
Normal file
106
src/index.go
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"./utils"
|
||||||
|
"./file"
|
||||||
|
"./user"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var tlsCert = "localcert.crt"
|
||||||
|
var tlsKey= "localcert.key"
|
||||||
|
var serverPortHTTP = os.Getenv("HTTP_PORT")
|
||||||
|
var serverPortHTTPS = os.Getenv("HTTPS_PORT")
|
||||||
|
|
||||||
|
func startHTTPServer(router *mux.Router) {
|
||||||
|
log.Println("Listening to HTTP on :" + serverPortHTTP)
|
||||||
|
|
||||||
|
err := http.ListenAndServe("0.0.0.0:" + serverPortHTTP, router)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startHTTPSServer(router *mux.Router) {
|
||||||
|
// redirect http to https
|
||||||
|
go (func () {
|
||||||
|
err := http.ListenAndServe("0.0.0.0:" + serverPortHTTP, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// change port in host
|
||||||
|
if strings.HasSuffix(r.Host, ":" + serverPortHTTP) {
|
||||||
|
if serverPortHTTPS != "443" {
|
||||||
|
r.Host = r.Host[:len(r.Host)-len(":" + serverPortHTTP)] + ":" + serverPortHTTPS
|
||||||
|
} else {
|
||||||
|
r.Host = r.Host[:len(r.Host)-len(":" + serverPortHTTP)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Redirect(w, r, "https://"+r.Host+r.URL.String(), http.StatusMovedPermanently)
|
||||||
|
}))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
|
||||||
|
log.Println("Listening to HTTP on :" + serverPortHTTP)
|
||||||
|
log.Println("Listening to HTTPS on :" + serverPortHTTPS)
|
||||||
|
|
||||||
|
// start https server
|
||||||
|
err := http.ListenAndServeTLS("0.0.0.0:" + serverPortHTTPS, tlsCert, tlsKey, router)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log.Println("Starting...")
|
||||||
|
|
||||||
|
if serverPortHTTP == "" {
|
||||||
|
serverPortHTTP = "80"
|
||||||
|
}
|
||||||
|
|
||||||
|
if serverPortHTTPS == "" {
|
||||||
|
serverPortHTTPS = "443"
|
||||||
|
}
|
||||||
|
|
||||||
|
router := mux.NewRouter().StrictSlash(true)
|
||||||
|
|
||||||
|
utils.DB()
|
||||||
|
defer utils.Disconnect()
|
||||||
|
|
||||||
|
router.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write([]byte("OK"))
|
||||||
|
})
|
||||||
|
|
||||||
|
router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
|
||||||
|
|
||||||
|
router.HandleFunc("/file/list", file.FileList)
|
||||||
|
router.HandleFunc("/file/get", file.FileGet)
|
||||||
|
router.HandleFunc("/file/delete", file.FileDelete)
|
||||||
|
router.HandleFunc("/file/copy", file.FileCopy)
|
||||||
|
router.HandleFunc("/file/move", file.FileMove)
|
||||||
|
|
||||||
|
router.HandleFunc("/user/login", user.UserLogin)
|
||||||
|
// router.HandleFunc("/user/register", user.UserRegister)
|
||||||
|
// router.HandleFunc("/user/edit", )
|
||||||
|
// router.HandleFunc("/user/delete", )
|
||||||
|
|
||||||
|
// router.HandleFunc("/config/get", )
|
||||||
|
// router.HandleFunc("/config/set", )
|
||||||
|
|
||||||
|
// router.HandleFunc("/db", )
|
||||||
|
|
||||||
|
if utils.FileExists(tlsCert) && utils.FileExists(tlsKey) {
|
||||||
|
log.Println("TLS certificate found, starting HTTPS servers and redirecting HTTP to HTTPS")
|
||||||
|
startHTTPSServer(router)
|
||||||
|
} else {
|
||||||
|
log.Println("No TLS certificate found, starting HTTP server only")
|
||||||
|
startHTTPServer(router)
|
||||||
|
}
|
||||||
|
}
|
28
src/user/login.go
Normal file
28
src/user/login.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"log"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"../utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UserLogin(w http.ResponseWriter, req *http.Request) {
|
||||||
|
utils.SetHeaders(w)
|
||||||
|
|
||||||
|
if(req.Method == "POST") {
|
||||||
|
nickname := req.FormValue("nickname")
|
||||||
|
password := req.FormValue("password")
|
||||||
|
|
||||||
|
log.Println("UserLogin: nickname: " + nickname)
|
||||||
|
log.Println("UserLogin: password: " + password) // im just testing ok dont panic
|
||||||
|
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||||
|
"Status": "OK",
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
log.Println("UserLogin: Method not allowed" + req.Method)
|
||||||
|
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||||
|
}
|
||||||
|
}
|
43
src/user/register.go
Normal file
43
src/user/register.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"log"
|
||||||
|
// "io"
|
||||||
|
// "os"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"../utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UserRegister(w http.ResponseWriter, req *http.Request) {
|
||||||
|
utils.SetHeaders(w)
|
||||||
|
|
||||||
|
if(req.Method == "GET") {
|
||||||
|
// sedn form
|
||||||
|
}
|
||||||
|
if(req.Method == "POST") {
|
||||||
|
// check origin
|
||||||
|
|
||||||
|
// check password strength
|
||||||
|
|
||||||
|
user := &utils.User{
|
||||||
|
Nickname: req.FormValue("nickname"),
|
||||||
|
Password: req.FormValue("password"),
|
||||||
|
Role: (utils.Role)(req.FormValue("role")),
|
||||||
|
}
|
||||||
|
|
||||||
|
err := utils.Validate.Struct(user)
|
||||||
|
|
||||||
|
if(err != nil) {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.ParseForm()
|
||||||
|
}
|
||||||
|
|
||||||
|
// return json object
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||||
|
"Status": "OK",
|
||||||
|
})
|
||||||
|
}
|
53
src/utils/config.go
Normal file
53
src/utils/config.go
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
|
||||||
|
"github.com/imdario/mergo"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GucoConfiguration struct {
|
||||||
|
Test string
|
||||||
|
Caca string
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultConfig = GucoConfiguration{
|
||||||
|
Test: "test",
|
||||||
|
Caca: "prout",
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetConfigs() GucoConfiguration {
|
||||||
|
c := GetCollection("GUCO", "Configurations")
|
||||||
|
config := GucoConfiguration{}
|
||||||
|
err := c.FindOne(context.TODO(), bson.M{"_id": "GUCO"}).Decode(&config)
|
||||||
|
if err == mongo.ErrNoDocuments {
|
||||||
|
log.Println("Record does not exist")
|
||||||
|
} else if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mergo.Merge(&config, defaultConfig)
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetConfig(config GucoConfiguration) {
|
||||||
|
currentConfig := GetConfigs()
|
||||||
|
|
||||||
|
mergo.Merge(&config, currentConfig)
|
||||||
|
|
||||||
|
c := GetCollection("GUCO", "Configurations")
|
||||||
|
|
||||||
|
opts := options.Update().SetUpsert(true)
|
||||||
|
filter := bson.D{{"_id", "GUCO"}}
|
||||||
|
update := bson.D{{"$set", config}}
|
||||||
|
|
||||||
|
_, err := c.UpdateOne(context.Background(), filter, update, opts)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
54
src/utils/db.go
Normal file
54
src/utils/db.go
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/readpref"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
var client *mongo.Client
|
||||||
|
|
||||||
|
func DB() {
|
||||||
|
log.Println("Connecting to the database...")
|
||||||
|
|
||||||
|
uri := os.Getenv("MONGODB") + "/?retryWrites=true&w=majority"
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
client, err = mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Ping the primary
|
||||||
|
if err := client.Ping(context.TODO(), readpref.Primary()); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("Successfully connected to the database.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Disconnect() {
|
||||||
|
if err := client.Disconnect(context.TODO()); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCollection(applicationId string, collection string) *mongo.Collection {
|
||||||
|
name := os.Getenv("MONGODB_NAME"); if name == "" {
|
||||||
|
name = "GUCO"
|
||||||
|
}
|
||||||
|
log.Println("Getting collection " + applicationId + "_" + collection + " from database " + name)
|
||||||
|
c := client.Database(name).Collection(applicationId + "_" + collection)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// func query(q string) (*sql.Rows, error) {
|
||||||
|
// return db.Query(q)
|
||||||
|
// }
|
29
src/utils/types.go
Normal file
29
src/utils/types.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Role string
|
||||||
|
|
||||||
|
const (
|
||||||
|
GUEST string = "GUEST"
|
||||||
|
USER = "USER"
|
||||||
|
ADMIN = "ADMIN"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileStats struct {
|
||||||
|
Name string
|
||||||
|
Path string
|
||||||
|
Size int64
|
||||||
|
Mode os.FileMode
|
||||||
|
ModTime time.Time
|
||||||
|
IsDir bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Nickname string `validate:"required"`
|
||||||
|
Password string `validate:"required"`
|
||||||
|
Role Role `validate:"required"`
|
||||||
|
}
|
38
src/utils/utils.go
Normal file
38
src/utils/utils.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetRealPath(fullPath string) string {
|
||||||
|
var dataPathsObject = map[string]string{
|
||||||
|
"data": "/mnt/d/",
|
||||||
|
"diskE": "/mnt/e/",
|
||||||
|
}
|
||||||
|
|
||||||
|
path := dataPathsObject[strings.Split(fullPath, "/")[0]]
|
||||||
|
if path == "" {
|
||||||
|
log.Println("No path specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
return path + strings.Join(strings.Split(fullPath, "/")[1:], "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetHeaders(w http.ResponseWriter) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
||||||
|
w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
|
||||||
|
}
|
||||||
|
|
||||||
|
func FileExists(path string) bool {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
if err == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
log.Println(err)
|
||||||
|
return false
|
||||||
|
}
|
5
src/utils/validator.go
Normal file
5
src/utils/validator.go
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import "github.com/go-playground/validator/v10"
|
||||||
|
|
||||||
|
var Validate = validator.New()
|
9
vite.config.js
Normal file
9
vite.config.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import react from '@vitejs/plugin-react'
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [react()],
|
||||||
|
root: 'client',
|
||||||
|
outDir: 'static',
|
||||||
|
})
|
Loading…
Reference in a new issue