Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
037e29a708 | ||
|
|
fda8a99292 | ||
|
|
208535a8cc | ||
|
|
464b581953 | ||
|
|
20312ff18e | ||
|
|
219582c0b0 | ||
|
|
4fd18a382c | ||
|
|
94ec786d34 | ||
|
|
25e9b85259 | ||
|
|
ffa893e9ac | ||
|
|
b8151a038a | ||
|
|
943e5340d0 | ||
|
|
88aa56f53b | ||
|
|
a12a612970 | ||
|
|
a2d80c62c1 | ||
|
|
1faa21844f | ||
|
|
7a93b2a062 | ||
|
|
032d6c7520 | ||
|
|
9595f3939c | ||
|
|
60b1ee8bb9 | ||
|
|
79d1aa9229 | ||
|
|
20bfd131c6 | ||
|
|
f89975603e | ||
|
|
2d3b64ecf6 | ||
|
|
579756dbb5 | ||
|
|
c11c986b73 | ||
|
|
3fdca6dfd9 | ||
|
|
cf966578d8 | ||
|
|
6d4c867672 | ||
|
|
169e97e6f9 | ||
|
|
7fa3432f25 | ||
|
|
e9ce7fa5aa | ||
|
|
849f5ad443 | ||
|
|
c1715992bd | ||
|
|
e4f2503298 | ||
|
|
152f8302f7 | ||
|
|
4cbb4b73af | ||
|
|
58cc874828 | ||
|
|
124def5cd7 | ||
|
|
2d88c06761 | ||
|
|
204a3f0eea | ||
|
|
f029c3005e | ||
|
|
a6934e40ff | ||
|
|
98662ac5ec | ||
|
|
5cf8ce8db5 | ||
|
|
062dc414f8 | ||
|
|
63582b644c |
87
CHANGELOG.md
87
CHANGELOG.md
@@ -2,6 +2,93 @@
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
## Multistage build: First stage fetches dependencies
|
||||
FROM alpine:3.22 AS fetcher
|
||||
FROM alpine:3.23 AS fetcher
|
||||
|
||||
# install and copy ca-certificates, mailcap, and tini-static; download JSON.sh
|
||||
RUN apk update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ghcr.io/linuxserver/baseimage-alpine:3.22
|
||||
FROM ghcr.io/linuxserver/baseimage-alpine:3.23
|
||||
|
||||
RUN apk update && \
|
||||
apk --no-cache add ca-certificates mailcap jq libcap
|
||||
|
||||
41
auth/hook.go
41
auth/hook.go
@@ -11,7 +11,7 @@ import (
|
||||
"slices"
|
||||
"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/settings"
|
||||
"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
|
||||
func (a *HookAuth) SaveUser() (*users.User, error) {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -158,16 +158,17 @@ func (a *HookAuth) SaveUser() (*users.User, error) {
|
||||
|
||||
// create user with the provided credentials
|
||||
d := &users.User{
|
||||
Username: a.Cred.Username,
|
||||
Password: pass,
|
||||
Scope: a.Settings.Defaults.Scope,
|
||||
Locale: a.Settings.Defaults.Locale,
|
||||
ViewMode: a.Settings.Defaults.ViewMode,
|
||||
SingleClick: a.Settings.Defaults.SingleClick,
|
||||
Sorting: a.Settings.Defaults.Sorting,
|
||||
Perm: a.Settings.Defaults.Perm,
|
||||
Commands: a.Settings.Defaults.Commands,
|
||||
HideDotfiles: a.Settings.Defaults.HideDotfiles,
|
||||
Username: a.Cred.Username,
|
||||
Password: pass,
|
||||
Scope: a.Settings.Defaults.Scope,
|
||||
Locale: a.Settings.Defaults.Locale,
|
||||
ViewMode: a.Settings.Defaults.ViewMode,
|
||||
SingleClick: a.Settings.Defaults.SingleClick,
|
||||
RedirectAfterCopyMove: a.Settings.Defaults.RedirectAfterCopyMove,
|
||||
Sorting: a.Settings.Defaults.Sorting,
|
||||
Perm: a.Settings.Defaults.Perm,
|
||||
Commands: a.Settings.Defaults.Commands,
|
||||
HideDotfiles: a.Settings.Defaults.HideDotfiles,
|
||||
}
|
||||
u = a.GetUser(d)
|
||||
|
||||
@@ -219,13 +220,14 @@ func (a *HookAuth) GetUser(d *users.User) *users.User {
|
||||
Download: isAdmin || a.Fields.GetBoolean("user.perm.download", d.Perm.Download),
|
||||
}
|
||||
user := users.User{
|
||||
ID: d.ID,
|
||||
Username: d.Username,
|
||||
Password: d.Password,
|
||||
Scope: a.Fields.GetString("user.scope", d.Scope),
|
||||
Locale: a.Fields.GetString("user.locale", d.Locale),
|
||||
ViewMode: users.ViewMode(a.Fields.GetString("user.viewMode", string(d.ViewMode))),
|
||||
SingleClick: a.Fields.GetBoolean("user.singleClick", d.SingleClick),
|
||||
ID: d.ID,
|
||||
Username: d.Username,
|
||||
Password: d.Password,
|
||||
Scope: a.Fields.GetString("user.scope", d.Scope),
|
||||
Locale: a.Fields.GetString("user.locale", d.Locale),
|
||||
ViewMode: users.ViewMode(a.Fields.GetString("user.viewMode", string(d.ViewMode))),
|
||||
SingleClick: a.Fields.GetBoolean("user.singleClick", d.SingleClick),
|
||||
RedirectAfterCopyMove: a.Fields.GetBoolean("user.redirectAfterCopyMove", d.RedirectAfterCopyMove),
|
||||
Sorting: files.Sorting{
|
||||
Asc: a.Fields.GetBoolean("user.sorting.asc", d.Sorting.Asc),
|
||||
By: a.Fields.GetString("user.sorting.by", d.Sorting.By),
|
||||
@@ -251,6 +253,7 @@ var validHookFields = []string{
|
||||
"user.locale",
|
||||
"user.viewMode",
|
||||
"user.singleClick",
|
||||
"user.redirectAfterCopyMove",
|
||||
"user.sorting.by",
|
||||
"user.sorting.asc",
|
||||
"user.commands",
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"errors"
|
||||
"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/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) {
|
||||
username := r.Header.Get(a.Header)
|
||||
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 user, err
|
||||
|
||||
@@ -2,7 +2,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
nerrors "errors"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/auth"
|
||||
"github.com/filebrowser/filebrowser/v2/errors"
|
||||
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
"github.com/filebrowser/filebrowser/v2/settings"
|
||||
)
|
||||
|
||||
@@ -99,12 +99,12 @@ func getProxyAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (a
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if header == "" {
|
||||
if header == "" && defaultAuther != nil {
|
||||
header = defaultAuther["header"].(string)
|
||||
}
|
||||
|
||||
if header == "" {
|
||||
return nil, nerrors.New("you must set the flag 'auth.header' for method 'proxy'")
|
||||
return nil, errors.New("you must set the flag 'auth.header' for method 'proxy'")
|
||||
}
|
||||
|
||||
return &auth.ProxyAuth{Header: header}, nil
|
||||
@@ -163,7 +163,7 @@ func getHookAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (au
|
||||
}
|
||||
|
||||
if command == "" {
|
||||
return nil, nerrors.New("you must set the flag 'auth.command' for method 'hook'")
|
||||
return nil, errors.New("you must set the flag 'auth.command' for method 'hook'")
|
||||
}
|
||||
|
||||
return &auth.HookAuth{Command: command}, nil
|
||||
@@ -186,7 +186,7 @@ func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (settings.
|
||||
case auth.MethodHookAuth:
|
||||
auther, err = getHookAuth(flags, defaultAuther)
|
||||
default:
|
||||
return "", nil, errors.ErrInvalidAuthMethod
|
||||
return "", nil, fberrors.ErrInvalidAuthMethod
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -240,6 +240,7 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
|
||||
fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale)
|
||||
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, "\tRedirect after Copy/Move:\t%t\n", set.Defaults.RedirectAfterCopyMove)
|
||||
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, "\tCommands:\t%s\n", strings.Join(set.Defaults.Commands, " "))
|
||||
@@ -308,6 +309,9 @@ func getSettings(flags *pflag.FlagSet, set *settings.Settings, ser *settings.Ser
|
||||
case "disableTypeDetectionByHeader":
|
||||
ser.TypeDetectionByHeader, err = flags.GetBool(flag.Name)
|
||||
ser.TypeDetectionByHeader = !ser.TypeDetectionByHeader
|
||||
case "disableImageResolutionCalc":
|
||||
ser.ImageResolutionCal, err = flags.GetBool(flag.Name)
|
||||
ser.ImageResolutionCal = !ser.ImageResolutionCal
|
||||
|
||||
// Settings flags from [addConfigFlags]
|
||||
case "signup":
|
||||
@@ -361,7 +365,7 @@ func getSettings(flags *pflag.FlagSet, set *settings.Settings, ser *settings.Ser
|
||||
flags.Visit(visit)
|
||||
}
|
||||
|
||||
err := nerrors.Join(errs...)
|
||||
err := errors.Join(errs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -53,6 +53,10 @@ The path must be for a json or yaml file.`,
|
||||
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
|
||||
err = st.Settings.Save(file.Settings)
|
||||
if err != nil {
|
||||
|
||||
20
cmd/root.go
20
cmd/root.go
@@ -108,6 +108,7 @@ func addServerFlags(flags *pflag.FlagSet) {
|
||||
flags.Bool("disablePreviewResize", false, "disable resize of image previews")
|
||||
flags.Bool("disableExec", true, "disables Command Runner feature")
|
||||
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{
|
||||
@@ -135,6 +136,11 @@ file named .filebrowser.{json, toml, yaml, yml} in the following directories:
|
||||
- $HOME/
|
||||
- /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:
|
||||
|
||||
- Flags
|
||||
@@ -331,6 +337,10 @@ func getServerSettings(v *viper.Viper, st *storage.Storage) (*settings.Server, e
|
||||
server.TypeDetectionByHeader = !v.GetBool("disableTypeDetectionByHeader")
|
||||
}
|
||||
|
||||
if v.IsSet("disableImageResolutionCalc") {
|
||||
server.ImageResolutionCal = !v.GetBool("disableImageResolutionCalc")
|
||||
}
|
||||
|
||||
if v.IsSet("disableExec") {
|
||||
server.EnableExec = !v.GetBool("disableExec")
|
||||
}
|
||||
@@ -383,10 +393,11 @@ func quickSetup(v *viper.Viper, s *storage.Storage) error {
|
||||
MinimumPasswordLength: settings.DefaultMinimumPasswordLength,
|
||||
UserHomeBasePath: settings.DefaultUsersHomeBasePath,
|
||||
Defaults: settings.UserDefaults{
|
||||
Scope: ".",
|
||||
Locale: "en",
|
||||
SingleClick: false,
|
||||
AceEditorTheme: v.GetString("defaults.aceEditorTheme"),
|
||||
Scope: ".",
|
||||
Locale: "en",
|
||||
SingleClick: false,
|
||||
RedirectAfterCopyMove: true,
|
||||
AceEditorTheme: v.GetString("defaults.aceEditorTheme"),
|
||||
Perm: users.Permissions{
|
||||
Admin: false,
|
||||
Execute: true,
|
||||
@@ -439,6 +450,7 @@ func quickSetup(v *viper.Viper, s *storage.Storage) error {
|
||||
ResizePreview: !v.GetBool("disablePreviewResize"),
|
||||
EnableExec: !v.GetBool("disableExec"),
|
||||
TypeDetectionByHeader: !v.GetBool("disableTypeDetectionByHeader"),
|
||||
ImageResolutionCal: !v.GetBool("disableImageResolutionCalc"),
|
||||
}
|
||||
|
||||
err = s.Settings.SaveServer(ser)
|
||||
|
||||
@@ -30,13 +30,14 @@ 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")
|
||||
|
||||
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\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%t\t\n",
|
||||
u.ID,
|
||||
u.Username,
|
||||
u.Scope,
|
||||
u.Locale,
|
||||
u.ViewMode,
|
||||
u.SingleClick,
|
||||
u.RedirectAfterCopyMove,
|
||||
u.Perm.Admin,
|
||||
u.Perm.Execute,
|
||||
u.Perm.Create,
|
||||
@@ -77,6 +78,7 @@ func addUserFlags(flags *pflag.FlagSet) {
|
||||
flags.String("locale", "en", "locale for users")
|
||||
flags.String("viewMode", string(users.ListViewMode), "view mode for users")
|
||||
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("hideDotfiles", false, "hide dotfiles")
|
||||
flags.String("aceEditorTheme", "", "ace editor's syntax highlighting theme for users")
|
||||
@@ -110,6 +112,8 @@ func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all
|
||||
defaults.ViewMode, err = getAndParseViewMode(flags)
|
||||
case "singleClick":
|
||||
defaults.SingleClick, err = flags.GetBool(flag.Name)
|
||||
case "redirectAfterCopyMove":
|
||||
defaults.RedirectAfterCopyMove, err = flags.GetBool(flag.Name)
|
||||
case "aceEditorTheme":
|
||||
defaults.AceEditorTheme, err = flags.GetString(flag.Name)
|
||||
case "perm.admin":
|
||||
|
||||
@@ -52,13 +52,14 @@ options you want to change.`,
|
||||
}
|
||||
|
||||
defaults := settings.UserDefaults{
|
||||
Scope: user.Scope,
|
||||
Locale: user.Locale,
|
||||
ViewMode: user.ViewMode,
|
||||
SingleClick: user.SingleClick,
|
||||
Perm: user.Perm,
|
||||
Sorting: user.Sorting,
|
||||
Commands: user.Commands,
|
||||
Scope: user.Scope,
|
||||
Locale: user.Locale,
|
||||
ViewMode: user.ViewMode,
|
||||
SingleClick: user.SingleClick,
|
||||
RedirectAfterCopyMove: user.RedirectAfterCopyMove,
|
||||
Perm: user.Perm,
|
||||
Sorting: user.Sorting,
|
||||
Commands: user.Commands,
|
||||
}
|
||||
|
||||
err = getUserDefaults(flags, &defaults, false)
|
||||
@@ -70,6 +71,7 @@ options you want to change.`,
|
||||
user.Locale = defaults.Locale
|
||||
user.ViewMode = defaults.ViewMode
|
||||
user.SingleClick = defaults.SingleClick
|
||||
user.RedirectAfterCopyMove = defaults.RedirectAfterCopyMove
|
||||
user.Perm = defaults.Perm
|
||||
user.Commands = defaults.Commands
|
||||
user.Sorting = defaults.Sorting
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package errors
|
||||
package fberrors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -6,22 +6,23 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrEmptyKey = errors.New("empty key")
|
||||
ErrExist = errors.New("the resource already exists")
|
||||
ErrNotExist = errors.New("the resource does not exist")
|
||||
ErrEmptyPassword = errors.New("password is empty")
|
||||
ErrEasyPassword = errors.New("password is too easy")
|
||||
ErrEmptyUsername = errors.New("username is empty")
|
||||
ErrEmptyRequest = errors.New("empty request")
|
||||
ErrScopeIsRelative = errors.New("scope is a relative path")
|
||||
ErrInvalidDataType = errors.New("invalid data type")
|
||||
ErrIsDirectory = errors.New("file is directory")
|
||||
ErrInvalidOption = errors.New("invalid option")
|
||||
ErrInvalidAuthMethod = errors.New("invalid auth method")
|
||||
ErrPermissionDenied = errors.New("permission denied")
|
||||
ErrInvalidRequestParams = errors.New("invalid request params")
|
||||
ErrSourceIsParent = errors.New("source is parent")
|
||||
ErrRootUserDeletion = errors.New("user with id 1 can't be deleted")
|
||||
ErrEmptyKey = errors.New("empty key")
|
||||
ErrExist = errors.New("the resource already exists")
|
||||
ErrNotExist = errors.New("the resource does not exist")
|
||||
ErrEmptyPassword = errors.New("password is empty")
|
||||
ErrEasyPassword = errors.New("password is too easy")
|
||||
ErrEmptyUsername = errors.New("username is empty")
|
||||
ErrEmptyRequest = errors.New("empty request")
|
||||
ErrScopeIsRelative = errors.New("scope is a relative path")
|
||||
ErrInvalidDataType = errors.New("invalid data type")
|
||||
ErrIsDirectory = errors.New("file is directory")
|
||||
ErrInvalidOption = errors.New("invalid option")
|
||||
ErrInvalidAuthMethod = errors.New("invalid auth method")
|
||||
ErrPermissionDenied = errors.New("permission denied")
|
||||
ErrInvalidRequestParams = errors.New("invalid request params")
|
||||
ErrSourceIsParent = errors.New("source is parent")
|
||||
ErrRootUserDeletion = errors.New("user with id 1 can't be deleted")
|
||||
ErrCurrentPasswordIncorrect = errors.New("the current password is incorrect")
|
||||
)
|
||||
|
||||
type ErrShortPassword struct {
|
||||
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
|
||||
"github.com/spf13/afero"
|
||||
|
||||
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
"github.com/filebrowser/filebrowser/v2/rules"
|
||||
)
|
||||
|
||||
@@ -60,6 +60,7 @@ type FileOptions struct {
|
||||
Modify bool
|
||||
Expand bool
|
||||
ReadHeader bool
|
||||
CalcImgRes bool
|
||||
Token string
|
||||
Checker rules.Checker
|
||||
Content bool
|
||||
@@ -90,13 +91,13 @@ func NewFileInfo(opts *FileOptions) (*FileInfo, error) {
|
||||
|
||||
if opts.Expand {
|
||||
if file.IsDir {
|
||||
if err := file.readListing(opts.Checker, opts.ReadHeader); err != nil {
|
||||
if err := file.readListing(opts.Checker, opts.ReadHeader, opts.CalcImgRes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return file, nil
|
||||
}
|
||||
|
||||
err = file.detectType(opts.Modify, opts.Content, true)
|
||||
err = file.detectType(opts.Modify, opts.Content, true, opts.CalcImgRes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -168,7 +169,7 @@ func stat(opts *FileOptions) (*FileInfo, error) {
|
||||
// algorithm. The checksums data is saved on File object.
|
||||
func (i *FileInfo) Checksum(algo string) error {
|
||||
if i.IsDir {
|
||||
return fbErrors.ErrIsDirectory
|
||||
return fberrors.ErrIsDirectory
|
||||
}
|
||||
|
||||
if i.Checksums == nil {
|
||||
@@ -193,7 +194,7 @@ func (i *FileInfo) Checksum(algo string) error {
|
||||
case "sha512":
|
||||
h = sha512.New()
|
||||
default:
|
||||
return fbErrors.ErrInvalidOption
|
||||
return fberrors.ErrInvalidOption
|
||||
}
|
||||
|
||||
_, err = io.Copy(h, reader)
|
||||
@@ -218,7 +219,7 @@ func (i *FileInfo) RealPath() string {
|
||||
return i.Path
|
||||
}
|
||||
|
||||
func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
|
||||
func (i *FileInfo) detectType(modify, saveContent, readHeader bool, calcImgRes bool) error {
|
||||
if IsNamedPipe(i.Mode) {
|
||||
i.Type = "blob"
|
||||
return nil
|
||||
@@ -249,11 +250,13 @@ func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
|
||||
return nil
|
||||
case strings.HasPrefix(mimetype, "image"):
|
||||
i.Type = "image"
|
||||
resolution, err := calculateImageResolution(i.Fs, i.Path)
|
||||
if err != nil {
|
||||
log.Printf("Error calculating image resolution: %v", err)
|
||||
} else {
|
||||
i.Resolution = resolution
|
||||
if calcImgRes {
|
||||
resolution, err := calculateImageResolution(i.Fs, i.Path)
|
||||
if err != nil {
|
||||
log.Printf("Error calculating image resolution: %v", err)
|
||||
} else {
|
||||
i.Resolution = resolution
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case strings.HasSuffix(mimetype, "pdf"):
|
||||
@@ -387,7 +390,7 @@ func (i *FileInfo) addSubtitle(fPath string) {
|
||||
i.Subtitles = append(i.Subtitles, fPath)
|
||||
}
|
||||
|
||||
func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
||||
func (i *FileInfo) readListing(checker rules.Checker, readHeader bool, calcImgRes bool) error {
|
||||
afs := &afero.Afero{Fs: i.Fs}
|
||||
dir, err := afs.ReadDir(i.Path)
|
||||
if err != nil {
|
||||
@@ -434,7 +437,7 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
||||
currentDir: dir,
|
||||
}
|
||||
|
||||
if !file.IsDir && strings.HasPrefix(mime.TypeByExtension(file.Extension), "image/") {
|
||||
if !file.IsDir && strings.HasPrefix(mime.TypeByExtension(file.Extension), "image/") && calcImgRes {
|
||||
resolution, err := calculateImageResolution(file.Fs, file.Path)
|
||||
if err != nil {
|
||||
log.Printf("Error calculating resolution for image %s: %v", file.Path, err)
|
||||
@@ -451,7 +454,7 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
||||
if isInvalidLink {
|
||||
file.Type = "invalid_link"
|
||||
} else {
|
||||
err := file.detectType(true, false, readHeader)
|
||||
err := file.detectType(true, false, readHeader, calcImgRes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -71,5 +71,5 @@
|
||||
"vite-plugin-compression2": "^2.3.1",
|
||||
"vue-tsc": "^3.1.3"
|
||||
},
|
||||
"packageManager": "pnpm@10.24.0+sha512.01ff8ae71b4419903b65c60fb2dc9d34cf8bb6e06d03bde112ef38f7a34d6904c424ba66bea5cdcf12890230bf39f9580473140ed9c946fef328b6e5238a345a"
|
||||
"packageManager": "pnpm@10.28.0+sha512.05df71d1421f21399e053fde567cea34d446fa02c76571441bfc1c7956e98e363088982d940465fd34480d4d90a0668bc12362f8aa88000a64e83d0b0e47be48"
|
||||
}
|
||||
|
||||
1404
frontend/pnpm-lock.yaml
generated
1404
frontend/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -41,12 +41,12 @@ export function download(
|
||||
let url = `${baseURL}/api/public/dl/${hash}`;
|
||||
|
||||
if (files.length === 1) {
|
||||
url += encodeURIComponent(files[0]) + "?";
|
||||
url += files[0] + "?";
|
||||
} else {
|
||||
let arg = "";
|
||||
|
||||
for (const file of files) {
|
||||
arg += encodeURIComponent(file) + ",";
|
||||
arg += file + ",";
|
||||
}
|
||||
|
||||
arg = arg.substring(0, arg.length - 1);
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import { fetchURL, removePrefix } from "./utils";
|
||||
import { fetchURL, removePrefix, StatusError } from "./utils";
|
||||
import url from "../utils/url";
|
||||
|
||||
export default async function search(base: string, query: string) {
|
||||
export default async function search(
|
||||
base: string,
|
||||
query: string,
|
||||
signal: AbortSignal,
|
||||
callback: (item: ResourceItem) => void
|
||||
) {
|
||||
base = removePrefix(base);
|
||||
query = encodeURIComponent(query);
|
||||
|
||||
@@ -9,19 +14,60 @@ export default async function search(base: string, query: string) {
|
||||
base += "/";
|
||||
}
|
||||
|
||||
const res = await fetchURL(`/api/search${base}?query=${query}`, {});
|
||||
const res = await fetchURL(`/api/search${base}?query=${query}`, { signal });
|
||||
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;
|
||||
|
||||
let data = await res.json();
|
||||
|
||||
data = data.map((item: ResourceItem & { dir: boolean }) => {
|
||||
item.url = `/files${base}` + url.encodePath(item.path);
|
||||
|
||||
if (item.dir) {
|
||||
item.url += "/";
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
});
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
// Check if the error is an intentional cancellation
|
||||
if (e instanceof Error && e.name === "AbortError") {
|
||||
throw new StatusError("000 No connection", 0, true);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,13 @@ export async function get(id: number) {
|
||||
return fetchJSON<IUser>(`/api/users/${id}`, {});
|
||||
}
|
||||
|
||||
export async function create(user: IUser) {
|
||||
export async function create(user: IUser, currentPassword: string) {
|
||||
const res = await fetchURL(`/api/users`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
what: "user",
|
||||
which: [],
|
||||
current_password: currentPassword,
|
||||
data: user,
|
||||
}),
|
||||
});
|
||||
@@ -25,12 +26,17 @@ export async function create(user: IUser) {
|
||||
throw new StatusError(await res.text(), res.status);
|
||||
}
|
||||
|
||||
export async function update(user: Partial<IUser>, which = ["all"]) {
|
||||
export async function update(
|
||||
user: Partial<IUser>,
|
||||
which = ["all"],
|
||||
currentPassword: string | null = null
|
||||
) {
|
||||
await fetchURL(`/api/users/${user.id}`, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({
|
||||
what: "user",
|
||||
which: which,
|
||||
...(currentPassword != null ? { current_password: currentPassword } : {}),
|
||||
data: user,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
v-if="active"
|
||||
class="action"
|
||||
@click="close"
|
||||
:aria-label="$t('buttons.close')"
|
||||
:title="$t('buttons.close')"
|
||||
:aria-label="closeButtonTitle"
|
||||
:title="closeButtonTitle"
|
||||
>
|
||||
<i class="material-icons">arrow_back</i>
|
||||
<i v-if="ongoing" class="material-icons">stop_circle</i>
|
||||
<i v-else class="material-icons">arrow_back</i>
|
||||
</button>
|
||||
<i v-else class="material-icons">search</i>
|
||||
<input
|
||||
@@ -21,6 +22,15 @@
|
||||
:aria-label="$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 id="result" ref="result">
|
||||
@@ -57,9 +67,6 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p id="renew">
|
||||
<i class="material-icons spin">autorenew</i>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -70,10 +77,11 @@ import { useLayoutStore } from "@/stores/layout";
|
||||
|
||||
import url from "@/utils/url";
|
||||
import { search } from "@/api";
|
||||
import { computed, inject, onMounted, ref, watch } from "vue";
|
||||
import { computed, inject, onMounted, ref, watch, onUnmounted } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useRoute } from "vue-router";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { StatusError } from "@/api/utils";
|
||||
|
||||
const boxes = {
|
||||
image: { label: "images", icon: "insert_photo" },
|
||||
@@ -84,6 +92,7 @@ const boxes = {
|
||||
|
||||
const layoutStore = useLayoutStore();
|
||||
const fileStore = useFileStore();
|
||||
let searchAbortController = new AbortController();
|
||||
|
||||
const { currentPromptName } = storeToRefs(layoutStore);
|
||||
|
||||
@@ -124,9 +133,7 @@ watch(currentPromptName, (newVal, oldVal) => {
|
||||
});
|
||||
|
||||
watch(prompt, () => {
|
||||
if (results.value.length) {
|
||||
reset();
|
||||
}
|
||||
reset();
|
||||
});
|
||||
|
||||
// ...mapState(useFileStore, ["isListing"]),
|
||||
@@ -149,6 +156,10 @@ const filteredResults = computed(() => {
|
||||
return results.value.slice(0, resultsCount.value);
|
||||
});
|
||||
|
||||
const closeButtonTitle = computed(() => {
|
||||
return ongoing.value ? t("buttons.stopSearch") : t("buttons.close");
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
if (result.value === null) {
|
||||
return;
|
||||
@@ -164,14 +175,23 @@ onMounted(() => {
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
abortLastSearch();
|
||||
});
|
||||
|
||||
const open = () => {
|
||||
!active.value && layoutStore.showHover("search");
|
||||
};
|
||||
|
||||
const close = (event: Event) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
layoutStore.closeHovers();
|
||||
if (ongoing.value) {
|
||||
abortLastSearch();
|
||||
ongoing.value = false;
|
||||
} else {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
layoutStore.closeHovers();
|
||||
}
|
||||
};
|
||||
|
||||
const keyup = (event: KeyboardEvent) => {
|
||||
@@ -188,11 +208,16 @@ const init = (string: string) => {
|
||||
};
|
||||
|
||||
const reset = () => {
|
||||
abortLastSearch();
|
||||
ongoing.value = false;
|
||||
resultsCount.value = 50;
|
||||
results.value = [];
|
||||
};
|
||||
|
||||
const abortLastSearch = () => {
|
||||
searchAbortController.abort();
|
||||
};
|
||||
|
||||
const submit = async (event: Event) => {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -208,8 +233,16 @@ const submit = async (event: Event) => {
|
||||
ongoing.value = true;
|
||||
|
||||
try {
|
||||
results.value = await search(path, prompt.value);
|
||||
abortLastSearch();
|
||||
searchAbortController = new AbortController();
|
||||
results.value = [];
|
||||
await search(path, prompt.value, searchAbortController.signal, (item) =>
|
||||
results.value.push(item)
|
||||
);
|
||||
} catch (error: any) {
|
||||
if (error instanceof StatusError && error.is_canceled) {
|
||||
return;
|
||||
}
|
||||
$showError(error);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,12 +8,7 @@
|
||||
<i class="material-icons">description</i>
|
||||
<p>{{ $t("files.lonely") }}</p>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="csv-table-container"
|
||||
@wheel.stop
|
||||
@touchmove.stop
|
||||
>
|
||||
<div v-else class="csv-table-container" @wheel.stop @touchmove.stop>
|
||||
<table class="csv-table">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -30,9 +25,31 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div v-if="data.rows.length > 100" class="csv-info">
|
||||
<i class="material-icons">info</i>
|
||||
<span>Showing {{ data.rows.length }} rows</span>
|
||||
<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>
|
||||
@@ -40,7 +57,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { parseCSV, type CsvData } from "@/utils/csv";
|
||||
import { computed } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
|
||||
interface Props {
|
||||
content: string;
|
||||
@@ -51,9 +68,11 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
error: "",
|
||||
});
|
||||
|
||||
const columnSeparator = ref([","]);
|
||||
|
||||
const data = computed<CsvData>(() => {
|
||||
try {
|
||||
return parseCSV(props.content);
|
||||
return parseCSV(props.content, columnSeparator.value);
|
||||
} catch (e) {
|
||||
console.error("Failed to parse CSV:", e);
|
||||
return { headers: [], rows: [] };
|
||||
@@ -66,7 +85,11 @@ const displayError = computed(() => {
|
||||
return props.error;
|
||||
}
|
||||
// Check for parse errors
|
||||
if (props.content && props.content.trim().length > 0 && data.value.headers.length === 0) {
|
||||
if (
|
||||
props.content &&
|
||||
props.content.trim().length > 0 &&
|
||||
data.value.headers.length === 0
|
||||
) {
|
||||
return "Failed to parse CSV file";
|
||||
}
|
||||
return null;
|
||||
@@ -182,6 +205,18 @@ const displayError = computed(() => {
|
||||
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;
|
||||
@@ -195,6 +230,21 @@ const displayError = computed(() => {
|
||||
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);
|
||||
|
||||
@@ -265,7 +265,15 @@ const click = (event: Event | KeyboardEvent) => {
|
||||
}
|
||||
|
||||
if (fileStore.selected.indexOf(props.index) !== -1) {
|
||||
fileStore.removeSelected(props.index);
|
||||
if (
|
||||
(event as KeyboardEvent).ctrlKey ||
|
||||
(event as KeyboardEvent).metaKey ||
|
||||
fileStore.multiple
|
||||
) {
|
||||
fileStore.removeSelected(props.index);
|
||||
} else {
|
||||
fileStore.selected = [props.index];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -291,7 +299,6 @@ const click = (event: Event | KeyboardEvent) => {
|
||||
}
|
||||
|
||||
if (
|
||||
!singleClick.value &&
|
||||
!(event as KeyboardEvent).ctrlKey &&
|
||||
!(event as KeyboardEvent).metaKey &&
|
||||
!fileStore.multiple
|
||||
|
||||
@@ -109,7 +109,8 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$router.push({ path: this.dest });
|
||||
if (this.user.redirectAfterCopyMove)
|
||||
this.$router.push({ path: this.dest });
|
||||
})
|
||||
.catch((e) => {
|
||||
buttons.done("copy");
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, nextTick, defineProps } from "vue";
|
||||
import { ref, computed, watch, nextTick } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useFileStore } from "@/stores/file";
|
||||
import url from "@/utils/url";
|
||||
|
||||
@@ -79,7 +79,7 @@ export default {
|
||||
computed: {
|
||||
...mapState(useFileStore, ["req", "selected"]),
|
||||
...mapState(useAuthStore, ["user"]),
|
||||
...mapWritableState(useFileStore, ["preselect"]),
|
||||
...mapWritableState(useFileStore, ["reload", "preselect"]),
|
||||
excludedFolders() {
|
||||
return this.selected
|
||||
.filter((idx) => this.req.items[idx].isDir)
|
||||
@@ -108,7 +108,9 @@ export default {
|
||||
.then(() => {
|
||||
buttons.success("move");
|
||||
this.preselect = removePrefix(items[0].to);
|
||||
this.$router.push({ path: this.dest });
|
||||
if (this.user.redirectAfterCopyMove)
|
||||
this.$router.push({ path: this.dest });
|
||||
else this.reload = true;
|
||||
})
|
||||
.catch((e) => {
|
||||
buttons.done("move");
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"ok": "موافق",
|
||||
"permalink": "الحصول على رابط دائم",
|
||||
"previous": "السابق",
|
||||
"preview": "Preview",
|
||||
"preview": "معاينة",
|
||||
"publish": "نشر",
|
||||
"rename": "إعادة تسمية",
|
||||
"replace": "استبدال",
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "رفع",
|
||||
"openFile": "فتح الملف",
|
||||
"discardChanges": "إلغاء التغييرات",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"stopSearch": "توقف عن البحث",
|
||||
"saveChanges": "حفظ التغييرات",
|
||||
"editAsText": "تعديل على شكل نص",
|
||||
"increaseFontSize": "زيادة حجم الخط",
|
||||
"decreaseFontSize": "تصغير حجم الخط"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "تحميل الملف",
|
||||
@@ -77,8 +80,15 @@
|
||||
"sortByName": "الترتيب باﻹسم",
|
||||
"sortBySize": "الترتيب بالحجم",
|
||||
"noPreview": "لا يوجد عرض مسبق لهذا الملف.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"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": {
|
||||
"click": "حدد الملف أو المجلد",
|
||||
@@ -128,7 +138,7 @@
|
||||
"filesSelected": "تم تحديد {count} ملفات.",
|
||||
"lastModified": "آخر تعديل",
|
||||
"move": "نقل",
|
||||
"moveMessage": "إختر مكان جديد للملفات أو المجلدات المراد نقلها:",
|
||||
"moveMessage": "اختر منزلاً جديداً لملفك (ملفاتك)/مجلدك (مجلداتك):",
|
||||
"newArchetype": "إنشاء منشور من المنشور اﻷصلي. الملف سيتم انشاءه في مجلد المحتويات.",
|
||||
"newDir": "مجلد جديد",
|
||||
"newDirMessage": "أدخل اسم المجلد الجديد.",
|
||||
@@ -179,15 +189,15 @@
|
||||
"commandRunner": "منفذ اﻷوامر",
|
||||
"commandRunnerHelp": "هنا بإمكانك تعيين اﻷوامر التي سيتم تنفيذها في اﻷحداث المسماة. يجب كتابة أمر واحد في كل سطر. ستكون المتغيرات البيئية (env) {0} و {1} متاحة، حيث {0} نسبي لـ {1}. لمزيد من المعلومات حول هذه الميزة و المتغيرات البيئية المتاحة، يرجى قراءة {2}.",
|
||||
"commandsUpdated": "تم تحديث اﻷوامر",
|
||||
"createUserDir": "إنشاء مجلد المستخدم (home) تلقائياً عند إنشاء مستخدم جديد",
|
||||
"createUserDir": "إنشاء مجلد المستخدم الرئيسي تلقائياً عند إنشاء مستخدم جديد",
|
||||
"minimumPasswordLength": "Minimum password length",
|
||||
"tusUploads": "التحميلات المتقطعة",
|
||||
"tusUploadsHelp": "يدعم متصفح الملفات تحميل الملفات المتقطعة، مما يسمح بتحميلات الملفات بشكل فعال و موثوق و قابلة للمتابغة و متقطعة حتى على الشبكات غير الموثوقة.",
|
||||
"tusUploadsChunkSize": "يشير إلى الحد اﻷقصى لحجم الطلب (سيتم استخدام التحميل المباشر للتحميلات صغيرة الخحم). يمكنك إدخال عدد صحيح عادي يدل على الحجم بوحدة البايت أو نمظ مثل10MB, 1GB, إلخ.",
|
||||
"tusUploadsRetryCount": "عدد مرات إعادة المحاولة إذا فشلت عملية تحميل القطعة.",
|
||||
"userHomeBasePath": "المسار الرئيسي لمجلد المستخدم (home)",
|
||||
"userHomeBasePath": "المسار الرئيسي لمجلد المستخدم الرئيسي",
|
||||
"userScopeGenerationPlaceholder": "سيتم تعيين نطاق المستخدم تلقائياً",
|
||||
"createUserHomeDirectory": "إنشاء مجلد المستخدم (home)",
|
||||
"createUserHomeDirectory": "إنشاء مجلد المستخدم الرئيسي",
|
||||
"customStylesheet": "ستايل مخصص",
|
||||
"defaultUserDescription": "هذه اﻹعدادات اﻹفتراضية للمستخدمين الجدد.",
|
||||
"disableExternalLinks": "تعطيل الروابط الخارجية (بإسثناء الوثائق)",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "إدارة المستخدمين",
|
||||
"userUpdated": "تم تعديل المستخدم",
|
||||
"username": "إسم المستخدم",
|
||||
"users": "المستخدمين"
|
||||
"users": "المستخدمين",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "مساعدة",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Качи",
|
||||
"openFile": "Отвори файл",
|
||||
"discardChanges": "Изчисти",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Запиши промените",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Свали файл",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Подредба по размер",
|
||||
"noPreview": "За този файл не е наличен преглед.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "избери файл или директория",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Управление на потребители",
|
||||
"userUpdated": "Потребителя е обновен!",
|
||||
"username": "Потребителско име",
|
||||
"users": "Потребители"
|
||||
"users": "Потребители",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Помощ",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Pujar",
|
||||
"openFile": "Obrir fitxer",
|
||||
"discardChanges": "Descartar",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Descarregar fitxer",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Ordenar per mida",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "seleccionar fitxer o carpeta",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Administració d'usuaris",
|
||||
"userUpdated": "Usuari actualitzat!",
|
||||
"username": "Usuari",
|
||||
"users": "Usuaris"
|
||||
"users": "Usuaris",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Ajuda",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Nahrát",
|
||||
"openFile": "Otevřít soubor",
|
||||
"discardChanges": "Zrušit změny",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Stáhnout soubor",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Seřadit podle velikosti",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "vyberte soubor nebo adresář",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Správa uživatelů",
|
||||
"userUpdated": "Uživatel aktualizován!",
|
||||
"username": "Uživatelské jméno",
|
||||
"users": "Uživatelé"
|
||||
"users": "Uživatelé",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Nápověda",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Upload",
|
||||
"openFile": "Datei öffnen",
|
||||
"discardChanges": "Verwerfen",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"stopSearch": "Suche abbrechen",
|
||||
"saveChanges": "Änderungen speichern",
|
||||
"editAsText": "Als Text bearbeiten",
|
||||
"increaseFontSize": "Schriftgröße vergrößern",
|
||||
"decreaseFontSize": "Schriftgröße verkleinern"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Download Datei",
|
||||
@@ -77,8 +80,15 @@
|
||||
"sortByName": "Nach Namen sortieren",
|
||||
"sortBySize": "Nach Größe sortieren",
|
||||
"noPreview": "Für diese Datei ist keine Vorschau verfügbar.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"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": {
|
||||
"click": "Wähle Datei oder Ordner",
|
||||
@@ -105,9 +115,9 @@
|
||||
"username": "Benutzername",
|
||||
"usernameTaken": "Benutzername ist bereits vergeben",
|
||||
"wrongCredentials": "Falsche Zugangsdaten",
|
||||
"passwordTooShort": "Password must be at least {min} characters",
|
||||
"passwordTooShort": "Passwort muss mindestens {min} Zeichen lang sein",
|
||||
"logout_reasons": {
|
||||
"inactivity": "You have been logged out due to inactivity."
|
||||
"inactivity": "Du wurdest aufgrund von Inaktivität abgemeldet."
|
||||
}
|
||||
},
|
||||
"permanent": "Permanent",
|
||||
@@ -162,7 +172,7 @@
|
||||
"video": "Video"
|
||||
},
|
||||
"settings": {
|
||||
"aceEditorTheme": "Ace editor theme",
|
||||
"aceEditorTheme": "Ace Editor Theme",
|
||||
"admin": "Admin",
|
||||
"administrator": "Administrator",
|
||||
"allowCommands": "Befehle ausführen",
|
||||
@@ -170,7 +180,7 @@
|
||||
"allowNew": "Erstellen neuer Dateien und Ordner",
|
||||
"allowPublish": "Veröffentlichen von neuen Beiträgen und Seiten",
|
||||
"allowSignup": "Erlaube Benutzern sich zu registrieren",
|
||||
"hideLoginButton": "Hide the login button from public pages",
|
||||
"hideLoginButton": "Den Login-Button auf öffentlichen Seiten ausblenden",
|
||||
"avoidChanges": "(leer lassen, um Änderungen zu vermeiden)",
|
||||
"branding": "Design",
|
||||
"brandingDirectoryPath": "Designverzeichnispfad",
|
||||
@@ -180,7 +190,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}.",
|
||||
"commandsUpdated": "Befehle aktualisiert!",
|
||||
"createUserDir": "Automatisches Erstellen des Home-Verzeichnisses beim Anlegen neuer Benutzer",
|
||||
"minimumPasswordLength": "Minimum password length",
|
||||
"minimumPasswordLength": "Mindestlänge für Passwörter",
|
||||
"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.",
|
||||
"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",
|
||||
@@ -204,7 +214,7 @@
|
||||
"instanceName": "Instanzname",
|
||||
"language": "Sprache",
|
||||
"lockPassword": "Verhindere, dass der Benutzer sein Passwort ändert",
|
||||
"newPassword": "Ihr neues Passwort.",
|
||||
"newPassword": "Ihr neues Passwort",
|
||||
"newPasswordConfirm": "Bestätigen Sie Ihr neues Passwort",
|
||||
"newUser": "Neuer Benutzer",
|
||||
"password": "Passwort",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Benutzerverwaltung",
|
||||
"userUpdated": "Benutzer aktualisiert!",
|
||||
"username": "Nutzername",
|
||||
"users": "Nutzer"
|
||||
"users": "Nutzer",
|
||||
"currentPassword": "Ihr aktuelles Passwort"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Hilfe",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Μεταφόρτωση",
|
||||
"openFile": "Άνοιγμα αρχείου",
|
||||
"discardChanges": "Discard",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Λήψη αρχείου",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Ταξινόμηση κατά μέγεθος",
|
||||
"noPreview": "Η προεπισκόπηση δεν είναι διαθέσιμη για αυτό το αρχείο.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "επιλέξτε αρχείο ή φάκελο",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Διαχείριση χρηστών",
|
||||
"userUpdated": "Ο χρήστης ενημερώθηκε!",
|
||||
"username": "Όνομα χρήστη",
|
||||
"users": "Χρήστες"
|
||||
"users": "Χρήστες",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Βοήθεια",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Upload",
|
||||
"openFile": "Open file",
|
||||
"discardChanges": "Discard",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Download File",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Sort by size",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "select file or directory",
|
||||
@@ -222,6 +232,7 @@
|
||||
"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",
|
||||
"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",
|
||||
"ruleExample2": "blocks the access to the file named Caddyfile on the root of the scope.",
|
||||
"rules": "Rules",
|
||||
@@ -248,7 +259,8 @@
|
||||
"userManagement": "User Management",
|
||||
"userUpdated": "User updated!",
|
||||
"username": "Username",
|
||||
"users": "Users"
|
||||
"users": "Users",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Help",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Subir",
|
||||
"openFile": "Abrir archivo",
|
||||
"discardChanges": "Discard",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Guardar cambios",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Descargar fichero",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Ordenar por tamaño",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "seleccionar archivo o carpeta",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Administración de usuarios",
|
||||
"userUpdated": "¡Usuario actualizado!",
|
||||
"username": "Usuario",
|
||||
"users": "Usuarios"
|
||||
"users": "Usuarios",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Ayuda",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "آپلود",
|
||||
"openFile": "باز کردن فایل",
|
||||
"discardChanges": "لغو کردن",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "دانلود فایل",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "مرتب سازی اندازه",
|
||||
"noPreview": "این فایل قابل نمایش نیست",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "انتخاب فایل یا پوشه",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "مدیریت کاربران",
|
||||
"userUpdated": "کاربر به روز شد!",
|
||||
"username": "نام کاربری",
|
||||
"users": "کاربران"
|
||||
"users": "کاربران",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "راهنما",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Importer",
|
||||
"openFile": "Ouvrir le fichier",
|
||||
"discardChanges": "Annuler",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"stopSearch": "Arrêter recherche",
|
||||
"saveChanges": "Enregistrer changements",
|
||||
"editAsText": "Editer comme Texte",
|
||||
"increaseFontSize": "Augmenter taille police",
|
||||
"decreaseFontSize": "Réduire taille police"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Télécharger le fichier",
|
||||
@@ -77,8 +80,15 @@
|
||||
"sortByName": "Trier par nom",
|
||||
"sortBySize": "Trier par taille",
|
||||
"noPreview": "L'aperçu n'est pas disponible pour ce fichier.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"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": {
|
||||
"click": "Sélectionner un fichier ou dossier",
|
||||
@@ -105,9 +115,9 @@
|
||||
"username": "Utilisateur·ice",
|
||||
"usernameTaken": "Le nom d'utilisateur·ice est déjà pris",
|
||||
"wrongCredentials": "Identifiants incorrects !",
|
||||
"passwordTooShort": "Password must be at least {min} characters",
|
||||
"passwordTooShort": "Le mot de passe doit contenir au moins {min} caractères",
|
||||
"logout_reasons": {
|
||||
"inactivity": "You have been logged out due to inactivity."
|
||||
"inactivity": "Vous avez été déconnecté(e) en raison d'une inactivité prolongée."
|
||||
}
|
||||
},
|
||||
"permanent": "Permanent",
|
||||
@@ -162,7 +172,7 @@
|
||||
"video": "Vidéo"
|
||||
},
|
||||
"settings": {
|
||||
"aceEditorTheme": "Ace editor theme",
|
||||
"aceEditorTheme": "Éditeur de Thème Ace",
|
||||
"admin": "Admin",
|
||||
"administrator": "Administrateur·ice",
|
||||
"allowCommands": "Exécuter des commandes",
|
||||
@@ -170,7 +180,7 @@
|
||||
"allowNew": "Créer de nouveaux fichiers et dossiers",
|
||||
"allowPublish": "Publier de nouveaux posts et pages",
|
||||
"allowSignup": "Autoriser les utilisateur·ices à s'inscrire",
|
||||
"hideLoginButton": "Hide the login button from public pages",
|
||||
"hideLoginButton": "Cacher le bouton d’identification sur les pages publiques",
|
||||
"avoidChanges": "(Laisser vide pour conserver l'actuel)",
|
||||
"branding": "Image de marque",
|
||||
"brandingDirectoryPath": "Chemin du dossier d'image de marque",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Gestion des utilisateur·ices",
|
||||
"userUpdated": "Utilisateur·ice mis à jour !",
|
||||
"username": "Nom d'utilisateur·ice",
|
||||
"users": "Utilisateur·ices"
|
||||
"users": "Utilisateur·ices",
|
||||
"currentPassword": "Mot de Passe Actuel"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Aide",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "העלאה",
|
||||
"openFile": "פתח קובץ",
|
||||
"discardChanges": "זריקת השינויים",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "הורד קובץ",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "מיין לפי גודל",
|
||||
"noPreview": "לא זמינה תצוגה מקדימה לקובץ זה",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "בחר קובץ או תיקייה",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "ניהול משתמש",
|
||||
"userUpdated": "המשתמש עודכן!",
|
||||
"username": "שם משתמש",
|
||||
"users": "משתמשים"
|
||||
"users": "משתמשים",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "עזרה",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Prenesi",
|
||||
"openFile": "Otvori datoteku",
|
||||
"discardChanges": "Odbaci",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Spremi promjene",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Uredi kao tekst",
|
||||
"increaseFontSize": "Povećaj veličinu fonta",
|
||||
"decreaseFontSize": "Smanji veličinu fonta"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Preuzmi Datoteku",
|
||||
@@ -77,8 +80,15 @@
|
||||
"sortByName": "Sortiraj po nazivu",
|
||||
"sortBySize": "Sortiraj po veličini",
|
||||
"noPreview": "Pregled nije dostupan za ovu datoteku.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"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": {
|
||||
"click": "odaberi datoteku ili mapu",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Upravljanje Korisnicima",
|
||||
"userUpdated": "Korisnik ažuriran!",
|
||||
"username": "Korisničko ime",
|
||||
"users": "Korisnici"
|
||||
"users": "Korisnici",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Pomoć",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Feltöltés",
|
||||
"openFile": "Fájl megnyitása",
|
||||
"discardChanges": "Discard",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Fájl letöltése",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Rendezés méret szerint",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "mappa vagy fájl kijelölése",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Felhasználókezelés",
|
||||
"userUpdated": "Felhasználó frissítve!",
|
||||
"username": "Felhasználói név",
|
||||
"users": "Felhasználók"
|
||||
"users": "Felhasználók",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Súgó",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Hlaða upp",
|
||||
"openFile": "Open file",
|
||||
"discardChanges": "Discard",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Sækja skjal",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Flokka eftir stærð",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "velja skjal eða möppu",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Notendastýring",
|
||||
"userUpdated": "Notandastillingar vistaðar!",
|
||||
"username": "Notendanafn",
|
||||
"users": "Notendur"
|
||||
"users": "Notendur",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Hjálp",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Carica",
|
||||
"openFile": "Apri file",
|
||||
"discardChanges": "Ignora",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Scarica file",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Ordina per dimensione",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "seleziona un file o una cartella",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Gestione degli utenti",
|
||||
"userUpdated": "Utente aggiornato!",
|
||||
"username": "Nome utente",
|
||||
"users": "Utenti"
|
||||
"users": "Utenti",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Aiuto",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "アップロード",
|
||||
"openFile": "ファイルを開く",
|
||||
"discardChanges": "Discard",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "ファイルのダウンロード",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "サイズで並べ替え",
|
||||
"noPreview": "プレビューはこのファイルでは利用できません",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "ファイルやフォルダーを選択",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "ユーザー管理",
|
||||
"userUpdated": "ユーザーを更新しました!",
|
||||
"username": "ユーザー名",
|
||||
"users": "ユーザー"
|
||||
"users": "ユーザー",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "ヘルプ",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "업로드",
|
||||
"openFile": "파일 열기",
|
||||
"discardChanges": "변경 사항 취소",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "변경사항 저장",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "파일 다운로드",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "크기순",
|
||||
"noPreview": "미리 보기가 지원되지 않는 파일 유형입니다.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "파일이나 디렉토리를 선택해주세요.",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "사용자 관리",
|
||||
"userUpdated": "사용자 수정됨!",
|
||||
"username": "사용자 이름",
|
||||
"users": "사용자"
|
||||
"users": "사용자",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "도움말",
|
||||
|
||||
287
frontend/src/i18n/lv.json
Normal file
287
frontend/src/i18n/lv.json
Normal file
@@ -0,0 +1,287 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
287
frontend/src/i18n/lv_LV.json
Normal file
287
frontend/src/i18n/lv_LV.json
Normal file
@@ -0,0 +1,287 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Uploaden",
|
||||
"openFile": "Open file",
|
||||
"discardChanges": "Discard",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Bestand downloaden",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Sorteren op grootte",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "selecteer bestand of map",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Gebruikersbeheer",
|
||||
"userUpdated": "Gebruiker bijgewerkt!",
|
||||
"username": "Gebruikersnaam",
|
||||
"users": "Gebruikers"
|
||||
"users": "Gebruikers",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Help",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Last opp",
|
||||
"openFile": "Open file",
|
||||
"discardChanges": "Slett",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Lagre Endringane ",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Nedlast filen",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Sorter etter størrelse",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "velg fil eller katalog",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Brukeradministrasjon",
|
||||
"userUpdated": "Bruker opprettet!",
|
||||
"username": "Brukernavn",
|
||||
"users": "Bruker"
|
||||
"users": "Bruker",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Hjelp",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Wyślij",
|
||||
"openFile": "Otwórz plik",
|
||||
"discardChanges": "Odrzuć",
|
||||
"stopSearch": "Zatrzymaj wyszukiwanie",
|
||||
"saveChanges": "Zapisz zmiany",
|
||||
"editAsText": "Edytuj jako tekst"
|
||||
"editAsText": "Edytuj jako tekst",
|
||||
"increaseFontSize": "Zwiększ rozmiar czcionki",
|
||||
"decreaseFontSize": "Zmniejsz rozmiar czcionki"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Pobierz plik",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Sortuj wg rozmiaru",
|
||||
"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."
|
||||
"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": {
|
||||
"click": "zaznacz plik lub folder",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Zarządzanie użytkownikami",
|
||||
"userUpdated": "Użytkownik zapisany!",
|
||||
"username": "Nazwa użytkownika",
|
||||
"users": "Użytkownicy"
|
||||
"users": "Użytkownicy",
|
||||
"currentPassword": "Twoje aktualne hasło"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Pomoc",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Enviar",
|
||||
"openFile": "Abrir",
|
||||
"discardChanges": "Discard",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Baixar arquivo",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Ordenar pelo tamanho",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "selecionar pasta ou arquivo",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Gerenciamento de usuários",
|
||||
"userUpdated": "Usuário atualizado!",
|
||||
"username": "Nome do usuário",
|
||||
"users": "Usuários"
|
||||
"users": "Usuários",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Ajuda",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Enviar",
|
||||
"openFile": "Open file",
|
||||
"discardChanges": "Discard",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Descarregar ficheiro",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Ordenar pelo tamanho",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "selecionar pasta ou ficheiro",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Gestão de utilizadores",
|
||||
"userUpdated": "Utilizador atualizado!",
|
||||
"username": "Nome de utilizador",
|
||||
"users": "Utilizadores"
|
||||
"users": "Utilizadores",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Ajuda",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Încarcă",
|
||||
"openFile": "Open file",
|
||||
"discardChanges": "Discard",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Descarcă fișier",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Ordonează după dimensiune",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "alege fișier sau director",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Gestionare utilizatori",
|
||||
"userUpdated": "Utilizator actualizat!",
|
||||
"username": "Utilizator",
|
||||
"users": "Utilizatori"
|
||||
"users": "Utilizatori",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Ajutor",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Загрузить",
|
||||
"openFile": "Открыть файл",
|
||||
"discardChanges": "Отказаться",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Сохранить",
|
||||
"editAsText": "Редактировать как текст",
|
||||
"increaseFontSize": "Увеличить размер шрифта",
|
||||
"decreaseFontSize": "Уменьшить размер шрифта"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Скачать файл",
|
||||
@@ -77,8 +80,15 @@
|
||||
"sortByName": "Сортировка по имени",
|
||||
"sortBySize": "Сортировка по размеру",
|
||||
"noPreview": "Предварительный просмотр для этого файла недоступен.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvTooLarge": "Этот CSV файл слишком большой для предпросмотра (>5 МБ). Скачайте и откройте его локально.",
|
||||
"csvLoadFailed": "Не удалось загрузить этот CSV.",
|
||||
"showingRows": "Отображается {count} строк(а)",
|
||||
"columnSeparator": "Разделитель столбцов",
|
||||
"csvSeparators": {
|
||||
"comma": "Запятая (,)",
|
||||
"semicolon": "Точка с запятой (;)",
|
||||
"both": "Оба варианта — (,) и (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "выбрать файл или каталог",
|
||||
@@ -105,9 +115,9 @@
|
||||
"username": "Имя пользователя",
|
||||
"usernameTaken": "Данное имя пользователя уже занято",
|
||||
"wrongCredentials": "Неверные данные",
|
||||
"passwordTooShort": "Password must be at least {min} characters",
|
||||
"passwordTooShort": "Пароль должен состоять как минимум из {min} символов",
|
||||
"logout_reasons": {
|
||||
"inactivity": "You have been logged out due to inactivity."
|
||||
"inactivity": "Сессия завершена после долгого отсутствия."
|
||||
}
|
||||
},
|
||||
"permanent": "Постоянный",
|
||||
@@ -162,7 +172,7 @@
|
||||
"video": "Видео"
|
||||
},
|
||||
"settings": {
|
||||
"aceEditorTheme": "Ace editor theme",
|
||||
"aceEditorTheme": "Тема редактора Ace",
|
||||
"admin": "Админ",
|
||||
"administrator": "Администратор",
|
||||
"allowCommands": "Запуск команд",
|
||||
@@ -170,7 +180,7 @@
|
||||
"allowNew": "Создание новых файлов или каталогов",
|
||||
"allowPublish": "Публикация новых записей и страниц",
|
||||
"allowSignup": "Разрешить пользователям регистрироваться",
|
||||
"hideLoginButton": "Hide the login button from public pages",
|
||||
"hideLoginButton": "Спрятать кнопку входа с публичных страниц",
|
||||
"avoidChanges": "(оставьте поле пустым, чтобы избежать изменений)",
|
||||
"branding": "Брендинг",
|
||||
"brandingDirectoryPath": "Путь к каталогу брендов",
|
||||
@@ -180,7 +190,7 @@
|
||||
"commandRunnerHelp": "Здесь вы можете установить команды, которые будут выполняться в указанных событиях. Вы должны указать по одной команде в каждой строке. Переменные среды {0} и {1} будут доступны, будучи {0} относительно {1}. Дополнительные сведения об этой функции и доступных переменных среды см. В {2}.",
|
||||
"commandsUpdated": "Команды обновлены!",
|
||||
"createUserDir": "Автоматическое создание домашнего каталога пользователя при добавлении нового пользователя",
|
||||
"minimumPasswordLength": "Minimum password length",
|
||||
"minimumPasswordLength": "Минимальная длина пароля",
|
||||
"tusUploads": "Загруженные файлы",
|
||||
"tusUploadsHelp": " File Browser поддерживает загрузку файлов по частям, что позволяет работать в сетях низкого качества.",
|
||||
"tusUploadsChunkSize": "Указывает максимальный размер запроса (мелкие загрузки пойдут напрямую). Вы можете ввести простое целое число, обозначающее размер ввода в байтах, или строку, например 10MB, 1GB и т. д.",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Управление пользователями",
|
||||
"userUpdated": "Пользователь изменен!",
|
||||
"username": "Имя пользователя",
|
||||
"users": "Пользователи"
|
||||
"users": "Пользователи",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Помощь",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Nahrať",
|
||||
"openFile": "Otvoriť súbor",
|
||||
"discardChanges": "Zahodiť",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Uložiť zmeny",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Stiahnuť súbor",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Zoradiť podľa veľkosti",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "vyberie súbor alebo priečinok",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Správa používateľov",
|
||||
"userUpdated": "Používateľ upravený!",
|
||||
"username": "Meno používateľa",
|
||||
"users": "Používatelia"
|
||||
"users": "Používatelia",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Pomoc",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Ladda upp",
|
||||
"openFile": "Öppna fil",
|
||||
"discardChanges": "Förkasta",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Spara ändringar",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Ladda ner fil",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Sortera på storlek",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "välj fil eller mapp",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Användarehantering",
|
||||
"userUpdated": "Användare uppdaterad!",
|
||||
"username": "Användarnamn",
|
||||
"users": "Användare"
|
||||
"users": "Användare",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Hjälp",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Yükle",
|
||||
"openFile": "Dosyayı aç",
|
||||
"discardChanges": "Discard",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Dosyayı indir",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Boyuta göre sırala",
|
||||
"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."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "dosya veya klasör seçin",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Kullanıcı yönetimi",
|
||||
"userUpdated": "Kullanıcı güncellendi!",
|
||||
"username": "Kullanıcı adı",
|
||||
"users": "Kullanıcılar"
|
||||
"users": "Kullanıcılar",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Yardım",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Вивантажити",
|
||||
"openFile": "Відкрити файл",
|
||||
"discardChanges": "Скасувати",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Завантажити файл",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "Сортувати за розміром",
|
||||
"noPreview": "Попередній перегляд для цього файлу недоступний.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "вибрати файл чи каталог",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Керування користувачами",
|
||||
"userUpdated": "Користувача змінено!",
|
||||
"username": "Ім'я користувача",
|
||||
"users": "Користувачі"
|
||||
"users": "Користувачі",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Допомога",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "Tải lên",
|
||||
"openFile": "Mở tệp",
|
||||
"discardChanges": "Hủy bỏ thay đổi",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Tải xuống tệp tin",
|
||||
@@ -78,7 +81,14 @@
|
||||
"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.",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "chọn tập tin hoặc thư mục",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "Quản lý người dùng",
|
||||
"userUpdated": "Người dùng đã được cập nhật!",
|
||||
"username": "Tên người dùng",
|
||||
"users": "Người dùng"
|
||||
"users": "Người dùng",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Trợ giúp",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "上传",
|
||||
"openFile": "打开文件",
|
||||
"discardChanges": "放弃更改",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "保存更改",
|
||||
"editAsText": "以文本形式编辑",
|
||||
"increaseFontSize": "增大字体大小",
|
||||
"decreaseFontSize": "减小字体大小"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "下载文件",
|
||||
@@ -77,8 +80,15 @@
|
||||
"sortByName": "按名称排序",
|
||||
"sortBySize": "按大小排序",
|
||||
"noPreview": "此文件无法预览。",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvTooLarge": "CSV文件大到无法预览(>5MB)。请下载查看。",
|
||||
"csvLoadFailed": "加载 CSV 文件失败。",
|
||||
"showingRows": "正在显示 {count} 行",
|
||||
"columnSeparator": "列分隔符",
|
||||
"csvSeparators": {
|
||||
"comma": "逗号 (,)",
|
||||
"semicolon": "分号 (;)",
|
||||
"both": "逗号 (,) 和分号 (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "选择文件或文件夹",
|
||||
@@ -105,9 +115,9 @@
|
||||
"username": "用户名",
|
||||
"usernameTaken": "用户名已经被使用",
|
||||
"wrongCredentials": "用户名或密码错误",
|
||||
"passwordTooShort": "Password must be at least {min} characters",
|
||||
"passwordTooShort": "密码必须至少包含 {min} 个字符",
|
||||
"logout_reasons": {
|
||||
"inactivity": "You have been logged out due to inactivity."
|
||||
"inactivity": "由于未活动,您已登出。"
|
||||
}
|
||||
},
|
||||
"permanent": "永久",
|
||||
@@ -162,7 +172,7 @@
|
||||
"video": "视频"
|
||||
},
|
||||
"settings": {
|
||||
"aceEditorTheme": "Ace editor theme",
|
||||
"aceEditorTheme": "Ace编辑器主题",
|
||||
"admin": "管理员",
|
||||
"administrator": "管理员",
|
||||
"allowCommands": "执行命令(Shell 命令)",
|
||||
@@ -170,7 +180,7 @@
|
||||
"allowNew": "创建新文件和文件夹",
|
||||
"allowPublish": "发布新的帖子与页面",
|
||||
"allowSignup": "允许用户注册",
|
||||
"hideLoginButton": "Hide the login button from public pages",
|
||||
"hideLoginButton": "从公开页面隐藏登录按钮",
|
||||
"avoidChanges": "(留空以避免更改)",
|
||||
"branding": "品牌",
|
||||
"brandingDirectoryPath": "品牌信息文件夹路径",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "用户管理",
|
||||
"userUpdated": "用户已更新!",
|
||||
"username": "用户名",
|
||||
"users": "用户"
|
||||
"users": "用户",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "帮助",
|
||||
|
||||
@@ -43,8 +43,11 @@
|
||||
"upload": "上傳",
|
||||
"openFile": "開啟檔案",
|
||||
"discardChanges": "放棄變更",
|
||||
"stopSearch": "Stop searching",
|
||||
"saveChanges": "Save changes",
|
||||
"editAsText": "Edit as Text"
|
||||
"editAsText": "Edit as Text",
|
||||
"increaseFontSize": "Increase font size",
|
||||
"decreaseFontSize": "Decrease font size"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "下載檔案",
|
||||
@@ -78,7 +81,14 @@
|
||||
"sortBySize": "按大小排序",
|
||||
"noPreview": "此檔案無法預覽。",
|
||||
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||
"csvLoadFailed": "Failed to load CSV file."
|
||||
"csvLoadFailed": "Failed to load CSV file.",
|
||||
"showingRows": "Showing {count} row(s)",
|
||||
"columnSeparator": "Column Separator",
|
||||
"csvSeparators": {
|
||||
"comma": "Comma (,)",
|
||||
"semicolon": "Semicolon (;)",
|
||||
"both": "Both (,) and (;)"
|
||||
}
|
||||
},
|
||||
"help": {
|
||||
"click": "選擇檔案或目錄",
|
||||
@@ -248,7 +258,8 @@
|
||||
"userManagement": "使用者管理",
|
||||
"userUpdated": "使用者已更新!",
|
||||
"username": "使用者名稱",
|
||||
"users": "使用者"
|
||||
"users": "使用者",
|
||||
"currentPassword": "Your Current Password"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "幫助",
|
||||
|
||||
2
frontend/src/types/settings.d.ts
vendored
2
frontend/src/types/settings.d.ts
vendored
@@ -5,6 +5,7 @@ interface ISettings {
|
||||
minimumPasswordLength: number;
|
||||
userHomeBasePath: string;
|
||||
defaults: SettingsDefaults;
|
||||
authMethod: string;
|
||||
rules: any[];
|
||||
branding: SettingsBranding;
|
||||
tus: SettingsTus;
|
||||
@@ -17,6 +18,7 @@ interface SettingsDefaults {
|
||||
locale: string;
|
||||
viewMode: ViewModeType;
|
||||
singleClick: boolean;
|
||||
redirectAfterCopyMove: boolean;
|
||||
sorting: Sorting;
|
||||
perm: Permissions;
|
||||
commands: any[];
|
||||
|
||||
2
frontend/src/types/user.d.ts
vendored
2
frontend/src/types/user.d.ts
vendored
@@ -10,6 +10,7 @@ interface IUser {
|
||||
lockPassword: boolean;
|
||||
hideDotfiles: boolean;
|
||||
singleClick: boolean;
|
||||
redirectAfterCopyMove: boolean;
|
||||
dateFormat: boolean;
|
||||
viewMode: ViewModeType;
|
||||
sorting?: Sorting;
|
||||
@@ -30,6 +31,7 @@ interface IUserForm {
|
||||
lockPassword?: boolean;
|
||||
hideDotfiles?: boolean;
|
||||
singleClick?: boolean;
|
||||
redirectAfterCopyMove?: boolean;
|
||||
dateFormat?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,10 @@ export interface CsvData {
|
||||
* Parse CSV content into headers and rows
|
||||
* Supports quoted fields and handles commas within quotes
|
||||
*/
|
||||
export function parseCSV(content: string): CsvData {
|
||||
export function parseCSV(
|
||||
content: string,
|
||||
columnSeparator: Array<string>
|
||||
): CsvData {
|
||||
if (!content || content.trim().length === 0) {
|
||||
return { headers: [], rows: [] };
|
||||
}
|
||||
@@ -35,7 +38,7 @@ export function parseCSV(content: string): CsvData {
|
||||
// Toggle quote state
|
||||
inQuotes = !inQuotes;
|
||||
}
|
||||
} else if (char === "," && !inQuotes) {
|
||||
} else if (columnSeparator.includes(char) && !inQuotes) {
|
||||
// Field separator
|
||||
row.push(currentField);
|
||||
currentField = "";
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
ref="listing"
|
||||
class="file-icons"
|
||||
:class="authStore.user?.viewMode ?? ''"
|
||||
@click="handleEmptyAreaClick"
|
||||
>
|
||||
<div>
|
||||
<div class="item header">
|
||||
@@ -356,7 +357,7 @@ import {
|
||||
ref,
|
||||
watch,
|
||||
} from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useRoute, onBeforeRouteUpdate } from "vue-router";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { removePrefix } from "@/api/utils";
|
||||
@@ -379,6 +380,9 @@ const layoutStore = useLayoutStore();
|
||||
const { req } = storeToRefs(fileStore);
|
||||
|
||||
const route = useRoute();
|
||||
onBeforeRouteUpdate(() => {
|
||||
hideContextMenu();
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -1048,4 +1052,18 @@ const showContextMenu = (event: MouseEvent) => {
|
||||
const hideContextMenu = () => {
|
||||
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>
|
||||
<style scoped>
|
||||
#listing {
|
||||
min-height: calc(100vh - 8rem);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -15,6 +15,14 @@
|
||||
<input type="checkbox" name="singleClick" v-model="singleClick" />
|
||||
{{ t("settings.singleClick") }}
|
||||
</p>
|
||||
<p>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="redirectAfterCopyMove"
|
||||
v-model="redirectAfterCopyMove"
|
||||
/>
|
||||
{{ t("settings.redirectAfterCopyMove") }}
|
||||
</p>
|
||||
<p>
|
||||
<input type="checkbox" name="dateFormat" v-model="dateFormat" />
|
||||
{{ t("settings.setDateFormat") }}
|
||||
@@ -44,7 +52,7 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<div v-if="!noAuth" class="column">
|
||||
<form
|
||||
class="card"
|
||||
v-if="!authStore.user?.lockPassword"
|
||||
@@ -69,6 +77,15 @@
|
||||
v-model="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 class="card-action">
|
||||
@@ -92,6 +109,7 @@ import AceEditorTheme from "@/components/settings/AceEditorTheme.vue";
|
||||
import Languages from "@/components/settings/Languages.vue";
|
||||
import { computed, inject, onMounted, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { authMethod, noAuth } from "@/utils/constants";
|
||||
|
||||
const layoutStore = useLayoutStore();
|
||||
const authStore = useAuthStore();
|
||||
@@ -102,8 +120,11 @@ const $showError = inject<IToastError>("$showError")!;
|
||||
|
||||
const password = ref<string>("");
|
||||
const passwordConf = ref<string>("");
|
||||
const currentPassword = ref<string>("");
|
||||
const isCurrentPasswordRequired = ref<boolean>(false);
|
||||
const hideDotfiles = ref<boolean>(false);
|
||||
const singleClick = ref<boolean>(false);
|
||||
const redirectAfterCopyMove = ref<boolean>(false);
|
||||
const dateFormat = ref<boolean>(false);
|
||||
const locale = ref<string>("");
|
||||
const aceEditorTheme = ref<string>("");
|
||||
@@ -128,9 +149,12 @@ onMounted(async () => {
|
||||
locale.value = authStore.user.locale;
|
||||
hideDotfiles.value = authStore.user.hideDotfiles;
|
||||
singleClick.value = authStore.user.singleClick;
|
||||
redirectAfterCopyMove.value = authStore.user.redirectAfterCopyMove;
|
||||
dateFormat.value = authStore.user.dateFormat;
|
||||
aceEditorTheme.value = authStore.user.aceEditorTheme;
|
||||
layoutStore.loading = false;
|
||||
isCurrentPasswordRequired.value = authMethod == "json";
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -140,6 +164,7 @@ const updatePassword = async (event: Event) => {
|
||||
if (
|
||||
password.value !== passwordConf.value ||
|
||||
password.value === "" ||
|
||||
currentPassword.value === "" ||
|
||||
authStore.user === null
|
||||
) {
|
||||
return;
|
||||
@@ -151,7 +176,7 @@ const updatePassword = async (event: Event) => {
|
||||
id: authStore.user.id,
|
||||
password: password.value,
|
||||
};
|
||||
await api.update(data, ["password"]);
|
||||
await api.update(data, ["password"], currentPassword.value);
|
||||
authStore.updateUser(data);
|
||||
$showSuccess(t("settings.passwordUpdated"));
|
||||
} catch (e: any) {
|
||||
@@ -172,6 +197,7 @@ const updateSettings = async (event: Event) => {
|
||||
locale: locale.value,
|
||||
hideDotfiles: hideDotfiles.value,
|
||||
singleClick: singleClick.value,
|
||||
redirectAfterCopyMove: redirectAfterCopyMove.value,
|
||||
dateFormat: dateFormat.value,
|
||||
aceEditorTheme: aceEditorTheme.value,
|
||||
};
|
||||
@@ -180,6 +206,7 @@ const updateSettings = async (event: Event) => {
|
||||
"locale",
|
||||
"hideDotfiles",
|
||||
"singleClick",
|
||||
"redirectAfterCopyMove",
|
||||
"dateFormat",
|
||||
"aceEditorTheme",
|
||||
]);
|
||||
|
||||
@@ -15,6 +15,19 @@
|
||||
:isDefault="false"
|
||||
: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 class="card-action">
|
||||
@@ -63,6 +76,8 @@ const error = ref<StatusError>();
|
||||
const originalUser = ref<IUser>();
|
||||
const user = ref<IUser>();
|
||||
const createUserDir = ref<boolean>(false);
|
||||
const currentPassword = ref<string>("");
|
||||
const isCurrentPasswordRequired = ref<boolean>(false);
|
||||
|
||||
const $showError = inject<IToastError>("$showError")!;
|
||||
const $showSuccess = inject<IToastSuccess>("$showSuccess")!;
|
||||
@@ -90,7 +105,12 @@ const fetchData = async () => {
|
||||
|
||||
try {
|
||||
if (isNew.value) {
|
||||
const { defaults, createUserDir: _createUserDir } = await settings.get();
|
||||
const {
|
||||
authMethod,
|
||||
defaults,
|
||||
createUserDir: _createUserDir,
|
||||
} = await settings.get();
|
||||
isCurrentPasswordRequired.value = authMethod == "json";
|
||||
createUserDir.value = _createUserDir;
|
||||
user.value = {
|
||||
...defaults,
|
||||
@@ -101,6 +121,8 @@ const fetchData = async () => {
|
||||
id: 0,
|
||||
};
|
||||
} else {
|
||||
const { authMethod } = await settings.get();
|
||||
isCurrentPasswordRequired.value = authMethod == "json";
|
||||
const id = Array.isArray(route.params.id)
|
||||
? route.params.id.join("")
|
||||
: route.params.id;
|
||||
@@ -151,11 +173,11 @@ const save = async (event: Event) => {
|
||||
...user.value,
|
||||
};
|
||||
|
||||
const loc = await api.create(newUser);
|
||||
const loc = await api.create(newUser, currentPassword.value);
|
||||
router.push({ path: loc || "/settings/users" });
|
||||
$showSuccess(t("settings.userCreated"));
|
||||
} else {
|
||||
await api.update(user.value);
|
||||
await api.update(user.value, ["all"], currentPassword.value);
|
||||
|
||||
if (user.value.id === authStore.user?.id) {
|
||||
authStore.updateUser(user.value);
|
||||
|
||||
18
go.mod
18
go.mod
@@ -12,21 +12,21 @@ require (
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/jellydator/ttlcache/v3 v3.4.0
|
||||
github.com/maruel/natural v1.2.1
|
||||
github.com/maruel/natural v1.3.0
|
||||
github.com/marusama/semaphore/v2 v2.5.0
|
||||
github.com/mholt/archives v0.1.5
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/samber/lo v1.52.0
|
||||
github.com/shirou/gopsutil/v4 v4.25.10
|
||||
github.com/shirou/gopsutil/v4 v4.25.12
|
||||
github.com/spf13/afero v1.15.0
|
||||
github.com/spf13/cobra v1.10.1
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/spf13/pflag v1.0.10
|
||||
github.com/spf13/viper v1.21.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
|
||||
golang.org/x/crypto v0.45.0
|
||||
golang.org/x/image v0.33.0
|
||||
golang.org/x/text v0.31.0
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/image v0.34.0
|
||||
golang.org/x/text v0.33.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.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/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
|
||||
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 // indirect
|
||||
github.com/ebitengine/purego v0.9.0 // indirect
|
||||
github.com/ebitengine/purego v0.9.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/go-errors/errors v1.5.1 // 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
|
||||
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
36
go.sum
36
go.sum
@@ -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-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/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k=
|
||||
github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A=
|
||||
github.com/ebitengine/purego v0.9.1/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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
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.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/maruel/natural v1.2.1 h1:G/y4pwtTA07lbQsMefvsmEO0VN0NfqpxprxXDM4R/4o=
|
||||
github.com/maruel/natural v1.2.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
|
||||
github.com/maruel/natural v1.3.0 h1:VsmCsBmEyrR46RomtgHs5hbKADGRVtliHTyCOLFBpsg=
|
||||
github.com/maruel/natural v1.3.0/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/go.mod h1:z9nMiNUekt/LTpTUQdpp+4sJeYqUGpwMHfW0Z8V8fnQ=
|
||||
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/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw=
|
||||
github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0=
|
||||
github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA=
|
||||
github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM=
|
||||
github.com/shirou/gopsutil/v4 v4.25.12 h1:e7PvW/0RmJ8p8vPGJH4jvNkOyLmbkXgXW4m6ZPic6CY=
|
||||
github.com/shirou/gopsutil/v4 v4.25.12/go.mod h1:EivAfP5x2EhLp2ovdpKSozecVXn1TmuG7SMzs/Wh4PU=
|
||||
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/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/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
||||
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
||||
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
|
||||
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
|
||||
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/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-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.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -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-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.33.0 h1:LXRZRnv1+zGd5XBUVRFmYEphyyKJjQjCRiOuAP3sZfQ=
|
||||
golang.org/x/image v0.33.0/go.mod h1:DD3OsTYT9chzuzTQt+zMcOlBHgfoKQb1gry8p76Y1sc=
|
||||
golang.org/x/image v0.34.0 h1:33gCkyw9hmwbZJeZkct8XyR11yH889EQt/QH4VmXMn8=
|
||||
golang.org/x/image v0.34.0/go.mod h1:2RNFBZRB+vnwwFil8GkMdRvrJOFd1AzdZI6vOY+eJVU=
|
||||
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-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-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.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.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-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
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.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.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
|
||||
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
|
||||
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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
||||
52
http/auth.go
52
http/auth.go
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"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"
|
||||
)
|
||||
@@ -23,17 +23,18 @@ const (
|
||||
)
|
||||
|
||||
type userInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Locale string `json:"locale"`
|
||||
ViewMode users.ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Perm users.Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
Username string `json:"username"`
|
||||
AceEditorTheme string `json:"aceEditorTheme"`
|
||||
ID uint `json:"id"`
|
||||
Locale string `json:"locale"`
|
||||
ViewMode users.ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
RedirectAfterCopyMove bool `json:"redirectAfterCopyMove"`
|
||||
Perm users.Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
Username string `json:"username"`
|
||||
AceEditorTheme string `json:"aceEditorTheme"`
|
||||
}
|
||||
|
||||
type authToken struct {
|
||||
@@ -185,7 +186,7 @@ var signupHandler = func(_ http.ResponseWriter, r *http.Request, d *data) (int,
|
||||
log.Printf("new user: %s, home dir: [%s].", user.Username, userHome)
|
||||
|
||||
err = d.store.Users.Save(user)
|
||||
if errors.Is(err, fbErrors.ErrExist) {
|
||||
if errors.Is(err, fberrors.ErrExist) {
|
||||
return http.StatusConflict, err
|
||||
} else if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
@@ -204,17 +205,18 @@ func renewHandler(tokenExpireTime time.Duration) handleFunc {
|
||||
func printToken(w http.ResponseWriter, _ *http.Request, d *data, user *users.User, tokenExpirationTime time.Duration) (int, error) {
|
||||
claims := &authToken{
|
||||
User: userInfo{
|
||||
ID: user.ID,
|
||||
Locale: user.Locale,
|
||||
ViewMode: user.ViewMode,
|
||||
SingleClick: user.SingleClick,
|
||||
Perm: user.Perm,
|
||||
LockPassword: user.LockPassword,
|
||||
Commands: user.Commands,
|
||||
HideDotfiles: user.HideDotfiles,
|
||||
DateFormat: user.DateFormat,
|
||||
Username: user.Username,
|
||||
AceEditorTheme: user.AceEditorTheme,
|
||||
ID: user.ID,
|
||||
Locale: user.Locale,
|
||||
ViewMode: user.ViewMode,
|
||||
SingleClick: user.SingleClick,
|
||||
RedirectAfterCopyMove: user.RedirectAfterCopyMove,
|
||||
Perm: user.Perm,
|
||||
LockPassword: user.LockPassword,
|
||||
Commands: user.Commands,
|
||||
HideDotfiles: user.HideDotfiles,
|
||||
DateFormat: user.DateFormat,
|
||||
Username: user.Username,
|
||||
AceEditorTheme: user.AceEditorTheme,
|
||||
},
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//go:build !dev
|
||||
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
// global headers to append to every response
|
||||
var globalHeaders = map[string]string{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
@@ -11,8 +11,9 @@ import (
|
||||
)
|
||||
|
||||
type modifyRequest struct {
|
||||
What string `json:"what"` // Answer to: what data type?
|
||||
Which []string `json:"which"` // Answer to: which fields?
|
||||
What string `json:"what"` // Answer to: what data type?
|
||||
Which []string `json:"which"` // Answer to: which fields?
|
||||
CurrentPassword string `json:"current_password"` // Answer to: user logged password
|
||||
}
|
||||
|
||||
func NewHandler(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:generate go-enum --sql --marshal --names --file $GOFILE
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by go-enum
|
||||
// DO NOT EDIT!
|
||||
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -41,6 +41,7 @@ var withHashFile = func(fn handleFunc) handleFunc {
|
||||
Modify: d.user.Perm.Modify,
|
||||
Expand: false,
|
||||
ReadHeader: d.server.TypeDetectionByHeader,
|
||||
CalcImgRes: d.server.TypeDetectionByHeader,
|
||||
Checker: d,
|
||||
Token: link.Token,
|
||||
})
|
||||
@@ -74,6 +75,12 @@ var withHashFile = func(fn handleFunc) handleFunc {
|
||||
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
|
||||
return fn(w, r, d)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -123,6 +123,7 @@ func getFiles(d *data, path, commonPath string) ([]archives.FileInfo, error) {
|
||||
if path != commonPath {
|
||||
nameInArchive := strings.TrimPrefix(path, commonPath)
|
||||
nameInArchive = strings.TrimPrefix(nameInArchive, string(filepath.Separator))
|
||||
nameInArchive = filepath.ToSlash(nameInArchive)
|
||||
|
||||
archiveFiles = append(archiveFiles, archives.FileInfo{
|
||||
FileInfo: info,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
"github.com/shirou/gopsutil/v4/disk"
|
||||
"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/fileutils"
|
||||
)
|
||||
@@ -44,7 +44,7 @@ var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d
|
||||
|
||||
if checksum := r.URL.Query().Get("checksum"); checksum != "" {
|
||||
err := file.Checksum(checksum)
|
||||
if errors.Is(err, fbErrors.ErrInvalidOption) {
|
||||
if errors.Is(err, fberrors.ErrInvalidOption) {
|
||||
return http.StatusBadRequest, nil
|
||||
} else if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
@@ -238,7 +238,7 @@ func checkParent(src, dst string) error {
|
||||
|
||||
rel = filepath.ToSlash(rel)
|
||||
if !strings.HasPrefix(rel, "../") && rel != ".." && rel != "." {
|
||||
return fbErrors.ErrSourceIsParent
|
||||
return fberrors.ErrSourceIsParent
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -280,6 +280,12 @@ func writeFile(afs afero.Fs, dst string, in io.Reader, fileMode, dirMode fs.File
|
||||
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.
|
||||
info, err := file.Stat()
|
||||
if err != nil {
|
||||
@@ -304,13 +310,13 @@ func patchAction(ctx context.Context, action, src, dst string, d *data, fileCach
|
||||
switch action {
|
||||
case "copy":
|
||||
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)
|
||||
case "rename":
|
||||
if !d.user.Perm.Rename {
|
||||
return fbErrors.ErrPermissionDenied
|
||||
return fberrors.ErrPermissionDenied
|
||||
}
|
||||
src = path.Clean("/" + src)
|
||||
dst = path.Clean("/" + dst)
|
||||
@@ -335,7 +341,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)
|
||||
default:
|
||||
return fmt.Errorf("unsupported action %s: %w", action, fbErrors.ErrInvalidRequestParams)
|
||||
return fmt.Errorf("unsupported action %s: %w", action, fberrors.ErrInvalidRequestParams)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,82 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/search"
|
||||
)
|
||||
|
||||
const searchPingInterval = 5
|
||||
|
||||
var searchHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||
response := []map[string]interface{}{}
|
||||
response := make(chan 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")
|
||||
|
||||
err := search.Search(d.user.Fs, r.URL.Path, query, d, func(path string, f os.FileInfo) error {
|
||||
response = append(response, map[string]interface{}{
|
||||
err := search.Search(ctx, d.user.Fs, r.URL.Path, query, d, func(path string, f os.FileInfo) error {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case response <- map[string]interface{}{
|
||||
"dir": f.IsDir(),
|
||||
"path": path,
|
||||
})
|
||||
|
||||
return nil
|
||||
}:
|
||||
}
|
||||
return context.Cause(ctx)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
close(response)
|
||||
wg.Wait()
|
||||
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 renderJSON(w, r, response)
|
||||
return 0, nil
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -15,6 +15,7 @@ type settingsData struct {
|
||||
MinimumPasswordLength uint `json:"minimumPasswordLength"`
|
||||
UserHomeBasePath string `json:"userHomeBasePath"`
|
||||
Defaults settings.UserDefaults `json:"defaults"`
|
||||
AuthMethod settings.AuthMethod `json:"authMethod"`
|
||||
Rules []rules.Rule `json:"rules"`
|
||||
Branding settings.Branding `json:"branding"`
|
||||
Tus settings.Tus `json:"tus"`
|
||||
@@ -30,6 +31,7 @@ var settingsGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request,
|
||||
MinimumPasswordLength: d.settings.MinimumPasswordLength,
|
||||
UserHomeBasePath: d.settings.UserHomeBasePath,
|
||||
Defaults: d.settings.Defaults,
|
||||
AuthMethod: d.settings.AuthMethod,
|
||||
Rules: d.settings.Rules,
|
||||
Branding: d.settings.Branding,
|
||||
Tus: d.settings.Tus,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
@@ -38,7 +38,7 @@ var shareListHandler = withPermShare(func(w http.ResponseWriter, r *http.Request
|
||||
} else {
|
||||
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{})
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
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{})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -256,6 +256,12 @@ func tusPatchHandler() handleFunc {
|
||||
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
|
||||
w.Header().Set("Upload-Offset", strconv.FormatInt(newOffset, 10))
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -12,7 +12,8 @@ import (
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
"github.com/filebrowser/filebrowser/v2/auth"
|
||||
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
"github.com/filebrowser/filebrowser/v2/users"
|
||||
)
|
||||
|
||||
@@ -36,7 +37,7 @@ func getUserID(r *http.Request) (uint, error) {
|
||||
|
||||
func getUser(_ http.ResponseWriter, r *http.Request) (*modifyUserRequest, error) {
|
||||
if r.Body == nil {
|
||||
return nil, fbErrors.ErrEmptyRequest
|
||||
return nil, fberrors.ErrEmptyRequest
|
||||
}
|
||||
|
||||
req := &modifyUserRequest{}
|
||||
@@ -46,7 +47,7 @@ func getUser(_ http.ResponseWriter, r *http.Request) (*modifyUserRequest, error)
|
||||
}
|
||||
|
||||
if req.What != "user" {
|
||||
return nil, fbErrors.ErrInvalidDataType
|
||||
return nil, fberrors.ErrInvalidDataType
|
||||
}
|
||||
|
||||
return req, nil
|
||||
@@ -87,7 +88,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) {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -117,12 +118,18 @@ var userPostHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *
|
||||
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 {
|
||||
return http.StatusBadRequest, nil
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -153,6 +160,27 @@ var userPutHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request
|
||||
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) {
|
||||
return http.StatusBadRequest, nil
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package http
|
||||
package fbhttp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
@@ -10,5 +10,6 @@
|
||||
"postUpdateOptions": [
|
||||
"gomodUpdateImportPaths",
|
||||
"gomodTidy"
|
||||
]
|
||||
],
|
||||
"schedule": "* * * * 0,6"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package search
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -18,13 +19,17 @@ type searchOptions struct {
|
||||
}
|
||||
|
||||
// Search searches for a query in a fs.
|
||||
func Search(fs afero.Fs, scope, query string, checker rules.Checker, found func(path string, f os.FileInfo) error) error {
|
||||
func Search(ctx context.Context,
|
||||
fs afero.Fs, scope, query string, checker rules.Checker, found func(path string, f os.FileInfo) error) error {
|
||||
search := parseSearch(query)
|
||||
|
||||
scope = filepath.ToSlash(filepath.Clean(scope))
|
||||
scope = path.Join("/", scope)
|
||||
|
||||
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 = path.Join("/", fPath)
|
||||
relativePath := strings.TrimPrefix(fPath, scope)
|
||||
|
||||
@@ -8,16 +8,17 @@ import (
|
||||
// UserDefaults is a type that holds the default values
|
||||
// for some fields on User.
|
||||
type UserDefaults struct {
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
ViewMode users.ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Perm users.Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
AceEditorTheme string `json:"aceEditorTheme"`
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
ViewMode users.ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
RedirectAfterCopyMove bool `json:"redirectAfterCopyMove"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Perm users.Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
AceEditorTheme string `json:"aceEditorTheme"`
|
||||
}
|
||||
|
||||
// Apply applies the default options to a user.
|
||||
@@ -26,6 +27,7 @@ func (d *UserDefaults) Apply(u *users.User) {
|
||||
u.Locale = d.Locale
|
||||
u.ViewMode = d.ViewMode
|
||||
u.SingleClick = d.SingleClick
|
||||
u.RedirectAfterCopyMove = d.RedirectAfterCopyMove
|
||||
u.Perm = d.Perm
|
||||
u.Sorting = d.Sorting
|
||||
u.Commands = d.Commands
|
||||
|
||||
@@ -59,6 +59,7 @@ type Server struct {
|
||||
ResizePreview bool `json:"resizePreview"`
|
||||
EnableExec bool `json:"enableExec"`
|
||||
TypeDetectionByHeader bool `json:"typeDetectionByHeader"`
|
||||
ImageResolutionCal bool `json:"imageResolutionCalculation"`
|
||||
AuthHook string `json:"authHook"`
|
||||
TokenExpirationTime string `json:"tokenExpirationTime"`
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"github.com/filebrowser/filebrowser/v2/errors"
|
||||
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
"github.com/filebrowser/filebrowser/v2/rules"
|
||||
"github.com/filebrowser/filebrowser/v2/users"
|
||||
)
|
||||
@@ -72,7 +72,7 @@ var defaultEvents = []string{
|
||||
// Save saves the settings for the current instance.
|
||||
func (s *Storage) Save(set *Settings) error {
|
||||
if len(set.Key) == 0 {
|
||||
return errors.ErrEmptyKey
|
||||
return fberrors.ErrEmptyKey
|
||||
}
|
||||
|
||||
if set.Defaults.Locale == "" {
|
||||
|
||||
@@ -3,7 +3,7 @@ package share
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/errors"
|
||||
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
)
|
||||
|
||||
// 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 {
|
||||
return nil, err
|
||||
}
|
||||
return nil, errors.ErrNotExist
|
||||
return nil, fberrors.ErrNotExist
|
||||
}
|
||||
|
||||
return link, nil
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"github.com/asdine/storm/v3"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/auth"
|
||||
"github.com/filebrowser/filebrowser/v2/errors"
|
||||
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
"github.com/filebrowser/filebrowser/v2/settings"
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ func (s authBackend) Get(t settings.AuthMethod) (auth.Auther, error) {
|
||||
case auth.MethodNoAuth:
|
||||
auther = &auth.NoAuth{}
|
||||
default:
|
||||
return nil, errors.ErrInvalidAuthMethod
|
||||
return nil, fberrors.ErrInvalidAuthMethod
|
||||
}
|
||||
|
||||
return auther, get(s.db, "auther", auther)
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/asdine/storm/v3"
|
||||
"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"
|
||||
)
|
||||
|
||||
@@ -18,7 +18,7 @@ func (s shareBackend) All() ([]*share.Link, error) {
|
||||
var v []*share.Link
|
||||
err := s.db.All(&v)
|
||||
if errors.Is(err, storm.ErrNotFound) {
|
||||
return v, fbErrors.ErrNotExist
|
||||
return v, fberrors.ErrNotExist
|
||||
}
|
||||
|
||||
return v, err
|
||||
@@ -28,7 +28,7 @@ func (s shareBackend) FindByUserID(id uint) ([]*share.Link, error) {
|
||||
var v []*share.Link
|
||||
err := s.db.Select(q.Eq("UserID", id)).Find(&v)
|
||||
if errors.Is(err, storm.ErrNotFound) {
|
||||
return v, fbErrors.ErrNotExist
|
||||
return v, fberrors.ErrNotExist
|
||||
}
|
||||
|
||||
return v, err
|
||||
@@ -38,7 +38,7 @@ func (s shareBackend) GetByHash(hash string) (*share.Link, error) {
|
||||
var v share.Link
|
||||
err := s.db.One("Hash", hash, &v)
|
||||
if errors.Is(err, storm.ErrNotFound) {
|
||||
return nil, fbErrors.ErrNotExist
|
||||
return nil, fberrors.ErrNotExist
|
||||
}
|
||||
|
||||
return &v, err
|
||||
@@ -48,7 +48,7 @@ func (s shareBackend) GetPermanent(path string, id uint) (*share.Link, error) {
|
||||
var v share.Link
|
||||
err := s.db.Select(q.Eq("Path", path), q.Eq("Expire", 0), q.Eq("UserID", id)).First(&v)
|
||||
if errors.Is(err, storm.ErrNotFound) {
|
||||
return nil, fbErrors.ErrNotExist
|
||||
return nil, fberrors.ErrNotExist
|
||||
}
|
||||
|
||||
return &v, err
|
||||
@@ -58,7 +58,7 @@ func (s shareBackend) Gets(path string, id uint) ([]*share.Link, error) {
|
||||
var v []*share.Link
|
||||
err := s.db.Select(q.Eq("Path", path), q.Eq("UserID", id)).Find(&v)
|
||||
if errors.Is(err, storm.ErrNotFound) {
|
||||
return v, fbErrors.ErrNotExist
|
||||
return v, fberrors.ErrNotExist
|
||||
}
|
||||
|
||||
return v, err
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
@@ -25,14 +25,14 @@ func (st usersBackend) GetBy(i interface{}) (user *users.User, err error) {
|
||||
case string:
|
||||
arg = "Username"
|
||||
default:
|
||||
return nil, fbErrors.ErrInvalidDataType
|
||||
return nil, fberrors.ErrInvalidDataType
|
||||
}
|
||||
|
||||
err = st.db.One(arg, i, user)
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, storm.ErrNotFound) {
|
||||
return nil, fbErrors.ErrNotExist
|
||||
return nil, fberrors.ErrNotExist
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func (st usersBackend) Gets() ([]*users.User, error) {
|
||||
var allUsers []*users.User
|
||||
err := st.db.All(&allUsers)
|
||||
if errors.Is(err, storm.ErrNotFound) {
|
||||
return nil, fbErrors.ErrNotExist
|
||||
return nil, fberrors.ErrNotExist
|
||||
}
|
||||
|
||||
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 {
|
||||
err := st.db.Save(user)
|
||||
if errors.Is(err, storm.ErrAlreadyExists) {
|
||||
return fbErrors.ErrExist
|
||||
return fberrors.ErrExist
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -5,13 +5,13 @@ import (
|
||||
|
||||
"github.com/asdine/storm/v3"
|
||||
|
||||
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
)
|
||||
|
||||
func get(db *storm.DB, name string, to interface{}) error {
|
||||
err := db.Get("config", name, to)
|
||||
if errors.Is(err, storm.ErrNotFound) {
|
||||
return fbErrors.ErrNotExist
|
||||
return fberrors.ErrNotExist
|
||||
}
|
||||
|
||||
return err
|
||||
|
||||
@@ -6,17 +6,17 @@ import (
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
||||
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
)
|
||||
|
||||
// ValidateAndHashPwd validates and hashes a password.
|
||||
func ValidateAndHashPwd(password string, minimumLength uint) (string, error) {
|
||||
if uint(len(password)) < minimumLength {
|
||||
return "", fbErrors.ErrShortPassword{MinimumLength: minimumLength}
|
||||
return "", fberrors.ErrShortPassword{MinimumLength: minimumLength}
|
||||
}
|
||||
|
||||
if _, ok := commonPasswords[password]; ok {
|
||||
return "", fbErrors.ErrEasyPassword
|
||||
return "", fberrors.ErrEasyPassword
|
||||
}
|
||||
|
||||
return HashPwd(password)
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/errors"
|
||||
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
)
|
||||
|
||||
// StorageBackend is the interface to implement for a users storage.
|
||||
@@ -109,16 +109,16 @@ func (s *Storage) Delete(id interface{}) error {
|
||||
return err
|
||||
}
|
||||
if user.ID == 1 {
|
||||
return errors.ErrRootUserDeletion
|
||||
return fberrors.ErrRootUserDeletion
|
||||
}
|
||||
return s.back.DeleteByUsername(id)
|
||||
case uint:
|
||||
if id == 1 {
|
||||
return errors.ErrRootUserDeletion
|
||||
return fberrors.ErrRootUserDeletion
|
||||
}
|
||||
return s.back.DeleteByID(id)
|
||||
default:
|
||||
return errors.ErrInvalidDataType
|
||||
return fberrors.ErrInvalidDataType
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/spf13/afero"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/errors"
|
||||
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
"github.com/filebrowser/filebrowser/v2/files"
|
||||
"github.com/filebrowser/filebrowser/v2/rules"
|
||||
)
|
||||
@@ -20,22 +20,23 @@ const (
|
||||
|
||||
// User describes a user.
|
||||
type User struct {
|
||||
ID uint `storm:"id,increment" json:"id"`
|
||||
Username string `storm:"unique" json:"username"`
|
||||
Password string `json:"password"`
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
ViewMode ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Perm Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Fs afero.Fs `json:"-" yaml:"-"`
|
||||
Rules []rules.Rule `json:"rules"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
AceEditorTheme string `json:"aceEditorTheme"`
|
||||
ID uint `storm:"id,increment" json:"id"`
|
||||
Username string `storm:"unique" json:"username"`
|
||||
Password string `json:"password"`
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
ViewMode ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
RedirectAfterCopyMove bool `json:"redirectAfterCopyMove"`
|
||||
Perm Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Fs afero.Fs `json:"-" yaml:"-"`
|
||||
Rules []rules.Rule `json:"rules"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DateFormat bool `json:"dateFormat"`
|
||||
AceEditorTheme string `json:"aceEditorTheme"`
|
||||
}
|
||||
|
||||
// GetRules implements rules.Provider.
|
||||
@@ -64,11 +65,11 @@ func (u *User) Clean(baseScope string, fields ...string) error {
|
||||
switch field {
|
||||
case "Username":
|
||||
if u.Username == "" {
|
||||
return errors.ErrEmptyUsername
|
||||
return fberrors.ErrEmptyUsername
|
||||
}
|
||||
case "Password":
|
||||
if u.Password == "" {
|
||||
return errors.ErrEmptyPassword
|
||||
return fberrors.ErrEmptyPassword
|
||||
}
|
||||
case "ViewMode":
|
||||
if u.ViewMode == "" {
|
||||
|
||||
@@ -36,6 +36,7 @@ filebrowser config init [flags]
|
||||
--dateFormat use date format (true for absolute time, false for relative)
|
||||
--dirMode string mode bits that new directories are created with (default "0o750")
|
||||
--disableExec disables Command Runner feature (default true)
|
||||
--disableImageResolutionCalc disables image resolution calculation by reading image files
|
||||
--disablePreviewResize disable resize of image previews
|
||||
--disableThumbnails disable image thumbnails
|
||||
--disableTypeDetectionByHeader disables type detection by reading file headers
|
||||
@@ -60,6 +61,7 @@ filebrowser config init [flags]
|
||||
--recaptcha.host string use another host for ReCAPTCHA. recaptcha.net might be useful in China (default "https://www.google.com")
|
||||
--recaptcha.key string ReCaptcha site key
|
||||
--recaptcha.secret string ReCaptcha secret
|
||||
--redirectAfterCopyMove redirect to destination after copy/move
|
||||
-r, --root string root to prepend to relative paths (default ".")
|
||||
--scope string scope for users (default ".")
|
||||
--shell string shell command to which other commands should be appended
|
||||
|
||||
@@ -33,6 +33,7 @@ filebrowser config set [flags]
|
||||
--dateFormat use date format (true for absolute time, false for relative)
|
||||
--dirMode string mode bits that new directories are created with (default "0o750")
|
||||
--disableExec disables Command Runner feature (default true)
|
||||
--disableImageResolutionCalc disables image resolution calculation by reading image files
|
||||
--disablePreviewResize disable resize of image previews
|
||||
--disableThumbnails disable image thumbnails
|
||||
--disableTypeDetectionByHeader disables type detection by reading file headers
|
||||
@@ -57,6 +58,7 @@ filebrowser config set [flags]
|
||||
--recaptcha.host string use another host for ReCAPTCHA. recaptcha.net might be useful in China (default "https://www.google.com")
|
||||
--recaptcha.key string ReCaptcha site key
|
||||
--recaptcha.secret string ReCaptcha secret
|
||||
--redirectAfterCopyMove redirect to destination after copy/move
|
||||
-r, --root string root to prepend to relative paths (default ".")
|
||||
--scope string scope for users (default ".")
|
||||
--shell string shell command to which other commands should be appended
|
||||
|
||||
@@ -28,6 +28,7 @@ filebrowser users add <username> <password> [flags]
|
||||
--perm.modify modify perm for users (default true)
|
||||
--perm.rename rename perm for users (default true)
|
||||
--perm.share share perm for users (default true)
|
||||
--redirectAfterCopyMove redirect to destination after copy/move
|
||||
--scope string scope for users (default ".")
|
||||
--singleClick use single clicks only
|
||||
--sorting.asc sorting by ascending order
|
||||
|
||||
@@ -30,6 +30,7 @@ filebrowser users update <id|username> [flags]
|
||||
--perm.modify modify perm for users (default true)
|
||||
--perm.rename rename perm for users (default true)
|
||||
--perm.share share perm for users (default true)
|
||||
--redirectAfterCopyMove redirect to destination after copy/move
|
||||
--scope string scope for users (default ".")
|
||||
--singleClick use single clicks only
|
||||
--sorting.asc sorting by ascending order
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user