Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70d59ec03e | ||
|
|
bf37f88c32 | ||
|
|
7354eb6cf9 | ||
|
|
10684e5390 | ||
|
|
58fe817349 |
@@ -2,6 +2,14 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [2.34.1](https://github.com/filebrowser/filebrowser/compare/v2.34.0...v2.34.1) (2025-06-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* exclude to-be-moved folder from move dialog ([#5235](https://github.com/filebrowser/filebrowser/issues/5235)) ([7354eb6](https://github.com/filebrowser/filebrowser/commit/7354eb6cf966244141277c2808988855c004f908))
|
||||
* passthrough the minimum password length ([#5236](https://github.com/filebrowser/filebrowser/issues/5236)) ([bf37f88](https://github.com/filebrowser/filebrowser/commit/bf37f88c32222ad9c186482bb97338a9c9b4a93c))
|
||||
|
||||
## [2.34.0](https://github.com/filebrowser/filebrowser/compare/v2.33.10...v2.34.0) (2025-06-29)
|
||||
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -187,7 +187,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2018 File Browser contributors
|
||||
Copyright 2018 File Browser Contributors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -28,3 +28,11 @@ Documentation on how to install, configure, and contribute to this project is ho
|
||||
|
||||
[issues]: https://github.com/filebrowser/filebrowser/issues
|
||||
[discussions]: https://github.com/filebrowser/filebrowser/discussions
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are always welcome. To start contributing to this project, read our [guidelines](CONTRIBUTING.md) first.
|
||||
|
||||
## License
|
||||
|
||||
[Apache License 2.0](LICENSE) © File Browser Contributors
|
||||
|
||||
@@ -150,7 +150,7 @@ func (a *HookAuth) SaveUser() (*users.User, error) {
|
||||
}
|
||||
|
||||
if u == nil {
|
||||
pass, err := users.HashAndValidatePwd(a.Cred.Password, a.Settings.MinimumPasswordLength)
|
||||
pass, err := users.ValidateAndHashPwd(a.Cred.Password, a.Settings.MinimumPasswordLength)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -186,7 +186,7 @@ func (a *HookAuth) SaveUser() (*users.User, error) {
|
||||
|
||||
// update the password when it doesn't match the current
|
||||
if p {
|
||||
pass, err := users.HashAndValidatePwd(a.Cred.Password, a.Settings.MinimumPasswordLength)
|
||||
pass, err := users.ValidateAndHashPwd(a.Cred.Password, a.Settings.MinimumPasswordLength)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ func (a ProxyAuth) createUser(usr users.Store, setting *settings.Settings, srv *
|
||||
}
|
||||
|
||||
var hashedRandomPassword string
|
||||
hashedRandomPassword, err = users.HashAndValidatePwd(pwd, setting.MinimumPasswordLength)
|
||||
hashedRandomPassword, err = users.ValidateAndHashPwd(pwd, setting.MinimumPasswordLength)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -432,7 +432,7 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
|
||||
|
||||
log.Println("Randomly generated password for user 'admin':", pwd)
|
||||
|
||||
password, err = users.HashAndValidatePwd(pwd, set.MinimumPasswordLength)
|
||||
password, err = users.ValidateAndHashPwd(pwd, set.MinimumPasswordLength)
|
||||
checkErr(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ var usersAddCmd = &cobra.Command{
|
||||
checkErr(err)
|
||||
getUserDefaults(cmd.Flags(), &s.Defaults, false)
|
||||
|
||||
password, err := users.HashAndValidatePwd(args[1], s.MinimumPasswordLength)
|
||||
password, err := users.ValidateAndHashPwd(args[1], s.MinimumPasswordLength)
|
||||
checkErr(err)
|
||||
|
||||
user := &users.User{
|
||||
|
||||
@@ -66,7 +66,7 @@ options you want to change.`,
|
||||
}
|
||||
|
||||
if password != "" {
|
||||
user.Password, err = users.HashAndValidatePwd(password, s.MinimumPasswordLength)
|
||||
user.Password, err = users.ValidateAndHashPwd(password, s.MinimumPasswordLength)
|
||||
checkErr(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
package errors
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrEmptyKey = errors.New("empty key")
|
||||
ErrExist = errors.New("the resource already exists")
|
||||
ErrNotExist = errors.New("the resource does not exist")
|
||||
ErrEmptyPassword = errors.New("password is empty")
|
||||
ErrShortPassword = errors.New("password is too short")
|
||||
ErrEasyPassword = errors.New("password is too easy")
|
||||
ErrEmptyUsername = errors.New("username is empty")
|
||||
ErrEmptyRequest = errors.New("empty request")
|
||||
ErrScopeIsRelative = errors.New("scope is a relative path")
|
||||
@@ -20,3 +23,11 @@ var (
|
||||
ErrSourceIsParent = errors.New("source is parent")
|
||||
ErrRootUserDeletion = errors.New("user with id 1 can't be deleted")
|
||||
)
|
||||
|
||||
type ErrShortPassword struct {
|
||||
MinimumLength uint
|
||||
}
|
||||
|
||||
func (e ErrShortPassword) Error() string {
|
||||
return fmt.Sprintf("password is too short, minimum length is %d", e.MinimumLength)
|
||||
}
|
||||
|
||||
@@ -35,6 +35,12 @@ import { StatusError } from "@/api/utils.js";
|
||||
|
||||
export default {
|
||||
name: "file-list",
|
||||
props: {
|
||||
exclude: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
items: [],
|
||||
@@ -90,6 +96,7 @@ export default {
|
||||
// move options.
|
||||
for (const item of req.items) {
|
||||
if (!item.isDir) continue;
|
||||
if (this.exclude?.includes(item.url)) continue;
|
||||
|
||||
this.items.push({
|
||||
name: item.name,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<file-list
|
||||
ref="fileList"
|
||||
@update:selected="(val) => (dest = val)"
|
||||
:exclude="excludedFolders"
|
||||
tabindex="1"
|
||||
/>
|
||||
</div>
|
||||
@@ -76,6 +77,11 @@ export default {
|
||||
computed: {
|
||||
...mapState(useFileStore, ["req", "selected"]),
|
||||
...mapState(useAuthStore, ["user"]),
|
||||
excludedFolders() {
|
||||
return this.selected
|
||||
.filter((idx) => this.req.items[idx].isDir)
|
||||
.map((idx) => this.req.items[idx].url);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useLayoutStore, ["showHover", "closeHovers"]),
|
||||
|
||||
@@ -151,9 +151,9 @@ var signupHandler = func(_ http.ResponseWriter, r *http.Request, d *data) (int,
|
||||
|
||||
d.settings.Defaults.Apply(user)
|
||||
|
||||
pwd, err := users.HashAndValidatePwd(info.Password, d.settings.MinimumPasswordLength)
|
||||
pwd, err := users.ValidateAndHashPwd(info.Password, d.settings.MinimumPasswordLength)
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
return http.StatusBadRequest, err
|
||||
}
|
||||
|
||||
user.Password = pwd
|
||||
|
||||
@@ -125,13 +125,9 @@ var userPostHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *
|
||||
return http.StatusBadRequest, fbErrors.ErrEmptyPassword
|
||||
}
|
||||
|
||||
if len(req.Data.Password) < int(d.settings.MinimumPasswordLength) {
|
||||
return http.StatusBadRequest, fbErrors.ErrShortPassword
|
||||
}
|
||||
|
||||
req.Data.Password, err = users.HashAndValidatePwd(req.Data.Password, d.settings.MinimumPasswordLength)
|
||||
req.Data.Password, err = users.ValidateAndHashPwd(req.Data.Password, d.settings.MinimumPasswordLength)
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
return http.StatusBadRequest, err
|
||||
}
|
||||
|
||||
userHome, err := d.settings.MakeUserDir(req.Data.Username, req.Data.Scope, d.server.Root)
|
||||
@@ -167,17 +163,19 @@ var userPutHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
|
||||
if req.Data.Password != "" {
|
||||
req.Data.Password, err = users.HashAndValidatePwd(req.Data.Password, d.settings.MinimumPasswordLength)
|
||||
req.Data.Password, err = users.ValidateAndHashPwd(req.Data.Password, d.settings.MinimumPasswordLength)
|
||||
if err != nil {
|
||||
return http.StatusBadRequest, err
|
||||
}
|
||||
} else {
|
||||
var suser *users.User
|
||||
suser, err = d.store.Users.Get(d.server.Root, d.raw.(uint))
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
req.Data.Password = suser.Password
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
||||
req.Which = []string{}
|
||||
}
|
||||
|
||||
@@ -190,13 +188,9 @@ var userPutHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request
|
||||
return http.StatusForbidden, nil
|
||||
}
|
||||
|
||||
if len(req.Data.Password) < int(d.settings.MinimumPasswordLength) {
|
||||
return http.StatusBadRequest, fbErrors.ErrShortPassword
|
||||
}
|
||||
|
||||
req.Data.Password, err = users.HashAndValidatePwd(req.Data.Password, d.settings.MinimumPasswordLength)
|
||||
req.Data.Password, err = users.ValidateAndHashPwd(req.Data.Password, d.settings.MinimumPasswordLength)
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
return http.StatusBadRequest, err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
26
users/assets.go
Normal file
26
users/assets.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package users
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//go:embed assets
|
||||
var assets embed.FS
|
||||
var commonPasswords map[string]struct{}
|
||||
|
||||
//nolint:gochecknoinits
|
||||
func init() {
|
||||
// Password list sourced from:
|
||||
// https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/100k-most-used-passwords-NCSC.txt
|
||||
data, err := assets.ReadFile("assets/common-passwords.txt")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
passwords := strings.Split(strings.TrimSpace(string(data)), "\n")
|
||||
commonPasswords = make(map[string]struct{}, len(passwords))
|
||||
for _, password := range passwords {
|
||||
commonPasswords[strings.TrimSpace(password)] = struct{}{}
|
||||
}
|
||||
}
|
||||
100000
users/assets/common-passwords.txt
Normal file
100000
users/assets/common-passwords.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,10 +9,14 @@ import (
|
||||
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
)
|
||||
|
||||
// HashPwd hashes a password.
|
||||
func HashAndValidatePwd(password string, minimumLength uint) (string, error) {
|
||||
// ValidateAndHashPwd validates and hashes a password.
|
||||
func ValidateAndHashPwd(password string, minimumLength uint) (string, error) {
|
||||
if uint(len(password)) < minimumLength {
|
||||
return "", fbErrors.ErrShortPassword
|
||||
return "", fbErrors.ErrShortPassword{MinimumLength: minimumLength}
|
||||
}
|
||||
|
||||
if _, ok := commonPasswords[password]; ok {
|
||||
return "", fbErrors.ErrEasyPassword
|
||||
}
|
||||
|
||||
return HashPwd(password)
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
<img src="https://raw.githubusercontent.com/filebrowser/logo/master/banner.png" width="550"/>
|
||||
</p>
|
||||
|
||||

|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> This project is currently on **maintenance-only** mode. For more information, read the information on [GitHub](https://github.com/filebrowser/filebrowser#project-status).
|
||||
|
||||

|
||||
|
||||
File Browser provides a file managing interface within a specified directory and it can be used to upload, delete, preview and edit your files. It is a **create-your-own-cloud**-kind of software where you can just install it on your server, direct it to a path and access your files through a nice web interface.
|
||||
|
||||
## Features
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
site_name: File Browser
|
||||
site_description: 'A web-based file browser and manager for your files'
|
||||
site_author: 'File Browser Community'
|
||||
site_author: 'File Browser Contributors'
|
||||
site_url: 'https://filebrowser.org'
|
||||
|
||||
repo_name: 'filebrowser/filebrowser'
|
||||
repo_url: 'https://github.com/filebrowser/filebrowser'
|
||||
|
||||
copyright: 'Copyright © 2025 File Browser Community'
|
||||
copyright: 'Copyright © 2025 File Browser Contributors'
|
||||
|
||||
theme:
|
||||
name: material
|
||||
|
||||
Reference in New Issue
Block a user