Compare commits

..

No commits in common. "master" and "v2.49.0" have entirely different histories.

109 changed files with 974 additions and 3147 deletions

View File

@ -28,11 +28,9 @@ jobs:
if: github.event_name == 'push' && github.ref == 'refs/heads/master' if: github.event_name == 'push' && github.ref == 'refs/heads/master'
name: Build and Release Docs name: Build and Release Docs
permissions: permissions:
pages: write contents: read
id-token: write deployments: write
environment: pull-requests: write
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 5 timeout-minutes: 5
steps: steps:
@ -44,9 +42,11 @@ jobs:
uses: go-task/setup-task@v1 uses: go-task/setup-task@v1
- name: Build site - name: Build site
run: task docs run: task docs
- name: Upload static files as artifact - name: Deploy to Cloudflare Pages
uses: actions/upload-pages-artifact@v4 uses: cloudflare/wrangler-action@v3
with: with:
path: www/public apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
- name: Deploy to GitHub Pages accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
uses: actions/deploy-pages@v4 command: pages deploy www/public --project-name=${{ secrets.CLOUDFLARE_PROJECT_NAME }}
gitHubToken: ${{ secrets.GITHUB_TOKEN }}

View File

@ -2,108 +2,6 @@
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines. All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
## [2.54.0](https://github.com/filebrowser/filebrowser/compare/v2.53.1...v2.54.0) (2026-01-10)
### Features
* add "redirect after copy/move" user setting ([#5662](https://github.com/filebrowser/filebrowser/issues/5662)) ([fda8a99](https://github.com/filebrowser/filebrowser/commit/fda8a992929b1466e75fb2813f2c4e293c12d244))
* force file sync while uploading file ([#5668](https://github.com/filebrowser/filebrowser/issues/5668)) ([4fd18a3](https://github.com/filebrowser/filebrowser/commit/4fd18a382c31bbe7059d6733ffa371e70051865b))
* update translations ([#5659](https://github.com/filebrowser/filebrowser/issues/5659)) ([464b581](https://github.com/filebrowser/filebrowser/commit/464b581953139c17e3276b774e381e4052827125))
### Bug Fixes
* clear selection by clicking on empty area ([#5663](https://github.com/filebrowser/filebrowser/issues/5663)) ([208535a](https://github.com/filebrowser/filebrowser/commit/208535a8cc23254de0013dfab9008486707ee6c2))
* hide "change password form" in noauth setting ([#5652](https://github.com/filebrowser/filebrowser/issues/5652)) ([219582c](https://github.com/filebrowser/filebrowser/commit/219582c0b03fd90979b1d1398dba7919d086a23f))
## [2.53.1](https://github.com/filebrowser/filebrowser/compare/v2.53.0...v2.53.1) (2026-01-03)
### Bug Fixes
* download path encoding file paths ([#5655](https://github.com/filebrowser/filebrowser/issues/5655)) ([ffa893e](https://github.com/filebrowser/filebrowser/commit/ffa893e9ac387a49dba5917a41df7c3b7ce120fc))
* request a password to change sensitive user data ([#5629](https://github.com/filebrowser/filebrowser/issues/5629)) ([b8151a0](https://github.com/filebrowser/filebrowser/commit/b8151a038a1ea55afae8073b439b74e364cac12f))
## [2.53.0](https://github.com/filebrowser/filebrowser/compare/v2.52.0...v2.53.0) (2025-12-29)
### Features
* add "disable image resolution calculation" flag ([#5638](https://github.com/filebrowser/filebrowser/issues/5638)) ([a2d80c6](https://github.com/filebrowser/filebrowser/commit/a2d80c62c1c17962e566f68fb7cac6960ed3e4cb))
* support streaming response for search results ([#5630](https://github.com/filebrowser/filebrowser/issues/5630)) ([20bfd13](https://github.com/filebrowser/filebrowser/commit/20bfd131c6a4fca48a645b52171c2d1cc3ce92b7))
* update translations ([a12a612](https://github.com/filebrowser/filebrowser/commit/a12a612970d6cc3dfbca1b35ef3a60a887a4effb))
* update translations ([#5626](https://github.com/filebrowser/filebrowser/issues/5626)) ([f899756](https://github.com/filebrowser/filebrowser/commit/f89975603e29b9f1fc05aec58afb42bbd56ed696))
* update translations ([#5631](https://github.com/filebrowser/filebrowser/issues/5631)) ([032d6c7](https://github.com/filebrowser/filebrowser/commit/032d6c7520a64686c9d9b1218562256f629b4703))
### Bug Fixes
* conversion of backslashes in file paths for archive creation ([#5637](https://github.com/filebrowser/filebrowser/issues/5637)) ([9595f39](https://github.com/filebrowser/filebrowser/commit/9595f3939c1c129ed875a47adcc4fbcfad9a0e65))
* Don't crash on invalid config import ([#5640](https://github.com/filebrowser/filebrowser/issues/5640)) ([79d1aa9](https://github.com/filebrowser/filebrowser/commit/79d1aa9229b076ee8e3b71d6cf061fc90738f4da))
* fix nil deref in config set command ([#5641](https://github.com/filebrowser/filebrowser/issues/5641)) ([60b1ee8](https://github.com/filebrowser/filebrowser/commit/60b1ee8bb9e18b21d7f2c04cb1cc90046cecd3e1))
## [2.52.0](https://github.com/filebrowser/filebrowser/compare/v2.51.2...v2.52.0) (2025-12-13)
### Features
* sync translations with Transifex ([7fa3432](https://github.com/filebrowser/filebrowser/commit/7fa3432f25610bbb55a718bc709b9a7bf41d92f0))
* update translations ([#5615](https://github.com/filebrowser/filebrowser/issues/5615)) ([3fdca6d](https://github.com/filebrowser/filebrowser/commit/3fdca6dfd9a18c3f4895b4ef3cbd216824dbb57a))
### Bug Fixes
* display the directory name in the shared folder view ([#5617](https://github.com/filebrowser/filebrowser/issues/5617)) ([6d4c867](https://github.com/filebrowser/filebrowser/commit/6d4c86767239dad4f09f30f48678f2f3a716eb12))
* hide the context menu when changing the route ([#5613](https://github.com/filebrowser/filebrowser/issues/5613)) ([cf96657](https://github.com/filebrowser/filebrowser/commit/cf966578d8c6beab111b74f495bac6bdec173f41))
## [2.51.2](https://github.com/filebrowser/filebrowser/compare/v2.51.1...v2.51.2) (2025-12-07)
### Bug Fixes
* **frontend:** add missing i18n strings ([c171599](https://github.com/filebrowser/filebrowser/commit/c1715992bda46517f801c1aa496df8a3b42a4e4d))
## [2.51.1](https://github.com/filebrowser/filebrowser/compare/v2.51.0...v2.51.1) (2025-12-07)
### Bug Fixes
* **frontend:** csv viewer i18n strings ([4cbb4b7](https://github.com/filebrowser/filebrowser/commit/4cbb4b73af816104475f15c1d996640b56203602))
* prevent the right-click from selecting multiple items when the "single-click" option is active ([#5608](https://github.com/filebrowser/filebrowser/issues/5608)) ([152f830](https://github.com/filebrowser/filebrowser/commit/152f8302f7cda21bde37692b175c22c124233f45))
## [2.51.0](https://github.com/filebrowser/filebrowser/compare/v2.50.0...v2.51.0) (2025-12-06)
### Features
* update translations ([2d88c06](https://github.com/filebrowser/filebrowser/commit/2d88c067611e936056dbbf04247f1c1c709b2a09))
### Bug Fixes
* added column separator select (comma, semicolon and both) in CSV viewer ([#5604](https://github.com/filebrowser/filebrowser/issues/5604)) ([204a3f0](https://github.com/filebrowser/filebrowser/commit/204a3f0eeaa0c68781b60651bf27c4b27eac44e6))
### Refactorings
* cleanup package names ([#5605](https://github.com/filebrowser/filebrowser/issues/5605)) ([f029c30](https://github.com/filebrowser/filebrowser/commit/f029c3005e450cfbebb074c42dbdf65db9c8d56a))
## [2.50.0](https://github.com/filebrowser/filebrowser/compare/v2.49.0...v2.50.0) (2025-11-30)
### Features
* configurable logout page URL for proxy/hook auth ([#3884](https://github.com/filebrowser/filebrowser/issues/3884)) ([b9ac45d](https://github.com/filebrowser/filebrowser/commit/b9ac45d5dac4b4eb2ba364629090fbf306cffd2b))
* render CSVs as table ([#5569](https://github.com/filebrowser/filebrowser/issues/5569)) ([982405e](https://github.com/filebrowser/filebrowser/commit/982405ec944f94baf43594b0ed2f06329ff4e9ed))
* update frontend/src/i18n/hr.json ([279a5cc](https://github.com/filebrowser/filebrowser/commit/279a5ccd1e8d7bde4568b63cb3c506af48b6c618))
* update translations ([78e0395](https://github.com/filebrowser/filebrowser/commit/78e039596070a3a9e643a693cc99960c69dcfe92))
### Bug Fixes
* do not close editor if save failed ([701522a](https://github.com/filebrowser/filebrowser/commit/701522a0600cfa542469540ed764630c0ba1a732)), closes [#5591](https://github.com/filebrowser/filebrowser/issues/5591)
## [2.49.0](https://github.com/filebrowser/filebrowser/compare/v2.48.2...v2.49.0) (2025-11-22) ## [2.49.0](https://github.com/filebrowser/filebrowser/compare/v2.48.2...v2.49.0) (2025-11-22)

View File

@ -1,5 +1,5 @@
## Multistage build: First stage fetches dependencies ## Multistage build: First stage fetches dependencies
FROM alpine:3.23 AS fetcher FROM alpine:3.22 AS fetcher
# install and copy ca-certificates, mailcap, and tini-static; download JSON.sh # install and copy ca-certificates, mailcap, and tini-static; download JSON.sh
RUN apk update && \ RUN apk update && \

View File

@ -1,4 +1,4 @@
FROM ghcr.io/linuxserver/baseimage-alpine:3.23 FROM ghcr.io/linuxserver/baseimage-alpine:3.22
RUN apk update && \ RUN apk update && \
apk --no-cache add ca-certificates mailcap jq libcap apk --no-cache add ca-certificates mailcap jq libcap

View File

@ -11,7 +11,7 @@ import (
"slices" "slices"
"strings" "strings"
fberrors "github.com/filebrowser/filebrowser/v2/errors" fbErrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/files" "github.com/filebrowser/filebrowser/v2/files"
"github.com/filebrowser/filebrowser/v2/settings" "github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
@ -146,7 +146,7 @@ func (a *HookAuth) GetValues(s string) {
// SaveUser updates the existing user or creates a new one when not found // SaveUser updates the existing user or creates a new one when not found
func (a *HookAuth) SaveUser() (*users.User, error) { func (a *HookAuth) SaveUser() (*users.User, error) {
u, err := a.Users.Get(a.Server.Root, a.Cred.Username) u, err := a.Users.Get(a.Server.Root, a.Cred.Username)
if err != nil && !errors.Is(err, fberrors.ErrNotExist) { if err != nil && !errors.Is(err, fbErrors.ErrNotExist) {
return nil, err return nil, err
} }
@ -158,17 +158,16 @@ func (a *HookAuth) SaveUser() (*users.User, error) {
// create user with the provided credentials // create user with the provided credentials
d := &users.User{ d := &users.User{
Username: a.Cred.Username, Username: a.Cred.Username,
Password: pass, Password: pass,
Scope: a.Settings.Defaults.Scope, Scope: a.Settings.Defaults.Scope,
Locale: a.Settings.Defaults.Locale, Locale: a.Settings.Defaults.Locale,
ViewMode: a.Settings.Defaults.ViewMode, ViewMode: a.Settings.Defaults.ViewMode,
SingleClick: a.Settings.Defaults.SingleClick, SingleClick: a.Settings.Defaults.SingleClick,
RedirectAfterCopyMove: a.Settings.Defaults.RedirectAfterCopyMove, Sorting: a.Settings.Defaults.Sorting,
Sorting: a.Settings.Defaults.Sorting, Perm: a.Settings.Defaults.Perm,
Perm: a.Settings.Defaults.Perm, Commands: a.Settings.Defaults.Commands,
Commands: a.Settings.Defaults.Commands, HideDotfiles: a.Settings.Defaults.HideDotfiles,
HideDotfiles: a.Settings.Defaults.HideDotfiles,
} }
u = a.GetUser(d) u = a.GetUser(d)
@ -220,14 +219,13 @@ func (a *HookAuth) GetUser(d *users.User) *users.User {
Download: isAdmin || a.Fields.GetBoolean("user.perm.download", d.Perm.Download), Download: isAdmin || a.Fields.GetBoolean("user.perm.download", d.Perm.Download),
} }
user := users.User{ user := users.User{
ID: d.ID, ID: d.ID,
Username: d.Username, Username: d.Username,
Password: d.Password, Password: d.Password,
Scope: a.Fields.GetString("user.scope", d.Scope), Scope: a.Fields.GetString("user.scope", d.Scope),
Locale: a.Fields.GetString("user.locale", d.Locale), Locale: a.Fields.GetString("user.locale", d.Locale),
ViewMode: users.ViewMode(a.Fields.GetString("user.viewMode", string(d.ViewMode))), ViewMode: users.ViewMode(a.Fields.GetString("user.viewMode", string(d.ViewMode))),
SingleClick: a.Fields.GetBoolean("user.singleClick", d.SingleClick), SingleClick: a.Fields.GetBoolean("user.singleClick", d.SingleClick),
RedirectAfterCopyMove: a.Fields.GetBoolean("user.redirectAfterCopyMove", d.RedirectAfterCopyMove),
Sorting: files.Sorting{ Sorting: files.Sorting{
Asc: a.Fields.GetBoolean("user.sorting.asc", d.Sorting.Asc), Asc: a.Fields.GetBoolean("user.sorting.asc", d.Sorting.Asc),
By: a.Fields.GetString("user.sorting.by", d.Sorting.By), By: a.Fields.GetString("user.sorting.by", d.Sorting.By),
@ -253,7 +251,6 @@ var validHookFields = []string{
"user.locale", "user.locale",
"user.viewMode", "user.viewMode",
"user.singleClick", "user.singleClick",
"user.redirectAfterCopyMove",
"user.sorting.by", "user.sorting.by",
"user.sorting.asc", "user.sorting.asc",
"user.commands", "user.commands",

View File

@ -4,7 +4,7 @@ import (
"errors" "errors"
"net/http" "net/http"
fberrors "github.com/filebrowser/filebrowser/v2/errors" fbErrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/settings" "github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
) )
@ -21,7 +21,7 @@ type ProxyAuth struct {
func (a ProxyAuth) Auth(r *http.Request, usr users.Store, setting *settings.Settings, srv *settings.Server) (*users.User, error) { func (a ProxyAuth) Auth(r *http.Request, usr users.Store, setting *settings.Settings, srv *settings.Server) (*users.User, error) {
username := r.Header.Get(a.Header) username := r.Header.Get(a.Header)
user, err := usr.Get(srv.Root, username) user, err := usr.Get(srv.Root, username)
if errors.Is(err, fberrors.ErrNotExist) { if errors.Is(err, fbErrors.ErrNotExist) {
return a.createUser(usr, setting, srv, username) return a.createUser(usr, setting, srv, username)
} }
return user, err return user, err

View File

@ -2,7 +2,7 @@ package cmd
import ( import (
"encoding/json" "encoding/json"
"errors" nerrors "errors"
"fmt" "fmt"
"os" "os"
"strings" "strings"
@ -12,7 +12,7 @@ import (
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/filebrowser/filebrowser/v2/auth" "github.com/filebrowser/filebrowser/v2/auth"
fberrors "github.com/filebrowser/filebrowser/v2/errors" "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/settings" "github.com/filebrowser/filebrowser/v2/settings"
) )
@ -45,7 +45,6 @@ func addConfigFlags(flags *pflag.FlagSet) {
flags.String("auth.method", string(auth.MethodJSONAuth), "authentication type") flags.String("auth.method", string(auth.MethodJSONAuth), "authentication type")
flags.String("auth.header", "", "HTTP header for auth.method=proxy") flags.String("auth.header", "", "HTTP header for auth.method=proxy")
flags.String("auth.command", "", "command for auth.method=hook") flags.String("auth.command", "", "command for auth.method=hook")
flags.String("auth.logoutPage", "", "url of custom logout page")
flags.String("recaptcha.host", "https://www.google.com", "use another host for ReCAPTCHA. recaptcha.net might be useful in China") flags.String("recaptcha.host", "https://www.google.com", "use another host for ReCAPTCHA. recaptcha.net might be useful in China")
flags.String("recaptcha.key", "", "ReCaptcha site key") flags.String("recaptcha.key", "", "ReCaptcha site key")
@ -99,12 +98,12 @@ func getProxyAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (a
return nil, err return nil, err
} }
if header == "" && defaultAuther != nil { if header == "" {
header = defaultAuther["header"].(string) header = defaultAuther["header"].(string)
} }
if header == "" { if header == "" {
return nil, errors.New("you must set the flag 'auth.header' for method 'proxy'") return nil, nerrors.New("you must set the flag 'auth.header' for method 'proxy'")
} }
return &auth.ProxyAuth{Header: header}, nil return &auth.ProxyAuth{Header: header}, nil
@ -163,7 +162,7 @@ func getHookAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (au
} }
if command == "" { if command == "" {
return nil, errors.New("you must set the flag 'auth.command' for method 'hook'") return nil, nerrors.New("you must set the flag 'auth.command' for method 'hook'")
} }
return &auth.HookAuth{Command: command}, nil return &auth.HookAuth{Command: command}, nil
@ -186,7 +185,7 @@ func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (settings.
case auth.MethodHookAuth: case auth.MethodHookAuth:
auther, err = getHookAuth(flags, defaultAuther) auther, err = getHookAuth(flags, defaultAuther)
default: default:
return "", nil, fberrors.ErrInvalidAuthMethod return "", nil, errors.ErrInvalidAuthMethod
} }
if err != nil { if err != nil {
@ -202,7 +201,6 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup) fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup)
fmt.Fprintf(w, "Hide Login Button:\t%t\n", set.HideLoginButton) fmt.Fprintf(w, "Hide Login Button:\t%t\n", set.HideLoginButton)
fmt.Fprintf(w, "Create User Dir:\t%t\n", set.CreateUserDir) fmt.Fprintf(w, "Create User Dir:\t%t\n", set.CreateUserDir)
fmt.Fprintf(w, "Logout Page:\t%s\n", set.LogoutPage)
fmt.Fprintf(w, "Minimum Password Length:\t%d\n", set.MinimumPasswordLength) fmt.Fprintf(w, "Minimum Password Length:\t%d\n", set.MinimumPasswordLength)
fmt.Fprintf(w, "Auth Method:\t%s\n", set.AuthMethod) fmt.Fprintf(w, "Auth Method:\t%s\n", set.AuthMethod)
fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " ")) fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " "))
@ -240,7 +238,6 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale) fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale)
fmt.Fprintf(w, "\tView mode:\t%s\n", set.Defaults.ViewMode) fmt.Fprintf(w, "\tView mode:\t%s\n", set.Defaults.ViewMode)
fmt.Fprintf(w, "\tSingle Click:\t%t\n", set.Defaults.SingleClick) fmt.Fprintf(w, "\tSingle Click:\t%t\n", set.Defaults.SingleClick)
fmt.Fprintf(w, "\tRedirect after Copy/Move:\t%t\n", set.Defaults.RedirectAfterCopyMove)
fmt.Fprintf(w, "\tFile Creation Mode:\t%O\n", set.FileMode) fmt.Fprintf(w, "\tFile Creation Mode:\t%O\n", set.FileMode)
fmt.Fprintf(w, "\tDirectory Creation Mode:\t%O\n", set.DirMode) fmt.Fprintf(w, "\tDirectory Creation Mode:\t%O\n", set.DirMode)
fmt.Fprintf(w, "\tCommands:\t%s\n", strings.Join(set.Defaults.Commands, " ")) fmt.Fprintf(w, "\tCommands:\t%s\n", strings.Join(set.Defaults.Commands, " "))
@ -309,9 +306,6 @@ func getSettings(flags *pflag.FlagSet, set *settings.Settings, ser *settings.Ser
case "disableTypeDetectionByHeader": case "disableTypeDetectionByHeader":
ser.TypeDetectionByHeader, err = flags.GetBool(flag.Name) ser.TypeDetectionByHeader, err = flags.GetBool(flag.Name)
ser.TypeDetectionByHeader = !ser.TypeDetectionByHeader ser.TypeDetectionByHeader = !ser.TypeDetectionByHeader
case "disableImageResolutionCalc":
ser.ImageResolutionCal, err = flags.GetBool(flag.Name)
ser.ImageResolutionCal = !ser.ImageResolutionCal
// Settings flags from [addConfigFlags] // Settings flags from [addConfigFlags]
case "signup": case "signup":
@ -334,8 +328,6 @@ func getSettings(flags *pflag.FlagSet, set *settings.Settings, ser *settings.Ser
set.DirMode, err = getAndParseFileMode(flags, flag.Name) set.DirMode, err = getAndParseFileMode(flags, flag.Name)
case "auth.method": case "auth.method":
hasAuth = true hasAuth = true
case "auth.logoutPage":
set.LogoutPage, err = flags.GetString(flag.Name)
case "branding.name": case "branding.name":
set.Branding.Name, err = flags.GetString(flag.Name) set.Branding.Name, err = flags.GetString(flag.Name)
case "branding.theme": case "branding.theme":
@ -365,7 +357,7 @@ func getSettings(flags *pflag.FlagSet, set *settings.Settings, ser *settings.Ser
flags.Visit(visit) flags.Visit(visit)
} }
err := errors.Join(errs...) err := nerrors.Join(errs...)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -53,10 +53,6 @@ The path must be for a json or yaml file.`,
return err return err
} }
if file.Settings == nil || file.Server == nil {
return errors.New("invalid configuration file: 'settings' or 'server' fields are missing. Please ensure you are importing a file generated by the 'config export' command")
}
file.Settings.Key = key file.Settings.Key = key
err = st.Settings.Save(file.Settings) err = st.Settings.Save(file.Settings)
if err != nil { if err != nil {

View File

@ -108,7 +108,6 @@ func addServerFlags(flags *pflag.FlagSet) {
flags.Bool("disablePreviewResize", false, "disable resize of image previews") flags.Bool("disablePreviewResize", false, "disable resize of image previews")
flags.Bool("disableExec", true, "disables Command Runner feature") flags.Bool("disableExec", true, "disables Command Runner feature")
flags.Bool("disableTypeDetectionByHeader", false, "disables type detection by reading file headers") flags.Bool("disableTypeDetectionByHeader", false, "disables type detection by reading file headers")
flags.Bool("disableImageResolutionCalc", false, "disables image resolution calculation by reading image files")
} }
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{
@ -136,11 +135,6 @@ file named .filebrowser.{json, toml, yaml, yml} in the following directories:
- $HOME/ - $HOME/
- /etc/filebrowser/ - /etc/filebrowser/
**Note:** Only the options listed below can be set via the config file or
environment variables. Other configuration options live exclusively in the
database and so they must be set by the "config set" or "config
import" commands.
The precedence of the configuration values are as follows: The precedence of the configuration values are as follows:
- Flags - Flags
@ -337,10 +331,6 @@ func getServerSettings(v *viper.Viper, st *storage.Storage) (*settings.Server, e
server.TypeDetectionByHeader = !v.GetBool("disableTypeDetectionByHeader") server.TypeDetectionByHeader = !v.GetBool("disableTypeDetectionByHeader")
} }
if v.IsSet("disableImageResolutionCalc") {
server.ImageResolutionCal = !v.GetBool("disableImageResolutionCalc")
}
if v.IsSet("disableExec") { if v.IsSet("disableExec") {
server.EnableExec = !v.GetBool("disableExec") server.EnableExec = !v.GetBool("disableExec")
} }
@ -393,11 +383,10 @@ func quickSetup(v *viper.Viper, s *storage.Storage) error {
MinimumPasswordLength: settings.DefaultMinimumPasswordLength, MinimumPasswordLength: settings.DefaultMinimumPasswordLength,
UserHomeBasePath: settings.DefaultUsersHomeBasePath, UserHomeBasePath: settings.DefaultUsersHomeBasePath,
Defaults: settings.UserDefaults{ Defaults: settings.UserDefaults{
Scope: ".", Scope: ".",
Locale: "en", Locale: "en",
SingleClick: false, SingleClick: false,
RedirectAfterCopyMove: true, AceEditorTheme: v.GetString("defaults.aceEditorTheme"),
AceEditorTheme: v.GetString("defaults.aceEditorTheme"),
Perm: users.Permissions{ Perm: users.Permissions{
Admin: false, Admin: false,
Execute: true, Execute: true,
@ -450,7 +439,6 @@ func quickSetup(v *viper.Viper, s *storage.Storage) error {
ResizePreview: !v.GetBool("disablePreviewResize"), ResizePreview: !v.GetBool("disablePreviewResize"),
EnableExec: !v.GetBool("disableExec"), EnableExec: !v.GetBool("disableExec"),
TypeDetectionByHeader: !v.GetBool("disableTypeDetectionByHeader"), TypeDetectionByHeader: !v.GetBool("disableTypeDetectionByHeader"),
ImageResolutionCal: !v.GetBool("disableImageResolutionCalc"),
} }
err = s.Settings.SaveServer(ser) err = s.Settings.SaveServer(ser)

View File

@ -30,14 +30,13 @@ func printUsers(usrs []*users.User) {
fmt.Fprintln(w, "ID\tUsername\tScope\tLocale\tV. Mode\tS.Click\tAdmin\tExecute\tCreate\tRename\tModify\tDelete\tShare\tDownload\tPwd Lock") fmt.Fprintln(w, "ID\tUsername\tScope\tLocale\tV. Mode\tS.Click\tAdmin\tExecute\tCreate\tRename\tModify\tDelete\tShare\tDownload\tPwd Lock")
for _, u := range usrs { for _, u := range usrs {
fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t\n", fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t\n",
u.ID, u.ID,
u.Username, u.Username,
u.Scope, u.Scope,
u.Locale, u.Locale,
u.ViewMode, u.ViewMode,
u.SingleClick, u.SingleClick,
u.RedirectAfterCopyMove,
u.Perm.Admin, u.Perm.Admin,
u.Perm.Execute, u.Perm.Execute,
u.Perm.Create, u.Perm.Create,
@ -78,7 +77,6 @@ func addUserFlags(flags *pflag.FlagSet) {
flags.String("locale", "en", "locale for users") flags.String("locale", "en", "locale for users")
flags.String("viewMode", string(users.ListViewMode), "view mode for users") flags.String("viewMode", string(users.ListViewMode), "view mode for users")
flags.Bool("singleClick", false, "use single clicks only") flags.Bool("singleClick", false, "use single clicks only")
flags.Bool("redirectAfterCopyMove", false, "redirect to destination after copy/move")
flags.Bool("dateFormat", false, "use date format (true for absolute time, false for relative)") flags.Bool("dateFormat", false, "use date format (true for absolute time, false for relative)")
flags.Bool("hideDotfiles", false, "hide dotfiles") flags.Bool("hideDotfiles", false, "hide dotfiles")
flags.String("aceEditorTheme", "", "ace editor's syntax highlighting theme for users") flags.String("aceEditorTheme", "", "ace editor's syntax highlighting theme for users")
@ -112,8 +110,6 @@ func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all
defaults.ViewMode, err = getAndParseViewMode(flags) defaults.ViewMode, err = getAndParseViewMode(flags)
case "singleClick": case "singleClick":
defaults.SingleClick, err = flags.GetBool(flag.Name) defaults.SingleClick, err = flags.GetBool(flag.Name)
case "redirectAfterCopyMove":
defaults.RedirectAfterCopyMove, err = flags.GetBool(flag.Name)
case "aceEditorTheme": case "aceEditorTheme":
defaults.AceEditorTheme, err = flags.GetString(flag.Name) defaults.AceEditorTheme, err = flags.GetString(flag.Name)
case "perm.admin": case "perm.admin":

View File

@ -52,14 +52,13 @@ options you want to change.`,
} }
defaults := settings.UserDefaults{ defaults := settings.UserDefaults{
Scope: user.Scope, Scope: user.Scope,
Locale: user.Locale, Locale: user.Locale,
ViewMode: user.ViewMode, ViewMode: user.ViewMode,
SingleClick: user.SingleClick, SingleClick: user.SingleClick,
RedirectAfterCopyMove: user.RedirectAfterCopyMove, Perm: user.Perm,
Perm: user.Perm, Sorting: user.Sorting,
Sorting: user.Sorting, Commands: user.Commands,
Commands: user.Commands,
} }
err = getUserDefaults(flags, &defaults, false) err = getUserDefaults(flags, &defaults, false)
@ -71,7 +70,6 @@ options you want to change.`,
user.Locale = defaults.Locale user.Locale = defaults.Locale
user.ViewMode = defaults.ViewMode user.ViewMode = defaults.ViewMode
user.SingleClick = defaults.SingleClick user.SingleClick = defaults.SingleClick
user.RedirectAfterCopyMove = defaults.RedirectAfterCopyMove
user.Perm = defaults.Perm user.Perm = defaults.Perm
user.Commands = defaults.Commands user.Commands = defaults.Commands
user.Sorting = defaults.Sorting user.Sorting = defaults.Sorting

View File

@ -1,4 +1,4 @@
package fberrors package errors
import ( import (
"errors" "errors"
@ -6,23 +6,22 @@ import (
) )
var ( var (
ErrEmptyKey = errors.New("empty key") ErrEmptyKey = errors.New("empty key")
ErrExist = errors.New("the resource already exists") ErrExist = errors.New("the resource already exists")
ErrNotExist = errors.New("the resource does not exist") ErrNotExist = errors.New("the resource does not exist")
ErrEmptyPassword = errors.New("password is empty") ErrEmptyPassword = errors.New("password is empty")
ErrEasyPassword = errors.New("password is too easy") ErrEasyPassword = errors.New("password is too easy")
ErrEmptyUsername = errors.New("username is empty") ErrEmptyUsername = errors.New("username is empty")
ErrEmptyRequest = errors.New("empty request") ErrEmptyRequest = errors.New("empty request")
ErrScopeIsRelative = errors.New("scope is a relative path") ErrScopeIsRelative = errors.New("scope is a relative path")
ErrInvalidDataType = errors.New("invalid data type") ErrInvalidDataType = errors.New("invalid data type")
ErrIsDirectory = errors.New("file is directory") ErrIsDirectory = errors.New("file is directory")
ErrInvalidOption = errors.New("invalid option") ErrInvalidOption = errors.New("invalid option")
ErrInvalidAuthMethod = errors.New("invalid auth method") ErrInvalidAuthMethod = errors.New("invalid auth method")
ErrPermissionDenied = errors.New("permission denied") ErrPermissionDenied = errors.New("permission denied")
ErrInvalidRequestParams = errors.New("invalid request params") ErrInvalidRequestParams = errors.New("invalid request params")
ErrSourceIsParent = errors.New("source is parent") ErrSourceIsParent = errors.New("source is parent")
ErrRootUserDeletion = errors.New("user with id 1 can't be deleted") ErrRootUserDeletion = errors.New("user with id 1 can't be deleted")
ErrCurrentPasswordIncorrect = errors.New("the current password is incorrect")
) )
type ErrShortPassword struct { type ErrShortPassword struct {

View File

@ -23,7 +23,7 @@ import (
"github.com/spf13/afero" "github.com/spf13/afero"
fberrors "github.com/filebrowser/filebrowser/v2/errors" fbErrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/rules" "github.com/filebrowser/filebrowser/v2/rules"
) )
@ -60,7 +60,6 @@ type FileOptions struct {
Modify bool Modify bool
Expand bool Expand bool
ReadHeader bool ReadHeader bool
CalcImgRes bool
Token string Token string
Checker rules.Checker Checker rules.Checker
Content bool Content bool
@ -91,13 +90,13 @@ func NewFileInfo(opts *FileOptions) (*FileInfo, error) {
if opts.Expand { if opts.Expand {
if file.IsDir { if file.IsDir {
if err := file.readListing(opts.Checker, opts.ReadHeader, opts.CalcImgRes); err != nil { if err := file.readListing(opts.Checker, opts.ReadHeader); err != nil {
return nil, err return nil, err
} }
return file, nil return file, nil
} }
err = file.detectType(opts.Modify, opts.Content, true, opts.CalcImgRes) err = file.detectType(opts.Modify, opts.Content, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -169,7 +168,7 @@ func stat(opts *FileOptions) (*FileInfo, error) {
// algorithm. The checksums data is saved on File object. // algorithm. The checksums data is saved on File object.
func (i *FileInfo) Checksum(algo string) error { func (i *FileInfo) Checksum(algo string) error {
if i.IsDir { if i.IsDir {
return fberrors.ErrIsDirectory return fbErrors.ErrIsDirectory
} }
if i.Checksums == nil { if i.Checksums == nil {
@ -194,7 +193,7 @@ func (i *FileInfo) Checksum(algo string) error {
case "sha512": case "sha512":
h = sha512.New() h = sha512.New()
default: default:
return fberrors.ErrInvalidOption return fbErrors.ErrInvalidOption
} }
_, err = io.Copy(h, reader) _, err = io.Copy(h, reader)
@ -219,7 +218,7 @@ func (i *FileInfo) RealPath() string {
return i.Path return i.Path
} }
func (i *FileInfo) detectType(modify, saveContent, readHeader bool, calcImgRes bool) error { func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
if IsNamedPipe(i.Mode) { if IsNamedPipe(i.Mode) {
i.Type = "blob" i.Type = "blob"
return nil return nil
@ -250,13 +249,11 @@ func (i *FileInfo) detectType(modify, saveContent, readHeader bool, calcImgRes b
return nil return nil
case strings.HasPrefix(mimetype, "image"): case strings.HasPrefix(mimetype, "image"):
i.Type = "image" i.Type = "image"
if calcImgRes { resolution, err := calculateImageResolution(i.Fs, i.Path)
resolution, err := calculateImageResolution(i.Fs, i.Path) if err != nil {
if err != nil { log.Printf("Error calculating image resolution: %v", err)
log.Printf("Error calculating image resolution: %v", err) } else {
} else { i.Resolution = resolution
i.Resolution = resolution
}
} }
return nil return nil
case strings.HasSuffix(mimetype, "pdf"): case strings.HasSuffix(mimetype, "pdf"):
@ -390,7 +387,7 @@ func (i *FileInfo) addSubtitle(fPath string) {
i.Subtitles = append(i.Subtitles, fPath) i.Subtitles = append(i.Subtitles, fPath)
} }
func (i *FileInfo) readListing(checker rules.Checker, readHeader bool, calcImgRes bool) error { func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
afs := &afero.Afero{Fs: i.Fs} afs := &afero.Afero{Fs: i.Fs}
dir, err := afs.ReadDir(i.Path) dir, err := afs.ReadDir(i.Path)
if err != nil { if err != nil {
@ -437,7 +434,7 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool, calcImgRe
currentDir: dir, currentDir: dir,
} }
if !file.IsDir && strings.HasPrefix(mime.TypeByExtension(file.Extension), "image/") && calcImgRes { if !file.IsDir && strings.HasPrefix(mime.TypeByExtension(file.Extension), "image/") {
resolution, err := calculateImageResolution(file.Fs, file.Path) resolution, err := calculateImageResolution(file.Fs, file.Path)
if err != nil { if err != nil {
log.Printf("Error calculating resolution for image %s: %v", file.Path, err) log.Printf("Error calculating resolution for image %s: %v", file.Path, err)
@ -454,7 +451,7 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool, calcImgRe
if isInvalidLink { if isInvalidLink {
file.Type = "invalid_link" file.Type = "invalid_link"
} else { } else {
err := file.detectType(true, false, readHeader, calcImgRes) err := file.detectType(true, false, readHeader)
if err != nil { if err != nil {
return err return err
} }

View File

@ -39,7 +39,6 @@
DisableUsedPercentage: false, DisableUsedPercentage: false,
EnableExec: true, EnableExec: true,
EnableThumbs: true, EnableThumbs: true,
LogoutPage: "",
LoginPage: true, LoginPage: true,
Name: "", Name: "",
NoAuth: false, NoAuth: false,

View File

@ -71,5 +71,5 @@
"vite-plugin-compression2": "^2.3.1", "vite-plugin-compression2": "^2.3.1",
"vue-tsc": "^3.1.3" "vue-tsc": "^3.1.3"
}, },
"packageManager": "pnpm@10.28.0+sha512.05df71d1421f21399e053fde567cea34d446fa02c76571441bfc1c7956e98e363088982d940465fd34480d4d90a0668bc12362f8aa88000a64e83d0b0e47be48" "packageManager": "pnpm@10.23.0+sha512.21c4e5698002ade97e4efe8b8b4a89a8de3c85a37919f957e7a0f30f38fbc5bbdd05980ffe29179b2fb6e6e691242e098d945d1601772cad0fef5fb6411e2a4b"
} }

1451
frontend/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -41,12 +41,12 @@ export function download(
let url = `${baseURL}/api/public/dl/${hash}`; let url = `${baseURL}/api/public/dl/${hash}`;
if (files.length === 1) { if (files.length === 1) {
url += files[0] + "?"; url += encodeURIComponent(files[0]) + "?";
} else { } else {
let arg = ""; let arg = "";
for (const file of files) { for (const file of files) {
arg += file + ","; arg += encodeURIComponent(file) + ",";
} }
arg = arg.substring(0, arg.length - 1); arg = arg.substring(0, arg.length - 1);

View File

@ -1,12 +1,7 @@
import { fetchURL, removePrefix, StatusError } from "./utils"; import { fetchURL, removePrefix } from "./utils";
import url from "../utils/url"; import url from "../utils/url";
export default async function search( export default async function search(base: string, query: string) {
base: string,
query: string,
signal: AbortSignal,
callback: (item: ResourceItem) => void
) {
base = removePrefix(base); base = removePrefix(base);
query = encodeURIComponent(query); query = encodeURIComponent(query);
@ -14,60 +9,19 @@ export default async function search(
base += "/"; base += "/";
} }
const res = await fetchURL(`/api/search${base}?query=${query}`, { signal }); const res = await fetchURL(`/api/search${base}?query=${query}`, {});
if (!res.body) {
throw new StatusError("000 No connection", 0);
}
try {
// Try streaming approach first (modern browsers)
if (res.body && typeof res.body.pipeThrough === "function") {
const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
let buffer = "";
while (true) {
const { done, value } = await reader.read();
if (value) {
buffer += value;
}
const lines = buffer.split(/\n/);
let lastLine = lines.pop();
// Save incomplete last line
if (!lastLine) {
lastLine = "";
}
buffer = lastLine;
for (const line of lines) { let data = await res.json();
if (line) {
const item = JSON.parse(line) as ResourceItem; data = data.map((item: ResourceItem & { dir: boolean }) => {
item.url = `/files${base}` + url.encodePath(item.path); item.url = `/files${base}` + url.encodePath(item.path);
if (item.isDir) {
item.url += "/"; if (item.dir) {
} item.url += "/";
callback(item);
}
}
if (done) break;
}
} else {
// Fallback for browsers without streaming support (e.g., Safari)
const text = await res.text();
const lines = text.split(/\n/);
for (const line of lines) {
if (line) {
const item = JSON.parse(line) as ResourceItem;
item.url = `/files${base}` + url.encodePath(item.path);
if (item.isDir) {
item.url += "/";
}
callback(item);
}
}
} }
} catch (e) {
// Check if the error is an intentional cancellation return item;
if (e instanceof Error && e.name === "AbortError") { });
throw new StatusError("000 No connection", 0, true);
} return data;
throw e;
}
} }

View File

@ -8,13 +8,12 @@ export async function get(id: number) {
return fetchJSON<IUser>(`/api/users/${id}`, {}); return fetchJSON<IUser>(`/api/users/${id}`, {});
} }
export async function create(user: IUser, currentPassword: string) { export async function create(user: IUser) {
const res = await fetchURL(`/api/users`, { const res = await fetchURL(`/api/users`, {
method: "POST", method: "POST",
body: JSON.stringify({ body: JSON.stringify({
what: "user", what: "user",
which: [], which: [],
current_password: currentPassword,
data: user, data: user,
}), }),
}); });
@ -26,17 +25,12 @@ export async function create(user: IUser, currentPassword: string) {
throw new StatusError(await res.text(), res.status); throw new StatusError(await res.text(), res.status);
} }
export async function update( export async function update(user: Partial<IUser>, which = ["all"]) {
user: Partial<IUser>,
which = ["all"],
currentPassword: string | null = null
) {
await fetchURL(`/api/users/${user.id}`, { await fetchURL(`/api/users/${user.id}`, {
method: "PUT", method: "PUT",
body: JSON.stringify({ body: JSON.stringify({
what: "user", what: "user",
which: which, which: which,
...(currentPassword != null ? { current_password: currentPassword } : {}),
data: user, data: user,
}), }),
}); });

View File

@ -5,11 +5,10 @@
v-if="active" v-if="active"
class="action" class="action"
@click="close" @click="close"
:aria-label="closeButtonTitle" :aria-label="$t('buttons.close')"
:title="closeButtonTitle" :title="$t('buttons.close')"
> >
<i v-if="ongoing" class="material-icons">stop_circle</i> <i class="material-icons">arrow_back</i>
<i v-else class="material-icons">arrow_back</i>
</button> </button>
<i v-else class="material-icons">search</i> <i v-else class="material-icons">search</i>
<input <input
@ -22,15 +21,6 @@
:aria-label="$t('search.search')" :aria-label="$t('search.search')"
:placeholder="$t('search.search')" :placeholder="$t('search.search')"
/> />
<i
v-show="ongoing"
class="material-icons spin"
style="display: inline-block"
>autorenew
</i>
<span style="margin-top: 5px" v-show="results.length > 0">
{{ results.length }}
</span>
</div> </div>
<div id="result" ref="result"> <div id="result" ref="result">
@ -67,6 +57,9 @@
</li> </li>
</ul> </ul>
</div> </div>
<p id="renew">
<i class="material-icons spin">autorenew</i>
</p>
</div> </div>
</div> </div>
</template> </template>
@ -77,11 +70,10 @@ import { useLayoutStore } from "@/stores/layout";
import url from "@/utils/url"; import url from "@/utils/url";
import { search } from "@/api"; import { search } from "@/api";
import { computed, inject, onMounted, ref, watch, onUnmounted } from "vue"; import { computed, inject, onMounted, ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { StatusError } from "@/api/utils";
const boxes = { const boxes = {
image: { label: "images", icon: "insert_photo" }, image: { label: "images", icon: "insert_photo" },
@ -92,7 +84,6 @@ const boxes = {
const layoutStore = useLayoutStore(); const layoutStore = useLayoutStore();
const fileStore = useFileStore(); const fileStore = useFileStore();
let searchAbortController = new AbortController();
const { currentPromptName } = storeToRefs(layoutStore); const { currentPromptName } = storeToRefs(layoutStore);
@ -133,7 +124,9 @@ watch(currentPromptName, (newVal, oldVal) => {
}); });
watch(prompt, () => { watch(prompt, () => {
reset(); if (results.value.length) {
reset();
}
}); });
// ...mapState(useFileStore, ["isListing"]), // ...mapState(useFileStore, ["isListing"]),
@ -156,10 +149,6 @@ const filteredResults = computed(() => {
return results.value.slice(0, resultsCount.value); return results.value.slice(0, resultsCount.value);
}); });
const closeButtonTitle = computed(() => {
return ongoing.value ? t("buttons.stopSearch") : t("buttons.close");
});
onMounted(() => { onMounted(() => {
if (result.value === null) { if (result.value === null) {
return; return;
@ -175,23 +164,14 @@ onMounted(() => {
}); });
}); });
onUnmounted(() => {
abortLastSearch();
});
const open = () => { const open = () => {
!active.value && layoutStore.showHover("search"); !active.value && layoutStore.showHover("search");
}; };
const close = (event: Event) => { const close = (event: Event) => {
if (ongoing.value) { event.stopPropagation();
abortLastSearch(); event.preventDefault();
ongoing.value = false; layoutStore.closeHovers();
} else {
event.stopPropagation();
event.preventDefault();
layoutStore.closeHovers();
}
}; };
const keyup = (event: KeyboardEvent) => { const keyup = (event: KeyboardEvent) => {
@ -208,16 +188,11 @@ const init = (string: string) => {
}; };
const reset = () => { const reset = () => {
abortLastSearch();
ongoing.value = false; ongoing.value = false;
resultsCount.value = 50; resultsCount.value = 50;
results.value = []; results.value = [];
}; };
const abortLastSearch = () => {
searchAbortController.abort();
};
const submit = async (event: Event) => { const submit = async (event: Event) => {
event.preventDefault(); event.preventDefault();
@ -233,16 +208,8 @@ const submit = async (event: Event) => {
ongoing.value = true; ongoing.value = true;
try { try {
abortLastSearch(); results.value = await search(path, prompt.value);
searchAbortController = new AbortController();
results.value = [];
await search(path, prompt.value, searchAbortController.signal, (item) =>
results.value.push(item)
);
} catch (error: any) { } catch (error: any) {
if (error instanceof StatusError && error.is_canceled) {
return;
}
$showError(error); $showError(error);
} }

View File

@ -129,7 +129,6 @@ import {
disableExternal, disableExternal,
disableUsedPercentage, disableUsedPercentage,
noAuth, noAuth,
logoutPage,
loginPage, loginPage,
} from "@/utils/constants"; } from "@/utils/constants";
import { files as api } from "@/api"; import { files as api } from "@/api";
@ -160,7 +159,7 @@ export default {
version: () => version, version: () => version,
disableExternal: () => disableExternal, disableExternal: () => disableExternal,
disableUsedPercentage: () => disableUsedPercentage, disableUsedPercentage: () => disableUsedPercentage,
canLogout: () => !noAuth && (loginPage || logoutPage !== "/login"), canLogout: () => !noAuth && loginPage,
}, },
methods: { methods: {
...mapActions(useLayoutStore, ["closeHovers", "showHover"]), ...mapActions(useLayoutStore, ["closeHovers", "showHover"]),

View File

@ -1,252 +0,0 @@
<template>
<div class="csv-viewer">
<div v-if="displayError" class="csv-error">
<i class="material-icons">error</i>
<p>{{ displayError }}</p>
</div>
<div v-else-if="data.headers.length === 0" class="csv-empty">
<i class="material-icons">description</i>
<p>{{ $t("files.lonely") }}</p>
</div>
<div v-else class="csv-table-container" @wheel.stop @touchmove.stop>
<table class="csv-table">
<thead>
<tr>
<th v-for="(header, index) in data.headers" :key="index">
{{ header || `Column ${index + 1}` }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, rowIndex) in data.rows" :key="rowIndex">
<td v-for="(cell, cellIndex) in row" :key="cellIndex">
{{ cell }}
</td>
</tr>
</tbody>
</table>
<div class="csv-footer">
<div class="csv-info" v-if="data.rows.length > 100">
<i class="material-icons">info</i>
<span>
{{ $t("files.showingRows", { count: data.rows.length }) }}</span
>
</div>
<div class="column-separator">
<label for="columnSeparator">{{ $t("files.columnSeparator") }}</label>
<select
id="columnSeparator"
class="input input--block"
v-model="columnSeparator"
>
<option :value="[',']">
{{ $t("files.csvSeparators.comma") }}
</option>
<option :value="[';']">
{{ $t("files.csvSeparators.semicolon") }}
</option>
<option :value="[',', ';']">
{{ $t("files.csvSeparators.both") }}
</option>
</select>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { parseCSV, type CsvData } from "@/utils/csv";
import { computed, ref } from "vue";
interface Props {
content: string;
error?: string;
}
const props = withDefaults(defineProps<Props>(), {
error: "",
});
const columnSeparator = ref([","]);
const data = computed<CsvData>(() => {
try {
return parseCSV(props.content, columnSeparator.value);
} catch (e) {
console.error("Failed to parse CSV:", e);
return { headers: [], rows: [] };
}
});
const displayError = computed(() => {
// External error takes priority (e.g., file too large)
if (props.error) {
return props.error;
}
// Check for parse errors
if (
props.content &&
props.content.trim().length > 0 &&
data.value.headers.length === 0
) {
return "Failed to parse CSV file";
}
return null;
});
</script>
<style scoped>
.csv-viewer {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
background-color: var(--surfacePrimary);
color: var(--textSecondary);
padding: 1rem;
padding-top: 4em;
box-sizing: border-box;
}
.csv-error,
.csv-empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
gap: 1rem;
color: var(--textPrimary);
}
.csv-error i,
.csv-empty i {
font-size: 4rem;
opacity: 0.5;
}
.csv-error p,
.csv-empty p {
font-size: 1.1rem;
margin: 0;
}
.csv-table-container {
flex: 1;
overflow: auto;
background-color: var(--surfacePrimary);
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
/* Scrollbar styling for better visibility */
.csv-table-container::-webkit-scrollbar {
width: 12px;
height: 12px;
}
.csv-table-container::-webkit-scrollbar-track {
background: var(--background);
border-radius: 4px;
}
.csv-table-container::-webkit-scrollbar-thumb {
background: var(--borderSecondary);
border-radius: 4px;
}
.csv-table-container::-webkit-scrollbar-thumb:hover {
background: var(--textPrimary);
}
.csv-table {
width: 100%;
border-collapse: collapse;
font-size: 0.875rem;
background-color: var(--surfacePrimary);
}
.csv-table thead {
position: sticky;
top: 0;
z-index: 10;
background-color: var(--surfaceSecondary);
}
.csv-table th {
padding: 0.875rem 1rem;
text-align: left;
font-weight: 600;
border-bottom: 2px solid var(--borderSecondary);
background-color: var(--surfaceSecondary);
white-space: nowrap;
color: var(--textSecondary);
font-size: 0.875rem;
}
.csv-table td {
padding: 0.75rem 1rem;
text-align: left;
border-bottom: 1px solid var(--borderPrimary);
white-space: nowrap;
max-width: 400px;
overflow: hidden;
text-overflow: ellipsis;
color: var(--textSecondary);
}
.csv-table tbody tr:nth-child(even) {
background-color: var(--background);
}
.csv-table tbody tr:hover {
background-color: var(--hover);
transition: background-color 0.15s ease;
}
.csv-footer {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
padding: 0.5rem;
}
.csv-footer > :only-child {
margin-left: auto;
}
.csv-info {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.75rem 1rem;
margin-top: 0.5rem;
background-color: var(--surfaceSecondary);
border-radius: 4px;
border-left: 3px solid var(--blue);
color: var(--textSecondary);
font-size: 0.875rem;
}
.column-separator {
display: flex;
align-items: center;
gap: 0.5rem;
}
.column-separator > label {
font-size: small;
text-align: end;
}
.column-separator > select {
margin-bottom: 0;
}
.csv-info i {
font-size: 1.2rem;
color: var(--blue);
}
</style>

View File

@ -265,15 +265,7 @@ const click = (event: Event | KeyboardEvent) => {
} }
if (fileStore.selected.indexOf(props.index) !== -1) { if (fileStore.selected.indexOf(props.index) !== -1) {
if ( fileStore.removeSelected(props.index);
(event as KeyboardEvent).ctrlKey ||
(event as KeyboardEvent).metaKey ||
fileStore.multiple
) {
fileStore.removeSelected(props.index);
} else {
fileStore.selected = [props.index];
}
return; return;
} }
@ -299,6 +291,7 @@ const click = (event: Event | KeyboardEvent) => {
} }
if ( if (
!singleClick.value &&
!(event as KeyboardEvent).ctrlKey && !(event as KeyboardEvent).ctrlKey &&
!(event as KeyboardEvent).metaKey && !(event as KeyboardEvent).metaKey &&
!fileStore.multiple !fileStore.multiple

View File

@ -109,8 +109,7 @@ export default {
return; return;
} }
if (this.user.redirectAfterCopyMove) this.$router.push({ path: this.dest });
this.$router.push({ path: this.dest });
}) })
.catch((e) => { .catch((e) => {
buttons.done("copy"); buttons.done("copy");

View File

@ -18,7 +18,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch, nextTick } from "vue"; import { ref, computed, watch, nextTick, defineProps } from "vue";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import { useFileStore } from "@/stores/file"; import { useFileStore } from "@/stores/file";
import url from "@/utils/url"; import url from "@/utils/url";

View File

@ -79,7 +79,7 @@ export default {
computed: { computed: {
...mapState(useFileStore, ["req", "selected"]), ...mapState(useFileStore, ["req", "selected"]),
...mapState(useAuthStore, ["user"]), ...mapState(useAuthStore, ["user"]),
...mapWritableState(useFileStore, ["reload", "preselect"]), ...mapWritableState(useFileStore, ["preselect"]),
excludedFolders() { excludedFolders() {
return this.selected return this.selected
.filter((idx) => this.req.items[idx].isDir) .filter((idx) => this.req.items[idx].isDir)
@ -108,9 +108,7 @@ export default {
.then(() => { .then(() => {
buttons.success("move"); buttons.success("move");
this.preselect = removePrefix(items[0].to); this.preselect = removePrefix(items[0].to);
if (this.user.redirectAfterCopyMove) this.$router.push({ path: this.dest });
this.$router.push({ path: this.dest });
else this.reload = true;
}) })
.catch((e) => { .catch((e) => {
buttons.done("move"); buttons.done("move");

View File

@ -24,7 +24,7 @@
"ok": "موافق", "ok": "موافق",
"permalink": "الحصول على رابط دائم", "permalink": "الحصول على رابط دائم",
"previous": "السابق", "previous": "السابق",
"preview": "معاينة", "preview": "Preview",
"publish": "نشر", "publish": "نشر",
"rename": "إعادة تسمية", "rename": "إعادة تسمية",
"replace": "استبدال", "replace": "استبدال",
@ -43,11 +43,7 @@
"upload": "رفع", "upload": "رفع",
"openFile": "فتح الملف", "openFile": "فتح الملف",
"discardChanges": "إلغاء التغييرات", "discardChanges": "إلغاء التغييرات",
"stopSearch": "توقف عن البحث", "saveChanges": "Save changes"
"saveChanges": "حفظ التغييرات",
"editAsText": "تعديل على شكل نص",
"increaseFontSize": "زيادة حجم الخط",
"decreaseFontSize": "تصغير حجم الخط"
}, },
"download": { "download": {
"downloadFile": "تحميل الملف", "downloadFile": "تحميل الملف",
@ -79,16 +75,7 @@
"sortByLastModified": "الترتيب بآخر تعديل", "sortByLastModified": "الترتيب بآخر تعديل",
"sortByName": "الترتيب باﻹسم", "sortByName": "الترتيب باﻹسم",
"sortBySize": "الترتيب بالحجم", "sortBySize": "الترتيب بالحجم",
"noPreview": "لا يوجد عرض مسبق لهذا الملف.", "noPreview": "لا يوجد عرض مسبق لهذا الملف."
"csvTooLarge": "حجم الملف اكبر من (<5MB), يرجى تحميل الملف للمعاينة",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "حدد الملف أو المجلد", "click": "حدد الملف أو المجلد",
@ -138,7 +125,7 @@
"filesSelected": "تم تحديد {count} ملفات.", "filesSelected": "تم تحديد {count} ملفات.",
"lastModified": "آخر تعديل", "lastModified": "آخر تعديل",
"move": "نقل", "move": "نقل",
"moveMessage": "اختر منزلاً جديداً لملفك (ملفاتك)/مجلدك (مجلداتك):", "moveMessage": "إختر مكان جديد للملفات أو المجلدات المراد نقلها:",
"newArchetype": "إنشاء منشور من المنشور اﻷصلي. الملف سيتم انشاءه في مجلد المحتويات.", "newArchetype": "إنشاء منشور من المنشور اﻷصلي. الملف سيتم انشاءه في مجلد المحتويات.",
"newDir": "مجلد جديد", "newDir": "مجلد جديد",
"newDirMessage": "أدخل اسم المجلد الجديد.", "newDirMessage": "أدخل اسم المجلد الجديد.",
@ -189,15 +176,15 @@
"commandRunner": "منفذ اﻷوامر", "commandRunner": "منفذ اﻷوامر",
"commandRunnerHelp": "هنا بإمكانك تعيين اﻷوامر التي سيتم تنفيذها في اﻷحداث المسماة. يجب كتابة أمر واحد في كل سطر. ستكون المتغيرات البيئية (env) {0} و {1} متاحة، حيث {0} نسبي لـ {1}. لمزيد من المعلومات حول هذه الميزة و المتغيرات البيئية المتاحة، يرجى قراءة {2}.", "commandRunnerHelp": "هنا بإمكانك تعيين اﻷوامر التي سيتم تنفيذها في اﻷحداث المسماة. يجب كتابة أمر واحد في كل سطر. ستكون المتغيرات البيئية (env) {0} و {1} متاحة، حيث {0} نسبي لـ {1}. لمزيد من المعلومات حول هذه الميزة و المتغيرات البيئية المتاحة، يرجى قراءة {2}.",
"commandsUpdated": "تم تحديث اﻷوامر", "commandsUpdated": "تم تحديث اﻷوامر",
"createUserDir": "إنشاء مجلد المستخدم الرئيسي تلقائياً عند إنشاء مستخدم جديد", "createUserDir": "إنشاء مجلد المستخدم (home) تلقائياً عند إنشاء مستخدم جديد",
"minimumPasswordLength": "Minimum password length", "minimumPasswordLength": "Minimum password length",
"tusUploads": "التحميلات المتقطعة", "tusUploads": "التحميلات المتقطعة",
"tusUploadsHelp": "يدعم متصفح الملفات تحميل الملفات المتقطعة، مما يسمح بتحميلات الملفات بشكل فعال و موثوق و قابلة للمتابغة و متقطعة حتى على الشبكات غير الموثوقة.", "tusUploadsHelp": "يدعم متصفح الملفات تحميل الملفات المتقطعة، مما يسمح بتحميلات الملفات بشكل فعال و موثوق و قابلة للمتابغة و متقطعة حتى على الشبكات غير الموثوقة.",
"tusUploadsChunkSize": "يشير إلى الحد اﻷقصى لحجم الطلب (سيتم استخدام التحميل المباشر للتحميلات صغيرة الخحم). يمكنك إدخال عدد صحيح عادي يدل على الحجم بوحدة البايت أو نمظ مثل10MB, 1GB, إلخ.", "tusUploadsChunkSize": "يشير إلى الحد اﻷقصى لحجم الطلب (سيتم استخدام التحميل المباشر للتحميلات صغيرة الخحم). يمكنك إدخال عدد صحيح عادي يدل على الحجم بوحدة البايت أو نمظ مثل10MB, 1GB, إلخ.",
"tusUploadsRetryCount": "عدد مرات إعادة المحاولة إذا فشلت عملية تحميل القطعة.", "tusUploadsRetryCount": "عدد مرات إعادة المحاولة إذا فشلت عملية تحميل القطعة.",
"userHomeBasePath": "المسار الرئيسي لمجلد المستخدم الرئيسي", "userHomeBasePath": "المسار الرئيسي لمجلد المستخدم (home)",
"userScopeGenerationPlaceholder": "سيتم تعيين نطاق المستخدم تلقائياً", "userScopeGenerationPlaceholder": "سيتم تعيين نطاق المستخدم تلقائياً",
"createUserHomeDirectory": "إنشاء مجلد المستخدم الرئيسي", "createUserHomeDirectory": "إنشاء مجلد المستخدم (home)",
"customStylesheet": "ستايل مخصص", "customStylesheet": "ستايل مخصص",
"defaultUserDescription": "هذه اﻹعدادات اﻹفتراضية للمستخدمين الجدد.", "defaultUserDescription": "هذه اﻹعدادات اﻹفتراضية للمستخدمين الجدد.",
"disableExternalLinks": "تعطيل الروابط الخارجية (بإسثناء الوثائق)", "disableExternalLinks": "تعطيل الروابط الخارجية (بإسثناء الوثائق)",
@ -258,8 +245,7 @@
"userManagement": "إدارة المستخدمين", "userManagement": "إدارة المستخدمين",
"userUpdated": "تم تعديل المستخدم", "userUpdated": "تم تعديل المستخدم",
"username": "إسم المستخدم", "username": "إسم المستخدم",
"users": "المستخدمين", "users": "المستخدمين"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "مساعدة", "help": "مساعدة",

View File

@ -43,11 +43,7 @@
"upload": "Качи", "upload": "Качи",
"openFile": "Отвори файл", "openFile": "Отвори файл",
"discardChanges": "Изчисти", "discardChanges": "Изчисти",
"stopSearch": "Stop searching", "saveChanges": "Запиши промените"
"saveChanges": "Запиши промените",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Свали файл", "downloadFile": "Свали файл",
@ -79,16 +75,7 @@
"sortByLastModified": "Подредба по последна промяна", "sortByLastModified": "Подредба по последна промяна",
"sortByName": "Подредба по име", "sortByName": "Подредба по име",
"sortBySize": "Подредба по размер", "sortBySize": "Подредба по размер",
"noPreview": "За този файл не е наличен преглед.", "noPreview": "За този файл не е наличен преглед."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "избери файл или директория", "click": "избери файл или директория",
@ -258,8 +245,7 @@
"userManagement": "Управление на потребители", "userManagement": "Управление на потребители",
"userUpdated": "Потребителя е обновен!", "userUpdated": "Потребителя е обновен!",
"username": "Потребителско име", "username": "Потребителско име",
"users": "Потребители", "users": "Потребители"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Помощ", "help": "Помощ",

View File

@ -43,11 +43,7 @@
"upload": "Pujar", "upload": "Pujar",
"openFile": "Obrir fitxer", "openFile": "Obrir fitxer",
"discardChanges": "Descartar", "discardChanges": "Descartar",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Descarregar fitxer", "downloadFile": "Descarregar fitxer",
@ -79,16 +75,7 @@
"sortByLastModified": "Ordenar per última modificació", "sortByLastModified": "Ordenar per última modificació",
"sortByName": "Ordenar per nom", "sortByName": "Ordenar per nom",
"sortBySize": "Ordenar per mida", "sortBySize": "Ordenar per mida",
"noPreview": "La vista prèvia no està disponible per a aquest fitxer.", "noPreview": "La vista prèvia no està disponible per a aquest fitxer."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "seleccionar fitxer o carpeta", "click": "seleccionar fitxer o carpeta",
@ -258,8 +245,7 @@
"userManagement": "Administració d'usuaris", "userManagement": "Administració d'usuaris",
"userUpdated": "Usuari actualitzat!", "userUpdated": "Usuari actualitzat!",
"username": "Usuari", "username": "Usuari",
"users": "Usuaris", "users": "Usuaris"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Ajuda", "help": "Ajuda",

View File

@ -43,11 +43,7 @@
"upload": "Nahrát", "upload": "Nahrát",
"openFile": "Otevřít soubor", "openFile": "Otevřít soubor",
"discardChanges": "Zrušit změny", "discardChanges": "Zrušit změny",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Stáhnout soubor", "downloadFile": "Stáhnout soubor",
@ -79,16 +75,7 @@
"sortByLastModified": "Seřadit podle poslední změny", "sortByLastModified": "Seřadit podle poslední změny",
"sortByName": "Seřadit podle názvu", "sortByName": "Seřadit podle názvu",
"sortBySize": "Seřadit podle velikosti", "sortBySize": "Seřadit podle velikosti",
"noPreview": "Náhled pro tento soubor není k dispozici.", "noPreview": "Náhled pro tento soubor není k dispozici."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "vyberte soubor nebo adresář", "click": "vyberte soubor nebo adresář",
@ -258,8 +245,7 @@
"userManagement": "Správa uživatelů", "userManagement": "Správa uživatelů",
"userUpdated": "Uživatel aktualizován!", "userUpdated": "Uživatel aktualizován!",
"username": "Uživatelské jméno", "username": "Uživatelské jméno",
"users": "Uživatelé", "users": "Uživatelé"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Nápověda", "help": "Nápověda",

View File

@ -43,11 +43,7 @@
"upload": "Upload", "upload": "Upload",
"openFile": "Datei öffnen", "openFile": "Datei öffnen",
"discardChanges": "Verwerfen", "discardChanges": "Verwerfen",
"stopSearch": "Suche abbrechen", "saveChanges": "Save changes"
"saveChanges": "Änderungen speichern",
"editAsText": "Als Text bearbeiten",
"increaseFontSize": "Schriftgröße vergrößern",
"decreaseFontSize": "Schriftgröße verkleinern"
}, },
"download": { "download": {
"downloadFile": "Download Datei", "downloadFile": "Download Datei",
@ -79,16 +75,7 @@
"sortByLastModified": "Nach Änderungsdatum sortieren", "sortByLastModified": "Nach Änderungsdatum sortieren",
"sortByName": "Nach Namen sortieren", "sortByName": "Nach Namen sortieren",
"sortBySize": "Nach Größe sortieren", "sortBySize": "Nach Größe sortieren",
"noPreview": "Für diese Datei ist keine Vorschau verfügbar.", "noPreview": "Für diese Datei ist keine Vorschau verfügbar."
"csvTooLarge": "Die CSV-Datei ist zu groß für die Vorschau (>5 MB). Bitte herunterladen, um sie anzuzeigen.",
"csvLoadFailed": "Fehler beim Laden der CSV-Datei.",
"showingRows": "{count} Zeile(n) werden angezeigt",
"columnSeparator": "Spaltentrennzeichen",
"csvSeparators": {
"comma": "Komma (,)",
"semicolon": "Semikolon (;)",
"both": "Sowohl (,) als auch (;)"
}
}, },
"help": { "help": {
"click": "Wähle Datei oder Ordner", "click": "Wähle Datei oder Ordner",
@ -115,9 +102,9 @@
"username": "Benutzername", "username": "Benutzername",
"usernameTaken": "Benutzername ist bereits vergeben", "usernameTaken": "Benutzername ist bereits vergeben",
"wrongCredentials": "Falsche Zugangsdaten", "wrongCredentials": "Falsche Zugangsdaten",
"passwordTooShort": "Passwort muss mindestens {min} Zeichen lang sein", "passwordTooShort": "Password must be at least {min} characters",
"logout_reasons": { "logout_reasons": {
"inactivity": "Du wurdest aufgrund von Inaktivität abgemeldet." "inactivity": "You have been logged out due to inactivity."
} }
}, },
"permanent": "Permanent", "permanent": "Permanent",
@ -172,7 +159,7 @@
"video": "Video" "video": "Video"
}, },
"settings": { "settings": {
"aceEditorTheme": "Ace Editor Theme", "aceEditorTheme": "Ace editor theme",
"admin": "Admin", "admin": "Admin",
"administrator": "Administrator", "administrator": "Administrator",
"allowCommands": "Befehle ausführen", "allowCommands": "Befehle ausführen",
@ -180,7 +167,7 @@
"allowNew": "Erstellen neuer Dateien und Ordner", "allowNew": "Erstellen neuer Dateien und Ordner",
"allowPublish": "Veröffentlichen von neuen Beiträgen und Seiten", "allowPublish": "Veröffentlichen von neuen Beiträgen und Seiten",
"allowSignup": "Erlaube Benutzern sich zu registrieren", "allowSignup": "Erlaube Benutzern sich zu registrieren",
"hideLoginButton": "Den Login-Button auf öffentlichen Seiten ausblenden", "hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(leer lassen, um Änderungen zu vermeiden)", "avoidChanges": "(leer lassen, um Änderungen zu vermeiden)",
"branding": "Design", "branding": "Design",
"brandingDirectoryPath": "Designverzeichnispfad", "brandingDirectoryPath": "Designverzeichnispfad",
@ -190,7 +177,7 @@
"commandRunnerHelp": "Hier könne Sie Befehle eintragen, welche bei den benannten Aktionen ausgeführt werden. Sie müssen pro Zeile jeweils einen Befehl eingeben. Die Umgebungsvariable {0} und {1} sind verfügbar, wobei {0} relative zu {1} ist. Für mehr Informationen über diese Funktion und die verfügbaren Umgebungsvariablen lesen Sie bitte die {2}.", "commandRunnerHelp": "Hier könne Sie Befehle eintragen, welche bei den benannten Aktionen ausgeführt werden. Sie müssen pro Zeile jeweils einen Befehl eingeben. Die Umgebungsvariable {0} und {1} sind verfügbar, wobei {0} relative zu {1} ist. Für mehr Informationen über diese Funktion und die verfügbaren Umgebungsvariablen lesen Sie bitte die {2}.",
"commandsUpdated": "Befehle aktualisiert!", "commandsUpdated": "Befehle aktualisiert!",
"createUserDir": "Automatisches Erstellen des Home-Verzeichnisses beim Anlegen neuer Benutzer", "createUserDir": "Automatisches Erstellen des Home-Verzeichnisses beim Anlegen neuer Benutzer",
"minimumPasswordLength": "Mindestlänge für Passwörter", "minimumPasswordLength": "Minimum password length",
"tusUploads": "Gestückelter Upload", "tusUploads": "Gestückelter Upload",
"tusUploadsHelp": "File Browser unterstützt das Hochladen von gestückelten Dateien und ermöglicht so einen effizienten, zuverlässigen, fortsetzbaren und gestückelten Datei-Upload auch in unzuverlässigen Netzwerken.", "tusUploadsHelp": "File Browser unterstützt das Hochladen von gestückelten Dateien und ermöglicht so einen effizienten, zuverlässigen, fortsetzbaren und gestückelten Datei-Upload auch in unzuverlässigen Netzwerken.",
"tusUploadsChunkSize": "Gibt die maximale Größe pro Anfrage an (direkte Uploads werden für kleinere Uploads verwendet). Bitte geben Sie eine Byte-Angabe oder eine Zeichenfolge wie 10 MB, 1 GB usw. an", "tusUploadsChunkSize": "Gibt die maximale Größe pro Anfrage an (direkte Uploads werden für kleinere Uploads verwendet). Bitte geben Sie eine Byte-Angabe oder eine Zeichenfolge wie 10 MB, 1 GB usw. an",
@ -214,7 +201,7 @@
"instanceName": "Instanzname", "instanceName": "Instanzname",
"language": "Sprache", "language": "Sprache",
"lockPassword": "Verhindere, dass der Benutzer sein Passwort ändert", "lockPassword": "Verhindere, dass der Benutzer sein Passwort ändert",
"newPassword": "Ihr neues Passwort", "newPassword": "Ihr neues Passwort.",
"newPasswordConfirm": "Bestätigen Sie Ihr neues Passwort", "newPasswordConfirm": "Bestätigen Sie Ihr neues Passwort",
"newUser": "Neuer Benutzer", "newUser": "Neuer Benutzer",
"password": "Passwort", "password": "Passwort",
@ -258,8 +245,7 @@
"userManagement": "Benutzerverwaltung", "userManagement": "Benutzerverwaltung",
"userUpdated": "Benutzer aktualisiert!", "userUpdated": "Benutzer aktualisiert!",
"username": "Nutzername", "username": "Nutzername",
"users": "Nutzer", "users": "Nutzer"
"currentPassword": "Ihr aktuelles Passwort"
}, },
"sidebar": { "sidebar": {
"help": "Hilfe", "help": "Hilfe",

View File

@ -43,11 +43,7 @@
"upload": "Μεταφόρτωση", "upload": "Μεταφόρτωση",
"openFile": "Άνοιγμα αρχείου", "openFile": "Άνοιγμα αρχείου",
"discardChanges": "Discard", "discardChanges": "Discard",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Λήψη αρχείου", "downloadFile": "Λήψη αρχείου",
@ -79,16 +75,7 @@
"sortByLastModified": "Ταξινόμηση κατά πρόσφατη τροποποίηση", "sortByLastModified": "Ταξινόμηση κατά πρόσφατη τροποποίηση",
"sortByName": "Ταξινόμηση κατά όνομα", "sortByName": "Ταξινόμηση κατά όνομα",
"sortBySize": "Ταξινόμηση κατά μέγεθος", "sortBySize": "Ταξινόμηση κατά μέγεθος",
"noPreview": "Η προεπισκόπηση δεν είναι διαθέσιμη για αυτό το αρχείο.", "noPreview": "Η προεπισκόπηση δεν είναι διαθέσιμη για αυτό το αρχείο."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "επιλέξτε αρχείο ή φάκελο", "click": "επιλέξτε αρχείο ή φάκελο",
@ -258,8 +245,7 @@
"userManagement": "Διαχείριση χρηστών", "userManagement": "Διαχείριση χρηστών",
"userUpdated": "Ο χρήστης ενημερώθηκε!", "userUpdated": "Ο χρήστης ενημερώθηκε!",
"username": "Όνομα χρήστη", "username": "Όνομα χρήστη",
"users": "Χρήστες", "users": "Χρήστες"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Βοήθεια", "help": "Βοήθεια",

View File

@ -43,11 +43,7 @@
"upload": "Upload", "upload": "Upload",
"openFile": "Open file", "openFile": "Open file",
"discardChanges": "Discard", "discardChanges": "Discard",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Download File", "downloadFile": "Download File",
@ -79,16 +75,7 @@
"sortByLastModified": "Sort by last modified", "sortByLastModified": "Sort by last modified",
"sortByName": "Sort by name", "sortByName": "Sort by name",
"sortBySize": "Sort by size", "sortBySize": "Sort by size",
"noPreview": "Preview is not available for this file.", "noPreview": "Preview is not available for this file."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "select file or directory", "click": "select file or directory",
@ -232,7 +219,6 @@
"permissions": "Permissions", "permissions": "Permissions",
"permissionsHelp": "You can set the user to be an administrator or choose the permissions individually. If you select \"Administrator\", all of the other options will be automatically checked. The management of users remains a privilege of an administrator.\n", "permissionsHelp": "You can set the user to be an administrator or choose the permissions individually. If you select \"Administrator\", all of the other options will be automatically checked. The management of users remains a privilege of an administrator.\n",
"profileSettings": "Profile Settings", "profileSettings": "Profile Settings",
"redirectAfterCopyMove": "Redirect to destination after copy/move",
"ruleExample1": "prevents the access to any dotfile (such as .git, .gitignore) in every folder.\n", "ruleExample1": "prevents the access to any dotfile (such as .git, .gitignore) in every folder.\n",
"ruleExample2": "blocks the access to the file named Caddyfile on the root of the scope.", "ruleExample2": "blocks the access to the file named Caddyfile on the root of the scope.",
"rules": "Rules", "rules": "Rules",
@ -259,8 +245,7 @@
"userManagement": "User Management", "userManagement": "User Management",
"userUpdated": "User updated!", "userUpdated": "User updated!",
"username": "Username", "username": "Username",
"users": "Users", "users": "Users"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Help", "help": "Help",

View File

@ -43,11 +43,7 @@
"upload": "Subir", "upload": "Subir",
"openFile": "Abrir archivo", "openFile": "Abrir archivo",
"discardChanges": "Discard", "discardChanges": "Discard",
"stopSearch": "Stop searching", "saveChanges": "Guardar cambios"
"saveChanges": "Guardar cambios",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Descargar fichero", "downloadFile": "Descargar fichero",
@ -79,16 +75,7 @@
"sortByLastModified": "Ordenar por última modificación", "sortByLastModified": "Ordenar por última modificación",
"sortByName": "Ordenar por nombre", "sortByName": "Ordenar por nombre",
"sortBySize": "Ordenar por tamaño", "sortBySize": "Ordenar por tamaño",
"noPreview": "La vista previa no está disponible para este archivo.", "noPreview": "La vista previa no está disponible para este archivo."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "seleccionar archivo o carpeta", "click": "seleccionar archivo o carpeta",
@ -258,8 +245,7 @@
"userManagement": "Administración de usuarios", "userManagement": "Administración de usuarios",
"userUpdated": "¡Usuario actualizado!", "userUpdated": "¡Usuario actualizado!",
"username": "Usuario", "username": "Usuario",
"users": "Usuarios", "users": "Usuarios"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Ayuda", "help": "Ayuda",

View File

@ -43,11 +43,7 @@
"upload": "آپلود", "upload": "آپلود",
"openFile": "باز کردن فایل", "openFile": "باز کردن فایل",
"discardChanges": "لغو کردن", "discardChanges": "لغو کردن",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "دانلود فایل", "downloadFile": "دانلود فایل",
@ -79,16 +75,7 @@
"sortByLastModified": "مرتب سازی آخرین ویرایش", "sortByLastModified": "مرتب سازی آخرین ویرایش",
"sortByName": "مرتب سازی نام", "sortByName": "مرتب سازی نام",
"sortBySize": "مرتب سازی اندازه", "sortBySize": "مرتب سازی اندازه",
"noPreview": "این فایل قابل نمایش نیست", "noPreview": "این فایل قابل نمایش نیست"
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "انتخاب فایل یا پوشه", "click": "انتخاب فایل یا پوشه",
@ -258,8 +245,7 @@
"userManagement": "مدیریت کاربران", "userManagement": "مدیریت کاربران",
"userUpdated": "کاربر به روز شد!", "userUpdated": "کاربر به روز شد!",
"username": "نام کاربری", "username": "نام کاربری",
"users": "کاربران", "users": "کاربران"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "راهنما", "help": "راهنما",

View File

@ -43,11 +43,7 @@
"upload": "Importer", "upload": "Importer",
"openFile": "Ouvrir le fichier", "openFile": "Ouvrir le fichier",
"discardChanges": "Annuler", "discardChanges": "Annuler",
"stopSearch": "Arrêter recherche", "saveChanges": "Save changes"
"saveChanges": "Enregistrer changements",
"editAsText": "Editer comme Texte",
"increaseFontSize": "Augmenter taille police",
"decreaseFontSize": "Réduire taille police"
}, },
"download": { "download": {
"downloadFile": "Télécharger le fichier", "downloadFile": "Télécharger le fichier",
@ -79,16 +75,7 @@
"sortByLastModified": "Trier par date de modification", "sortByLastModified": "Trier par date de modification",
"sortByName": "Trier par nom", "sortByName": "Trier par nom",
"sortBySize": "Trier par taille", "sortBySize": "Trier par taille",
"noPreview": "L'aperçu n'est pas disponible pour ce fichier.", "noPreview": "L'aperçu n'est pas disponible pour ce fichier."
"csvTooLarge": "Le fichier CSV est trop volumineux pour être prévisualisé (>5MB). Veuillez le télécharger pour le voir.",
"csvLoadFailed": "Impossible de charger le fichier CSV.",
"showingRows": "Affichage de {count} ligne(s)",
"columnSeparator": "Séparateur de Colonnes",
"csvSeparators": {
"comma": "Virgule (,)",
"semicolon": "Point-virgule (;)",
"both": "Les (,) et (;)"
}
}, },
"help": { "help": {
"click": "Sélectionner un fichier ou dossier", "click": "Sélectionner un fichier ou dossier",
@ -115,9 +102,9 @@
"username": "Utilisateur·ice", "username": "Utilisateur·ice",
"usernameTaken": "Le nom d'utilisateur·ice est déjà pris", "usernameTaken": "Le nom d'utilisateur·ice est déjà pris",
"wrongCredentials": "Identifiants incorrects !", "wrongCredentials": "Identifiants incorrects !",
"passwordTooShort": "Le mot de passe doit contenir au moins {min} caractères", "passwordTooShort": "Password must be at least {min} characters",
"logout_reasons": { "logout_reasons": {
"inactivity": "Vous avez été déconnecté(e) en raison d'une inactivité prolongée." "inactivity": "You have been logged out due to inactivity."
} }
}, },
"permanent": "Permanent", "permanent": "Permanent",
@ -172,7 +159,7 @@
"video": "Vidéo" "video": "Vidéo"
}, },
"settings": { "settings": {
"aceEditorTheme": "Éditeur de Thème Ace", "aceEditorTheme": "Ace editor theme",
"admin": "Admin", "admin": "Admin",
"administrator": "Administrateur·ice", "administrator": "Administrateur·ice",
"allowCommands": "Exécuter des commandes", "allowCommands": "Exécuter des commandes",
@ -180,7 +167,7 @@
"allowNew": "Créer de nouveaux fichiers et dossiers", "allowNew": "Créer de nouveaux fichiers et dossiers",
"allowPublish": "Publier de nouveaux posts et pages", "allowPublish": "Publier de nouveaux posts et pages",
"allowSignup": "Autoriser les utilisateur·ices à s'inscrire", "allowSignup": "Autoriser les utilisateur·ices à s'inscrire",
"hideLoginButton": "Cacher le bouton didentification sur les pages publiques", "hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(Laisser vide pour conserver l'actuel)", "avoidChanges": "(Laisser vide pour conserver l'actuel)",
"branding": "Image de marque", "branding": "Image de marque",
"brandingDirectoryPath": "Chemin du dossier d'image de marque", "brandingDirectoryPath": "Chemin du dossier d'image de marque",
@ -258,8 +245,7 @@
"userManagement": "Gestion des utilisateur·ices", "userManagement": "Gestion des utilisateur·ices",
"userUpdated": "Utilisateur·ice mis à jour !", "userUpdated": "Utilisateur·ice mis à jour !",
"username": "Nom d'utilisateur·ice", "username": "Nom d'utilisateur·ice",
"users": "Utilisateur·ices", "users": "Utilisateur·ices"
"currentPassword": "Mot de Passe Actuel"
}, },
"sidebar": { "sidebar": {
"help": "Aide", "help": "Aide",

View File

@ -43,11 +43,7 @@
"upload": "העלאה", "upload": "העלאה",
"openFile": "פתח קובץ", "openFile": "פתח קובץ",
"discardChanges": "זריקת השינויים", "discardChanges": "זריקת השינויים",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "הורד קובץ", "downloadFile": "הורד קובץ",
@ -79,16 +75,7 @@
"sortByLastModified": "מיין לפי השינוי האחרון", "sortByLastModified": "מיין לפי השינוי האחרון",
"sortByName": "מיין לפי שם", "sortByName": "מיין לפי שם",
"sortBySize": "מיין לפי גודל", "sortBySize": "מיין לפי גודל",
"noPreview": "לא זמינה תצוגה מקדימה לקובץ זה", "noPreview": "לא זמינה תצוגה מקדימה לקובץ זה"
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "בחר קובץ או תיקייה", "click": "בחר קובץ או תיקייה",
@ -258,8 +245,7 @@
"userManagement": "ניהול משתמש", "userManagement": "ניהול משתמש",
"userUpdated": "המשתמש עודכן!", "userUpdated": "המשתמש עודכן!",
"username": "שם משתמש", "username": "שם משתמש",
"users": "משתמשים", "users": "משתמשים"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "עזרה", "help": "עזרה",

View File

@ -43,11 +43,7 @@
"upload": "Prenesi", "upload": "Prenesi",
"openFile": "Otvori datoteku", "openFile": "Otvori datoteku",
"discardChanges": "Odbaci", "discardChanges": "Odbaci",
"stopSearch": "Stop searching", "saveChanges": "Spremi promjene"
"saveChanges": "Spremi promjene",
"editAsText": "Uredi kao tekst",
"increaseFontSize": "Povećaj veličinu fonta",
"decreaseFontSize": "Smanji veličinu fonta"
}, },
"download": { "download": {
"downloadFile": "Preuzmi Datoteku", "downloadFile": "Preuzmi Datoteku",
@ -79,16 +75,7 @@
"sortByLastModified": "Sortiraj po zadnjoj izmjeni", "sortByLastModified": "Sortiraj po zadnjoj izmjeni",
"sortByName": "Sortiraj po nazivu", "sortByName": "Sortiraj po nazivu",
"sortBySize": "Sortiraj po veličini", "sortBySize": "Sortiraj po veličini",
"noPreview": "Pregled nije dostupan za ovu datoteku.", "noPreview": "Pregled nije dostupan za ovu datoteku."
"csvTooLarge": "CSV datoteka je prevelika za pregled (>5MB). Molimo preuzmite da bi ste ju pregledali.",
"csvLoadFailed": "Neuspješno učitavanje CSV datoteke.",
"showingRows": "Prikazuje se {count} red(ova)",
"columnSeparator": "Separator stupaca",
"csvSeparators": {
"comma": "Zarez (,)",
"semicolon": "Točka zarez (;)",
"both": "I (,) i (;)"
}
}, },
"help": { "help": {
"click": "odaberi datoteku ili mapu", "click": "odaberi datoteku ili mapu",
@ -115,7 +102,7 @@
"username": "Korisničko ime", "username": "Korisničko ime",
"usernameTaken": "Korisničko ime zauzeto", "usernameTaken": "Korisničko ime zauzeto",
"wrongCredentials": "Neispravno korisničko ime/lozinka", "wrongCredentials": "Neispravno korisničko ime/lozinka",
"passwordTooShort": "Lozinka mora sadržavati minimalno {min} znakova", "passwordTooShort": "Password must be at least {min} characters",
"logout_reasons": { "logout_reasons": {
"inactivity": "Odjavljeni ste zbog neaktivnosti." "inactivity": "Odjavljeni ste zbog neaktivnosti."
} }
@ -180,7 +167,7 @@
"allowNew": "Stvori nove datoteke i mape", "allowNew": "Stvori nove datoteke i mape",
"allowPublish": "Objavi nove objave i stranice", "allowPublish": "Objavi nove objave i stranice",
"allowSignup": "Dopusti registraciju korisnicima", "allowSignup": "Dopusti registraciju korisnicima",
"hideLoginButton": "Sakrij tipku za prijavu s javnih stranica", "hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(ostavite prazno kako biste izbjegli promjene)", "avoidChanges": "(ostavite prazno kako biste izbjegli promjene)",
"branding": "Brendiranje", "branding": "Brendiranje",
"brandingDirectoryPath": "Put brendiranja", "brandingDirectoryPath": "Put brendiranja",
@ -258,8 +245,7 @@
"userManagement": "Upravljanje Korisnicima", "userManagement": "Upravljanje Korisnicima",
"userUpdated": "Korisnik ažuriran!", "userUpdated": "Korisnik ažuriran!",
"username": "Korisničko ime", "username": "Korisničko ime",
"users": "Korisnici", "users": "Korisnici"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Pomoć", "help": "Pomoć",

View File

@ -43,11 +43,7 @@
"upload": "Feltöltés", "upload": "Feltöltés",
"openFile": "Fájl megnyitása", "openFile": "Fájl megnyitása",
"discardChanges": "Discard", "discardChanges": "Discard",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Fájl letöltése", "downloadFile": "Fájl letöltése",
@ -79,16 +75,7 @@
"sortByLastModified": "Rendezés utolsó módosítás szerint", "sortByLastModified": "Rendezés utolsó módosítás szerint",
"sortByName": "Rendezés név szerint", "sortByName": "Rendezés név szerint",
"sortBySize": "Rendezés méret szerint", "sortBySize": "Rendezés méret szerint",
"noPreview": "Ehhez a fájlhoz nincs előnézet.", "noPreview": "Ehhez a fájlhoz nincs előnézet."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "mappa vagy fájl kijelölése", "click": "mappa vagy fájl kijelölése",
@ -258,8 +245,7 @@
"userManagement": "Felhasználókezelés", "userManagement": "Felhasználókezelés",
"userUpdated": "Felhasználó frissítve!", "userUpdated": "Felhasználó frissítve!",
"username": "Felhasználói név", "username": "Felhasználói név",
"users": "Felhasználók", "users": "Felhasználók"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Súgó", "help": "Súgó",

View File

@ -43,11 +43,7 @@
"upload": "Hlaða upp", "upload": "Hlaða upp",
"openFile": "Open file", "openFile": "Open file",
"discardChanges": "Discard", "discardChanges": "Discard",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Sækja skjal", "downloadFile": "Sækja skjal",
@ -79,16 +75,7 @@
"sortByLastModified": "Flokka eftir Seinast breytt", "sortByLastModified": "Flokka eftir Seinast breytt",
"sortByName": "Flokka eftir nafni", "sortByName": "Flokka eftir nafni",
"sortBySize": "Flokka eftir stærð", "sortBySize": "Flokka eftir stærð",
"noPreview": "Preview is not available for this file.", "noPreview": "Preview is not available for this file."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "velja skjal eða möppu", "click": "velja skjal eða möppu",
@ -258,8 +245,7 @@
"userManagement": "Notendastýring", "userManagement": "Notendastýring",
"userUpdated": "Notandastillingar vistaðar!", "userUpdated": "Notandastillingar vistaðar!",
"username": "Notendanafn", "username": "Notendanafn",
"users": "Notendur", "users": "Notendur"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Hjálp", "help": "Hjálp",

View File

@ -43,11 +43,7 @@
"upload": "Carica", "upload": "Carica",
"openFile": "Apri file", "openFile": "Apri file",
"discardChanges": "Ignora", "discardChanges": "Ignora",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Scarica file", "downloadFile": "Scarica file",
@ -79,16 +75,7 @@
"sortByLastModified": "Ordina per ultima modifica", "sortByLastModified": "Ordina per ultima modifica",
"sortByName": "Ordina per nome", "sortByName": "Ordina per nome",
"sortBySize": "Ordina per dimensione", "sortBySize": "Ordina per dimensione",
"noPreview": "L'anteprima non è disponibile per questo file.", "noPreview": "L'anteprima non è disponibile per questo file."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "seleziona un file o una cartella", "click": "seleziona un file o una cartella",
@ -258,8 +245,7 @@
"userManagement": "Gestione degli utenti", "userManagement": "Gestione degli utenti",
"userUpdated": "Utente aggiornato!", "userUpdated": "Utente aggiornato!",
"username": "Nome utente", "username": "Nome utente",
"users": "Utenti", "users": "Utenti"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Aiuto", "help": "Aiuto",

View File

@ -43,11 +43,7 @@
"upload": "アップロード", "upload": "アップロード",
"openFile": "ファイルを開く", "openFile": "ファイルを開く",
"discardChanges": "Discard", "discardChanges": "Discard",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "ファイルのダウンロード", "downloadFile": "ファイルのダウンロード",
@ -79,16 +75,7 @@
"sortByLastModified": "更新日時で並べ替え", "sortByLastModified": "更新日時で並べ替え",
"sortByName": "名前で並べ替え", "sortByName": "名前で並べ替え",
"sortBySize": "サイズで並べ替え", "sortBySize": "サイズで並べ替え",
"noPreview": "プレビューはこのファイルでは利用できません", "noPreview": "プレビューはこのファイルでは利用できません"
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "ファイルやフォルダーを選択", "click": "ファイルやフォルダーを選択",
@ -258,8 +245,7 @@
"userManagement": "ユーザー管理", "userManagement": "ユーザー管理",
"userUpdated": "ユーザーを更新しました!", "userUpdated": "ユーザーを更新しました!",
"username": "ユーザー名", "username": "ユーザー名",
"users": "ユーザー", "users": "ユーザー"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "ヘルプ", "help": "ヘルプ",

View File

@ -43,11 +43,7 @@
"upload": "업로드", "upload": "업로드",
"openFile": "파일 열기", "openFile": "파일 열기",
"discardChanges": "변경 사항 취소", "discardChanges": "변경 사항 취소",
"stopSearch": "Stop searching", "saveChanges": "변경사항 저장"
"saveChanges": "변경사항 저장",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "파일 다운로드", "downloadFile": "파일 다운로드",
@ -79,16 +75,7 @@
"sortByLastModified": "수정시간순 정렬", "sortByLastModified": "수정시간순 정렬",
"sortByName": "이름순", "sortByName": "이름순",
"sortBySize": "크기순", "sortBySize": "크기순",
"noPreview": "미리 보기가 지원되지 않는 파일 유형입니다.", "noPreview": "미리 보기가 지원되지 않는 파일 유형입니다."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "파일이나 디렉토리를 선택해주세요.", "click": "파일이나 디렉토리를 선택해주세요.",
@ -258,8 +245,7 @@
"userManagement": "사용자 관리", "userManagement": "사용자 관리",
"userUpdated": "사용자 수정됨!", "userUpdated": "사용자 수정됨!",
"username": "사용자 이름", "username": "사용자 이름",
"users": "사용자", "users": "사용자"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "도움말", "help": "도움말",

View File

@ -1,287 +0,0 @@
{
"buttons": {
"cancel": "Atcelt",
"clear": "Tīrs",
"close": "Aizvērt",
"continue": "Turpināt",
"copy": "Kopēt",
"copyFile": "Kopēt failu",
"copyToClipboard": "Kopēt starpliktuvē",
"copyDownloadLinkToClipboard": "Kopēt lejupielādes saiti starpliktuvē",
"create": "Izveidot",
"delete": "Dzēst",
"download": "Lejupielādēt",
"file": "Fails",
"folder": "Mape",
"fullScreen": "Pārslēgt pilnekrāna režīmu",
"hideDotfiles": "Slēpt punktfailus",
"info": "Informācija",
"more": "Vairāk",
"move": "Pārvietot",
"moveFile": "Pārvietot failu",
"new": "Jauns",
"next": "Nākamais",
"ok": "Labi",
"permalink": "Iegūt pastāvīgo saiti",
"previous": "Iepriekšējais",
"preview": "Priekšskatījums",
"publish": "Publicēt",
"rename": "Pārdēvēt",
"replace": "Aizstāt",
"reportIssue": "Ziņot par problēmu",
"save": "Saglabāt",
"schedule": "Grafiks",
"search": "Meklēt",
"select": "Izvēlieties",
"selectMultiple": "Izvēlieties vairākus",
"share": "Dalīties",
"shell": "Pārslēgt apvalku",
"submit": "Iesniegt",
"switchView": "Pārslēgt skatu",
"toggleSidebar": "Pārslēgt sānjoslu",
"update": "Atjaunināt",
"upload": "Augšupielādēt",
"openFile": "Atvērt failu",
"discardChanges": "Izmest",
"stopSearch": "Stop searching",
"saveChanges": "Saglabāt izmaiņas",
"editAsText": "Rediģēt kā tekstu",
"increaseFontSize": "Palieliniet fonta lielumu",
"decreaseFontSize": "Samaziniet fonta lielumu"
},
"download": {
"downloadFile": "Lejupielādēt failu",
"downloadFolder": "Lejupielādēt mapi",
"downloadSelected": "Lejupielādēt atlasīto"
},
"upload": {
"abortUpload": "Vai tiešām vēlaties pārtraukt?"
},
"errors": {
"forbidden": "Jums nav atļaujas piekļūt šim.",
"internal": "Kaut kas tiešām nogāja greizi.",
"notFound": "Šo atrašanās vietu nevar sasniegt.",
"connection": "Ar serveri nevar sazināties."
},
"files": {
"body": "Ķermenis",
"closePreview": "Aizvērt priekšskatījumu",
"files": "Faili",
"folders": "Mapes",
"home": "Sākums",
"lastModified": "Pēdējoreiz modificēts",
"loading": "Notiek ielāde...",
"lonely": "Šeit ir tukša vieta...",
"metadata": "Metadati",
"multipleSelectionEnabled": "Vairākas atlases ir iespējotas",
"name": "Vārds",
"size": "Izmērs",
"sortByLastModified": "Kārtot pēc pēdējās modifikācijas",
"sortByName": "Kārtot pēc nosaukuma",
"sortBySize": "Kārtot pēc izmēra",
"noPreview": "Šim failam nav pieejams priekšskatījums.",
"csvTooLarge": "CSV fails ir pārāk liels priekšskatīšanai (>5 MB). Lūdzu, lejupielādējiet to, lai skatītu",
"csvLoadFailed": "Neizdevās ielādēt CSV failu.",
"showingRows": "Rāda {count} rindu(as)",
"columnSeparator": "Kolonnu atdalītājs",
"csvSeparators": {
"comma": "Komats (,)",
"semicolon": "Semikols (;)",
"both": "Gan (,) gan (;)"
}
},
"help": {
"click": "atlasiet failu vai direktoriju",
"ctrl": {
"click": "atlasīt vairākus failus vai direktorijus",
"f": "atver meklēšanu",
"s": "saglabājiet failu vai lejupielādējiet direktoriju, kurā atrodaties"
},
"del": "dzēst atlasītos vienumus",
"doubleClick": "atvērt failu vai direktoriju",
"esc": "notīrīt atlasi un/vai aizvērt uzvedni",
"f1": "šo informāciju",
"f2": "pārdēvēt failu",
"help": "Palīdzība"
},
"login": {
"createAnAccount": "Izveidot kontu",
"loginInstead": "Jau ir konts",
"password": "Parole",
"passwordConfirm": "Paroles apstiprināšana",
"passwordsDontMatch": "Paroles nesakrīt",
"signup": "Reģistrēšanās",
"submit": "Pieteikties",
"username": "Lietotājvārds",
"usernameTaken": "Lietotājvārds jau aizņemts",
"wrongCredentials": "Nepareizi akreditācijas dati",
"passwordTooShort": "Parolei jābūt vismaz {min} rakstzīmju garai",
"logout_reasons": {
"inactivity": "Jūs esat atteicies no sistēmas neaktivitātes dēļ."
}
},
"permanent": "Pastāvīgs",
"prompts": {
"copy": "Kopēt",
"copyMessage": "Izvēlieties atrašanās vietu, uz kuru kopēt failus:",
"currentlyNavigating": "Pašlaik navigācija:",
"deleteMessageMultiple": "Vai tiešām vēlaties dzēst {count} failu(s)?",
"deleteMessageSingle": "Vai tiešām vēlaties dzēst šo failu/mapi?",
"deleteMessageShare": "Vai tiešām vēlaties dzēst šo koplietojumu({path})?",
"deleteUser": "Vai tiešām vēlaties dzēst šo lietotāju?",
"deleteTitle": "Dzēst failus",
"displayName": "Displeja nosaukums:",
"download": "Lejupielādēt failus",
"downloadMessage": "Izvēlieties formātu, kuru vēlaties lejupielādēt.",
"error": "Kaut kas nogāja greizi",
"fileInfo": "Informācija par failu",
"filesSelected": "{count} atlasīti faili",
"lastModified": "Pēdējās izmaiņas",
"move": "Pārvietot",
"moveMessage": "Izvēlieties jaunu mājvietu failam(iem)/mapei(ēm):",
"newArchetype": "Izveidojiet jaunu ierakstu, pamatojoties uz arhtipu. Jūsu fails tiks izveidots satura mapē.",
"newDir": "Jauna direktorija",
"newDirMessage": "Nosaukums savai jaunajai direktorijai.",
"newFile": "Jauns fails",
"newFileMessage": "Nosauciet savu jauno failu.",
"numberDirs": "Katalogu skaits",
"numberFiles": "Failu skaits",
"rename": "Pārdēvēt",
"renameMessage": "Ievietojiet jaunu nosaukumu",
"replace": "Aizstāt",
"replaceMessage": "Vienam no failiem, kurus mēģināt augšupielādēt, ir konfliktējošs nosaukums. Vai vēlaties izlaist šo failu un turpināt augšupielādi vai aizstāt esošo?\n",
"schedule": "Grafiks",
"scheduleMessage": "Izvēlieties datumu un laiku, lai ieplānotu šī ieraksta publicēšanu.",
"show": "Rādīt",
"size": "Izmērs",
"upload": "Augšupielādēt",
"uploadFiles": "Notiek {files} failu augšupielāde...",
"uploadMessage": "Atlasiet augšupielādes opciju.",
"optionalPassword": "Izvēles parole",
"resolution": "Izšķirtspēja",
"discardEditorChanges": "Vai tiešām vēlaties atmest veiktās izmaiņas?"
},
"search": {
"images": "Attēli",
"music": "Mūzika",
"pdf": "PDF",
"pressToSearch": "Nospiediet taustiņu Enter, lai meklētu...",
"search": "Meklē...",
"typeToSearch": "Ierakstiet, lai meklētu...",
"types": "Veidi",
"video": "Video"
},
"settings": {
"aceEditorTheme": "Ace redaktora tēma",
"admin": "Admin",
"administrator": "Administrator",
"allowCommands": "Izpildīt komandas",
"allowEdit": "Rediģēt, pārdēvēt un dzēst failus vai direktorijus",
"allowNew": "Izveidojiet jaunus failus un direktorijus",
"allowPublish": "Publicēt jaunus ierakstus un lapas",
"allowSignup": "Atļaut lietotājiem reģistrēties",
"hideLoginButton": "Paslēpt pieteikšanās pogu publiskajās lapās",
"avoidChanges": "(atstājiet tukšu, lai izvairītos no izmaiņām)",
"branding": "Zīmols",
"brandingDirectoryPath": "Zīmola direktorijas ceļš",
"brandingHelp": "Jūs varat pielāgot sava failu pārlūka instances izskatu un darbību, mainot tās nosaukumu, aizstājot logotipu, pievienojot pielāgotus stilus un pat atspējojot ārējās saites uz GitHub.\nLai iegūtu plašāku informāciju par pielāgotu zīmola veidošanu, lūdzu, skatiet {0}.",
"changePassword": "Mainīt paroli",
"commandRunner": "Komandu skrējējs",
"commandRunnerHelp": "Šeit varat iestatīt komandas, kas tiek izpildītas nosauktajos notikumos. Katrā rindā jāraksta pa vienai. Būs pieejami vides mainīgie {0} un {1}, kas ir {0} relatīvi pret {1}. Lai iegūtu plašāku informāciju par šo funkciju un pieejamajiem vides mainīgajiem, lūdzu, izlasiet {2}.",
"commandsUpdated": "Komandas atjauninātas!",
"createUserDir": "Automātiski izveidot lietotāja mājas direktoriju, pievienojot jaunu lietotāju",
"minimumPasswordLength": "Minimālais paroles garums",
"tusUploads": "Sadalītas augšupielādes",
"tusUploadsHelp": "Failu pārlūks atbalsta failu augšupielādi fragmentos, ļaujot izveidot efektīvu, uzticamu, atsākamu un fragmentos sadalītu failu augšupielādi pat neuzticamos tīklos.",
"tusUploadsChunkSize": "Norāda pieprasījuma maksimālo izmēru (mazākiem augšupielādes apjomiem tiks izmantota tieša augšupielāde). Varat ievadīt vienkāršu veselu skaitli, kas apzīmē baitu izmēru, vai virkni, piemēram, 10 MB, 1 GB utt.",
"tusUploadsRetryCount": "Atkārtotu mēģinājumu skaits, kas jāveic, ja fragmenta augšupielāde neizdodas.",
"userHomeBasePath": "Lietotāja mājas direktoriju bāzes ceļš",
"userScopeGenerationPlaceholder": "Darbības joma tiks ģenerēta automātiski",
"createUserHomeDirectory": "Izveidojiet lietotāja mājas direktoriju",
"customStylesheet": "Pielāgota stila lapa",
"defaultUserDescription": "Šie ir noklusējuma iestatījumi jaunajiem lietotājiem.",
"disableExternalLinks": "Atspējot ārējās saites (izņemot dokumentāciju)",
"disableUsedDiskPercentage": "Atspējot izmantotā diska procentuālās daļas grafiku",
"documentation": "dokumentācija",
"examples": "Piemēri",
"executeOnShell": "Izpildīt uz čaulas",
"executeOnShellDescription": "Pēc noklusējuma failu pārlūks izpilda komandas, tieši izsaucot to bināros failus. Ja vēlaties tās palaist čaulā (piemēram, Bash vai PowerShell), varat to definēt šeit ar nepieciešamajiem argumentiem un karodziņiem. Ja tas ir iestatīts, izpildītā komanda tiks pievienota kā arguments. Tas attiecas gan uz lietotāja komandām, gan notikumu piesaistes rīkiem.",
"globalRules": "Šis ir globāls atļaušanas un aizliegšanas noteikumu kopums. Tie attiecas uz katru lietotāju. Katra lietotāja iestatījumos varat definēt konkrētus noteikumus, lai tos ignorētu.",
"globalSettings": "Globālie iestatījumi",
"hideDotfiles": "Slēpt punktfailus",
"insertPath": "Ievietojiet ceļu",
"insertRegex": "Ievietojiet regex izteiksmi",
"instanceName": "Gadījuma nosaukums",
"language": "Valoda",
"lockPassword": "Neļaut lietotājam mainīt paroli",
"newPassword": "Jūsu jaunā parole",
"newPasswordConfirm": "Apstipriniet savu jauno paroli",
"newUser": "Jauns lietotājs",
"password": "Parole",
"passwordUpdated": "Parole atjaunināta!",
"path": "Ceļš",
"perm": {
"create": "Izveidojiet failus un direktorijus",
"delete": "Dzēst failus un direktorijus",
"download": "Lejupielādēt",
"execute": "Izpildīt komandas",
"modify": "Rediģēt failus",
"rename": "Pārdēvēt vai pārvietot failus un direktorijus",
"share": "Kopīgojiet failus"
},
"permissions": "Atļaujas",
"permissionsHelp": "Varat iestatīt lietotāju kā administratoru vai izvēlēties atļaujas individuāli. Ja atlasīsiet “Administrators”, visas pārējās opcijas tiks automātiski atzīmētas. Lietotāju pārvaldība joprojām ir administratora privilēģija.\n",
"profileSettings": "Profila iestatījumi",
"ruleExample1": "neļauj piekļūt jebkuram dotfile failam (piemēram, .git, .gitignore) katrā mapē.\n",
"ruleExample2": "bloķē piekļuvi failam ar nosaukumu Caddyfile darbības jomas saknē.",
"rules": "Noteikumi",
"rulesHelp": "Šeit varat definēt atļaušanas un aizliegšanas noteikumu kopu šim konkrētajam lietotājam. Bloķētie faili netiks rādīti sarakstos, un lietotājs tiem nevarēs piekļūt. Mēs atbalstām regulārās izteiksmes un ceļus attiecībā pret lietotāja darbības jomu.\n",
"scope": "Darbības joma",
"setDateFormat": "Iestatiet precīzu datuma formātu",
"settingsUpdated": "Iestatījumi atjaunināti!",
"shareDuration": "Kopīgošanas ilgums",
"shareManagement": "Kopīgošanas pārvaldība",
"shareDeleted": "Kopīgošana ir izdzēsta!",
"singleClick": "Failu un direktoriju atvēršanai izmantojiet vienus klikšķi",
"themes": {
"default": "Sistēmas noklusējums",
"dark": "Tumša",
"light": "Gaiša",
"title": "Tēma"
},
"user": "Lietotājs",
"userCommands": "Komandas",
"userCommandsHelp": "Ar atstarpi atdalīts saraksts ar šim lietotājam pieejamajām komandām. Piemērs:\n",
"userCreated": "Lietotājs izveidots!",
"userDefaults": "Lietotāja noklusējuma iestatījumi",
"userDeleted": "Lietotājs izdzēsts!",
"userManagement": "Lietotāju pārvaldība",
"userUpdated": "Lietotājs atjaunināts!",
"username": "Lietotājvārds",
"users": "Lietotāji",
"currentPassword": "Your Current Password"
},
"sidebar": {
"help": "Palīdzība",
"hugoNew": "Hugo Jauns",
"login": "Pieteikties",
"logout": "Atteikties",
"myFiles": "Mani faili",
"newFile": "Jauns fails",
"newFolder": "Jauna mape",
"preview": "Priekšskatījums",
"settings": "Iestatījumi",
"signup": "Reģistrēties",
"siteSettings": "Vietnes iestatījumi"
},
"success": {
"linkCopied": "Saite nokopēta!"
},
"time": {
"days": "Dienas",
"hours": "Stundas",
"minutes": "Minūtes",
"seconds": "Sekundes",
"unit": "Laika vienība"
}
}

View File

@ -1,287 +0,0 @@
{
"buttons": {
"cancel": "Atcelt",
"clear": "Tīrs",
"close": "Aizvērt",
"continue": "Turpināt",
"copy": "Kopēt",
"copyFile": "Kopēt failu",
"copyToClipboard": "Kopēt starpliktuvē",
"copyDownloadLinkToClipboard": "Kopēt lejupielādes saiti starpliktuvē",
"create": "Izveidot",
"delete": "Dzēst",
"download": "Lejupielādēt",
"file": "Fails",
"folder": "Mape",
"fullScreen": "Pārslēgt pilnekrāna režīmu",
"hideDotfiles": "Slēpt punktfailus",
"info": "Informācija",
"more": "Vairāk",
"move": "Pārvietot",
"moveFile": "Pārvietot failu",
"new": "Jauns",
"next": "Nākamais",
"ok": "Labi",
"permalink": "Iegūt pastāvīgo saiti",
"previous": "Iepriekšējais",
"preview": "Priekšskatījums",
"publish": "Publicēt",
"rename": "Pārdēvēt",
"replace": "Aizstāt",
"reportIssue": "Ziņot par problēmu",
"save": "Saglabāt",
"schedule": "Grafiks",
"search": "Meklēt",
"select": "Izvēlieties",
"selectMultiple": "Izvēlieties vairākus",
"share": "Dalīties",
"shell": "Pārslēgt apvalku",
"submit": "Iesniegt",
"switchView": "Pārslēgt skatu",
"toggleSidebar": "Pārslēgt sānjoslu",
"update": "Atjaunināt",
"upload": "Augšupielādēt",
"openFile": "Atvērt failu",
"discardChanges": "Izmest",
"stopSearch": "Stop searching",
"saveChanges": "Saglabāt izmaiņas",
"editAsText": "Rediģēt kā tekstu",
"increaseFontSize": "Palieliniet fonta lielumu",
"decreaseFontSize": "Samaziniet fonta lielumu"
},
"download": {
"downloadFile": "Lejupielādēt failu",
"downloadFolder": "Lejupielādēt mapi",
"downloadSelected": "Lejupielādēt atlasīto"
},
"upload": {
"abortUpload": "Vai tiešām vēlaties pārtraukt?"
},
"errors": {
"forbidden": "Jums nav atļaujas piekļūt šim.",
"internal": "Kaut kas tiešām nogāja greizi.",
"notFound": "Šo atrašanās vietu nevar sasniegt.",
"connection": "Ar serveri nevar sazināties."
},
"files": {
"body": "Ķermenis",
"closePreview": "Aizvērt priekšskatījumu",
"files": "Faili",
"folders": "Mapes",
"home": "Sākums",
"lastModified": "Pēdējoreiz modificēts",
"loading": "Notiek ielāde...",
"lonely": "Šeit ir tukša vieta...",
"metadata": "Metadati",
"multipleSelectionEnabled": "Vairākas atlases ir iespējotas",
"name": "Vārds",
"size": "Izmērs",
"sortByLastModified": "Kārtot pēc pēdējās modifikācijas",
"sortByName": "Kārtot pēc nosaukuma",
"sortBySize": "Kārtot pēc izmēra",
"noPreview": "Šim failam nav pieejams priekšskatījums.",
"csvTooLarge": "CSV fails ir pārāk liels priekšskatīšanai (>5 MB). Lūdzu, lejupielādējiet to, lai skatītu",
"csvLoadFailed": "Neizdevās ielādēt CSV failu.",
"showingRows": "Rāda {count} rindu(as)",
"columnSeparator": "Kolonnu atdalītājs",
"csvSeparators": {
"comma": "Komats (,)",
"semicolon": "Semikols (;)",
"both": "Gan (,) gan (;)"
}
},
"help": {
"click": "atlasiet failu vai direktoriju",
"ctrl": {
"click": "atlasīt vairākus failus vai direktorijus",
"f": "atver meklēšanu",
"s": "saglabājiet failu vai lejupielādējiet direktoriju, kurā atrodaties"
},
"del": "dzēst atlasītos vienumus",
"doubleClick": "atvērt failu vai direktoriju",
"esc": "notīrīt atlasi un/vai aizvērt uzvedni",
"f1": "šo informāciju",
"f2": "pārdēvēt failu",
"help": "Palīdzība"
},
"login": {
"createAnAccount": "Izveidot kontu",
"loginInstead": "Jau ir konts",
"password": "Parole",
"passwordConfirm": "Paroles apstiprināšana",
"passwordsDontMatch": "Paroles nesakrīt",
"signup": "Reģistrēšanās",
"submit": "Pieteikties",
"username": "Lietotājvārds",
"usernameTaken": "Lietotājvārds jau aizņemts",
"wrongCredentials": "Nepareizi akreditācijas dati",
"passwordTooShort": "Parolei jābūt vismaz {min} rakstzīmju garai",
"logout_reasons": {
"inactivity": "Jūs esat atteicies no sistēmas neaktivitātes dēļ."
}
},
"permanent": "Pastāvīgs",
"prompts": {
"copy": "Kopēt",
"copyMessage": "Izvēlieties atrašanās vietu, uz kuru kopēt failus:",
"currentlyNavigating": "Pašlaik navigācija:",
"deleteMessageMultiple": "Vai tiešām vēlaties dzēst {count} failu(s)?",
"deleteMessageSingle": "Vai tiešām vēlaties dzēst šo failu/mapi?",
"deleteMessageShare": "Vai tiešām vēlaties dzēst šo koplietojumu({path})?",
"deleteUser": "Vai tiešām vēlaties dzēst šo lietotāju?",
"deleteTitle": "Dzēst failus",
"displayName": "Displeja nosaukums:",
"download": "Lejupielādēt failus",
"downloadMessage": "Izvēlieties formātu, kuru vēlaties lejupielādēt.",
"error": "Kaut kas nogāja greizi",
"fileInfo": "Informācija par failu",
"filesSelected": "{count} atlasīti faili",
"lastModified": "Pēdējās izmaiņas",
"move": "Pārvietot",
"moveMessage": "Izvēlieties jaunu mājvietu failam(iem)/mapei(ēm):",
"newArchetype": "Izveidojiet jaunu ierakstu, pamatojoties uz arhtipu. Jūsu fails tiks izveidots satura mapē.",
"newDir": "Jauna direktorija",
"newDirMessage": "Nosaukums savai jaunajai direktorijai.",
"newFile": "Jauns fails",
"newFileMessage": "Nosauciet savu jauno failu.",
"numberDirs": "Katalogu skaits",
"numberFiles": "Failu skaits",
"rename": "Pārdēvēt",
"renameMessage": "Ievietojiet jaunu nosaukumu",
"replace": "Aizstāt",
"replaceMessage": "Vienam no failiem, kurus mēģināt augšupielādēt, ir konfliktējošs nosaukums. Vai vēlaties izlaist šo failu un turpināt augšupielādi vai aizstāt esošo?\n",
"schedule": "Grafiks",
"scheduleMessage": "Izvēlieties datumu un laiku, lai ieplānotu šī ieraksta publicēšanu.",
"show": "Rādīt",
"size": "Izmērs",
"upload": "Augšupielādēt",
"uploadFiles": "Notiek {files} failu augšupielāde...",
"uploadMessage": "Atlasiet augšupielādes opciju.",
"optionalPassword": "Izvēles parole",
"resolution": "Izšķirtspēja",
"discardEditorChanges": "Vai tiešām vēlaties atmest veiktās izmaiņas?"
},
"search": {
"images": "Attēli",
"music": "Mūzika",
"pdf": "PDF",
"pressToSearch": "Nospiediet taustiņu Enter, lai meklētu...",
"search": "Meklē...",
"typeToSearch": "Ierakstiet, lai meklētu...",
"types": "Veidi",
"video": "Video"
},
"settings": {
"aceEditorTheme": "Ace redaktora tēma",
"admin": "Admin",
"administrator": "Administrator",
"allowCommands": "Izpildīt komandas",
"allowEdit": "Rediģēt, pārdēvēt un dzēst failus vai direktorijus",
"allowNew": "Izveidojiet jaunus failus un direktorijus",
"allowPublish": "Publicēt jaunus ierakstus un lapas",
"allowSignup": "Atļaut lietotājiem reģistrēties",
"hideLoginButton": "Paslēpt pieteikšanās pogu publiskajās lapās",
"avoidChanges": "(atstājiet tukšu, lai izvairītos no izmaiņām)",
"branding": "Zīmols",
"brandingDirectoryPath": "Zīmola direktorijas ceļš",
"brandingHelp": "Jūs varat pielāgot sava failu pārlūka instances izskatu un darbību, mainot tās nosaukumu, aizstājot logotipu, pievienojot pielāgotus stilus un pat atspējojot ārējās saites uz GitHub.\nLai iegūtu plašāku informāciju par pielāgotu zīmola veidošanu, lūdzu, skatiet {0}.",
"changePassword": "Mainīt paroli",
"commandRunner": "Komandu skrējējs",
"commandRunnerHelp": "Šeit varat iestatīt komandas, kas tiek izpildītas nosauktajos notikumos. Katrā rindā jāraksta pa vienai. Būs pieejami vides mainīgie {0} un {1}, kas ir {0} relatīvi pret {1}. Lai iegūtu plašāku informāciju par šo funkciju un pieejamajiem vides mainīgajiem, lūdzu, izlasiet {2}.",
"commandsUpdated": "Komandas atjauninātas!",
"createUserDir": "Automātiski izveidot lietotāja mājas direktoriju, pievienojot jaunu lietotāju",
"minimumPasswordLength": "Minimālais paroles garums",
"tusUploads": "Sadalītas augšupielādes",
"tusUploadsHelp": "Failu pārlūks atbalsta failu augšupielādi fragmentos, ļaujot izveidot efektīvu, uzticamu, atsākamu un fragmentos sadalītu failu augšupielādi pat neuzticamos tīklos.",
"tusUploadsChunkSize": "Norāda pieprasījuma maksimālo izmēru (mazākiem augšupielādes apjomiem tiks izmantota tieša augšupielāde). Varat ievadīt vienkāršu veselu skaitli, kas apzīmē baitu izmēru, vai virkni, piemēram, 10 MB, 1 GB utt.",
"tusUploadsRetryCount": "Atkārtotu mēģinājumu skaits, kas jāveic, ja fragmenta augšupielāde neizdodas.",
"userHomeBasePath": "Lietotāja mājas direktoriju bāzes ceļš",
"userScopeGenerationPlaceholder": "Darbības joma tiks ģenerēta automātiski",
"createUserHomeDirectory": "Izveidojiet lietotāja mājas direktoriju",
"customStylesheet": "Pielāgota stila lapa",
"defaultUserDescription": "Šie ir noklusējuma iestatījumi jaunajiem lietotājiem.",
"disableExternalLinks": "Atspējot ārējās saites (izņemot dokumentāciju)",
"disableUsedDiskPercentage": "Atspējot izmantotā diska procentuālās daļas grafiku",
"documentation": "dokumentācija",
"examples": "Piemēri",
"executeOnShell": "Izpildīt uz čaulas",
"executeOnShellDescription": "Pēc noklusējuma failu pārlūks izpilda komandas, tieši izsaucot to bināros failus. Ja vēlaties tās palaist čaulā (piemēram, Bash vai PowerShell), varat to definēt šeit ar nepieciešamajiem argumentiem un karodziņiem. Ja tas ir iestatīts, izpildītā komanda tiks pievienota kā arguments. Tas attiecas gan uz lietotāja komandām, gan notikumu piesaistes rīkiem.",
"globalRules": "Šis ir globāls atļaušanas un aizliegšanas noteikumu kopums. Tie attiecas uz katru lietotāju. Katra lietotāja iestatījumos varat definēt konkrētus noteikumus, lai tos ignorētu.",
"globalSettings": "Globālie iestatījumi",
"hideDotfiles": "Slēpt punktfailus",
"insertPath": "Ievietojiet ceļu",
"insertRegex": "Ievietojiet regex izteiksmi",
"instanceName": "Gadījuma nosaukums",
"language": "Valoda",
"lockPassword": "Neļaut lietotājam mainīt paroli",
"newPassword": "Jūsu jaunā parole",
"newPasswordConfirm": "Apstipriniet savu jauno paroli",
"newUser": "Jauns lietotājs",
"password": "Parole",
"passwordUpdated": "Parole atjaunināta!",
"path": "Ceļš",
"perm": {
"create": "Izveidojiet failus un direktorijus",
"delete": "Dzēst failus un direktorijus",
"download": "Lejupielādēt",
"execute": "Izpildīt komandas",
"modify": "Rediģēt failus",
"rename": "Pārdēvēt vai pārvietot failus un direktorijus",
"share": "Kopīgojiet failus"
},
"permissions": "Atļaujas",
"permissionsHelp": "Varat iestatīt lietotāju kā administratoru vai izvēlēties atļaujas individuāli. Ja atlasīsiet “Administrators”, visas pārējās opcijas tiks automātiski atzīmētas. Lietotāju pārvaldība joprojām ir administratora privilēģija.\n",
"profileSettings": "Profila iestatījumi",
"ruleExample1": "neļauj piekļūt jebkuram dotfile failam (piemēram, .git, .gitignore) katrā mapē.\n",
"ruleExample2": "bloķē piekļuvi failam ar nosaukumu Caddyfile darbības jomas saknē.",
"rules": "Noteikumi",
"rulesHelp": "Šeit varat definēt atļaušanas un aizliegšanas noteikumu kopu šim konkrētajam lietotājam. Bloķētie faili netiks rādīti sarakstos, un lietotājs tiem nevarēs piekļūt. Mēs atbalstām regulārās izteiksmes un ceļus attiecībā pret lietotāja darbības jomu.\n",
"scope": "Darbības joma",
"setDateFormat": "Iestatiet precīzu datuma formātu",
"settingsUpdated": "Iestatījumi atjaunināti!",
"shareDuration": "Kopīgošanas ilgums",
"shareManagement": "Kopīgošanas pārvaldība",
"shareDeleted": "Kopīgošana ir izdzēsta!",
"singleClick": "Failu un direktoriju atvēršanai izmantojiet vienus klikšķi",
"themes": {
"default": "Sistēmas noklusējums",
"dark": "Tumša",
"light": "Gaiša",
"title": "Tēma"
},
"user": "Lietotājs",
"userCommands": "Komandas",
"userCommandsHelp": "Ar atstarpi atdalīts saraksts ar šim lietotājam pieejamajām komandām. Piemērs:\n",
"userCreated": "Lietotājs izveidots!",
"userDefaults": "Lietotāja noklusējuma iestatījumi",
"userDeleted": "Lietotājs izdzēsts!",
"userManagement": "Lietotāju pārvaldība",
"userUpdated": "Lietotājs atjaunināts!",
"username": "Lietotājvārds",
"users": "Lietotāji",
"currentPassword": "Your Current Password"
},
"sidebar": {
"help": "Palīdzība",
"hugoNew": "Hugo Jauns",
"login": "Pieteikties",
"logout": "Atteikties",
"myFiles": "Mani faili",
"newFile": "Jauns fails",
"newFolder": "Jauna mape",
"preview": "Priekšskatījums",
"settings": "Iestatījumi",
"signup": "Reģistrēties",
"siteSettings": "Vietnes iestatījumi"
},
"success": {
"linkCopied": "Saite nokopēta!"
},
"time": {
"days": "Dienas",
"hours": "Stundas",
"minutes": "Minūtes",
"seconds": "Sekundes",
"unit": "Laika vienība"
}
}

View File

@ -43,11 +43,7 @@
"upload": "Uploaden", "upload": "Uploaden",
"openFile": "Open file", "openFile": "Open file",
"discardChanges": "Discard", "discardChanges": "Discard",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Bestand downloaden", "downloadFile": "Bestand downloaden",
@ -79,16 +75,7 @@
"sortByLastModified": "Sorteren op laatst bewerkt", "sortByLastModified": "Sorteren op laatst bewerkt",
"sortByName": "Sorteren op naam", "sortByName": "Sorteren op naam",
"sortBySize": "Sorteren op grootte", "sortBySize": "Sorteren op grootte",
"noPreview": "Preview is not available for this file.", "noPreview": "Preview is not available for this file."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "selecteer bestand of map", "click": "selecteer bestand of map",
@ -258,8 +245,7 @@
"userManagement": "Gebruikersbeheer", "userManagement": "Gebruikersbeheer",
"userUpdated": "Gebruiker bijgewerkt!", "userUpdated": "Gebruiker bijgewerkt!",
"username": "Gebruikersnaam", "username": "Gebruikersnaam",
"users": "Gebruikers", "users": "Gebruikers"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Help", "help": "Help",

View File

@ -43,11 +43,7 @@
"upload": "Last opp", "upload": "Last opp",
"openFile": "Open file", "openFile": "Open file",
"discardChanges": "Slett", "discardChanges": "Slett",
"stopSearch": "Stop searching", "saveChanges": "Lagre Endringane "
"saveChanges": "Lagre Endringane ",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Nedlast filen", "downloadFile": "Nedlast filen",
@ -79,16 +75,7 @@
"sortByLastModified": "Sorter etter sist endret", "sortByLastModified": "Sorter etter sist endret",
"sortByName": "Sorter etter navn", "sortByName": "Sorter etter navn",
"sortBySize": "Sorter etter størrelse", "sortBySize": "Sorter etter størrelse",
"noPreview": "Forhåndsvisning er ikkje tilgjengeleg for denne filen.", "noPreview": "Forhåndsvisning er ikkje tilgjengeleg for denne filen."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "velg fil eller katalog", "click": "velg fil eller katalog",
@ -258,8 +245,7 @@
"userManagement": "Brukeradministrasjon", "userManagement": "Brukeradministrasjon",
"userUpdated": "Bruker opprettet!", "userUpdated": "Bruker opprettet!",
"username": "Brukernavn", "username": "Brukernavn",
"users": "Bruker", "users": "Bruker"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Hjelp", "help": "Hjelp",

View File

@ -43,11 +43,7 @@
"upload": "Wyślij", "upload": "Wyślij",
"openFile": "Otwórz plik", "openFile": "Otwórz plik",
"discardChanges": "Odrzuć", "discardChanges": "Odrzuć",
"stopSearch": "Zatrzymaj wyszukiwanie", "saveChanges": "Zapisz zmiany"
"saveChanges": "Zapisz zmiany",
"editAsText": "Edytuj jako tekst",
"increaseFontSize": "Zwiększ rozmiar czcionki",
"decreaseFontSize": "Zmniejsz rozmiar czcionki"
}, },
"download": { "download": {
"downloadFile": "Pobierz plik", "downloadFile": "Pobierz plik",
@ -79,16 +75,7 @@
"sortByLastModified": "Sortuj wg ostatniej modyfikacji", "sortByLastModified": "Sortuj wg ostatniej modyfikacji",
"sortByName": "Sortuj wg nazwy", "sortByName": "Sortuj wg nazwy",
"sortBySize": "Sortuj wg rozmiaru", "sortBySize": "Sortuj wg rozmiaru",
"noPreview": "Podgląd tego pliku jest niedostępny.", "noPreview": "Podgląd tego pliku jest niedostępny."
"csvTooLarge": "Plik CSV jest za duży do podglądu (>5 MB). Pobierz, aby wyświetlić.",
"csvLoadFailed": "Nie udało się załadować pliku CSV.",
"showingRows": "Wyświetlanie wierszy: {count}",
"columnSeparator": "Separator kolumn",
"csvSeparators": {
"comma": "Przecinek (,)",
"semicolon": "Średnik (;)",
"both": "Zarówno (,), jak i (;)"
}
}, },
"help": { "help": {
"click": "zaznacz plik lub folder", "click": "zaznacz plik lub folder",
@ -258,8 +245,7 @@
"userManagement": "Zarządzanie użytkownikami", "userManagement": "Zarządzanie użytkownikami",
"userUpdated": "Użytkownik zapisany!", "userUpdated": "Użytkownik zapisany!",
"username": "Nazwa użytkownika", "username": "Nazwa użytkownika",
"users": "Użytkownicy", "users": "Użytkownicy"
"currentPassword": "Twoje aktualne hasło"
}, },
"sidebar": { "sidebar": {
"help": "Pomoc", "help": "Pomoc",

View File

@ -43,11 +43,7 @@
"upload": "Enviar", "upload": "Enviar",
"openFile": "Abrir", "openFile": "Abrir",
"discardChanges": "Discard", "discardChanges": "Discard",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Baixar arquivo", "downloadFile": "Baixar arquivo",
@ -79,16 +75,7 @@
"sortByLastModified": "Ordenar pela última modificação", "sortByLastModified": "Ordenar pela última modificação",
"sortByName": "Ordenar pelo nome", "sortByName": "Ordenar pelo nome",
"sortBySize": "Ordenar pelo tamanho", "sortBySize": "Ordenar pelo tamanho",
"noPreview": "Pré-visualização não disponível para este arquivo.", "noPreview": "Pré-visualização não disponível para este arquivo."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "selecionar pasta ou arquivo", "click": "selecionar pasta ou arquivo",
@ -258,8 +245,7 @@
"userManagement": "Gerenciamento de usuários", "userManagement": "Gerenciamento de usuários",
"userUpdated": "Usuário atualizado!", "userUpdated": "Usuário atualizado!",
"username": "Nome do usuário", "username": "Nome do usuário",
"users": "Usuários", "users": "Usuários"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Ajuda", "help": "Ajuda",

View File

@ -43,11 +43,7 @@
"upload": "Enviar", "upload": "Enviar",
"openFile": "Open file", "openFile": "Open file",
"discardChanges": "Discard", "discardChanges": "Discard",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Descarregar ficheiro", "downloadFile": "Descarregar ficheiro",
@ -79,16 +75,7 @@
"sortByLastModified": "Ordenar pela última alteração", "sortByLastModified": "Ordenar pela última alteração",
"sortByName": "Ordenar pelo nome", "sortByName": "Ordenar pelo nome",
"sortBySize": "Ordenar pelo tamanho", "sortBySize": "Ordenar pelo tamanho",
"noPreview": "Preview is not available for this file.", "noPreview": "Preview is not available for this file."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "selecionar pasta ou ficheiro", "click": "selecionar pasta ou ficheiro",
@ -258,8 +245,7 @@
"userManagement": "Gestão de utilizadores", "userManagement": "Gestão de utilizadores",
"userUpdated": "Utilizador atualizado!", "userUpdated": "Utilizador atualizado!",
"username": "Nome de utilizador", "username": "Nome de utilizador",
"users": "Utilizadores", "users": "Utilizadores"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Ajuda", "help": "Ajuda",

View File

@ -43,11 +43,7 @@
"upload": "Încarcă", "upload": "Încarcă",
"openFile": "Open file", "openFile": "Open file",
"discardChanges": "Discard", "discardChanges": "Discard",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Descarcă fișier", "downloadFile": "Descarcă fișier",
@ -79,16 +75,7 @@
"sortByLastModified": "Ordonează dup ultima modificare", "sortByLastModified": "Ordonează dup ultima modificare",
"sortByName": "Ordonează după nume", "sortByName": "Ordonează după nume",
"sortBySize": "Ordonează după dimensiune", "sortBySize": "Ordonează după dimensiune",
"noPreview": "Preview is not available for this file.", "noPreview": "Preview is not available for this file."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "alege fișier sau director", "click": "alege fișier sau director",
@ -258,8 +245,7 @@
"userManagement": "Gestionare utilizatori", "userManagement": "Gestionare utilizatori",
"userUpdated": "Utilizator actualizat!", "userUpdated": "Utilizator actualizat!",
"username": "Utilizator", "username": "Utilizator",
"users": "Utilizatori", "users": "Utilizatori"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Ajutor", "help": "Ajutor",

View File

@ -43,11 +43,7 @@
"upload": "Загрузить", "upload": "Загрузить",
"openFile": "Открыть файл", "openFile": "Открыть файл",
"discardChanges": "Отказаться", "discardChanges": "Отказаться",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Сохранить",
"editAsText": "Редактировать как текст",
"increaseFontSize": "Увеличить размер шрифта",
"decreaseFontSize": "Уменьшить размер шрифта"
}, },
"download": { "download": {
"downloadFile": "Скачать файл", "downloadFile": "Скачать файл",
@ -79,16 +75,7 @@
"sortByLastModified": "Сортировка по дате изменения", "sortByLastModified": "Сортировка по дате изменения",
"sortByName": "Сортировка по имени", "sortByName": "Сортировка по имени",
"sortBySize": "Сортировка по размеру", "sortBySize": "Сортировка по размеру",
"noPreview": "Предварительный просмотр для этого файла недоступен.", "noPreview": "Предварительный просмотр для этого файла недоступен."
"csvTooLarge": "Этот CSV файл слишком большой для предпросмотра (>5 МБ). Скачайте и откройте его локально.",
"csvLoadFailed": "Не удалось загрузить этот CSV.",
"showingRows": "Отображается {count} строк(а)",
"columnSeparator": "Разделитель столбцов",
"csvSeparators": {
"comma": "Запятая (,)",
"semicolon": "Точка с запятой (;)",
"both": "Оба варианта — (,) и (;)"
}
}, },
"help": { "help": {
"click": "выбрать файл или каталог", "click": "выбрать файл или каталог",
@ -115,9 +102,9 @@
"username": "Имя пользователя", "username": "Имя пользователя",
"usernameTaken": "Данное имя пользователя уже занято", "usernameTaken": "Данное имя пользователя уже занято",
"wrongCredentials": "Неверные данные", "wrongCredentials": "Неверные данные",
"passwordTooShort": "Пароль должен состоять как минимум из {min} символов", "passwordTooShort": "Password must be at least {min} characters",
"logout_reasons": { "logout_reasons": {
"inactivity": "Сессия завершена после долгого отсутствия." "inactivity": "You have been logged out due to inactivity."
} }
}, },
"permanent": "Постоянный", "permanent": "Постоянный",
@ -172,7 +159,7 @@
"video": "Видео" "video": "Видео"
}, },
"settings": { "settings": {
"aceEditorTheme": "Тема редактора Ace", "aceEditorTheme": "Ace editor theme",
"admin": "Админ", "admin": "Админ",
"administrator": "Администратор", "administrator": "Администратор",
"allowCommands": "Запуск команд", "allowCommands": "Запуск команд",
@ -180,7 +167,7 @@
"allowNew": "Создание новых файлов или каталогов", "allowNew": "Создание новых файлов или каталогов",
"allowPublish": "Публикация новых записей и страниц", "allowPublish": "Публикация новых записей и страниц",
"allowSignup": "Разрешить пользователям регистрироваться", "allowSignup": "Разрешить пользователям регистрироваться",
"hideLoginButton": "Спрятать кнопку входа с публичных страниц", "hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(оставьте поле пустым, чтобы избежать изменений)", "avoidChanges": "(оставьте поле пустым, чтобы избежать изменений)",
"branding": "Брендинг", "branding": "Брендинг",
"brandingDirectoryPath": "Путь к каталогу брендов", "brandingDirectoryPath": "Путь к каталогу брендов",
@ -190,7 +177,7 @@
"commandRunnerHelp": "Здесь вы можете установить команды, которые будут выполняться в указанных событиях. Вы должны указать по одной команде в каждой строке. Переменные среды {0} и {1} будут доступны, будучи {0} относительно {1}. Дополнительные сведения об этой функции и доступных переменных среды см. В {2}.", "commandRunnerHelp": "Здесь вы можете установить команды, которые будут выполняться в указанных событиях. Вы должны указать по одной команде в каждой строке. Переменные среды {0} и {1} будут доступны, будучи {0} относительно {1}. Дополнительные сведения об этой функции и доступных переменных среды см. В {2}.",
"commandsUpdated": "Команды обновлены!", "commandsUpdated": "Команды обновлены!",
"createUserDir": "Автоматическое создание домашнего каталога пользователя при добавлении нового пользователя", "createUserDir": "Автоматическое создание домашнего каталога пользователя при добавлении нового пользователя",
"minimumPasswordLength": "Минимальная длина пароля", "minimumPasswordLength": "Minimum password length",
"tusUploads": "Загруженные файлы", "tusUploads": "Загруженные файлы",
"tusUploadsHelp": " File Browser поддерживает загрузку файлов по частям, что позволяет работать в сетях низкого качества.", "tusUploadsHelp": " File Browser поддерживает загрузку файлов по частям, что позволяет работать в сетях низкого качества.",
"tusUploadsChunkSize": "Указывает максимальный размер запроса (мелкие загрузки пойдут напрямую). Вы можете ввести простое целое число, обозначающее размер ввода в байтах, или строку, например 10MB, 1GB и т. д.", "tusUploadsChunkSize": "Указывает максимальный размер запроса (мелкие загрузки пойдут напрямую). Вы можете ввести простое целое число, обозначающее размер ввода в байтах, или строку, например 10MB, 1GB и т. д.",
@ -258,8 +245,7 @@
"userManagement": "Управление пользователями", "userManagement": "Управление пользователями",
"userUpdated": "Пользователь изменен!", "userUpdated": "Пользователь изменен!",
"username": "Имя пользователя", "username": "Имя пользователя",
"users": "Пользователи", "users": "Пользователи"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Помощь", "help": "Помощь",

View File

@ -43,11 +43,7 @@
"upload": "Nahrať", "upload": "Nahrať",
"openFile": "Otvoriť súbor", "openFile": "Otvoriť súbor",
"discardChanges": "Zahodiť", "discardChanges": "Zahodiť",
"stopSearch": "Stop searching", "saveChanges": "Uložiť zmeny"
"saveChanges": "Uložiť zmeny",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Stiahnuť súbor", "downloadFile": "Stiahnuť súbor",
@ -79,16 +75,7 @@
"sortByLastModified": "Zoradiť podľa dátumu", "sortByLastModified": "Zoradiť podľa dátumu",
"sortByName": "Zoradiť podľa názvu", "sortByName": "Zoradiť podľa názvu",
"sortBySize": "Zoradiť podľa veľkosti", "sortBySize": "Zoradiť podľa veľkosti",
"noPreview": "Pre tento súbor nie je dostupný náhľad.", "noPreview": "Pre tento súbor nie je dostupný náhľad."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "vyberie súbor alebo priečinok", "click": "vyberie súbor alebo priečinok",
@ -258,8 +245,7 @@
"userManagement": "Správa používateľov", "userManagement": "Správa používateľov",
"userUpdated": "Používateľ upravený!", "userUpdated": "Používateľ upravený!",
"username": "Meno používateľa", "username": "Meno používateľa",
"users": "Používatelia", "users": "Používatelia"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Pomoc", "help": "Pomoc",

View File

@ -43,11 +43,7 @@
"upload": "Ladda upp", "upload": "Ladda upp",
"openFile": "Öppna fil", "openFile": "Öppna fil",
"discardChanges": "Förkasta", "discardChanges": "Förkasta",
"stopSearch": "Stop searching", "saveChanges": "Spara ändringar"
"saveChanges": "Spara ändringar",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Ladda ner fil", "downloadFile": "Ladda ner fil",
@ -79,16 +75,7 @@
"sortByLastModified": "Sortera på senast ändrad", "sortByLastModified": "Sortera på senast ändrad",
"sortByName": "Sortera på namn", "sortByName": "Sortera på namn",
"sortBySize": "Sortera på storlek", "sortBySize": "Sortera på storlek",
"noPreview": "Förhandsvisning är inte tillgänglig för denna fil.", "noPreview": "Förhandsvisning är inte tillgänglig för denna fil."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "välj fil eller mapp", "click": "välj fil eller mapp",
@ -258,8 +245,7 @@
"userManagement": "Användarehantering", "userManagement": "Användarehantering",
"userUpdated": "Användare uppdaterad!", "userUpdated": "Användare uppdaterad!",
"username": "Användarnamn", "username": "Användarnamn",
"users": "Användare", "users": "Användare"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Hjälp", "help": "Hjälp",

View File

@ -43,11 +43,7 @@
"upload": "Yükle", "upload": "Yükle",
"openFile": "Dosyayı aç", "openFile": "Dosyayı aç",
"discardChanges": "Discard", "discardChanges": "Discard",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Dosyayı indir", "downloadFile": "Dosyayı indir",
@ -79,16 +75,7 @@
"sortByLastModified": "Güncelleme tarihine göre sırala", "sortByLastModified": "Güncelleme tarihine göre sırala",
"sortByName": "İsme göre sırala", "sortByName": "İsme göre sırala",
"sortBySize": "Boyuta göre sırala", "sortBySize": "Boyuta göre sırala",
"noPreview": "Bu dosya için önizleme aktif değil", "noPreview": "Bu dosya için önizleme aktif değil"
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "dosya veya klasör seçin", "click": "dosya veya klasör seçin",
@ -258,8 +245,7 @@
"userManagement": "Kullanıcı yönetimi", "userManagement": "Kullanıcı yönetimi",
"userUpdated": "Kullanıcı güncellendi!", "userUpdated": "Kullanıcı güncellendi!",
"username": "Kullanıcı adı", "username": "Kullanıcı adı",
"users": "Kullanıcılar", "users": "Kullanıcılar"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Yardım", "help": "Yardım",

View File

@ -43,11 +43,7 @@
"upload": "Вивантажити", "upload": "Вивантажити",
"openFile": "Відкрити файл", "openFile": "Відкрити файл",
"discardChanges": "Скасувати", "discardChanges": "Скасувати",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Завантажити файл", "downloadFile": "Завантажити файл",
@ -79,16 +75,7 @@
"sortByLastModified": "Сортувати за останнім зміненням", "sortByLastModified": "Сортувати за останнім зміненням",
"sortByName": "Сортувати за іменем", "sortByName": "Сортувати за іменем",
"sortBySize": "Сортувати за розміром", "sortBySize": "Сортувати за розміром",
"noPreview": "Попередній перегляд для цього файлу недоступний.", "noPreview": "Попередній перегляд для цього файлу недоступний."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "вибрати файл чи каталог", "click": "вибрати файл чи каталог",
@ -258,8 +245,7 @@
"userManagement": "Керування користувачами", "userManagement": "Керування користувачами",
"userUpdated": "Користувача змінено!", "userUpdated": "Користувача змінено!",
"username": "Ім'я користувача", "username": "Ім'я користувача",
"users": "Користувачі", "users": "Користувачі"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Допомога", "help": "Допомога",

View File

@ -43,11 +43,7 @@
"upload": "Tải lên", "upload": "Tải lên",
"openFile": "Mở tệp", "openFile": "Mở tệp",
"discardChanges": "Hủy bỏ thay đổi", "discardChanges": "Hủy bỏ thay đổi",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "Tải xuống tệp tin", "downloadFile": "Tải xuống tệp tin",
@ -79,16 +75,7 @@
"sortByLastModified": "Sắp xếp theo ngày sửa đổi", "sortByLastModified": "Sắp xếp theo ngày sửa đổi",
"sortByName": "Sắp xếp theo tên", "sortByName": "Sắp xếp theo tên",
"sortBySize": "Sắp xếp theo kích thước", "sortBySize": "Sắp xếp theo kích thước",
"noPreview": "Không có bản xem trước cho tập tin này.", "noPreview": "Không có bản xem trước cho tập tin này."
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "chọn tập tin hoặc thư mục", "click": "chọn tập tin hoặc thư mục",
@ -258,8 +245,7 @@
"userManagement": "Quản lý người dùng", "userManagement": "Quản lý người dùng",
"userUpdated": "Người dùng đã được cập nhật!", "userUpdated": "Người dùng đã được cập nhật!",
"username": "Tên người dùng", "username": "Tên người dùng",
"users": "Người dùng", "users": "Người dùng"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "Trợ giúp", "help": "Trợ giúp",

View File

@ -43,11 +43,7 @@
"upload": "上传", "upload": "上传",
"openFile": "打开文件", "openFile": "打开文件",
"discardChanges": "放弃更改", "discardChanges": "放弃更改",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "保存更改",
"editAsText": "以文本形式编辑",
"increaseFontSize": "增大字体大小",
"decreaseFontSize": "减小字体大小"
}, },
"download": { "download": {
"downloadFile": "下载文件", "downloadFile": "下载文件",
@ -79,16 +75,7 @@
"sortByLastModified": "按最后修改时间排序", "sortByLastModified": "按最后修改时间排序",
"sortByName": "按名称排序", "sortByName": "按名称排序",
"sortBySize": "按大小排序", "sortBySize": "按大小排序",
"noPreview": "此文件无法预览。", "noPreview": "此文件无法预览。"
"csvTooLarge": "CSV文件大到无法预览(>5MB)。请下载查看。",
"csvLoadFailed": "加载 CSV 文件失败。",
"showingRows": "正在显示 {count} 行",
"columnSeparator": "列分隔符",
"csvSeparators": {
"comma": "逗号 (,)",
"semicolon": "分号 (;)",
"both": "逗号 (,) 和分号 (;)"
}
}, },
"help": { "help": {
"click": "选择文件或文件夹", "click": "选择文件或文件夹",
@ -115,9 +102,9 @@
"username": "用户名", "username": "用户名",
"usernameTaken": "用户名已经被使用", "usernameTaken": "用户名已经被使用",
"wrongCredentials": "用户名或密码错误", "wrongCredentials": "用户名或密码错误",
"passwordTooShort": "密码必须至少包含 {min} 个字符", "passwordTooShort": "Password must be at least {min} characters",
"logout_reasons": { "logout_reasons": {
"inactivity": "由于未活动,您已登出。" "inactivity": "You have been logged out due to inactivity."
} }
}, },
"permanent": "永久", "permanent": "永久",
@ -172,7 +159,7 @@
"video": "视频" "video": "视频"
}, },
"settings": { "settings": {
"aceEditorTheme": "Ace编辑器主题", "aceEditorTheme": "Ace editor theme",
"admin": "管理员", "admin": "管理员",
"administrator": "管理员", "administrator": "管理员",
"allowCommands": "执行命令Shell 命令)", "allowCommands": "执行命令Shell 命令)",
@ -180,7 +167,7 @@
"allowNew": "创建新文件和文件夹", "allowNew": "创建新文件和文件夹",
"allowPublish": "发布新的帖子与页面", "allowPublish": "发布新的帖子与页面",
"allowSignup": "允许用户注册", "allowSignup": "允许用户注册",
"hideLoginButton": "从公开页面隐藏登录按钮", "hideLoginButton": "Hide the login button from public pages",
"avoidChanges": "(留空以避免更改)", "avoidChanges": "(留空以避免更改)",
"branding": "品牌", "branding": "品牌",
"brandingDirectoryPath": "品牌信息文件夹路径", "brandingDirectoryPath": "品牌信息文件夹路径",
@ -258,8 +245,7 @@
"userManagement": "用户管理", "userManagement": "用户管理",
"userUpdated": "用户已更新!", "userUpdated": "用户已更新!",
"username": "用户名", "username": "用户名",
"users": "用户", "users": "用户"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "帮助", "help": "帮助",

View File

@ -43,11 +43,7 @@
"upload": "上傳", "upload": "上傳",
"openFile": "開啟檔案", "openFile": "開啟檔案",
"discardChanges": "放棄變更", "discardChanges": "放棄變更",
"stopSearch": "Stop searching", "saveChanges": "Save changes"
"saveChanges": "Save changes",
"editAsText": "Edit as Text",
"increaseFontSize": "Increase font size",
"decreaseFontSize": "Decrease font size"
}, },
"download": { "download": {
"downloadFile": "下載檔案", "downloadFile": "下載檔案",
@ -79,16 +75,7 @@
"sortByLastModified": "按最後修改時間排序", "sortByLastModified": "按最後修改時間排序",
"sortByName": "按名稱排序", "sortByName": "按名稱排序",
"sortBySize": "按大小排序", "sortBySize": "按大小排序",
"noPreview": "此檔案無法預覽。", "noPreview": "此檔案無法預覽。"
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
"csvLoadFailed": "Failed to load CSV file.",
"showingRows": "Showing {count} row(s)",
"columnSeparator": "Column Separator",
"csvSeparators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}, },
"help": { "help": {
"click": "選擇檔案或目錄", "click": "選擇檔案或目錄",
@ -258,8 +245,7 @@
"userManagement": "使用者管理", "userManagement": "使用者管理",
"userUpdated": "使用者已更新!", "userUpdated": "使用者已更新!",
"username": "使用者名稱", "username": "使用者名稱",
"users": "使用者", "users": "使用者"
"currentPassword": "Your Current Password"
}, },
"sidebar": { "sidebar": {
"help": "幫助", "help": "幫助",

View File

@ -5,7 +5,6 @@ interface ISettings {
minimumPasswordLength: number; minimumPasswordLength: number;
userHomeBasePath: string; userHomeBasePath: string;
defaults: SettingsDefaults; defaults: SettingsDefaults;
authMethod: string;
rules: any[]; rules: any[];
branding: SettingsBranding; branding: SettingsBranding;
tus: SettingsTus; tus: SettingsTus;
@ -18,7 +17,6 @@ interface SettingsDefaults {
locale: string; locale: string;
viewMode: ViewModeType; viewMode: ViewModeType;
singleClick: boolean; singleClick: boolean;
redirectAfterCopyMove: boolean;
sorting: Sorting; sorting: Sorting;
perm: Permissions; perm: Permissions;
commands: any[]; commands: any[];

View File

@ -10,7 +10,6 @@ interface IUser {
lockPassword: boolean; lockPassword: boolean;
hideDotfiles: boolean; hideDotfiles: boolean;
singleClick: boolean; singleClick: boolean;
redirectAfterCopyMove: boolean;
dateFormat: boolean; dateFormat: boolean;
viewMode: ViewModeType; viewMode: ViewModeType;
sorting?: Sorting; sorting?: Sorting;
@ -31,7 +30,6 @@ interface IUserForm {
lockPassword?: boolean; lockPassword?: boolean;
hideDotfiles?: boolean; hideDotfiles?: boolean;
singleClick?: boolean; singleClick?: boolean;
redirectAfterCopyMove?: boolean;
dateFormat?: boolean; dateFormat?: boolean;
} }

View File

@ -2,7 +2,7 @@ import { useAuthStore } from "@/stores/auth";
import router from "@/router"; import router from "@/router";
import type { JwtPayload } from "jwt-decode"; import type { JwtPayload } from "jwt-decode";
import { jwtDecode } from "jwt-decode"; import { jwtDecode } from "jwt-decode";
import { authMethod, baseURL, noAuth, logoutPage } from "./constants"; import { baseURL, noAuth } from "./constants";
import { StatusError } from "@/api/utils"; import { StatusError } from "@/api/utils";
import { setSafeTimeout } from "@/api/utils"; import { setSafeTimeout } from "@/api/utils";
@ -18,12 +18,6 @@ export function parseToken(token: string) {
authStore.jwt = token; authStore.jwt = token;
authStore.setUser(data.user); authStore.setUser(data.user);
// proxy auth with custom logout subject to unknown external timeout
if (logoutPage !== "/login" && authMethod === "proxy") {
console.warn("idle timeout disabled with proxy auth and custom logout");
return;
}
if (authStore.logoutTimer) { if (authStore.logoutTimer) {
clearTimeout(authStore.logoutTimer); clearTimeout(authStore.logoutTimer);
} }
@ -124,8 +118,6 @@ export function logout(reason?: string) {
localStorage.setItem("jwt", ""); localStorage.setItem("jwt", "");
if (noAuth) { if (noAuth) {
window.location.reload(); window.location.reload();
} else if (logoutPage !== "/login") {
document.location.href = `${logoutPage}`;
} else { } else {
if (typeof reason === "string" && reason.trim() !== "") { if (typeof reason === "string" && reason.trim() !== "") {
router.push({ router.push({

View File

@ -10,7 +10,6 @@ const version: string = window.FileBrowser.Version;
const logoURL = `${staticURL}/img/logo.svg`; const logoURL = `${staticURL}/img/logo.svg`;
const noAuth: boolean = window.FileBrowser.NoAuth; const noAuth: boolean = window.FileBrowser.NoAuth;
const authMethod = window.FileBrowser.AuthMethod; const authMethod = window.FileBrowser.AuthMethod;
const logoutPage: string = window.FileBrowser.LogoutPage;
const loginPage: boolean = window.FileBrowser.LoginPage; const loginPage: boolean = window.FileBrowser.LoginPage;
const theme: UserTheme = window.FileBrowser.Theme; const theme: UserTheme = window.FileBrowser.Theme;
const enableThumbs: boolean = window.FileBrowser.EnableThumbs; const enableThumbs: boolean = window.FileBrowser.EnableThumbs;
@ -33,7 +32,6 @@ export {
version, version,
noAuth, noAuth,
authMethod, authMethod,
logoutPage,
loginPage, loginPage,
theme, theme,
enableThumbs, enableThumbs,

View File

@ -1,64 +0,0 @@
export interface CsvData {
headers: string[];
rows: string[][];
}
/**
* Parse CSV content into headers and rows
* Supports quoted fields and handles commas within quotes
*/
export function parseCSV(
content: string,
columnSeparator: Array<string>
): CsvData {
if (!content || content.trim().length === 0) {
return { headers: [], rows: [] };
}
const lines = content.split(/\r?\n/);
const result: string[][] = [];
for (const line of lines) {
if (line.trim().length === 0) continue;
const row: string[] = [];
let currentField = "";
let inQuotes = false;
for (let i = 0; i < line.length; i++) {
const char = line[i];
const nextChar = line[i + 1];
if (char === '"') {
if (inQuotes && nextChar === '"') {
// Escaped quote
currentField += '"';
i++; // Skip next quote
} else {
// Toggle quote state
inQuotes = !inQuotes;
}
} else if (columnSeparator.includes(char) && !inQuotes) {
// Field separator
row.push(currentField);
currentField = "";
} else {
currentField += char;
}
}
// Add the last field
row.push(currentField);
result.push(row);
}
if (result.length === 0) {
return { headers: [], rows: [] };
}
// First row is headers
const headers = result[0];
const rows = result.slice(1);
return { headers, rows };
}

View File

@ -69,12 +69,6 @@ const currentView = computed(() => {
if (fileStore.req.isDir) { if (fileStore.req.isDir) {
return FileListing; return FileListing;
} else if (fileStore.req.extension.toLowerCase() === ".csv") {
// CSV files use Preview for table view, unless ?edit=true
if (route.query.edit === "true") {
return Editor;
}
return Preview;
} else if ( } else if (
fileStore.req.type === "text" || fileStore.req.type === "text" ||
fileStore.req.type === "textImmutable" fileStore.req.type === "textImmutable"

View File

@ -186,7 +186,7 @@ const handlePageChange = (event: BeforeUnloadEvent) => {
} }
}; };
const save = async (throwError?: boolean) => { const save = async () => {
const button = "save"; const button = "save";
buttons.loading("save"); buttons.loading("save");
@ -197,7 +197,6 @@ const save = async (throwError?: boolean) => {
} catch (e: any) { } catch (e: any) {
buttons.done(button); buttons.done(button);
$showError(e); $showError(e);
if (throwError) throw e;
} }
}; };
@ -224,10 +223,8 @@ const close = () => {
finishClose(); finishClose();
}, },
saveAction: async () => { saveAction: async () => {
try { await save();
await save(true); finishClose();
finishClose();
} catch {}
}, },
}); });
return; return;

View File

@ -159,7 +159,6 @@
ref="listing" ref="listing"
class="file-icons" class="file-icons"
:class="authStore.user?.viewMode ?? ''" :class="authStore.user?.viewMode ?? ''"
@click="handleEmptyAreaClick"
> >
<div> <div>
<div class="item header"> <div class="item header">
@ -357,7 +356,7 @@ import {
ref, ref,
watch, watch,
} from "vue"; } from "vue";
import { useRoute, onBeforeRouteUpdate } from "vue-router"; import { useRoute } from "vue-router";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { removePrefix } from "@/api/utils"; import { removePrefix } from "@/api/utils";
@ -380,9 +379,6 @@ const layoutStore = useLayoutStore();
const { req } = storeToRefs(fileStore); const { req } = storeToRefs(fileStore);
const route = useRoute(); const route = useRoute();
onBeforeRouteUpdate(() => {
hideContextMenu();
});
const { t } = useI18n(); const { t } = useI18n();
@ -1052,18 +1048,4 @@ const showContextMenu = (event: MouseEvent) => {
const hideContextMenu = () => { const hideContextMenu = () => {
isContextMenuVisible.value = false; isContextMenuVisible.value = false;
}; };
const handleEmptyAreaClick = (e: MouseEvent) => {
const target = e.target;
if (!(target instanceof HTMLElement)) return;
if (target.closest("item") || target.closest(".item")) return;
fileStore.selected = [];
};
</script> </script>
<style scoped>
#listing {
min-height: calc(100vh - 8rem);
}
</style>

View File

@ -6,7 +6,7 @@
@mousemove="toggleNavigation" @mousemove="toggleNavigation"
@touchstart="toggleNavigation" @touchstart="toggleNavigation"
> >
<header-bar v-if="isPdf || isEpub || isCsv || showNav"> <header-bar v-if="isPdf || isEpub || showNav">
<action icon="close" :label="$t('buttons.close')" @action="close()" /> <action icon="close" :label="$t('buttons.close')" @action="close()" />
<title>{{ name }}</title> <title>{{ name }}</title>
<action <action
@ -24,13 +24,6 @@
:label="$t('buttons.rename')" :label="$t('buttons.rename')"
show="rename" show="rename"
/> />
<action
:disabled="layoutStore.loading"
v-if="isCsv && authStore.user?.perm.modify"
icon="edit_note"
:label="t('buttons.editAsText')"
@action="editAsText"
/>
<action <action
:disabled="layoutStore.loading" :disabled="layoutStore.loading"
v-if="authStore.user?.perm.delete" v-if="authStore.user?.perm.delete"
@ -94,7 +87,6 @@
<span>{{ size }}%</span> <span>{{ size }}%</span>
</div> </div>
</div> </div>
<CsvViewer v-else-if="isCsv" :content="csvContent" :error="csvError" />
<ExtendedImage <ExtendedImage
v-else-if="fileStore.req?.type == 'image'" v-else-if="fileStore.req?.type == 'image'"
:src="previewUrl" :src="previewUrl"
@ -184,17 +176,11 @@ import HeaderBar from "@/components/header/HeaderBar.vue";
import Action from "@/components/header/Action.vue"; import Action from "@/components/header/Action.vue";
import ExtendedImage from "@/components/files/ExtendedImage.vue"; import ExtendedImage from "@/components/files/ExtendedImage.vue";
import VideoPlayer from "@/components/files/VideoPlayer.vue"; import VideoPlayer from "@/components/files/VideoPlayer.vue";
import CsvViewer from "@/components/files/CsvViewer.vue";
import { VueReader } from "vue-reader"; import { VueReader } from "vue-reader";
import { computed, inject, onBeforeUnmount, onMounted, ref, watch } from "vue"; import { computed, inject, onBeforeUnmount, onMounted, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router"; import { useRoute, useRouter } from "vue-router";
import type { Rendition } from "epubjs"; import type { Rendition } from "epubjs";
import { getTheme } from "@/utils/theme"; import { getTheme } from "@/utils/theme";
import { useI18n } from "vue-i18n";
// CSV file size limit for preview (5MB)
// Prevents browser memory issues with large files
const CSV_MAX_SIZE = 5 * 1024 * 1024;
const location = useStorage("book-progress", 0, undefined, { const location = useStorage("book-progress", 0, undefined, {
serializer: { serializer: {
@ -253,8 +239,6 @@ const hoverNav = ref<boolean>(false);
const autoPlay = ref<boolean>(false); const autoPlay = ref<boolean>(false);
const previousRaw = ref<string>(""); const previousRaw = ref<string>("");
const nextRaw = ref<string>(""); const nextRaw = ref<string>("");
const csvContent = ref<string>("");
const csvError = ref<string>("");
const player = ref<HTMLVideoElement | HTMLAudioElement | null>(null); const player = ref<HTMLVideoElement | HTMLAudioElement | null>(null);
@ -264,8 +248,6 @@ const authStore = useAuthStore();
const fileStore = useFileStore(); const fileStore = useFileStore();
const layoutStore = useLayoutStore(); const layoutStore = useLayoutStore();
const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
@ -297,7 +279,6 @@ const isPdf = computed(() => fileStore.req?.extension.toLowerCase() == ".pdf");
const isEpub = computed( const isEpub = computed(
() => fileStore.req?.extension.toLowerCase() == ".epub" () => fileStore.req?.extension.toLowerCase() == ".epub"
); );
const isCsv = computed(() => fileStore.req?.extension.toLowerCase() == ".csv");
const isResizeEnabled = computed(() => resizePreview); const isResizeEnabled = computed(() => resizePreview);
@ -385,18 +366,6 @@ const updatePreview = async () => {
const dirs = route.fullPath.split("/"); const dirs = route.fullPath.split("/");
name.value = decodeURIComponent(dirs[dirs.length - 1]); name.value = decodeURIComponent(dirs[dirs.length - 1]);
// Load CSV content if it's a CSV file
if (isCsv.value && fileStore.req) {
csvContent.value = "";
csvError.value = "";
if (fileStore.req.size > CSV_MAX_SIZE) {
csvError.value = t("files.csvTooLarge");
} else {
csvContent.value = fileStore.req.content ?? "";
}
}
if (!listing.value) { if (!listing.value) {
try { try {
const path = url.removeLastDir(route.path); const path = url.removeLastDir(route.path);
@ -466,8 +435,4 @@ const close = () => {
}; };
const download = () => window.open(downloadUrl.value); const download = () => window.open(downloadUrl.value);
const editAsText = () => {
router.push({ path: route.path, query: { edit: "true" } });
};
</script> </script>

View File

@ -15,14 +15,6 @@
<input type="checkbox" name="singleClick" v-model="singleClick" /> <input type="checkbox" name="singleClick" v-model="singleClick" />
{{ t("settings.singleClick") }} {{ t("settings.singleClick") }}
</p> </p>
<p>
<input
type="checkbox"
name="redirectAfterCopyMove"
v-model="redirectAfterCopyMove"
/>
{{ t("settings.redirectAfterCopyMove") }}
</p>
<p> <p>
<input type="checkbox" name="dateFormat" v-model="dateFormat" /> <input type="checkbox" name="dateFormat" v-model="dateFormat" />
{{ t("settings.setDateFormat") }} {{ t("settings.setDateFormat") }}
@ -52,7 +44,7 @@
</form> </form>
</div> </div>
<div v-if="!noAuth" class="column"> <div class="column">
<form <form
class="card" class="card"
v-if="!authStore.user?.lockPassword" v-if="!authStore.user?.lockPassword"
@ -77,15 +69,6 @@
v-model="passwordConf" v-model="passwordConf"
name="passwordConf" name="passwordConf"
/> />
<input
v-if="isCurrentPasswordRequired"
:class="passwordClass"
type="password"
:placeholder="t('settings.currentPassword')"
v-model="currentPassword"
name="current_password"
autocomplete="current-password"
/>
</div> </div>
<div class="card-action"> <div class="card-action">
@ -109,7 +92,6 @@ import AceEditorTheme from "@/components/settings/AceEditorTheme.vue";
import Languages from "@/components/settings/Languages.vue"; import Languages from "@/components/settings/Languages.vue";
import { computed, inject, onMounted, ref } from "vue"; import { computed, inject, onMounted, ref } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { authMethod, noAuth } from "@/utils/constants";
const layoutStore = useLayoutStore(); const layoutStore = useLayoutStore();
const authStore = useAuthStore(); const authStore = useAuthStore();
@ -120,11 +102,8 @@ const $showError = inject<IToastError>("$showError")!;
const password = ref<string>(""); const password = ref<string>("");
const passwordConf = ref<string>(""); const passwordConf = ref<string>("");
const currentPassword = ref<string>("");
const isCurrentPasswordRequired = ref<boolean>(false);
const hideDotfiles = ref<boolean>(false); const hideDotfiles = ref<boolean>(false);
const singleClick = ref<boolean>(false); const singleClick = ref<boolean>(false);
const redirectAfterCopyMove = ref<boolean>(false);
const dateFormat = ref<boolean>(false); const dateFormat = ref<boolean>(false);
const locale = ref<string>(""); const locale = ref<string>("");
const aceEditorTheme = ref<string>(""); const aceEditorTheme = ref<string>("");
@ -149,12 +128,9 @@ onMounted(async () => {
locale.value = authStore.user.locale; locale.value = authStore.user.locale;
hideDotfiles.value = authStore.user.hideDotfiles; hideDotfiles.value = authStore.user.hideDotfiles;
singleClick.value = authStore.user.singleClick; singleClick.value = authStore.user.singleClick;
redirectAfterCopyMove.value = authStore.user.redirectAfterCopyMove;
dateFormat.value = authStore.user.dateFormat; dateFormat.value = authStore.user.dateFormat;
aceEditorTheme.value = authStore.user.aceEditorTheme; aceEditorTheme.value = authStore.user.aceEditorTheme;
layoutStore.loading = false; layoutStore.loading = false;
isCurrentPasswordRequired.value = authMethod == "json";
return true; return true;
}); });
@ -164,7 +140,6 @@ const updatePassword = async (event: Event) => {
if ( if (
password.value !== passwordConf.value || password.value !== passwordConf.value ||
password.value === "" || password.value === "" ||
currentPassword.value === "" ||
authStore.user === null authStore.user === null
) { ) {
return; return;
@ -176,7 +151,7 @@ const updatePassword = async (event: Event) => {
id: authStore.user.id, id: authStore.user.id,
password: password.value, password: password.value,
}; };
await api.update(data, ["password"], currentPassword.value); await api.update(data, ["password"]);
authStore.updateUser(data); authStore.updateUser(data);
$showSuccess(t("settings.passwordUpdated")); $showSuccess(t("settings.passwordUpdated"));
} catch (e: any) { } catch (e: any) {
@ -197,7 +172,6 @@ const updateSettings = async (event: Event) => {
locale: locale.value, locale: locale.value,
hideDotfiles: hideDotfiles.value, hideDotfiles: hideDotfiles.value,
singleClick: singleClick.value, singleClick: singleClick.value,
redirectAfterCopyMove: redirectAfterCopyMove.value,
dateFormat: dateFormat.value, dateFormat: dateFormat.value,
aceEditorTheme: aceEditorTheme.value, aceEditorTheme: aceEditorTheme.value,
}; };
@ -206,7 +180,6 @@ const updateSettings = async (event: Event) => {
"locale", "locale",
"hideDotfiles", "hideDotfiles",
"singleClick", "singleClick",
"redirectAfterCopyMove",
"dateFormat", "dateFormat",
"aceEditorTheme", "aceEditorTheme",
]); ]);

View File

@ -15,19 +15,6 @@
:isDefault="false" :isDefault="false"
:isNew="isNew" :isNew="isNew"
/> />
<p v-if="isCurrentPasswordRequired">
<label for="currentPassword">{{
t("settings.currentPassword")
}}</label>
<input
class="input input--block"
type="password"
v-model="currentPassword"
id="currentPassword"
autocomplete="current-password"
/>
</p>
</div> </div>
<div class="card-action"> <div class="card-action">
@ -76,8 +63,6 @@ const error = ref<StatusError>();
const originalUser = ref<IUser>(); const originalUser = ref<IUser>();
const user = ref<IUser>(); const user = ref<IUser>();
const createUserDir = ref<boolean>(false); const createUserDir = ref<boolean>(false);
const currentPassword = ref<string>("");
const isCurrentPasswordRequired = ref<boolean>(false);
const $showError = inject<IToastError>("$showError")!; const $showError = inject<IToastError>("$showError")!;
const $showSuccess = inject<IToastSuccess>("$showSuccess")!; const $showSuccess = inject<IToastSuccess>("$showSuccess")!;
@ -105,12 +90,7 @@ const fetchData = async () => {
try { try {
if (isNew.value) { if (isNew.value) {
const { const { defaults, createUserDir: _createUserDir } = await settings.get();
authMethod,
defaults,
createUserDir: _createUserDir,
} = await settings.get();
isCurrentPasswordRequired.value = authMethod == "json";
createUserDir.value = _createUserDir; createUserDir.value = _createUserDir;
user.value = { user.value = {
...defaults, ...defaults,
@ -121,8 +101,6 @@ const fetchData = async () => {
id: 0, id: 0,
}; };
} else { } else {
const { authMethod } = await settings.get();
isCurrentPasswordRequired.value = authMethod == "json";
const id = Array.isArray(route.params.id) const id = Array.isArray(route.params.id)
? route.params.id.join("") ? route.params.id.join("")
: route.params.id; : route.params.id;
@ -173,11 +151,11 @@ const save = async (event: Event) => {
...user.value, ...user.value,
}; };
const loc = await api.create(newUser, currentPassword.value); const loc = await api.create(newUser);
router.push({ path: loc || "/settings/users" }); router.push({ path: loc || "/settings/users" });
$showSuccess(t("settings.userCreated")); $showSuccess(t("settings.userCreated"));
} else { } else {
await api.update(user.value, ["all"], currentPassword.value); await api.update(user.value);
if (user.value.id === authStore.user?.id) { if (user.value.id === authStore.user?.id) {
authStore.updateUser(user.value); authStore.updateUser(user.value);

18
go.mod
View File

@ -12,21 +12,21 @@ require (
github.com/gorilla/mux v1.8.1 github.com/gorilla/mux v1.8.1
github.com/gorilla/websocket v1.5.3 github.com/gorilla/websocket v1.5.3
github.com/jellydator/ttlcache/v3 v3.4.0 github.com/jellydator/ttlcache/v3 v3.4.0
github.com/maruel/natural v1.3.0 github.com/maruel/natural v1.2.1
github.com/marusama/semaphore/v2 v2.5.0 github.com/marusama/semaphore/v2 v2.5.0
github.com/mholt/archives v0.1.5 github.com/mholt/archives v0.1.5
github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir v1.1.0
github.com/samber/lo v1.52.0 github.com/samber/lo v1.52.0
github.com/shirou/gopsutil/v4 v4.25.12 github.com/shirou/gopsutil/v4 v4.25.10
github.com/spf13/afero v1.15.0 github.com/spf13/afero v1.15.0
github.com/spf13/cobra v1.10.2 github.com/spf13/cobra v1.10.1
github.com/spf13/pflag v1.0.10 github.com/spf13/pflag v1.0.10
github.com/spf13/viper v1.21.0 github.com/spf13/viper v1.21.0
github.com/stretchr/testify v1.11.1 github.com/stretchr/testify v1.11.1
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
golang.org/x/crypto v0.46.0 golang.org/x/crypto v0.45.0
golang.org/x/image v0.34.0 golang.org/x/image v0.33.0
golang.org/x/text v0.33.0 golang.org/x/text v0.31.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1 gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )
@ -44,7 +44,7 @@ require (
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 // indirect github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 // indirect
github.com/ebitengine/purego v0.9.1 // indirect github.com/ebitengine/purego v0.9.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-errors/errors v1.5.1 // indirect github.com/go-errors/errors v1.5.1 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect
@ -74,8 +74,8 @@ require (
go.yaml.in/yaml/v3 v3.0.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect
go4.org v0.0.0-20230225012048-214862532bf5 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect
golang.org/x/net v0.47.0 // indirect golang.org/x/net v0.47.0 // indirect
golang.org/x/sync v0.19.0 // indirect golang.org/x/sync v0.18.0 // indirect
golang.org/x/sys v0.39.0 // indirect golang.org/x/sys v0.38.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
) )

36
go.sum
View File

@ -75,8 +75,8 @@ github.com/dsoprea/go-utility/v2 v2.0.0-20221003142440-7a1927d49d9d/go.mod h1:LV
github.com/dsoprea/go-utility/v2 v2.0.0-20221003160719-7bc88537c05e/go.mod h1:VZ7cB0pTjm1ADBWhJUOHESu4ZYy9JN+ZPqjfiW09EPU= github.com/dsoprea/go-utility/v2 v2.0.0-20221003160719-7bc88537c05e/go.mod h1:VZ7cB0pTjm1ADBWhJUOHESu4ZYy9JN+ZPqjfiW09EPU=
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 h1:DilThiXje0z+3UQ5YjYiSRRzVdtamFpvBQXKwMglWqw= github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 h1:DilThiXje0z+3UQ5YjYiSRRzVdtamFpvBQXKwMglWqw=
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349/go.mod h1:4GC5sXji84i/p+irqghpPFZBF8tRN/Q7+700G0/DLe8= github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349/go.mod h1:4GC5sXji84i/p+irqghpPFZBF8tRN/Q7+700G0/DLe8=
github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A= github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k=
github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
@ -169,8 +169,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/maruel/natural v1.3.0 h1:VsmCsBmEyrR46RomtgHs5hbKADGRVtliHTyCOLFBpsg= github.com/maruel/natural v1.2.1 h1:G/y4pwtTA07lbQsMefvsmEO0VN0NfqpxprxXDM4R/4o=
github.com/maruel/natural v1.3.0/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/maruel/natural v1.2.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
github.com/marusama/semaphore/v2 v2.5.0 h1:o/1QJD9DBYOWRnDhPwDVAXQn6mQYD0gZaS1Tpx6DJGM= github.com/marusama/semaphore/v2 v2.5.0 h1:o/1QJD9DBYOWRnDhPwDVAXQn6mQYD0gZaS1Tpx6DJGM=
github.com/marusama/semaphore/v2 v2.5.0/go.mod h1:z9nMiNUekt/LTpTUQdpp+4sJeYqUGpwMHfW0Z8V8fnQ= github.com/marusama/semaphore/v2 v2.5.0/go.mod h1:z9nMiNUekt/LTpTUQdpp+4sJeYqUGpwMHfW0Z8V8fnQ=
github.com/mholt/archives v0.1.5 h1:Fh2hl1j7VEhc6DZs2DLMgiBNChUux154a1G+2esNvzQ= github.com/mholt/archives v0.1.5 h1:Fh2hl1j7VEhc6DZs2DLMgiBNChUux154a1G+2esNvzQ=
@ -204,8 +204,8 @@ github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDc
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
github.com/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw= github.com/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw=
github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0=
github.com/shirou/gopsutil/v4 v4.25.12 h1:e7PvW/0RmJ8p8vPGJH4jvNkOyLmbkXgXW4m6ZPic6CY= github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA=
github.com/shirou/gopsutil/v4 v4.25.12/go.mod h1:EivAfP5x2EhLp2ovdpKSozecVXn1TmuG7SMzs/Wh4PU= github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM=
github.com/sorairolake/lzip-go v0.3.8 h1:j5Q2313INdTA80ureWYRhX+1K78mUXfMoPZCw/ivWik= github.com/sorairolake/lzip-go v0.3.8 h1:j5Q2313INdTA80ureWYRhX+1K78mUXfMoPZCw/ivWik=
github.com/sorairolake/lzip-go v0.3.8/go.mod h1:JcBqGMV0frlxwrsE9sMWXDjqn3EeVf0/54YPsw66qkU= github.com/sorairolake/lzip-go v0.3.8/go.mod h1:JcBqGMV0frlxwrsE9sMWXDjqn3EeVf0/54YPsw66qkU=
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
@ -214,8 +214,8 @@ github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
@ -266,8 +266,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 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-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -279,8 +279,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.34.0 h1:33gCkyw9hmwbZJeZkct8XyR11yH889EQt/QH4VmXMn8= golang.org/x/image v0.33.0 h1:LXRZRnv1+zGd5XBUVRFmYEphyyKJjQjCRiOuAP3sZfQ=
golang.org/x/image v0.34.0/go.mod h1:2RNFBZRB+vnwwFil8GkMdRvrJOFd1AzdZI6vOY+eJVU= golang.org/x/image v0.33.0/go.mod h1:DD3OsTYT9chzuzTQt+zMcOlBHgfoKQb1gry8p76Y1sc=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -333,8 +333,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -360,8 +360,8 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -372,8 +372,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"encoding/json" "encoding/json"
@ -12,9 +12,7 @@ import (
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
"github.com/golang-jwt/jwt/v5/request" "github.com/golang-jwt/jwt/v5/request"
fbAuth "github.com/filebrowser/filebrowser/v2/auth" fbErrors "github.com/filebrowser/filebrowser/v2/errors"
fberrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
) )
@ -23,18 +21,17 @@ const (
) )
type userInfo struct { type userInfo struct {
ID uint `json:"id"` ID uint `json:"id"`
Locale string `json:"locale"` Locale string `json:"locale"`
ViewMode users.ViewMode `json:"viewMode"` ViewMode users.ViewMode `json:"viewMode"`
SingleClick bool `json:"singleClick"` SingleClick bool `json:"singleClick"`
RedirectAfterCopyMove bool `json:"redirectAfterCopyMove"` Perm users.Permissions `json:"perm"`
Perm users.Permissions `json:"perm"` Commands []string `json:"commands"`
Commands []string `json:"commands"` LockPassword bool `json:"lockPassword"`
LockPassword bool `json:"lockPassword"` HideDotfiles bool `json:"hideDotfiles"`
HideDotfiles bool `json:"hideDotfiles"` DateFormat bool `json:"dateFormat"`
DateFormat bool `json:"dateFormat"` Username string `json:"username"`
Username string `json:"username"` AceEditorTheme string `json:"aceEditorTheme"`
AceEditorTheme string `json:"aceEditorTheme"`
} }
type authToken struct { type authToken struct {
@ -64,22 +61,6 @@ func (e extractor) ExtractToken(r *http.Request) (string, error) {
return "", request.ErrNoTokenInRequest return "", request.ErrNoTokenInRequest
} }
func renewableErr(err error, d *data) bool {
if d.settings.AuthMethod != fbAuth.MethodProxyAuth || err == nil {
return false
}
if d.settings.LogoutPage == settings.DefaultLogoutPage {
return false
}
if !errors.Is(err, jwt.ErrTokenExpired) {
return false
}
return true
}
func withUser(fn handleFunc) handleFunc { func withUser(fn handleFunc) handleFunc {
return func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { return func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
keyFunc := func(_ *jwt.Token) (interface{}, error) { keyFunc := func(_ *jwt.Token) (interface{}, error) {
@ -87,9 +68,13 @@ func withUser(fn handleFunc) handleFunc {
} }
var tk authToken var tk authToken
p := jwt.NewParser(jwt.WithValidMethods([]string{jwt.SigningMethodHS256.Alg()}), jwt.WithExpirationRequired()) token, err := request.ParseFromRequest(r, &extractor{}, keyFunc, request.WithClaims(&tk))
token, err := request.ParseFromRequest(r, &extractor{}, keyFunc, request.WithClaims(&tk), request.WithParser(p)) if err != nil || !token.Valid {
if (err != nil || !token.Valid) && !renewableErr(err, d) { return http.StatusUnauthorized, nil
}
err = jwt.NewValidator(jwt.WithExpirationRequired()).Validate(tk)
if err != nil {
return http.StatusUnauthorized, nil return http.StatusUnauthorized, nil
} }
@ -186,7 +171,7 @@ var signupHandler = func(_ http.ResponseWriter, r *http.Request, d *data) (int,
log.Printf("new user: %s, home dir: [%s].", user.Username, userHome) log.Printf("new user: %s, home dir: [%s].", user.Username, userHome)
err = d.store.Users.Save(user) err = d.store.Users.Save(user)
if errors.Is(err, fberrors.ErrExist) { if errors.Is(err, fbErrors.ErrExist) {
return http.StatusConflict, err return http.StatusConflict, err
} else if err != nil { } else if err != nil {
return http.StatusInternalServerError, err return http.StatusInternalServerError, err
@ -205,18 +190,17 @@ func renewHandler(tokenExpireTime time.Duration) handleFunc {
func printToken(w http.ResponseWriter, _ *http.Request, d *data, user *users.User, tokenExpirationTime time.Duration) (int, error) { func printToken(w http.ResponseWriter, _ *http.Request, d *data, user *users.User, tokenExpirationTime time.Duration) (int, error) {
claims := &authToken{ claims := &authToken{
User: userInfo{ User: userInfo{
ID: user.ID, ID: user.ID,
Locale: user.Locale, Locale: user.Locale,
ViewMode: user.ViewMode, ViewMode: user.ViewMode,
SingleClick: user.SingleClick, SingleClick: user.SingleClick,
RedirectAfterCopyMove: user.RedirectAfterCopyMove, Perm: user.Perm,
Perm: user.Perm, LockPassword: user.LockPassword,
LockPassword: user.LockPassword, Commands: user.Commands,
Commands: user.Commands, HideDotfiles: user.HideDotfiles,
HideDotfiles: user.HideDotfiles, DateFormat: user.DateFormat,
DateFormat: user.DateFormat, Username: user.Username,
Username: user.Username, AceEditorTheme: user.AceEditorTheme,
AceEditorTheme: user.AceEditorTheme,
}, },
RegisteredClaims: jwt.RegisteredClaims{ RegisteredClaims: jwt.RegisteredClaims{
IssuedAt: jwt.NewNumericDate(time.Now()), IssuedAt: jwt.NewNumericDate(time.Now()),

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"bufio" "bufio"

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"log" "log"

View File

@ -1,6 +1,6 @@
//go:build !dev //go:build !dev
package fbhttp package http
// global headers to append to every response // global headers to append to every response
var globalHeaders = map[string]string{ var globalHeaders = map[string]string{

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"io/fs" "io/fs"
@ -11,9 +11,8 @@ import (
) )
type modifyRequest struct { type modifyRequest struct {
What string `json:"what"` // Answer to: what data type? What string `json:"what"` // Answer to: what data type?
Which []string `json:"which"` // Answer to: which fields? Which []string `json:"which"` // Answer to: which fields?
CurrentPassword string `json:"current_password"` // Answer to: user logged password
} }
func NewHandler( func NewHandler(

View File

@ -1,5 +1,5 @@
//go:generate go-enum --sql --marshal --names --file $GOFILE //go:generate go-enum --sql --marshal --names --file $GOFILE
package fbhttp package http
import ( import (
"bytes" "bytes"

View File

@ -1,7 +1,7 @@
// Code generated by go-enum // Code generated by go-enum
// DO NOT EDIT! // DO NOT EDIT!
package fbhttp package http
import ( import (
"database/sql/driver" "database/sql/driver"

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"errors" "errors"
@ -41,7 +41,6 @@ var withHashFile = func(fn handleFunc) handleFunc {
Modify: d.user.Perm.Modify, Modify: d.user.Perm.Modify,
Expand: false, Expand: false,
ReadHeader: d.server.TypeDetectionByHeader, ReadHeader: d.server.TypeDetectionByHeader,
CalcImgRes: d.server.TypeDetectionByHeader,
Checker: d, Checker: d,
Token: link.Token, Token: link.Token,
}) })
@ -75,12 +74,6 @@ var withHashFile = func(fn handleFunc) handleFunc {
return errToStatus(err), err return errToStatus(err), err
} }
if file.IsDir {
// extract name from the last directory in the path
name := filepath.Base(strings.TrimRight(link.Path, string(filepath.Separator)))
file.Name = name
}
d.raw = file d.raw = file
return fn(w, r, d) return fn(w, r, d)
} }

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"fmt" "fmt"

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"errors" "errors"
@ -123,7 +123,6 @@ func getFiles(d *data, path, commonPath string) ([]archives.FileInfo, error) {
if path != commonPath { if path != commonPath {
nameInArchive := strings.TrimPrefix(path, commonPath) nameInArchive := strings.TrimPrefix(path, commonPath)
nameInArchive = strings.TrimPrefix(nameInArchive, string(filepath.Separator)) nameInArchive = strings.TrimPrefix(nameInArchive, string(filepath.Separator))
nameInArchive = filepath.ToSlash(nameInArchive)
archiveFiles = append(archiveFiles, archives.FileInfo{ archiveFiles = append(archiveFiles, archives.FileInfo{
FileInfo: info, FileInfo: info,

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"context" "context"
@ -17,7 +17,7 @@ import (
"github.com/shirou/gopsutil/v4/disk" "github.com/shirou/gopsutil/v4/disk"
"github.com/spf13/afero" "github.com/spf13/afero"
fberrors "github.com/filebrowser/filebrowser/v2/errors" fbErrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/files" "github.com/filebrowser/filebrowser/v2/files"
"github.com/filebrowser/filebrowser/v2/fileutils" "github.com/filebrowser/filebrowser/v2/fileutils"
) )
@ -44,7 +44,7 @@ var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d
if checksum := r.URL.Query().Get("checksum"); checksum != "" { if checksum := r.URL.Query().Get("checksum"); checksum != "" {
err := file.Checksum(checksum) err := file.Checksum(checksum)
if errors.Is(err, fberrors.ErrInvalidOption) { if errors.Is(err, fbErrors.ErrInvalidOption) {
return http.StatusBadRequest, nil return http.StatusBadRequest, nil
} else if err != nil { } else if err != nil {
return http.StatusInternalServerError, err return http.StatusInternalServerError, err
@ -238,7 +238,7 @@ func checkParent(src, dst string) error {
rel = filepath.ToSlash(rel) rel = filepath.ToSlash(rel)
if !strings.HasPrefix(rel, "../") && rel != ".." && rel != "." { if !strings.HasPrefix(rel, "../") && rel != ".." && rel != "." {
return fberrors.ErrSourceIsParent return fbErrors.ErrSourceIsParent
} }
return nil return nil
@ -280,12 +280,6 @@ func writeFile(afs afero.Fs, dst string, in io.Reader, fileMode, dirMode fs.File
return nil, err return nil, err
} }
// Sync the file to ensure all data is written to storage.
// to prevent file corruption.
if err := file.Sync(); err != nil {
return nil, err
}
// Gets the info about the file. // Gets the info about the file.
info, err := file.Stat() info, err := file.Stat()
if err != nil { if err != nil {
@ -310,13 +304,13 @@ func patchAction(ctx context.Context, action, src, dst string, d *data, fileCach
switch action { switch action {
case "copy": case "copy":
if !d.user.Perm.Create { if !d.user.Perm.Create {
return fberrors.ErrPermissionDenied return fbErrors.ErrPermissionDenied
} }
return fileutils.Copy(d.user.Fs, src, dst, d.settings.FileMode, d.settings.DirMode) return fileutils.Copy(d.user.Fs, src, dst, d.settings.FileMode, d.settings.DirMode)
case "rename": case "rename":
if !d.user.Perm.Rename { if !d.user.Perm.Rename {
return fberrors.ErrPermissionDenied return fbErrors.ErrPermissionDenied
} }
src = path.Clean("/" + src) src = path.Clean("/" + src)
dst = path.Clean("/" + dst) dst = path.Clean("/" + dst)
@ -341,7 +335,7 @@ func patchAction(ctx context.Context, action, src, dst string, d *data, fileCach
return fileutils.MoveFile(d.user.Fs, src, dst, d.settings.FileMode, d.settings.DirMode) return fileutils.MoveFile(d.user.Fs, src, dst, d.settings.FileMode, d.settings.DirMode)
default: default:
return fmt.Errorf("unsupported action %s: %w", action, fberrors.ErrInvalidRequestParams) return fmt.Errorf("unsupported action %s: %w", action, fbErrors.ErrInvalidRequestParams)
} }
} }

View File

@ -1,82 +1,28 @@
package fbhttp package http
import ( import (
"context"
"encoding/json"
"errors"
"net/http" "net/http"
"os" "os"
"sync"
"time"
"github.com/filebrowser/filebrowser/v2/search" "github.com/filebrowser/filebrowser/v2/search"
) )
const searchPingInterval = 5
var searchHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { var searchHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
response := make(chan map[string]interface{}) response := []map[string]interface{}{}
ctx, cancel := context.WithCancelCause(r.Context())
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
// Avoid connection timeout
timeout := time.NewTimer(searchPingInterval * time.Second)
defer timeout.Stop()
for {
var err error
var infoBytes []byte
select {
case info := <-response:
if info == nil {
return
}
infoBytes, err = json.Marshal(info)
case <-timeout.C:
// Send a heartbeat packet
infoBytes = nil
case <-ctx.Done():
return
}
if err != nil {
cancel(err)
return
}
_, err = w.Write(infoBytes)
if err == nil {
_, err = w.Write([]byte("\n"))
}
if err != nil {
cancel(err)
return
}
if flusher, ok := w.(http.Flusher); ok {
flusher.Flush()
}
}
}()
query := r.URL.Query().Get("query") query := r.URL.Query().Get("query")
err := search.Search(ctx, d.user.Fs, r.URL.Path, query, d, func(path string, f os.FileInfo) error { err := search.Search(d.user.Fs, r.URL.Path, query, d, func(path string, f os.FileInfo) error {
select { response = append(response, map[string]interface{}{
case <-ctx.Done():
case response <- map[string]interface{}{
"dir": f.IsDir(), "dir": f.IsDir(),
"path": path, "path": path,
}: })
}
return context.Cause(ctx) return nil
}) })
close(response)
wg.Wait() if err != nil {
if err == nil {
err = context.Cause(ctx)
}
// ignore cancellation errors from user aborts
if err != nil && !errors.Is(err, context.Canceled) {
return http.StatusInternalServerError, err return http.StatusInternalServerError, err
} }
return 0, nil return renderJSON(w, r, response)
}) })

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"encoding/json" "encoding/json"
@ -15,7 +15,6 @@ type settingsData struct {
MinimumPasswordLength uint `json:"minimumPasswordLength"` MinimumPasswordLength uint `json:"minimumPasswordLength"`
UserHomeBasePath string `json:"userHomeBasePath"` UserHomeBasePath string `json:"userHomeBasePath"`
Defaults settings.UserDefaults `json:"defaults"` Defaults settings.UserDefaults `json:"defaults"`
AuthMethod settings.AuthMethod `json:"authMethod"`
Rules []rules.Rule `json:"rules"` Rules []rules.Rule `json:"rules"`
Branding settings.Branding `json:"branding"` Branding settings.Branding `json:"branding"`
Tus settings.Tus `json:"tus"` Tus settings.Tus `json:"tus"`
@ -31,7 +30,6 @@ var settingsGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request,
MinimumPasswordLength: d.settings.MinimumPasswordLength, MinimumPasswordLength: d.settings.MinimumPasswordLength,
UserHomeBasePath: d.settings.UserHomeBasePath, UserHomeBasePath: d.settings.UserHomeBasePath,
Defaults: d.settings.Defaults, Defaults: d.settings.Defaults,
AuthMethod: d.settings.AuthMethod,
Rules: d.settings.Rules, Rules: d.settings.Rules,
Branding: d.settings.Branding, Branding: d.settings.Branding,
Tus: d.settings.Tus, Tus: d.settings.Tus,

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"crypto/rand" "crypto/rand"
@ -14,7 +14,7 @@ import (
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
fberrors "github.com/filebrowser/filebrowser/v2/errors" fbErrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/share" "github.com/filebrowser/filebrowser/v2/share"
) )
@ -38,7 +38,7 @@ var shareListHandler = withPermShare(func(w http.ResponseWriter, r *http.Request
} else { } else {
s, err = d.store.Share.FindByUserID(d.user.ID) s, err = d.store.Share.FindByUserID(d.user.ID)
} }
if errors.Is(err, fberrors.ErrNotExist) { if errors.Is(err, fbErrors.ErrNotExist) {
return renderJSON(w, r, []*share.Link{}) return renderJSON(w, r, []*share.Link{})
} }
@ -58,7 +58,7 @@ var shareListHandler = withPermShare(func(w http.ResponseWriter, r *http.Request
var shareGetsHandler = withPermShare(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { var shareGetsHandler = withPermShare(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
s, err := d.store.Share.Gets(r.URL.Path, d.user.ID) s, err := d.store.Share.Gets(r.URL.Path, d.user.ID)
if errors.Is(err, fberrors.ErrNotExist) { if errors.Is(err, fbErrors.ErrNotExist) {
return renderJSON(w, r, []*share.Link{}) return renderJSON(w, r, []*share.Link{})
} }

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"encoding/json" "encoding/json"
@ -38,7 +38,6 @@ func handleWithStaticData(w http.ResponseWriter, _ *http.Request, d *data, fSys
"Signup": d.settings.Signup, "Signup": d.settings.Signup,
"NoAuth": d.settings.AuthMethod == auth.MethodNoAuth, "NoAuth": d.settings.AuthMethod == auth.MethodNoAuth,
"AuthMethod": d.settings.AuthMethod, "AuthMethod": d.settings.AuthMethod,
"LogoutPage": d.settings.LogoutPage,
"LoginPage": auther.LoginPage(), "LoginPage": auther.LoginPage(),
"CSS": false, "CSS": false,
"ReCaptcha": false, "ReCaptcha": false,

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"bytes" "bytes"

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"context" "context"
@ -256,12 +256,6 @@ func tusPatchHandler() handleFunc {
return http.StatusInternalServerError, fmt.Errorf("could not write to file: %w", err) return http.StatusInternalServerError, fmt.Errorf("could not write to file: %w", err)
} }
// Sync the file to ensure all data is written to storage
// to prevent file corruption.
if err := openFile.Sync(); err != nil {
return http.StatusInternalServerError, fmt.Errorf("could not sync file: %w", err)
}
newOffset := uploadOffset + bytesWritten newOffset := uploadOffset + bytesWritten
w.Header().Set("Upload-Offset", strconv.FormatInt(newOffset, 10)) w.Header().Set("Upload-Offset", strconv.FormatInt(newOffset, 10))

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"encoding/json" "encoding/json"
@ -12,8 +12,7 @@ import (
"golang.org/x/text/cases" "golang.org/x/text/cases"
"golang.org/x/text/language" "golang.org/x/text/language"
"github.com/filebrowser/filebrowser/v2/auth" fbErrors "github.com/filebrowser/filebrowser/v2/errors"
fberrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
) )
@ -37,7 +36,7 @@ func getUserID(r *http.Request) (uint, error) {
func getUser(_ http.ResponseWriter, r *http.Request) (*modifyUserRequest, error) { func getUser(_ http.ResponseWriter, r *http.Request) (*modifyUserRequest, error) {
if r.Body == nil { if r.Body == nil {
return nil, fberrors.ErrEmptyRequest return nil, fbErrors.ErrEmptyRequest
} }
req := &modifyUserRequest{} req := &modifyUserRequest{}
@ -47,7 +46,7 @@ func getUser(_ http.ResponseWriter, r *http.Request) (*modifyUserRequest, error)
} }
if req.What != "user" { if req.What != "user" {
return nil, fberrors.ErrInvalidDataType return nil, fbErrors.ErrInvalidDataType
} }
return req, nil return req, nil
@ -88,7 +87,7 @@ var usersGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *
var userGetHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { var userGetHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
u, err := d.store.Users.Get(d.server.Root, d.raw.(uint)) u, err := d.store.Users.Get(d.server.Root, d.raw.(uint))
if errors.Is(err, fberrors.ErrNotExist) { if errors.Is(err, fbErrors.ErrNotExist) {
return http.StatusNotFound, err return http.StatusNotFound, err
} }
@ -118,18 +117,12 @@ var userPostHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *
return http.StatusBadRequest, err return http.StatusBadRequest, err
} }
if d.settings.AuthMethod == auth.MethodJSONAuth {
if !users.CheckPwd(req.CurrentPassword, d.user.Password) {
return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect
}
}
if len(req.Which) != 0 { if len(req.Which) != 0 {
return http.StatusBadRequest, nil return http.StatusBadRequest, nil
} }
if req.Data.Password == "" { if req.Data.Password == "" {
return http.StatusBadRequest, fberrors.ErrEmptyPassword return http.StatusBadRequest, fbErrors.ErrEmptyPassword
} }
req.Data.Password, err = users.ValidateAndHashPwd(req.Data.Password, d.settings.MinimumPasswordLength) req.Data.Password, err = users.ValidateAndHashPwd(req.Data.Password, d.settings.MinimumPasswordLength)
@ -160,27 +153,6 @@ var userPutHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request
return http.StatusBadRequest, err return http.StatusBadRequest, err
} }
if d.settings.AuthMethod == auth.MethodJSONAuth {
var sensibleFields = map[string]struct{}{
"all": {},
"username": {},
"password": {},
"scope": {},
"lockPassword": {},
"commands": {},
"perm": {},
}
for _, field := range req.Which {
if _, ok := sensibleFields[field]; ok {
if !users.CheckPwd(req.CurrentPassword, d.user.Password) {
return http.StatusBadRequest, fberrors.ErrCurrentPasswordIncorrect
}
break
}
}
}
if req.Data.ID != d.raw.(uint) { if req.Data.ID != d.raw.(uint) {
return http.StatusBadRequest, nil return http.StatusBadRequest, nil
} }

View File

@ -1,4 +1,4 @@
package fbhttp package http
import ( import (
"encoding/json" "encoding/json"

View File

@ -10,6 +10,5 @@
"postUpdateOptions": [ "postUpdateOptions": [
"gomodUpdateImportPaths", "gomodUpdateImportPaths",
"gomodTidy" "gomodTidy"
], ]
"schedule": "* * * * 0,6"
} }

View File

@ -1,7 +1,6 @@
package search package search
import ( import (
"context"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
@ -19,17 +18,13 @@ type searchOptions struct {
} }
// Search searches for a query in a fs. // Search searches for a query in a fs.
func Search(ctx context.Context, func Search(fs afero.Fs, scope, query string, checker rules.Checker, found func(path string, f os.FileInfo) error) error {
fs afero.Fs, scope, query string, checker rules.Checker, found func(path string, f os.FileInfo) error) error {
search := parseSearch(query) search := parseSearch(query)
scope = filepath.ToSlash(filepath.Clean(scope)) scope = filepath.ToSlash(filepath.Clean(scope))
scope = path.Join("/", scope) scope = path.Join("/", scope)
return afero.Walk(fs, scope, func(fPath string, f os.FileInfo, _ error) error { return afero.Walk(fs, scope, func(fPath string, f os.FileInfo, _ error) error {
if ctx.Err() != nil {
return context.Cause(ctx)
}
fPath = filepath.ToSlash(filepath.Clean(fPath)) fPath = filepath.ToSlash(filepath.Clean(fPath))
fPath = path.Join("/", fPath) fPath = path.Join("/", fPath)
relativePath := strings.TrimPrefix(fPath, scope) relativePath := strings.TrimPrefix(fPath, scope)

View File

@ -8,17 +8,16 @@ import (
// UserDefaults is a type that holds the default values // UserDefaults is a type that holds the default values
// for some fields on User. // for some fields on User.
type UserDefaults struct { type UserDefaults struct {
Scope string `json:"scope"` Scope string `json:"scope"`
Locale string `json:"locale"` Locale string `json:"locale"`
ViewMode users.ViewMode `json:"viewMode"` ViewMode users.ViewMode `json:"viewMode"`
SingleClick bool `json:"singleClick"` SingleClick bool `json:"singleClick"`
RedirectAfterCopyMove bool `json:"redirectAfterCopyMove"` Sorting files.Sorting `json:"sorting"`
Sorting files.Sorting `json:"sorting"` Perm users.Permissions `json:"perm"`
Perm users.Permissions `json:"perm"` Commands []string `json:"commands"`
Commands []string `json:"commands"` HideDotfiles bool `json:"hideDotfiles"`
HideDotfiles bool `json:"hideDotfiles"` DateFormat bool `json:"dateFormat"`
DateFormat bool `json:"dateFormat"` AceEditorTheme string `json:"aceEditorTheme"`
AceEditorTheme string `json:"aceEditorTheme"`
} }
// Apply applies the default options to a user. // Apply applies the default options to a user.
@ -27,7 +26,6 @@ func (d *UserDefaults) Apply(u *users.User) {
u.Locale = d.Locale u.Locale = d.Locale
u.ViewMode = d.ViewMode u.ViewMode = d.ViewMode
u.SingleClick = d.SingleClick u.SingleClick = d.SingleClick
u.RedirectAfterCopyMove = d.RedirectAfterCopyMove
u.Perm = d.Perm u.Perm = d.Perm
u.Sorting = d.Sorting u.Sorting = d.Sorting
u.Commands = d.Commands u.Commands = d.Commands

View File

@ -11,7 +11,6 @@ import (
) )
const DefaultUsersHomeBasePath = "/users" const DefaultUsersHomeBasePath = "/users"
const DefaultLogoutPage = "/login"
const DefaultMinimumPasswordLength = 12 const DefaultMinimumPasswordLength = 12
const DefaultFileMode = 0640 const DefaultFileMode = 0640
const DefaultDirMode = 0750 const DefaultDirMode = 0750
@ -28,7 +27,6 @@ type Settings struct {
UserHomeBasePath string `json:"userHomeBasePath"` UserHomeBasePath string `json:"userHomeBasePath"`
Defaults UserDefaults `json:"defaults"` Defaults UserDefaults `json:"defaults"`
AuthMethod AuthMethod `json:"authMethod"` AuthMethod AuthMethod `json:"authMethod"`
LogoutPage string `json:"logoutPage"`
Branding Branding `json:"branding"` Branding Branding `json:"branding"`
Tus Tus `json:"tus"` Tus Tus `json:"tus"`
Commands map[string][]string `json:"commands"` Commands map[string][]string `json:"commands"`
@ -59,7 +57,6 @@ type Server struct {
ResizePreview bool `json:"resizePreview"` ResizePreview bool `json:"resizePreview"`
EnableExec bool `json:"enableExec"` EnableExec bool `json:"enableExec"`
TypeDetectionByHeader bool `json:"typeDetectionByHeader"` TypeDetectionByHeader bool `json:"typeDetectionByHeader"`
ImageResolutionCal bool `json:"imageResolutionCalculation"`
AuthHook string `json:"authHook"` AuthHook string `json:"authHook"`
TokenExpirationTime string `json:"tokenExpirationTime"` TokenExpirationTime string `json:"tokenExpirationTime"`
} }

View File

@ -1,7 +1,7 @@
package settings package settings
import ( import (
fberrors "github.com/filebrowser/filebrowser/v2/errors" "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/rules" "github.com/filebrowser/filebrowser/v2/rules"
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
) )
@ -30,34 +30,24 @@ func (s *Storage) Get() (*Settings, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if set.UserHomeBasePath == "" { if set.UserHomeBasePath == "" {
set.UserHomeBasePath = DefaultUsersHomeBasePath set.UserHomeBasePath = DefaultUsersHomeBasePath
} }
if set.LogoutPage == "" {
set.LogoutPage = DefaultLogoutPage
}
if set.MinimumPasswordLength == 0 { if set.MinimumPasswordLength == 0 {
set.MinimumPasswordLength = DefaultMinimumPasswordLength set.MinimumPasswordLength = DefaultMinimumPasswordLength
} }
if set.Tus == (Tus{}) { if set.Tus == (Tus{}) {
set.Tus = Tus{ set.Tus = Tus{
ChunkSize: DefaultTusChunkSize, ChunkSize: DefaultTusChunkSize,
RetryCount: DefaultTusRetryCount, RetryCount: DefaultTusRetryCount,
} }
} }
if set.FileMode == 0 { if set.FileMode == 0 {
set.FileMode = DefaultFileMode set.FileMode = DefaultFileMode
} }
if set.DirMode == 0 { if set.DirMode == 0 {
set.DirMode = DefaultDirMode set.DirMode = DefaultDirMode
} }
return set, nil return set, nil
} }
@ -72,7 +62,7 @@ var defaultEvents = []string{
// Save saves the settings for the current instance. // Save saves the settings for the current instance.
func (s *Storage) Save(set *Settings) error { func (s *Storage) Save(set *Settings) error {
if len(set.Key) == 0 { if len(set.Key) == 0 {
return fberrors.ErrEmptyKey return errors.ErrEmptyKey
} }
if set.Defaults.Locale == "" { if set.Defaults.Locale == "" {

View File

@ -3,7 +3,7 @@ package share
import ( import (
"time" "time"
fberrors "github.com/filebrowser/filebrowser/v2/errors" "github.com/filebrowser/filebrowser/v2/errors"
) )
// StorageBackend is the interface to implement for a share storage. // StorageBackend is the interface to implement for a share storage.
@ -79,7 +79,7 @@ func (s *Storage) GetByHash(hash string) (*Link, error) {
if err := s.Delete(link.Hash); err != nil { if err := s.Delete(link.Hash); err != nil {
return nil, err return nil, err
} }
return nil, fberrors.ErrNotExist return nil, errors.ErrNotExist
} }
return link, nil return link, nil

View File

@ -4,7 +4,7 @@ import (
"github.com/asdine/storm/v3" "github.com/asdine/storm/v3"
"github.com/filebrowser/filebrowser/v2/auth" "github.com/filebrowser/filebrowser/v2/auth"
fberrors "github.com/filebrowser/filebrowser/v2/errors" "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/settings" "github.com/filebrowser/filebrowser/v2/settings"
) )
@ -25,7 +25,7 @@ func (s authBackend) Get(t settings.AuthMethod) (auth.Auther, error) {
case auth.MethodNoAuth: case auth.MethodNoAuth:
auther = &auth.NoAuth{} auther = &auth.NoAuth{}
default: default:
return nil, fberrors.ErrInvalidAuthMethod return nil, errors.ErrInvalidAuthMethod
} }
return auther, get(s.db, "auther", auther) return auther, get(s.db, "auther", auther)

View File

@ -6,7 +6,7 @@ import (
"github.com/asdine/storm/v3" "github.com/asdine/storm/v3"
"github.com/asdine/storm/v3/q" "github.com/asdine/storm/v3/q"
fberrors "github.com/filebrowser/filebrowser/v2/errors" fbErrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/share" "github.com/filebrowser/filebrowser/v2/share"
) )
@ -18,7 +18,7 @@ func (s shareBackend) All() ([]*share.Link, error) {
var v []*share.Link var v []*share.Link
err := s.db.All(&v) err := s.db.All(&v)
if errors.Is(err, storm.ErrNotFound) { if errors.Is(err, storm.ErrNotFound) {
return v, fberrors.ErrNotExist return v, fbErrors.ErrNotExist
} }
return v, err return v, err
@ -28,7 +28,7 @@ func (s shareBackend) FindByUserID(id uint) ([]*share.Link, error) {
var v []*share.Link var v []*share.Link
err := s.db.Select(q.Eq("UserID", id)).Find(&v) err := s.db.Select(q.Eq("UserID", id)).Find(&v)
if errors.Is(err, storm.ErrNotFound) { if errors.Is(err, storm.ErrNotFound) {
return v, fberrors.ErrNotExist return v, fbErrors.ErrNotExist
} }
return v, err return v, err
@ -38,7 +38,7 @@ func (s shareBackend) GetByHash(hash string) (*share.Link, error) {
var v share.Link var v share.Link
err := s.db.One("Hash", hash, &v) err := s.db.One("Hash", hash, &v)
if errors.Is(err, storm.ErrNotFound) { if errors.Is(err, storm.ErrNotFound) {
return nil, fberrors.ErrNotExist return nil, fbErrors.ErrNotExist
} }
return &v, err return &v, err
@ -48,7 +48,7 @@ func (s shareBackend) GetPermanent(path string, id uint) (*share.Link, error) {
var v share.Link var v share.Link
err := s.db.Select(q.Eq("Path", path), q.Eq("Expire", 0), q.Eq("UserID", id)).First(&v) err := s.db.Select(q.Eq("Path", path), q.Eq("Expire", 0), q.Eq("UserID", id)).First(&v)
if errors.Is(err, storm.ErrNotFound) { if errors.Is(err, storm.ErrNotFound) {
return nil, fberrors.ErrNotExist return nil, fbErrors.ErrNotExist
} }
return &v, err return &v, err
@ -58,7 +58,7 @@ func (s shareBackend) Gets(path string, id uint) ([]*share.Link, error) {
var v []*share.Link var v []*share.Link
err := s.db.Select(q.Eq("Path", path), q.Eq("UserID", id)).Find(&v) err := s.db.Select(q.Eq("Path", path), q.Eq("UserID", id)).Find(&v)
if errors.Is(err, storm.ErrNotFound) { if errors.Is(err, storm.ErrNotFound) {
return v, fberrors.ErrNotExist return v, fbErrors.ErrNotExist
} }
return v, err return v, err

View File

@ -7,7 +7,7 @@ import (
"github.com/asdine/storm/v3" "github.com/asdine/storm/v3"
fberrors "github.com/filebrowser/filebrowser/v2/errors" fbErrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
) )
@ -25,14 +25,14 @@ func (st usersBackend) GetBy(i interface{}) (user *users.User, err error) {
case string: case string:
arg = "Username" arg = "Username"
default: default:
return nil, fberrors.ErrInvalidDataType return nil, fbErrors.ErrInvalidDataType
} }
err = st.db.One(arg, i, user) err = st.db.One(arg, i, user)
if err != nil { if err != nil {
if errors.Is(err, storm.ErrNotFound) { if errors.Is(err, storm.ErrNotFound) {
return nil, fberrors.ErrNotExist return nil, fbErrors.ErrNotExist
} }
return nil, err return nil, err
} }
@ -44,7 +44,7 @@ func (st usersBackend) Gets() ([]*users.User, error) {
var allUsers []*users.User var allUsers []*users.User
err := st.db.All(&allUsers) err := st.db.All(&allUsers)
if errors.Is(err, storm.ErrNotFound) { if errors.Is(err, storm.ErrNotFound) {
return nil, fberrors.ErrNotExist return nil, fbErrors.ErrNotExist
} }
if err != nil { if err != nil {
@ -76,7 +76,7 @@ func (st usersBackend) Update(user *users.User, fields ...string) error {
func (st usersBackend) Save(user *users.User) error { func (st usersBackend) Save(user *users.User) error {
err := st.db.Save(user) err := st.db.Save(user)
if errors.Is(err, storm.ErrAlreadyExists) { if errors.Is(err, storm.ErrAlreadyExists) {
return fberrors.ErrExist return fbErrors.ErrExist
} }
return err return err
} }

Some files were not shown because too many files have changed in this diff Show More