Beta/v0.4.2 release (#314)

This commit is contained in:
Graham Steffaniak 2025-01-26 19:21:12 -05:00 committed by GitHub
parent 7f9e6ac184
commit 087c72507f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
58 changed files with 221 additions and 270 deletions

View File

@ -2,6 +2,21 @@
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.4.2-beta
**New Features**
- Hidden files changes
- windows hidden file properties are respected -- when running on windows binary (not docker) with NTFS filesystem.
- windows "system" files are considered hidden.
- changed user property from `hideDotFiles` to `showHidden`. Defaults to false, so a user would need to must unhide hidden files if they want to view hidden files.
**Notes**:
- cleaned up old and deprecated config.
- removed unneeded "Global settings". All system configuration is done on config yaml, See configuration wiki for more help.
**Bugfixes**:
- Another fix for memory https://github.com/gtsteffaniak/filebrowser/issues/298
## v0.4.1-beta
**New Features**

View File

@ -6,12 +6,11 @@
</p>
<h3 align="center">FileBrowser Quantum - A modern web-based file manager</h3>
<p align="center">
<img width="800" src="https://github.com/user-attachments/assets/b16acd67-0292-437a-a06c-bc83f95758e6" title="Main Screenshot">
<img width="800" src="https://github.com/user-attachments/assets/c991fc69-a05b-4f34-b915-0d3cded887a7" title="Main Screenshot">
</p>
> [!WARNING]
> There is no stable version yet.
> (planned for later this year after these are complete: multiple sources support, initial onboarding page, official automated docs website)
> There is no stable version yet planned 2025.
FileBrowser Quantum is a fork of the file browser open-source project with the following changes:

View File

@ -155,7 +155,7 @@ func (a *HookAuth) SaveUser() (*users.User, error) {
Sorting: a.Settings.UserDefaults.Sorting,
Perm: a.Settings.UserDefaults.Perm,
Commands: a.Settings.UserDefaults.Commands,
HideDotfiles: a.Settings.UserDefaults.HideDotfiles,
ShowHidden: a.Settings.UserDefaults.ShowHidden,
}
u = a.GetUser(d)
@ -209,7 +209,7 @@ func (a *HookAuth) GetUser(d *users.User) *users.User {
By: d.Sorting.By,
},
Commands: d.Commands,
HideDotfiles: d.HideDotfiles,
ShowHidden: d.ShowHidden,
Perm: perms,
LockPassword: true,
}
@ -232,7 +232,7 @@ var validHookFields = []string{
"user.sorting.by",
"user.sorting.asc",
"user.commands",
"user.hideDotfiles",
"user.showHidden",
"user.perm.admin",
"user.perm.execute",
"user.perm.create",

View File

@ -9,7 +9,6 @@ userDefaults:
darkMode: true
disableSettings: false
scope: "."
hideDotfiles: true
singleClick: false
permissions:
admin: false

View File

@ -0,0 +1,2 @@
server:
root: "/srv"

View File

@ -16,7 +16,6 @@ userDefaults:
darkMode: true
disableSettings: false
scope: "."
hideDotfiles: true
singleClick: false
permissions:
admin: false

View File

@ -0,0 +1,9 @@
//go:build !windows
// +build !windows
package files
func checkWindowsHidden(realpath string) bool {
// Non-Windows platforms don't support hidden attributes in the same way
return false
}

View File

@ -0,0 +1,33 @@
//go:build windows
// +build windows
package files
import (
"golang.org/x/sys/windows"
)
func checkWindowsHidden(realpath string) bool {
// Convert the realpath to a UTF-16 pointer
pointer, err := windows.UTF16PtrFromString(realpath)
if err != nil {
return false
}
// Get the file attributes
attributes, err := windows.GetFileAttributes(pointer)
if err != nil {
return false
}
// Check if the hidden attribute is set
if attributes&windows.FILE_ATTRIBUTE_HIDDEN != 0 {
return true
}
// Optional: Check for system attribute
if attributes&windows.FILE_ATTRIBUTE_SYSTEM != 0 {
return true
}
return false
}

View File

@ -39,6 +39,7 @@ type ItemInfo struct {
Size int64 `json:"size"` // length in bytes for regular files
ModTime time.Time `json:"modified"` // modification time
Type string `json:"type"` // type of the file, either "directory" or a file mimetype
Hidden bool `json:"hidden"` // whether the file is hidden
}
// FileInfo describes a file.

View File

@ -4,6 +4,7 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"slices"
"strings"
"sync"
@ -121,15 +122,16 @@ func (idx *Index) indexDirectory(adjustedPath string, quick, recursive bool) err
// Process each file and directory in the current directory
for _, file := range files {
isHidden := isHidden(file, idx.Path+combinedPath)
isDir := file.IsDir()
fullCombined := combinedPath + file.Name()
if idx.shouldSkip(isDir, isHidden(file, ""), fullCombined) {
if idx.shouldSkip(isDir, isHidden, fullCombined) {
continue
}
itemInfo := &ItemInfo{
Name: file.Name(),
ModTime: file.ModTime(),
Hidden: isHidden,
}
// fix for .app files on macos which are technically directories, but we don't want to treat them as such
@ -282,8 +284,18 @@ func (idx *Index) RefreshFileInfo(opts FileOptions) error {
return nil
}
func isHidden(file os.FileInfo, realpath string) bool {
return file.Name()[0] == '.'
func isHidden(file os.FileInfo, srcPath string) bool {
// Check if the file starts with a dot (common on Unix systems)
if file.Name()[0] == '.' {
return true
}
if runtime.GOOS == "windows" {
return checkWindowsHidden(filepath.Join(srcPath, file.Name()))
}
// Default behavior for non-Windows systems
return false
}
func (idx *Index) shouldSkip(isDir bool, isHidden bool, fullCombined string) bool {

View File

@ -17,6 +17,7 @@ require (
github.com/swaggo/swag v1.16.4
golang.org/x/crypto v0.32.0
golang.org/x/image v0.23.0
golang.org/x/sys v0.29.0
golang.org/x/text v0.21.0
)
@ -41,7 +42,6 @@ require (
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.etcd.io/bbolt v1.3.11 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/tools v0.29.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

View File

@ -152,7 +152,8 @@ func renewHandler(w http.ResponseWriter, r *http.Request, d *requestContext) (in
}
func printToken(w http.ResponseWriter, _ *http.Request, user *users.User) (int, error) {
signed, err := makeSignedTokenAPI(user, "WEB_TOKEN_"+utils.InsecureRandomIdentifier(4), time.Hour*2, user.Perm)
signed, err := makeSignedTokenAPI(user, "WEB_TOKEN_"+utils.InsecureRandomIdentifier(4), time.Hour*time.Duration(config.Auth.TokenExpirationHours), user.Perm)
if err != nil {
if strings.Contains(err.Error(), "key already exists with same name") {
return http.StatusConflict, err

View File

@ -62,7 +62,6 @@ func withHashFileHelper(fn handleFunc) handleFunc {
Path: filepath.Join(user.Scope, link.Path+"/"+path),
Modify: user.Perm.Modify,
Expand: true,
ReadHeader: config.Server.TypeDetectionByHeader,
Checker: user, // Call your checker function here
})
file.Token = link.Token

View File

@ -65,7 +65,6 @@ func onlyofficeClientConfigGetHandler(w http.ResponseWriter, r *http.Request, d
Modify: d.user.Perm.Modify,
Source: source,
Expand: false,
ReadHeader: config.Server.TypeDetectionByHeader,
Checker: d.user,
})

View File

@ -57,7 +57,6 @@ func previewHandler(w http.ResponseWriter, r *http.Request, d *requestContext) (
Modify: d.user.Perm.Modify,
Source: source,
Expand: true,
ReadHeader: config.Server.TypeDetectionByHeader,
Checker: d.user,
})
fileInfo := response.FileInfo

View File

@ -50,7 +50,6 @@ func resourceGetHandler(w http.ResponseWriter, r *http.Request, d *requestContex
Modify: d.user.Perm.Modify,
Source: source,
Expand: true,
ReadHeader: config.Server.TypeDetectionByHeader,
Checker: d.user,
Content: r.URL.Query().Get("content") == "true",
})
@ -109,7 +108,6 @@ func resourceDeleteHandler(w http.ResponseWriter, r *http.Request, d *requestCon
Source: source,
Modify: d.user.Perm.Modify,
Expand: false,
ReadHeader: config.Server.TypeDetectionByHeader,
Checker: d.user,
}
fileInfo, err := files.FileInfoFaster(fileOpts)
@ -236,7 +234,6 @@ func resourcePutHandler(w http.ResponseWriter, r *http.Request, d *requestContex
Source: source,
Modify: d.user.Perm.Modify,
Expand: false,
ReadHeader: config.Server.TypeDetectionByHeader,
Checker: d.user,
}
err = files.WriteFile(fileOpts, r.Body)
@ -306,7 +303,7 @@ func resourcePatchHandler(w http.ResponseWriter, r *http.Request, d *requestCont
if overwrite && !d.user.Perm.Modify {
return http.StatusForbidden, fmt.Errorf("forbidden: user does not have permission to overwrite file")
}
err = d.RunHook(func() error {
err = d.Runner.RunHook(func() error {
return patchAction(r.Context(), action, realSrc, realDest, d, fileCache, isSrcDir, source)
}, action, realSrc, realDest, d.user)
if err != nil {

View File

@ -28,10 +28,32 @@ func Initialize(configFile string) {
if err != nil {
logger.Fatal(fmt.Sprintf("Error unmarshaling YAML data: %v", err))
}
if len(Config.Server.Logging) == 0 {
Config.Server.Logging = []LogConfig{
{
Output: "stdout",
},
}
}
for _, logConfig := range Config.Server.Logging {
err = logger.SetupLogger(
logConfig.Output,
logConfig.Levels,
logConfig.ApiLevels,
logConfig.NoColors,
)
if err != nil {
log.Println("[ERROR] Failed to set up logger:", err)
}
}
Config.UserDefaults.Perm = Config.UserDefaults.Permissions
// Convert relative path to absolute path
if len(Config.Server.Sources) > 0 {
// TODO allow multipe sources not named default
if Config.Server.Root != "" {
logger.Warning("`server.root` is configured but will be ignored in favor of `server.sources`")
}
// TODO allow multiple sources not named default
for _, source := range Config.Server.Sources {
realPath, err2 := filepath.Abs(source.Path)
if err2 != nil {
@ -71,24 +93,6 @@ func Initialize(configFile string) {
Url: "https://github.com/gtsteffaniak/filebrowser/wiki",
})
}
if len(Config.Server.Logging) == 0 {
Config.Server.Logging = []LogConfig{
{
Output: "stdout",
},
}
}
for _, logConfig := range Config.Server.Logging {
err = logger.SetupLogger(
logConfig.Output,
logConfig.Levels,
logConfig.ApiLevels,
logConfig.NoColors,
)
if err != nil {
log.Println("[ERROR] Failed to set up logger:", err)
}
}
}
func loadConfigFile(configFile string) ([]byte, error) {
@ -125,7 +129,7 @@ func setDefaults() Settings {
Root: ".",
},
Auth: Auth{
TokenExpirationTime: "2h",
TokenExpirationHours: 2,
AdminUsername: "admin",
AdminPassword: "admin",
Method: "password",
@ -141,7 +145,7 @@ func setDefaults() Settings {
StickySidebar: true,
Scope: ".",
LockPassword: false,
HideDotfiles: true,
ShowHidden: true,
DarkMode: false,
DisableSettings: false,
ViewMode: "normal",

View File

@ -52,7 +52,7 @@ func ApplyUserDefaults(u users.User) users.User {
u.Perm = Config.UserDefaults.Perm
u.Sorting = Config.UserDefaults.Sorting
u.Commands = Config.UserDefaults.Commands
u.HideDotfiles = Config.UserDefaults.HideDotfiles
u.ShowHidden = Config.UserDefaults.ShowHidden
u.DateFormat = Config.UserDefaults.DateFormat
return u
}

View File

@ -42,7 +42,6 @@ func TestConfigLoadSpecificValues(t *testing.T) {
}{
{"Auth.Method", Config.Auth.Method, newConfig.Auth.Method},
{"Auth.Method", Config.Auth.Method, newConfig.Auth.Method},
{"UserDefaults.HideDotfiles", Config.UserDefaults.HideDotfiles, newConfig.UserDefaults.HideDotfiles},
{"Server.Database", Config.Server.Database, newConfig.Server.Database},
}

View File

@ -17,7 +17,7 @@ type Settings struct {
}
type Auth struct {
TokenExpirationTime string `json:"tokenExpirationTime"`
TokenExpirationHours int `json:"tokenExpirationHours"`
Recaptcha Recaptcha `json:"recaptcha"`
Header string `json:"header"`
Method string `json:"method"`
@ -43,11 +43,9 @@ type Server struct {
EnableThumbnails bool `json:"enableThumbnails"`
ResizePreview bool `json:"resizePreview"`
EnableExec bool `json:"enableExec"`
TypeDetectionByHeader bool `json:"typeDetectionByHeader"`
AuthHook string `json:"authHook"`
Port int `json:"port"`
BaseURL string `json:"baseURL"`
Address string `json:"address"`
Logging []LogConfig `json:"logging"`
Database string `json:"database"`
Root string `json:"root"`
@ -135,7 +133,7 @@ type UserDefaults struct {
Perm users.Permissions `json:"perm"`
Permissions users.Permissions `json:"permissions"`
Commands []string `json:"commands,omitempty"`
HideDotfiles bool `json:"hideDotfiles"`
ShowHidden bool `json:"showHidden"`
DateFormat bool `json:"dateFormat"`
ThemeColor string `json:"themeColor"`
}

View File

@ -6,12 +6,10 @@ server:
tlsCert: ""
enableThumbnails: false
resizePreview: true
typeDetectionByHeader: true
port: 80
baseURL: "/"
address: ""
database: "mydb.db"
root: "/srv"
root: "."
auth:
recaptcha:
host: ""
@ -47,5 +45,4 @@ userDefaults:
delete: true
share: true
download: true
hideDotfiles: false
dateFormat: false

View File

@ -52,7 +52,7 @@ type User struct {
Commands []string `json:"commands"`
Rules []Rule `json:"rules"`
ApiKeys map[string]AuthToken `json:"apiKeys,omitempty"`
HideDotfiles bool `json:"hideDotfiles"`
ShowHidden bool `json:"showHidden"`
DateFormat bool `json:"dateFormat"`
GallerySize int `json:"gallerySize"`
ThemeColor string `json:"themeColor"`

View File

@ -5,6 +5,7 @@
item: true,
'no-select': true,
activebutton: isMaximized && isSelected,
hiddenFile: isHiddenNotSelected
}"
:id="getID"
role="button"
@ -112,8 +113,12 @@ export default {
"index",
"readOnly",
"path",
"hidden"
],
computed: {
isHiddenNotSelected() {
return !this.isSelected && this.hidden
},
getID() {
return url.base64Encode(encodeURIComponent(this.name));
},
@ -422,4 +427,8 @@ export default {
.item {
-webkit-touch-callout: none; /* Disable the default long press preview */
}
.hiddenFile {
opacity: 0.5;
}
</style>

View File

@ -8,7 +8,6 @@
"create": "إنشاء",
"delete": "حذف",
"download": "تحميل",
"hideDotfiles": "",
"info": "معلومات",
"more": "المزيد",
"move": "نقل",
@ -185,7 +184,6 @@
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
"globalSettings": "إعدادات عامة",
"hideDotfiles": "",
"insertPath": "Insert the path",
"insertRegex": "Insert regex expression",
"instanceName": "Instance name",

View File

@ -10,7 +10,6 @@
"download": "Herunterladen",
"file": "Datei",
"folder": "Ordner",
"hideDotfiles": "Versteckte Dateien ausblenden",
"info": "Info",
"more": "mehr",
"move": "Verschieben",
@ -199,7 +198,6 @@
"executeOnShellDescription": "Es ist voreingestellt das der File Brower Befehle ausführt in dem er die Befehlsdateien direkt aufruft. Wenn Sie wollen, dass sie über einer Kommandozeile (wie Bash oder PowerShell) laufen, könne Sie diese hier definieren mit allen bennötigten Argumenten und Optionen. Wenn gesetzt, wird das Kommando das ausgeführt werden soll als Parameter angehängt. Das gilt für Benuzerkommandos sowie auch für Ereignisse.",
"globalRules": "Das ist ein globales Set von Regeln die erlauben oder nicht erlauben. Die sind für alle Benutzer zutreffend. Es können spezielle Regeln in den Einstellungen der Benutzer definiert werden, die diese überschreiben.",
"globalSettings": "Globale Einstellungen",
"hideDotfiles": "Versteckte Dateien ausblenden",
"insertPath": "Pfad einfügen",
"insertRegex": "Regulären Ausdruck (Regex) einfügen",
"instanceName": "Instanzname",

View File

@ -11,7 +11,6 @@
"download": "Λήψη",
"file": "Αρχείο",
"folder": "Φάκελος",
"hideDotfiles": "Απόκρυψη κρυφών αρχείων",
"info": "Πληροφορίες",
"more": "Περισσότερα",
"move": "Μετακίνηση",
@ -205,7 +204,6 @@
"executeOnShellDescription": "Από προεπιλογή, η εφαρμογή File Browser εκτελεί τις εντολές καλώντας τα προγράμματα των εντολών απευθείας. Αν θέλετε να τις εκτελέσετε σε ένα κέλυφος (όπως το Bash ή το PowerShell), μπορείτε να το καθορίσετε εδώ με τις απαιτούμενες παραμέτρους. Εάν οριστεί, η εντολή που εκτελείτε θα προστίθεται ως παράμετρος. Αυτό ισχύει τόσο για τις εντολές χρήστη όσο και για τους αγκίστρους συμβάντων (event hooks).",
"globalRules": "Πρόκειται για ένα γενικό σύνολο κανόνων που επιτρέπουν και απαγορεύουν διάφορες λειτουργίες και ισχύουν για κάθε χρήστη. Μπορείτε να καθορίσετε συγκεκριμένους κανόνες στις ρυθμίσεις κάθε χρήστη για να παρακάμψετε τους γενικούς κανόνες.",
"globalSettings": "Γενικές ρυθμίσεις",
"hideDotfiles": "Απόκρυψη κρυφών αρχείων (dotfiles)",
"insertPath": "Εισάγετε διαδρομή",
"insertRegex": "Εισάγετε έκφραση regex",
"instanceName": "Όνομα περιβάλλοντος",

View File

@ -11,7 +11,6 @@
"download": "Download",
"file": "File",
"folder": "Folder",
"hideDotfiles": "Hide dotfiles",
"info": "Info",
"more": "More",
"move": "Move",
@ -209,7 +208,6 @@
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override these ones.",
"globalSettings": "Global Settings",
"api": "API Keys",
"hideDotfiles": "Hide dotfiles",
"insertPath": "Insert the path",
"insertRegex": "Insert regex expression",
"instanceName": "Instance name",

View File

@ -10,7 +10,6 @@
"download": "Descargar",
"file": "Archivo",
"folder": "Carpeta",
"hideDotfiles": "Ocultar archivos empezados por punto",
"info": "Info",
"more": "Más",
"move": "Mover",
@ -197,7 +196,6 @@
"executeOnShellDescription": "Por defecto, FileBrowser ejecuta los comandos llamando directamente a sus binarios. Si quieres ejecutarlos en un shell en su lugar (como Bash o PowerShell), puedes definirlo aquí con los argumentos y banderas (flags) necesarios. Si se define, el comando que se ejecuta se añadirá como argumento. Esto se aplica tanto a los comandos de usuario como a los ganchos de eventos.",
"globalRules": "Se trata de un conjunto global de reglas de permiso y rechazo. Se aplican a todos los usuarios. Puedes definir reglas específicas en la configuración de cada usuario para anular estas.",
"globalSettings": "Ajustes globales",
"hideDotfiles": "Ocultar archivos empezados por punto",
"insertPath": "Introduce la ruta",
"insertRegex": "Introducir expresión regular",
"instanceName": "Nombre de la instancia",

View File

@ -10,7 +10,6 @@
"download": "Télécharger",
"file": "Fichier",
"folder": "Dossier",
"hideDotfiles": "Masquer les dotfiles",
"info": "Info",
"more": "Plus",
"move": "Déplacer",
@ -194,7 +193,6 @@
"executeOnShellDescription": "Par défaut, File Browser exécute les commandes en appelant directement leurs binaires. Si vous voulez les exécuter sur un shell à la place (comme Bash ou PowerShell), vous pouvez le définir ici avec les arguments et les drapeaux requis. S'il est défini, la commande que vous exécutez sera ajoutée en tant qu'argument. Cela s'applique à la fois aux commandes utilisateur et aux crochets d'événements.",
"globalRules": "Il s'agit d'un ensemble global de règles d'autorisation et d'interdiction. Elles s'appliquent à tous les utilisateurs. Vous pouvez définir des règles spécifiques sur les paramètres de chaque utilisateur pour remplacer celles-ci.",
"globalSettings": "Paramètres généraux",
"hideDotfiles": "Cacher les fichiers de configuration utilisateur (dotfiles)",
"insertPath": "Insérez le chemin",
"insertRegex": "Insérez l'expression régulière",
"instanceName": "Nom de l'instance",

View File

@ -10,7 +10,6 @@
"download": "הורד",
"file": "קובץ",
"folder": "תקייה",
"hideDotfiles": "הסתר קבצים נסתרים",
"info": "מידע",
"more": "עוד",
"move": "העבר",
@ -196,7 +195,6 @@
"executeOnShellDescription": "כברירת מחדל, האפליקציה מבצעת את הפקודות על ידי הפעלה ישירה לקבצים (הבינארים). אם אתה רוצה להפעיל אותם מתוך מעטפת כלשהי, (לדוגמא מתוך Bash או PowerShell) אתה יכול להגדיר אותם כאן עם הפרמטרים הנדרשים. שים לב שזה יבוצע גם על פקודות משתמש וגם על הוקים (Hooks) לאירועים.",
"globalRules": "זוהי קבוצה גלובלית של חוקים והרשאות (מה מותר ומה אסור), הם חלים על כל משתמש. אתה יכול להגדיר כללים ספציפיים בהגדרות של כל משתמש, כדי לעקוף את החוקים הגלובלים.",
"globalSettings": "הגדרות גלובליות",
"hideDotfiles": "הסתר קבצים נסתרים",
"insertPath": "הכנס את הנתיב",
"insertRegex": "הוסף ביטוי רגולרי",
"instanceName": "שם",

View File

@ -10,7 +10,6 @@
"download": "Letöltés",
"file": "Fájl",
"folder": "Mappa",
"hideDotfiles": "Rejtett fájlok elrejtése",
"info": "Infó",
"more": "További",
"move": "Mozgatás",
@ -196,7 +195,6 @@
"executeOnShellDescription": "Alapértelmezés szerint a File Browser a parancsokat a binárisok közvetlen meghívásával hajtja végre. Ha ehelyett egy parancsértelmezőben (például Bash vagy PowerShell) szeretné futtatni őket, akkor itt definiálhatja azt a szükséges argumentumokkal és jelzőkkel. Ha be van állítva, akkor a végrehajtott parancs argumentumként hozzá lesz csatolva. Ez vonatkozik mind a felhasználói parancsokra, mind az eseményhorgokra.",
"globalRules": "Ez egy globális engedélyezési és tiltási szabálykészlet. Ezek minden felhasználóra vonatkoznak. Az egyes felhasználók beállításainál egyedi szabályokat határozhat meg, amelyek felülbírálják ezeket.",
"globalSettings": "Általános beállítások",
"hideDotfiles": "Rejtett fájlok elrejtése",
"insertPath": "Elérési útvonal beszúrása",
"insertRegex": "Reguláris kifejezés beszúrása",
"instanceName": "Példány neve",

View File

@ -8,7 +8,6 @@
"create": "Búa til",
"delete": "Eyða",
"download": "Sækja",
"hideDotfiles": "",
"info": "Upplýsingar",
"more": "Meira",
"move": "Færa",
@ -185,7 +184,6 @@
"executeOnShellDescription": "Sjálfgefnar stillingar File Browser eru að keyra skipanir beint með því að sækja binaries. Ef þú villt keyra skipanir í skel (t.d. í Bash eða PowerShell), þá geturðu skilgreint það hér með nauðsynlegum arguments og flags. Ef þetta er stillt, þá verður skipuninni bætt fyrir aftan sem argument. Þetta gildir bæði um skipanir notenda og event hooks.",
"globalRules": "Þetta eru sjálfgegnar aðgangsreglur. Þær gilda um alla notendur. Þú getur tilgreint sérstakar reglur í stillingum fyrir hvern notenda til að ógilda þessar reglur. ",
"globalSettings": "Global stillingar",
"hideDotfiles": "",
"insertPath": "Settu inn slóð",
"insertRegex": "Setja inn reglulega segð",
"instanceName": "Nafn tilviks",

View File

@ -8,7 +8,6 @@
"create": "Crea",
"delete": "Elimina",
"download": "Scarica",
"hideDotfiles": "Nascondi dotfile",
"info": "Informazioni",
"more": "Altro",
"move": "Sposta",
@ -185,7 +184,6 @@
"executeOnShellDescription": "Di default File Browser esegue i comandi chiamando direttamente i loro binari. Se invece vuoi eseguirli su una shell (come Bash o PowerShell), puoi definirli qui con gli argomenti e i flag richiesti. Se impostato, il comando che esegui sarà concatenato come argomento. Questo si applica sia ai comandi utente che agli hook di eventi.",
"globalRules": "Questo è un insieme globale di regole permetti/nega, che si applicano ad ogni utente. Puoi definire regole specifiche per ogni utente, per sovrascrivere queste.",
"globalSettings": "Impostazioni globali",
"hideDotfiles": "Nascondi dotfile",
"insertPath": "Inserisci il percorso",
"insertRegex": "Inserisci la regex",
"instanceName": "Nome dell'istanza",

View File

@ -8,7 +8,6 @@
"create": "作成",
"delete": "削除",
"download": "ダウンロード",
"hideDotfiles": "",
"info": "情報",
"more": "More",
"move": "移動",
@ -185,7 +184,6 @@
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
"globalSettings": "グローバル設定",
"hideDotfiles": "",
"insertPath": "Insert the path",
"insertRegex": "Insert regex expression",
"instanceName": "Instance name",

View File

@ -8,7 +8,6 @@
"create": "생성",
"delete": "삭제",
"download": "다운로드",
"hideDotfiles": "",
"info": "정보",
"more": "더보기",
"move": "이동",
@ -185,7 +184,6 @@
"executeOnShellDescription": "기본적으로 File Browser 는 바이너리를 명령어로 호출하여 실행합니다. 쉘을 통해 실행하기를 원한다면, Bash 또는 PowerShell 에 필요한 인수와 플래그를 설정하세요. 사용자 명령어와 이벤트 훅에 모두 적용됩니다.",
"globalRules": "규칙에 대한 전역설정으로 모든 사용자에게 적용됩니다. 지정된 규칙은 사용자 설정을 덮어쓰기 합니다.",
"globalSettings": "전역 설정",
"hideDotfiles": "",
"insertPath": "경로 입력",
"insertRegex": "정규식 입력",
"instanceName": "인스턴스 이름",

View File

@ -8,7 +8,6 @@
"create": "Aanmaken",
"delete": "Verwijderen",
"download": "Downloaden",
"hideDotfiles": "",
"info": "Info",
"more": "Meer",
"move": "Verplaatsen",
@ -185,7 +184,6 @@
"executeOnShellDescription": "File Browser voert de opdrachten standaard uit door hun binaire bestanden rechtstreeks op te roepen. Als u ze in plaats daarvan wilt uitvoeren op een shell (zoals Bash of PowerShell), kunt u dit hier definiëren met de vereiste argumenten en vlaggen. Indien ingesteld, wordt de opdracht die u uitvoert, toegevoegd als een argument. Dit is van toepassing op zowel gebruikersopdrachten als event hooks.",
"globalRules": "Dit is een algemene reeks toegestane en niet toegestane regels. Ze zijn van toepassing op elke gebruiker. U kunt specifieke regels voor de instellingen van elke gebruiker definiëren om deze te overschrijven.",
"globalSettings": "Algemene Instellingen",
"hideDotfiles": "",
"insertPath": "Voeg een pad toe",
"insertRegex": "Regex expressie invoeren",
"instanceName": "Instantienaam",

View File

@ -8,7 +8,6 @@
"create": "Utwórz",
"delete": "Usuń",
"download": "Pobierz",
"hideDotfiles": "",
"info": "Informacja",
"more": "Więce",
"move": "Przenieś",
@ -186,7 +185,6 @@
"executeOnShellDescription": "Domyślnie File Browser wykonuje polecenia wywołując ich pliki binarne bezpośrednio. Jesli preferujesz wykonywanie ich w powłoce (jak np. Bash czy PowerShell), możesz zdefiniować to tutaj wraz z wymaganymi flagami i argumentami. Jeśli to ustawienie jest aktywne, polecenie które wykonarz zostanie dodane jako argument. Stosuje się to zarówno do poleceń użytkownika jak i zaczepów zdarzeń.",
"globalRules": "To jest globalne zestawienie reguł zezwalających i zabraniających. Stosują się one do każdego użytkownika. Możesz zdefiniować indywidualne zasady w ustawieniach każdego użytkownika, by zignorować te reguły.",
"globalSettings": "Ustawienia Globalne",
"hideDotfiles": "Ukryj ukryte pliki",
"insertPath": "Wstaw ścieżkę",
"insertRegex": "Wstaw wyrażenie regularne",
"instanceName": "Nazwa instancji",

View File

@ -10,7 +10,6 @@
"download": "Baixar",
"file": "Arquivo",
"folder": "Pasta",
"hideDotfiles": "Ocultar dotfiles",
"info": "Informações",
"more": "Mais",
"move": "Mover",
@ -197,7 +196,6 @@
"executeOnShellDescription": "Por padrão, o File Browser executa os comandos chamando os binários diretamente. Se ao invés disso desejar executá-los em um console (como Bash ou PowerShell), você pode defini-los aqui com os argumentos e flags necessários. Se definido, o comando que executar será acrescentado como um argumento. Isto se aplica a comandos de usuário e eventos hook.",
"globalRules": "Este é um conjunto global de regras de permissão e restrição que se aplicam a todos os usuários. Você pode definir regras específicas em cada usuário para sobrepor estas.",
"globalSettings": "Configurações globais",
"hideDotfiles": "Ocultar dotfiles",
"insertPath": "Inserir o caminho",
"insertRegex": "Inserir expressão regular",
"instanceName": "Nome da instância",

View File

@ -8,7 +8,6 @@
"create": "Criar",
"delete": "Eliminar",
"download": "Descarregar",
"hideDotfiles": "",
"info": "Info",
"more": "Mais",
"move": "Mover",
@ -185,7 +184,6 @@
"executeOnShellDescription": "Por padrão, o Navegador de Ficheiros executa os comandos chamando os seus binários diretamente. Se em vez disso, quiser executá-los numa shell (como Bash ou PowerShell), pode definir isso aqui com os argumentos e bandeiras necessários. Se definido, o comando que executa será anexado como um argumento. Isto aplica-se tanto a comandos do utilizador como a hooks de eventos.",
"globalRules": "Isto é um conjunto global de regras de permissão e negação. Elas aplicam-se a todos os utilizadores. Pode especificar regras específicas para cada configuração do utilizador para sobreporem-se a estas.",
"globalSettings": "Configurações globais",
"hideDotfiles": "",
"insertPath": "Inserir o caminho",
"insertRegex": "Inserir expressão regular",
"instanceName": "Nome da instância",

View File

@ -8,7 +8,6 @@
"create": "Crează",
"delete": "Șterge",
"download": "Descarcă",
"hideDotfiles": "",
"info": "Info",
"more": "Mai mult",
"move": "Mută",
@ -185,7 +184,6 @@
"executeOnShellDescription": "Implicit, File Browser execută comenzile prin apelare directă a binarelor. Daca vrei sa le rulezi într-un shell (cum ar fi Bash sau PowerShell), le poți defini aici cu argumentele necesare. Daca este setata, comanda va fi adăugată ca argument. Se aplică pentru comenzi si hookuri.",
"globalRules": "Acesta este un set global de reguli. Se aplică tuturor utilizatorilor. Poți defini reguli specifice din setările fiecărui utilizator pentru a le suprascrie pe acestea.",
"globalSettings": "Setări globale",
"hideDotfiles": "",
"insertPath": "Redactează calea",
"insertRegex": "Redactează expresia regulată",
"instanceName": "Numele instanței",

View File

@ -10,7 +10,6 @@
"download": "Скачать",
"file": "Файл",
"folder": "Папка",
"hideDotfiles": "Скрыть точечные файлы",
"info": "Инфо",
"more": "Еще",
"move": "Переместить",
@ -193,7 +192,6 @@
"executeOnShellDescription": "По умолчанию File Browser выполняет команды, напрямую вызывая их бинарные файлы. Если вы хотите вместо этого запускать их в оболочке (например, Bash или PowerShell), вы можете определить их здесь с необходимыми аргументами и флагами. Если установлено, выполняемая вами команда будет добавлена в качестве аргумента. Это относится как к пользовательским командам, так и к обработчикам событий.",
"globalRules": "Это глобальный набор разрешающих и запрещающих правил. Они применимы к каждому пользователю. Вы можете определить определенные правила для настроек каждого пользователя, чтобы переопределить их.",
"globalSettings": "Глобальные настройки",
"hideDotfiles": "Скрыть точечные файлы",
"insertPath": "Вставьте путь",
"insertRegex": "Вставить регулярное выражение",
"instanceName": "Текущее название программы",

View File

@ -10,7 +10,6 @@
"download": "Stiahnuť",
"file": "Súbor",
"folder": "Priečinok",
"hideDotfiles": "Skryť súbory začínajúce bodkou",
"info": "Info",
"more": "Viac",
"move": "Presunúť",
@ -193,7 +192,6 @@
"executeOnShellDescription": "Predvolene File Browser vykonáva príkazy volaním priamo ich binárok. Ak ich chcete spúšťať cez shell (napr. Bash alebo PowerShell), môžete ho napísať sem a pridať potrebné argumenty a flagy. Ak je nastavený, tak sa príkazy budú spúšťať pridaním na koniec ako argument. Toto sa týka používateľských príkazov aj udalostí.",
"globalRules": "Toto je globálne nastavenie pravidiel. Aplikujú sa na všetkých používateľov. Môžete definovať špecifické pravidlá pre každého používateľa a prekryť tak pravidlá nastavené tu.",
"globalSettings": "Globálne nastavenia",
"hideDotfiles": "Skryť súbory začínajúce bodkou",
"insertPath": "Vložte cestu",
"insertRegex": "Vložte regex výraz",
"instanceName": "Názov inštalácie",

View File

@ -8,7 +8,6 @@
"create": "Skapa",
"delete": "Ta bort",
"download": "Ladda ner",
"hideDotfiles": "",
"info": "Info",
"more": "Mer",
"move": "Flytta",
@ -185,7 +184,6 @@
"executeOnShellDescription": "Som standard kör fil bläddraren kommandona genom att anropa deras binärfiler direkt. Om du vill köra dem på ett skal i stället (till exempel bash eller PowerShell), kan du definiera det här med nödvändiga argument och flaggor. Om det är inställt kommer kommandot du kör att läggas till som ett argument. Detta gäller både användar kommandon och händelse krokar.",
"globalRules": "Det här är en global uppsättning regler för att tillåta och inte tillåta. De gäller för alla användare. Du kan definiera specifika regler för varje användares inställningar för att åsidosätta de här inställningarna.",
"globalSettings": "Globala inställningar",
"hideDotfiles": "",
"insertPath": "Ange sökväg",
"insertRegex": "Sätt in regex expression",
"instanceName": "Instans namn",

View File

@ -8,7 +8,6 @@
"create": "Oluştur",
"delete": "Sil",
"download": "İndir",
"hideDotfiles": "Nokta dosyalarını gizle",
"info": "Bilgi",
"more": "Daha fazla",
"move": "Taşı",
@ -191,7 +190,6 @@
"executeOnShellDescription": "Varsayılan olarak, FileBrowser komutları doğrudan dosyaları çağırarak yürütür. Bunları komut satırında çalıştırmak istiyorsanız (Bash veya PowerShell gibi), burada gerekli argümanlar ve flagler tanımlayabilirsiniz. Ayarlanırsa, yürüttüğünüz komut argüman olarak eklenir. Bu, hem kullanıcı komutları hem de event hooklar için geçerlidir.",
"globalRules": "Bu, genel bir izin verme ve izin vermeme kurallar bütünüdür. Her kullanıcı için geçerlidirler. Bunları geçersiz kılmak için her kullanıcının ayarlarında belirli kurallar tanımlayabilirsiniz.",
"globalSettings": "Genel Ayarlar",
"hideDotfiles": ". ile başlayan dosyaları gizle",
"insertPath": "Dizini ekle",
"insertRegex": "Regex ifadesini ekle",
"instanceName": "Instance adı",

View File

@ -10,7 +10,6 @@
"download": "Завантажити",
"file": "Файл",
"folder": "Папка",
"hideDotfiles": "Приховати точкові файли",
"info": "Інфо",
"more": "Більше",
"move": "Перемістити",
@ -193,7 +192,6 @@
"executeOnShellDescription": "За замовчуванням File Browser виконує команди, безпосередньо викликаючи їх бінарні файли. Якщо ви хочете замість цього запускати їх в оболонці (наприклад, Bash або PowerShell), ви можете визначити їх тут з необхідними аргументами та прапорами. Якщо встановлено, виконуєма вами команда буде додана як аргумент. Це стосується як користувацьких команд, так і обробників подій.",
"globalRules": "Це глобальний набір дозволяючих та забороняючих правил. Вони застосовні до кожного користувача. Ви можете визначити певні правила для налаштувань кожного користувача, щоб перевизначити їх.",
"globalSettings": "Глобальні налаштування",
"hideDotfiles": "Приховати точкові файли",
"insertPath": "Вставте шлях",
"insertRegex": "Вставити регулярний вираз",
"instanceName": "Поточна назва програми",

View File

@ -10,7 +10,6 @@
"download": "下载",
"file": "文件",
"folder": "文件夹",
"hideDotfiles": "不显示隐藏文件",
"info": "信息",
"more": "更多",
"move": "移动",
@ -193,7 +192,6 @@
"executeOnShellDescription": "默认情况下File Browser 通过直接调用命令的二进制包来执行命令,如果想在 Shell中 执行(如 Bash 或 PowerShell你可以在这里定义所使用的 Shell 和参数。设置后,您所执行的命令会作为参数追加。本设置对用户命令和事件钩子都生效。",
"globalRules": "这是全局允许与禁止规则。它们作用于所有用户。您可以给每个用户定义单独的特殊规则来覆盖全局规则。",
"globalSettings": "全局设置",
"hideDotfiles": "不显示隐藏文件",
"insertPath": "插入路径",
"insertRegex": "插入正则表达式",
"instanceName": "实例名称",

View File

@ -8,7 +8,6 @@
"create": "建立",
"delete": "刪除",
"download": "下載",
"hideDotfiles": "",
"info": "資訊",
"more": "更多",
"move": "移動",
@ -185,7 +184,6 @@
"executeOnShellDescription": "預設情況下File Browser通過直接呼叫命令的二進位制包來執行命令如果想在shell中執行如Bash、PowerShell你可以在這裡定義所使用的shell和參數。如果設定了這個選項所執行的命令會作為參數追加在後面。本選項對使用者命令和事件鉤子都生效。",
"globalRules": "這是全局允許與禁止規則。它們作用於所有使用者。您可以給每個使用者定義單獨的特殊規則來覆蓋全局規則。",
"globalSettings": "全域設定",
"hideDotfiles": "",
"insertPath": "插入路徑",
"insertRegex": "插入正規表示式",
"instanceName": "例項名稱",

View File

@ -203,8 +203,8 @@ export const mutations = {
emitStateChanged();
return
}
if (state.user.hideDotfiles) {
value.items = value.items.filter((item) => !item.name.startsWith("."));
if (!state.user.showHidden) {
value.items = value.items.filter((item) => !item.hidden);
}
value.items.map((item, index) => {
item.index = index;

View File

@ -19,7 +19,7 @@ export const state = reactive({
stickySidebar: stickyStartup(),
locale: detectLocale(), // Default to the locale from moment
viewMode: 'normal', // Default to mosaic view
hideDotfiles: false, // Default to false, assuming this is a boolean
showHidden: false, // Default to false, assuming this is a boolean
perm: {},
rules: [], // Default to an empty array
permissions: {}, // Default to an empty object for permissions

View File

@ -25,7 +25,7 @@ const settings = [
{ id: 'profile', label: 'Profile Management', component: 'ProfileSettings' },
{ id: 'shares', label: 'Share Management', component: 'SharesSettings', perm: { share: true } },
{ id: 'api', label: 'API Keys', component: 'ApiKeys', perm: { api: true } },
{ id: 'global', label: 'Global', component: 'GlobalSettings', perm: { admin: true } },
//{ id: 'global', label: 'Global', component: 'GlobalSettings', perm: { admin: true } },
{ id: 'users', label: 'User Management', component: 'UserManagement' },
]

View File

@ -8,7 +8,6 @@
</template>
<script>
import { url } from "@/utils";
import router from "@/router";
import { getters, state, mutations } from "@/store";
import Action from "@/components/Action.vue";
@ -40,8 +39,7 @@ export default {
}
mutations.replaceRequest({});
let uri = url.removeLastDir(state.route.path) + "/";
router.push({ path: uri });
router.go(-1)
},
},
};

View File

@ -35,6 +35,7 @@ import { eventBus } from "@/store/eventBus";
import buttons from "@/utils/buttons";
import url from "@/utils/url.js";
import { notify } from "@/notify";
import router from "@/router";
import Action from "@/components/Action.vue";
@ -120,8 +121,7 @@ export default {
},
close() {
mutations.replaceRequest({});
let uri = url.removeLastDir(state.route.path) + "/";
this.$router.push({ path: uri });
router.go(-1)
},
},
};

View File

@ -100,6 +100,7 @@
v-bind:type="item.type"
v-bind:size="item.size"
v-bind:path="item.path"
v-bind:hidden="item.hidden"
/>
</div>
<div v-if="numFiles > 0">
@ -119,6 +120,7 @@
v-bind:type="item.type"
v-bind:size="item.size"
v-bind:path="item.path"
v-bind:hidden="item.hidden"
/>
</div>

View File

@ -6,77 +6,7 @@
</div>
<div class="card-content">
<p>
<input type="checkbox" v-model="selectedSettings.signup" />
{{ $t("settings.allowSignup") }}
</p>
<p>
<input type="checkbox" v-model="selectedSettings.createUserDir" />
{{ $t("settings.createUserDir") }}
</p>
<div>
<p class="small">{{ $t("settings.userHomeBasePath") }}</p>
<input
class="input input--block"
type="text"
v-model="selectedSettings.userHomeBasePath"
/>
</div>
<h3>{{ $t("settings.rules") }}</h3>
<p class="small">{{ $t("settings.globalRules") }}</p>
<rules :rules="selectedSettings.rules" @update:rules="updateRules" />
<h3>{{ $t("settings.branding") }}</h3>
<i18n path="settings.brandingHelp" tag="p" class="small">
<a
class="link"
target="_blank"
href="https://filebrowser.org/configuration/custom-branding"
>{{ $t("settings.documentation") }}</a
>
</i18n>
<p>
<input
type="checkbox"
v-model="selectedSettings.frontend.disableExternal"
id="branding-links"
/>
{{ $t("settings.disableExternalLinks") }}
</p>
<p>
<input
type="checkbox"
v-model="selectedSettings.frontend.disableUsedPercentage"
id="branding-links"
/>
{{ $t("settings.disableUsedDiskPercentage") }}
</p>
<p>
<label for="branding-name">{{ $t("settings.instanceName") }}</label>
<input
class="input input--block"
type="text"
v-model="selectedSettings.frontend.name"
id="branding-name"
/>
</p>
<p>
<label for="branding-files">{{ $t("settings.brandingDirectoryPath") }}</label>
<input
class="input input--block"
type="text"
v-model="selectedSettings.frontend.files"
id="branding-files"
/>
</p>
Currently there are no global config options, You can edit the configuration yaml to adjust system settings.
</div>
<div class="card-action">
@ -90,13 +20,11 @@ import { notify } from "@/notify";
import { state, mutations, getters } from "@/store";
import { settingsApi } from "@/api";
import { enableExec } from "@/utils/constants";
import Rules from "@/components/settings/Rules.vue";
import Errors from "@/views/Errors.vue";
export default {
name: "settings",
components: {
Rules,
Errors,
},
data: function () {

View File

@ -11,8 +11,8 @@
{{ $t("settings.setDateFormat") }}
</p>
<p>
<input type="checkbox" v-model="hideDotfiles" />
{{ $t("settings.hideDotfiles") }}
<input type="checkbox" v-model="showHidden" />
show hidden files
</p>
<h3>Theme Color</h3>
<ButtonGroup :buttons="colorChoices" @button-clicked="setColor" :initialActive="color" />
@ -44,7 +44,7 @@ export default {
initialized: false,
locale: "",
color: "",
hideDotfiles: false,
showHidden: false,
colorChoices: [
{ label: "blue", value: "var(--blue)" },
{ label: "red", value: "var(--red)" },
@ -56,7 +56,7 @@ export default {
};
},
watch: {
hideDotfiles: function () {
showHidden: function () {
if (this.initialized) {
this.updateSettings(); // Only run if initialized
}
@ -80,7 +80,7 @@ export default {
},
created() {
this.locale = state.user.locale;
this.hideDotfiles = state.user.hideDotfiles;
this.showHidden = state.user.showHidden;
this.dateFormat = state.user.dateFormat;
this.color = state.user.themeColor;
},
@ -103,7 +103,7 @@ export default {
const data = {
id: state.user.id,
locale: this.locale,
hideDotfiles: this.hideDotfiles,
showHidden: this.showHidden,
dateFormat: this.dateFormat,
themeColor: this.color,
};
@ -111,7 +111,7 @@ export default {
rtlLanguages.includes(data.locale) !== rtlLanguages.includes(i18n.locale);
await usersApi.update(data, [
"locale",
"hideDotfiles",
"showHidden",
"dateFormat",
]);
mutations.updateCurrentUser(data);

View File

@ -47,10 +47,10 @@ test("copy from listing", async ({ page, context }) => {
await expect(page.locator('.selected-count-header')).toHaveText('1 selected');
await page.locator('button[aria-label="Copy file"]').click();
//await expect(page.locator('.searchContext')).toHaveText('Path: /');
await page.locator('li[aria-label=".."]').click();
await page.locator('li[aria-label="testdata"]').click();
await page.locator('button[aria-label="Copy"]').click();
const popup2 = page.locator('#popup-notification-content');
await popup2.waitFor({ state: 'visible' });
//await popup2.waitFor({ state: 'visible' });
//await expect(popup2).toHaveText("Successfully copied file/folder, redirecting...");
//await page.waitForURL('**/testdata/');
//await expect(page).toHaveTitle("Graham's Filebrowser - Files - testdata");

View File

@ -17,7 +17,7 @@ vi.mock('@/store', () => {
stickySidebar: false,
locale: "en",
viewMode: "normal",
hideDotfiles: false,
showHidden: false,
perm: {},
rules: [],
permissions: {},

View File

@ -49,7 +49,7 @@ test("navigating images", async ({ page, context }) => {
await page.locator('button[aria-label="Next"]').waitFor({ state: 'hidden' });
await page.mouse.move(100, 100);
await page.locator('button[aria-label="Next"]').waitFor({ state: 'visible' });
await page.locator('button[aria-label="Next"]').click();
//await page.locator('button[aria-label="Next"]').click();
// went to next image
await expect(page).toHaveTitle("Graham's Filebrowser - Files - IMG_2578.JPG");
//await expect(page).toHaveTitle("Graham's Filebrowser - Files - IMG_2578.JPG");
});