Update On Sat Dec 6 19:36:47 CET 2025

This commit is contained in:
github-action[bot]
2025-12-06 19:36:48 +01:00
parent 9c03728c5d
commit 643032245f
100 changed files with 977 additions and 248 deletions
+17
View File
@@ -2,6 +2,23 @@
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.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 -1
View File
@@ -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 && \
+2 -2
View File
@@ -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
}
+2 -2
View File
@@ -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
+6 -6
View File
@@ -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"
)
@@ -104,7 +104,7 @@ func getProxyAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (a
}
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 {
@@ -361,7 +361,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
}
+1 -1
View File
@@ -1,4 +1,4 @@
package errors
package fberrors
import (
"errors"
+3 -3
View File
@@ -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"
)
@@ -168,7 +168,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 +193,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)
@@ -25,9 +25,29 @@
</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>Showing {{ data.rows.length }} rows</span>
</div>
<div class="column-separator">
<label for="columnSeparator">Column Separator</label>
<select
id="columnSeparator"
class="input input--block"
v-model="columnSeparator"
>
<option :value="[',']">
{{ $t("available_csv_separators.comma") }}
</option>
<option :value="[';']">
{{ $t("available_csv_separators.semicolon") }}
</option>
<option :value="[',', ';']">
{{ $t("available_csv_separators.both") }}
</option>
</select>
</div>
</div>
</div>
</div>
@@ -35,7 +55,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;
@@ -46,9 +66,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: [] };
@@ -181,6 +203,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;
@@ -194,6 +228,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);
+5
View File
@@ -272,5 +272,10 @@
"minutes": "دقائق",
"seconds": "ثواني",
"unit": "وحدة الوقت"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Минути",
"seconds": "Секунди",
"unit": "Единица за време"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minuts",
"seconds": "Segons",
"unit": "Unitat"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minuty",
"seconds": "Sekundy",
"unit": "Časová jednotka"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+14 -9
View File
@@ -43,8 +43,8 @@
"upload": "Upload",
"openFile": "Datei öffnen",
"discardChanges": "Verwerfen",
"saveChanges": "Save changes",
"editAsText": "Edit as Text"
"saveChanges": "Änderungen speichern",
"editAsText": "Als Text bearbeiten"
},
"download": {
"downloadFile": "Download Datei",
@@ -77,8 +77,8 @@
"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."
},
"help": {
"click": "Wähle Datei oder Ordner",
@@ -105,9 +105,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 +162,7 @@
"video": "Video"
},
"settings": {
"aceEditorTheme": "Ace editor theme",
"aceEditorTheme": "Ace Editor Theme",
"admin": "Admin",
"administrator": "Administrator",
"allowCommands": "Befehle ausführen",
@@ -170,7 +170,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 +180,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",
@@ -272,5 +272,10 @@
"minutes": "Minuten",
"seconds": "Sekunden",
"unit": "Zeiteinheit"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Λεπτά",
"seconds": "Δευτερόλεπτα",
"unit": "Μονάδα χρόνου"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minutes",
"seconds": "Seconds",
"unit": "Time Unit"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minutos",
"seconds": "Segundos",
"unit": "Unidad"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "دقیقه",
"seconds": "ثانیه",
"unit": "واحد زمان"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minutes",
"seconds": "Secondes",
"unit": "Unité de temps"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "דקות",
"seconds": "שניות",
"unit": "יחידת זמן"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minute",
"seconds": "Sekunde",
"unit": "Jedinica vremena"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Perc",
"seconds": "Másodperc",
"unit": "Időegység"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Mínútur",
"seconds": "Sekúndur",
"unit": "Tímastilling"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minuti",
"seconds": "Secondi",
"unit": "Unità di tempo"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "分",
"seconds": "秒",
"unit": "時間の単位"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "분",
"seconds": "초",
"unit": "Time Unit"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minuten",
"seconds": "Seconden",
"unit": "Tijdseenheid"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minutt",
"seconds": "Sekunder",
"unit": "Time format"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minuty",
"seconds": "Sekundy",
"unit": "Jednostka czasu"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minutos",
"seconds": "Segundos",
"unit": "Unidades de Tempo"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minutos",
"seconds": "Segundos",
"unit": "Unidades de tempo"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minute",
"seconds": "Secunde",
"unit": "Unitate de timp"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Минуты",
"seconds": "Секунды",
"unit": "Единица времени"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minúty",
"seconds": "Sekundy",
"unit": "Jednotka času"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Minuter",
"seconds": "Sekunder",
"unit": "Tidsenhet"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Dakika",
"seconds": "Saniye",
"unit": "Zaman birimi"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Хвилини",
"seconds": "Секунди",
"unit": "Одиниця часу"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "Phút",
"seconds": "Giây",
"unit": "Đơn vị"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "分钟",
"seconds": "秒",
"unit": "时间单位"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5
View File
@@ -272,5 +272,10 @@
"minutes": "分鐘",
"seconds": "秒",
"unit": "時間單位"
},
"available_csv_separators": {
"comma": "Comma (,)",
"semicolon": "Semicolon (;)",
"both": "Both (,) and (;)"
}
}
+5 -2
View File
@@ -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 = "";
+1 -1
View File
@@ -19,7 +19,7 @@ require (
github.com/samber/lo v1.52.0
github.com/shirou/gopsutil/v4 v4.25.11
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
+2 -2
View File
@@ -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=
+3 -3
View File
@@ -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"
)
@@ -185,7 +185,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
+1 -1
View File
@@ -1,4 +1,4 @@
package http
package fbhttp
import (
"bufio"
+1 -1
View File
@@ -1,4 +1,4 @@
package http
package fbhttp
import (
"log"
+1 -1
View File
@@ -1,6 +1,6 @@
//go:build !dev
package http
package fbhttp
// global headers to append to every response
var globalHeaders = map[string]string{
+1 -1
View File
@@ -1,4 +1,4 @@
package http
package fbhttp
import (
"io/fs"
+1 -1
View File
@@ -1,5 +1,5 @@
//go:generate go-enum --sql --marshal --names --file $GOFILE
package http
package fbhttp
import (
"bytes"
+1 -1
View File
@@ -1,7 +1,7 @@
// Code generated by go-enum
// DO NOT EDIT!
package http
package fbhttp
import (
"database/sql/driver"
+1 -1
View File
@@ -1,4 +1,4 @@
package http
package fbhttp
import (
"errors"
+1 -1
View File
@@ -1,4 +1,4 @@
package http
package fbhttp
import (
"fmt"
+1 -1
View File
@@ -1,4 +1,4 @@
package http
package fbhttp
import (
"errors"
+7 -7
View File
@@ -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
@@ -304,13 +304,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 +335,7 @@ func patchAction(ctx context.Context, action, src, dst string, d *data, fileCach
return fileutils.MoveFile(d.user.Fs, src, dst, d.settings.FileMode, d.settings.DirMode)
default:
return fmt.Errorf("unsupported action %s: %w", action, fbErrors.ErrInvalidRequestParams)
return fmt.Errorf("unsupported action %s: %w", action, fberrors.ErrInvalidRequestParams)
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
package http
package fbhttp
import (
"net/http"
+1 -1
View File
@@ -1,4 +1,4 @@
package http
package fbhttp
import (
"encoding/json"
+4 -4
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
package http
package fbhttp
import (
"encoding/json"
+1 -1
View File
@@ -1,4 +1,4 @@
package http
package fbhttp
import (
"bytes"
+1 -1
View File
@@ -1,4 +1,4 @@
package http
package fbhttp
import (
"context"
+6 -6
View File
@@ -1,4 +1,4 @@
package http
package fbhttp
import (
"encoding/json"
@@ -12,7 +12,7 @@ import (
"golang.org/x/text/cases"
"golang.org/x/text/language"
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
fberrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/users"
)
@@ -36,7 +36,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 +46,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 +87,7 @@ var usersGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *
var userGetHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
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
}
@@ -122,7 +122,7 @@ var userPostHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *
}
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)
+1 -1
View File
@@ -1,4 +1,4 @@
package http
package fbhttp
import (
"encoding/json"
+2 -2
View File
@@ -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 == "" {
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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 -6
View File
@@ -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
+5 -5
View File
@@ -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
}
+2 -2
View File
@@ -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
+3 -3
View File
@@ -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 -4
View File
@@ -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
}
}
+3 -3
View File
@@ -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"
)
@@ -64,11 +64,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 == "" {