diff --git a/CHANGELOG.md b/CHANGELOG.md index bf409e12..cec194c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,15 +2,18 @@ All notable changes to this project will be documented in this file. For commit guidelines, please refer to [Standard Version](https://github.com/conventional-changelog/standard-version). +## v0.2.3 + +- Feature: token expiration time now configurable +- FIX: Hidden files are still directly accessible. (https://github.com/filebrowser/filebrowser/issues/2698) +- FIX: search/user context bug + ## v0.2.2 -- **Major Indexing Changes:** - - **Speed:** (0m57s) - Decreased by 78% compared to the previous release. - - **Memory Usage:** (41MB) - Reduced by 45% compared to the previous release. -- Now utilizes the index for file browser listings! -- **[Work in Progress]** Hidden files are still directly accessible. -- **[Work in Progress]** Editor issues fixed on save and themes. -- **[Work in Progress]** `running-config.yaml` gets updated when settings change, ensuring that running settings are up to date. +- CHG: **Speed:** (0m57s) - Decreased by 78% compared to the previous release. +- CHG: **Memory Usage:** (41MB) - Reduced by 45% compared to the previous release. +- Feature: Now utilizes the index for file browser listings! +- FIX: Editor issues fixed on save and themes. ## v0.2.1 diff --git a/backend/files/indexing.go b/backend/files/indexing.go index 24293eff..023627cd 100644 --- a/backend/files/indexing.go +++ b/backend/files/indexing.go @@ -119,8 +119,10 @@ func (si *Index) InsertFiles(path string) { buffer := bytes.Buffer{} for _, f := range si.GetQuickList() { - buffer.WriteString(f.Name + ";") - si.UpdateCount("files") + if !f.IsDir { + buffer.WriteString(f.Name + ";") + si.UpdateCount("files") + } } // Use GetMetadataInfo and SetFileMetadata for safer read and write operations subDirectory.Files = buffer.String() diff --git a/backend/files/search.go b/backend/files/search.go index 8f76d194..2333838a 100644 --- a/backend/files/search.go +++ b/backend/files/search.go @@ -16,16 +16,15 @@ var ( ) func (si *Index) Search(search string, scope string, sourceSession string) ([]string, map[string]map[string]bool) { - if scope == "" { - scope = "/" - } + // Remove slashes + scope = strings.TrimLeft(scope, "/") + scope = strings.TrimRight(scope, "/") runningHash := generateRandomHash(4) sessionInProgress.Store(sourceSession, runningHash) // Store the value in the sync.Map searchOptions := ParseSearch(search) fileListTypes := make(map[string]map[string]bool) matching := []string{} count := 0 - for _, searchTerm := range searchOptions.Terms { if searchTerm == "" { continue @@ -46,7 +45,6 @@ func (si *Index) Search(search string, scope string, sourceSession string) ([]st if pathName == "" { continue // path not matched } - fileTypes := map[string]bool{} matches, fileType := containsSearchTerm(dirName, searchTerm, *searchOptions, isDir, fileTypes) if matches { @@ -74,7 +72,6 @@ func (si *Index) Search(search string, scope string, sourceSession string) ([]st if !matches { continue } - fileListTypes[fullName] = fileType matching = append(matching, fullName) count++ @@ -91,11 +88,11 @@ func (si *Index) Search(search string, scope string, sourceSession string) ([]st } func scopedPathNameFilter(pathName string, scope string, isDir bool) string { - scope = strings.TrimPrefix(scope, "/") - pathName = strings.TrimPrefix(pathName, "/") - pathName = strings.TrimSuffix(pathName, "/") - if strings.HasPrefix(pathName, scope) { + pathName = strings.TrimLeft(pathName, "/") + pathName = strings.TrimRight(pathName, "/") + if strings.HasPrefix(pathName, scope) || scope == "" { pathName = strings.TrimPrefix(pathName, scope) + pathName = strings.TrimLeft(pathName, "/") if isDir { pathName = pathName + "/" } diff --git a/backend/files/search_test.go b/backend/files/search_test.go index 503efd35..5f727707 100644 --- a/backend/files/search_test.go +++ b/backend/files/search_test.go @@ -163,25 +163,38 @@ func TestSearchIndexes(t *testing.T) { } func Test_scopedPathNameFilter(t *testing.T) { - type args struct { - pathName string - scope string - } tests := []struct { name string - args args + args struct { + pathName string + scope string + isDir bool // Assuming isDir should be included in args + } want string }{ - // TODO: Add test cases. + { + name: "scope test", + args: struct { + pathName string + scope string + isDir bool + }{ + pathName: "/", + scope: "/", + isDir: false, + }, + want: "", // Update this with the expected result + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := scopedPathNameFilter(tt.args.pathName, tt.args.scope, false); got != tt.want { + if got := scopedPathNameFilter(tt.args.pathName, tt.args.scope, tt.args.isDir); got != tt.want { t.Errorf("scopedPathNameFilter() = %v, want %v", got, tt.want) } }) } } + func Test_isDoc(t *testing.T) { type args struct { extension string diff --git a/backend/go.mod b/backend/go.mod index b3dd71d6..f009f924 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -19,9 +19,9 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.4 github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce - golang.org/x/crypto v0.14.0 + golang.org/x/crypto v0.17.0 golang.org/x/image v0.12.0 - golang.org/x/text v0.13.0 + golang.org/x/text v0.14.0 ) require ( @@ -49,7 +49,7 @@ require ( github.com/yusufpapurcu/wmi v1.2.3 // indirect go.etcd.io/bbolt v1.3.4 // indirect golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect + golang.org/x/sys v0.15.0 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/backend/go.sum b/backend/go.sum index 91951de2..f334b597 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -280,8 +280,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -426,8 +426,8 @@ golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -440,8 +440,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/backend/http/auth.go b/backend/http/auth.go index 2d1327c7..67efaad2 100644 --- a/backend/http/auth.go +++ b/backend/http/auth.go @@ -2,6 +2,7 @@ package http import ( "encoding/json" + "fmt" "log" "net/http" "os" @@ -16,10 +17,6 @@ import ( "github.com/gtsteffaniak/filebrowser/users" ) -const ( - TokenExpirationTime = time.Hour * 2 -) - type authToken struct { User users.User `json:"user"` jwt.RegisteredClaims @@ -158,11 +155,16 @@ var renewHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data }) func printToken(w http.ResponseWriter, _ *http.Request, d *data, user *users.User) (int, error) { + duration, err := time.ParseDuration(settings.Config.Auth.TokenExpirationTime) + if err != nil { + fmt.Println("Error parsing duration:", err) + duration = time.Hour * 2 + } claims := &authToken{ User: *user, RegisteredClaims: jwt.RegisteredClaims{ IssuedAt: jwt.NewNumericDate(time.Now()), - ExpiresAt: jwt.NewNumericDate(time.Now().Add(TokenExpirationTime)), + ExpiresAt: jwt.NewNumericDate(time.Now().Add(duration)), Issuer: "File Browser", }, } diff --git a/backend/http/data.go b/backend/http/data.go index 904e10b5..0a688034 100644 --- a/backend/http/data.go +++ b/backend/http/data.go @@ -7,7 +7,6 @@ import ( "github.com/tomasen/realip" - "github.com/gtsteffaniak/filebrowser/rules" "github.com/gtsteffaniak/filebrowser/runner" "github.com/gtsteffaniak/filebrowser/settings" "github.com/gtsteffaniak/filebrowser/storage" @@ -27,9 +26,6 @@ type data struct { // Check implements rules.Checker. func (d *data) Check(path string) bool { - if d.user.HideDotfiles && rules.MatchHidden(path) { - return false - } allow := true for _, rule := range d.settings.Rules { diff --git a/backend/http/search.go b/backend/http/search.go index 25aee389..a82e86aa 100644 --- a/backend/http/search.go +++ b/backend/http/search.go @@ -16,7 +16,6 @@ var searchHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *dat userScope := r.Header.Get("UserScope") index := files.GetIndex(settings.Config.Server.Root) combinedScope := strings.TrimPrefix(userScope+r.URL.Path, ".") - combinedScope = strings.TrimPrefix(combinedScope, "/") results, fileTypes := index.Search(query, combinedScope, sessionId) for _, path := range results { responseObj := map[string]interface{}{ diff --git a/backend/settings/config.go b/backend/settings/config.go index bab4a9b2..56c5bbe0 100644 --- a/backend/settings/config.go +++ b/backend/settings/config.go @@ -60,10 +60,11 @@ func setDefaults() Settings { Root: "/srv", }, Auth: Auth{ - AdminUsername: "admin", - AdminPassword: "admin", - Method: "password", - Signup: false, + TokenExpirationTime: "2h", + AdminUsername: "admin", + AdminPassword: "admin", + Method: "password", + Signup: false, Recaptcha: Recaptcha{ Host: "", }, diff --git a/backend/settings/structs.go b/backend/settings/structs.go index 03ea86ab..bac5d1ae 100644 --- a/backend/settings/structs.go +++ b/backend/settings/structs.go @@ -17,15 +17,16 @@ type Settings struct { } type Auth struct { - Recaptcha Recaptcha `json:"recaptcha"` - Header string `json:"header"` - Method string `json:"method"` - Command string `json:"command"` - Signup bool `json:"signup"` - Shell string `json:"shell"` - AdminUsername string `json:"adminUsername"` - AdminPassword string `json:"adminPassword"` - Key []byte `json:"key"` + TokenExpirationTime string `json:"tokenExpirationTime"` + Recaptcha Recaptcha `json:"recaptcha"` + Header string `json:"header"` + Method string `json:"method"` + Command string `json:"command"` + Signup bool `json:"signup"` + Shell string `json:"shell"` + AdminUsername string `json:"adminUsername"` + AdminPassword string `json:"adminPassword"` + Key []byte `json:"key"` } type Recaptcha struct { diff --git a/backend/version/version.go b/backend/version/version.go index 86e67b04..9996b234 100644 --- a/backend/version/version.go +++ b/backend/version/version.go @@ -2,7 +2,7 @@ package version var ( // Version is the current File Browser version. - Version = "(0.2.2)" + Version = "(0.2.3)" // CommitSHA is the commmit sha. CommitSHA = "(unknown)" ) diff --git a/configuration.md b/configuration.md index 06bc00c9..c8aecee8 100644 --- a/configuration.md +++ b/configuration.md @@ -31,6 +31,7 @@ auth: host: "" key: "" secret: "" + tokenExpirationTime: 2h header: "" method: json command: "" diff --git a/frontend/package-lock.json b/frontend/package-lock.json index dd0cec37..4c4826b1 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1045,9 +1045,9 @@ }, "node_modules/@vue/vue-loader-v15": { "name": "vue-loader", - "version": "15.10.2", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.10.2.tgz", - "integrity": "sha512-ndeSe/8KQc/nlA7TJ+OBhv2qalmj1s+uBs7yHDRFaAXscFTApBzY9F1jES3bautmgWjDlDct0fw8rPuySDLwxw==", + "version": "15.11.1", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.11.1.tgz", + "integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==", "dev": true, "dependencies": { "@vue/component-compiler-utils": "^3.1.0", @@ -5341,9 +5341,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "funding": [ { "type": "github", @@ -5896,9 +5896,9 @@ } }, "node_modules/postcss": { - "version": "8.4.29", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", - "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", + "version": "8.4.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", + "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", "funding": [ { "type": "opencollective", @@ -5914,7 +5914,7 @@ } ], "dependencies": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, diff --git a/frontend/package.json b/frontend/package.json index e5288f61..a4ec895f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -43,11 +43,6 @@ "eslint-plugin-vue": "^9.17.0", "vue-template-compiler": "^2.6.10" }, - "postcss": { - "plugins": { - "autoprefixer": {} - } - }, "browserslist": [ "> 1%", "last 2 versions", diff --git a/frontend/src/components/Search.vue b/frontend/src/components/Search.vue index b5a61ede..93ab1ed3 100644 --- a/frontend/src/components/Search.vue +++ b/frontend/src/components/Search.vue @@ -30,7 +30,7 @@
@@ -535,7 +535,6 @@ export default {
name: "search",
data: function () {
return {
- searchContext: "./",
largerThan: "",
smallerThan: "",
noneMessage: "Start typing 3 or more characters to begin searching.",
@@ -632,10 +631,16 @@ export default {
searchHelp() {
return this.showHelp;
},
+ getContext() {
+ let path = this.$route.path
+ path = path.slice(1);
+ path = "./" + path.substring(path.indexOf("/") + 1);
+ path = path.replace(/\/+$/, "") + "/";
+ return path
+ },
},
mounted() {
window.addEventListener("resize", this.handleResize);
- this.searchContext = this.getContext(this.$route.path)
this.handleResize(); // Call this once to set the initial width
},
methods: {
@@ -647,19 +652,15 @@ export default {
await this.$nextTick();
setTimeout(() => this.$router.push(url), 0);
},
- getContext(url) {
- url = url.slice(1);
- let path = "./" + url.substring(url.indexOf("/") + 1);
- return path.replace(/\/+$/, "") + "/";
- },
basePath(str,isDir) {
let parts = str.replace(/(\/$|^\/)/, "").split("/");
- if (parts.length <= 2) {
+ if (parts.length <= 1) {
if (isDir) {
return "/"
}
return "";
}
+ console.log("basePath",parts)
parts.pop();
parts = parts.join("/") + "/";
if (isDir) {
diff --git a/frontend/src/components/settings/UserForm.vue b/frontend/src/components/settings/UserForm.vue
index b6bd3877..95c4958d 100644
--- a/frontend/src/components/settings/UserForm.vue
+++ b/frontend/src/components/settings/UserForm.vue
@@ -42,7 +42,7 @@
{{ $t("settings.rulesHelp") }}
-{{ $t("settings.globalRules") }}
-