Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7330997281 | ||
|
|
0787522d7c | ||
|
|
46df72ac0e | ||
|
|
6839c15a7b | ||
|
|
d50dc90a54 | ||
|
|
4039efe4b2 | ||
|
|
2ab1ea44ff | ||
|
|
23a2c60d9f | ||
|
|
54e66bbc05 | ||
|
|
69b262f91a | ||
|
|
731cc45e05 | ||
|
|
a3960ff9a3 | ||
|
|
5f986901e9 | ||
|
|
0b4d8df22d | ||
|
|
9619b4ee1d | ||
|
|
c75f3e0f59 | ||
|
|
6d71ab08ce | ||
|
|
121c695c1a | ||
|
|
6a1f9bbf69 | ||
|
|
ab54bc3c57 |
@@ -73,7 +73,3 @@ this are keywords case:insensitive
|
||||
# Contributing
|
||||
|
||||
The contributing guidelines can be found [here](https://github.com/hacdias/filemanager/blob/master/CONTRIBUTING.md).
|
||||
|
||||
# Donate
|
||||
|
||||
Enjoying this project? You can [donate to its creator](https://henriquedias.com/donate/). He will appreciate.
|
||||
|
||||
@@ -134,7 +134,7 @@ settings:
|
||||
您可以将该用户设置为管理员,也可以单独选择各项权限。\
|
||||
如果选择了“管理员”,则其他的选项会被自动勾上,\
|
||||
同时该用户可以管理其他用户。"
|
||||
profileSettings: 配置文件设置
|
||||
profileSettings: 个人设置
|
||||
ruleExample1: "\
|
||||
阻止用户访问所有文件夹下任何以 . 开头的文件\
|
||||
(隐藏文件, 例如: .git, .gitignore)。"
|
||||
|
||||
@@ -134,7 +134,7 @@ settings:
|
||||
您可以將該使用者設置為管理員,也可以單獨選擇各項權限。\
|
||||
如果選擇了“管理員”,則其他的選項會被自動勾上,\
|
||||
同時該使用者可以管理其他使用者。"
|
||||
profileSettings: 設定檔設定
|
||||
profileSettings: 個人設定
|
||||
ruleExample1: "\
|
||||
封鎖使用者存取所有資料夾下任何以 . 開頭的檔案\
|
||||
(隱藏文件, 例如: .git, .gitignore)。"
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<p class="small"><strong>{{ $t('settings.examples') }}</strong></p>
|
||||
|
||||
<ul class="small">
|
||||
<li><code>disallow regex \\/\\..+</code> - {{ $t('settings.ruleExample1') }}</li>
|
||||
<li><code>disallow regex [\\\/]\..+</code> - {{ $t('settings.ruleExample1') }}</li>
|
||||
<li><code>disallow /Caddyfile</code> - {{ $t('settings.ruleExample2') }}</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
}
|
||||
body > a h1 {
|
||||
margin-top: .2em;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
27
build.sh
27
build.sh
@@ -1,13 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install rice tool if not present
|
||||
if ! [ -x "$(command -v rice)" ]; then
|
||||
go get github.com/GeertJohan/go.rice/rice
|
||||
fi
|
||||
|
||||
# Clean the dist folder and build the assets
|
||||
rm -rf assets/dist
|
||||
npm run build
|
||||
|
||||
# Embed the assets using rice
|
||||
rice embed-go
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Install rice tool if not present
|
||||
if ! [ -x "$(command -v rice)" ]; then
|
||||
go get github.com/GeertJohan/go.rice/rice
|
||||
fi
|
||||
|
||||
# Clean the dist folder and build the assets
|
||||
rm -rf assets/dist
|
||||
npm run build
|
||||
|
||||
# Embed the assets using rice
|
||||
rice embed-go
|
||||
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
|
||||
const (
|
||||
// Version is the current File Manager version.
|
||||
Version = "(untracked)"
|
||||
Version = "1.4.6"
|
||||
|
||||
ListViewMode = "list"
|
||||
MosaicViewMode = "mosaic"
|
||||
|
||||
@@ -38,10 +38,7 @@ func reCaptcha(secret string, response string) (bool, error) {
|
||||
}
|
||||
|
||||
var data struct {
|
||||
Success bool `json:"success"`
|
||||
ChallengeTS time.Time `json:"challenge_ts"`
|
||||
Hostname string `json:"hostname"`
|
||||
ErrorCodes interface{} `json:"error-codes"`
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&data)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -45,72 +43,41 @@ func downloadHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int
|
||||
files = append(files, c.File.Path)
|
||||
}
|
||||
|
||||
// If the format is true, just set it to "zip".
|
||||
if query == "true" || query == "" {
|
||||
query = "zip"
|
||||
}
|
||||
|
||||
var (
|
||||
extension string
|
||||
temp string
|
||||
err error
|
||||
tempfile string
|
||||
ar archiver.Archiver
|
||||
)
|
||||
|
||||
// Create a temporary directory.
|
||||
temp, err = ioutil.TempDir("", "")
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
defer os.RemoveAll(temp)
|
||||
|
||||
tempfile = filepath.Join(temp, "temp")
|
||||
|
||||
switch query {
|
||||
case "zip":
|
||||
extension, err = ".zip", archiver.Zip.Make(tempfile, files)
|
||||
// If the format is true, just set it to "zip".
|
||||
case "zip", "true", "":
|
||||
extension, ar = ".zip", archiver.Zip
|
||||
case "tar":
|
||||
extension, err = ".tar", archiver.Tar.Make(tempfile, files)
|
||||
extension, ar = ".tar", archiver.Tar
|
||||
case "targz":
|
||||
extension, err = ".tar.gz", archiver.TarGz.Make(tempfile, files)
|
||||
extension, ar = ".tar.gz", archiver.TarGz
|
||||
case "tarbz2":
|
||||
extension, err = ".tar.bz2", archiver.TarBz2.Make(tempfile, files)
|
||||
extension, ar = ".tar.bz2", archiver.TarBz2
|
||||
case "tarxz":
|
||||
extension, err = ".tar.xz", archiver.TarXZ.Make(tempfile, files)
|
||||
extension, ar = ".tar.xz", archiver.TarXZ
|
||||
default:
|
||||
return http.StatusNotImplemented, nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
||||
// Defines the file name.
|
||||
name := c.File.Name
|
||||
if name == "." || name == "" {
|
||||
name = "download"
|
||||
name = "archive"
|
||||
}
|
||||
name += extension
|
||||
|
||||
// Opens the file so it can be downloaded.
|
||||
file, err := os.Open(temp + "/temp")
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
defer file.Close()
|
||||
w.Header().Set("Content-Disposition", "attachment; filename*=utf-8''"+url.QueryEscape(name))
|
||||
err := ar.Write(w, files)
|
||||
|
||||
w.Header().Set("Content-Disposition", "attachment; filename=\""+name+"\"")
|
||||
_, err = io.Copy(w, file)
|
||||
return 0, err
|
||||
}
|
||||
|
||||
func downloadFileHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
if r.URL.Query().Get("inline") == "true" {
|
||||
w.Header().Set("Content-Disposition", "inline")
|
||||
} else {
|
||||
w.Header().Set("Content-Disposition", `attachment; filename="`+c.File.Name+`"`)
|
||||
}
|
||||
|
||||
file, err := os.Open(c.File.Path)
|
||||
defer file.Close()
|
||||
|
||||
@@ -118,10 +85,19 @@ func downloadFileHandler(c *fm.Context, w http.ResponseWriter, r *http.Request)
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
||||
_, err = io.Copy(w, file)
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
||||
if r.URL.Query().Get("inline") == "true" {
|
||||
w.Header().Set("Content-Disposition", "inline")
|
||||
} else {
|
||||
// As per RFC6266 section 4.3
|
||||
w.Header().Set("Content-Disposition", "attachment; filename*=utf-8''"+url.QueryEscape(c.File.Name))
|
||||
}
|
||||
|
||||
http.ServeContent(w, r, stat.Name(), stat.ModTime(), file)
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
15
http/http.go
15
http/http.go
@@ -86,7 +86,7 @@ func serve(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
|
||||
// Any other request should show the index.html file.
|
||||
w.Header().Set("x-frame-options", "SAMEORIGIN")
|
||||
w.Header().Set("x-content-type", "nosniff")
|
||||
w.Header().Set("x-content-type-options", "nosniff")
|
||||
w.Header().Set("x-xss-protection", "1; mode=block")
|
||||
|
||||
return renderFile(c, w, "index.html")
|
||||
@@ -223,13 +223,12 @@ func renderFile(c *fm.Context, w http.ResponseWriter, file string) (int, error)
|
||||
w.Header().Set("Content-Type", contentType+"; charset=utf-8")
|
||||
|
||||
data := map[string]interface{}{
|
||||
"BaseURL": c.RootURL(),
|
||||
"NoAuth": c.NoAuth,
|
||||
"Version": fm.Version,
|
||||
"CSS": template.CSS(c.CSS),
|
||||
"ReCaptcha": c.ReCaptchaKey != "" && c.ReCaptchaSecret != "",
|
||||
"ReCaptchaKey": c.ReCaptchaKey,
|
||||
"ReCaptchaSecret": c.ReCaptchaSecret,
|
||||
"BaseURL": c.RootURL(),
|
||||
"NoAuth": c.NoAuth,
|
||||
"Version": fm.Version,
|
||||
"CSS": template.CSS(c.CSS),
|
||||
"ReCaptcha": c.ReCaptchaKey != "" && c.ReCaptchaSecret != "",
|
||||
"ReCaptchaKey": c.ReCaptchaKey,
|
||||
}
|
||||
|
||||
if c.StaticGen != nil {
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
"js-base64": "^2.4.0",
|
||||
"moment": "^2.19.2",
|
||||
"normalize.css": "^7.0.0",
|
||||
"noty": "^3.1.3",
|
||||
"noty": "^3.1.4",
|
||||
"vue": "^2.5.8",
|
||||
"vue-i18n": "^7.3.2",
|
||||
"vue-i18n": "^7.3.4",
|
||||
"vue-router": "^3.0.1",
|
||||
"vuex": "^3.0.1"
|
||||
},
|
||||
@@ -34,7 +34,7 @@
|
||||
"connect-history-api-fallback": "^1.5.0",
|
||||
"copy-webpack-plugin": "^4.2.1",
|
||||
"css-loader": "^0.28.7",
|
||||
"eslint": "^4.11.0",
|
||||
"eslint": "^4.15.0",
|
||||
"eslint-config-standard": "^10.2.1",
|
||||
"eslint-friendly-formatter": "^3.0.0",
|
||||
"eslint-loader": "^1.9.0",
|
||||
@@ -64,7 +64,7 @@
|
||||
"vue-template-compiler": "^2.5.8",
|
||||
"webpack": "^3.8.1",
|
||||
"webpack-bundle-analyzer": "^2.9.1",
|
||||
"webpack-dev-middleware": "^1.12.0",
|
||||
"webpack-dev-middleware": "^2.0.4",
|
||||
"webpack-hot-middleware": "^2.20.0",
|
||||
"webpack-merge": "^4.1.1",
|
||||
"yml-loader": "^2.1.0"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "Building assets"
|
||||
./build.sh
|
||||
@@ -8,7 +9,7 @@ sed -i "s|(untracked)|$1|g" filemanager.go
|
||||
|
||||
echo "Commiting..."
|
||||
git add -A
|
||||
git commit -m "Version $1"
|
||||
git commit -m "chore: version $1"
|
||||
git push
|
||||
|
||||
echo "Creating the tag..."
|
||||
@@ -18,7 +19,7 @@ git push --tags
|
||||
echo "Commiting untracked version notice..."
|
||||
sed -i "s|$1|(untracked)|g" filemanager.go
|
||||
git add -A
|
||||
git commit -m "[ci skip] auto: setting untracked version"
|
||||
git commit -m "chore: setting untracked version [ci skip]"
|
||||
git push
|
||||
|
||||
echo "Done!"
|
||||
|
||||
@@ -1 +1 @@
|
||||
68fc7a0753d0aa621970e56341f1af15c64a4f5d
|
||||
e48e71dd340a2bf3434e06c86032565365132976
|
||||
Reference in New Issue
Block a user