Compare commits

..
Author SHA1 Message Date
609e1d6482 Beta/v2.0.2 (#2845)
Co-authored-by: yzxcj797 <54314860+yzxcj797@users.noreply.github.com>
Co-authored-by: yzxcj797 <yzxcj797@users.noreply.github.com>
2026-08-24 19:33:27 -05:00
55 changed files with 937 additions and 1001 deletions

No files matched your search

+44
View File
@@ -5,6 +5,9 @@ on:
branches:
- "main"
permissions:
contents: write
jobs:
test_playwright:
name: Test Playwright
@@ -30,3 +33,44 @@ jobs:
context: .
file: ./_docker/Dockerfile.playwright-general
push: false
create_beta_release:
needs: [test_playwright]
if: startsWith(github.event.head_commit.message, 'Beta/v')
name: Create Beta Release
runs-on: ubuntu-24.04-arm
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
token: ${{ secrets.PAT }}
fetch-depth: 0
- name: Extract version from commit message
id: extract_version
shell: bash
run: |
tag_name=$(echo "${{ github.event.head_commit.message }}" | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+')-beta
if [ -z "$tag_name" ] || [ "$tag_name" = "-beta" ]; then
echo "Could not extract version from: ${{ github.event.head_commit.message }}"
exit 1
fi
echo "tag_name=$tag_name" >> $GITHUB_OUTPUT
- name: Tag release commit on main
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
TAG="${{ steps.extract_version.outputs.tag_name }}"
git tag -f "$TAG" "${{ github.sha }}"
git push origin "refs/tags/$TAG" --force
- name: Create Release
uses: softprops/action-gh-release@v2
with:
target_commitish: ${{ github.sha }}
token: ${{ secrets.PAT }}
tag_name: ${{ steps.extract_version.outputs.tag_name }}
prerelease: false
make_latest: false
draft: false
generate_release_notes: true
overwrite_existing: true
name: ${{ steps.extract_version.outputs.tag_name }}
+2 -5
View File
@@ -22,11 +22,8 @@ jobs:
- uses: actions/setup-go@v5
with:
go-version: 'stable'
- uses: golangci/golangci-lint-action@v7
with:
version: 'v2.1.6'
working-directory: backend
install-mode: goinstall
- working-directory: backend
run: go tool golangci-lint run --path-prefix=backend
format-backend:
runs-on: ubuntu-24.04-arm
steps:
-66
View File
@@ -1,66 +0,0 @@
name: beta release
on:
push:
branches:
- "beta/v[0-9]+.[0-9]+.[0-9]+"
permissions:
contents: write
jobs:
test_playwright:
name: Test Playwright - regular
runs-on: ubuntu-24.04-arm
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.0.0
- uses: actions/setup-node@v4
- working-directory: frontend
run: npm i && npm run build
- uses: actions/setup-go@v5
with:
go-version: 'stable'
- working-directory: backend
run: go build -o filebrowser .
- name: Build
uses: docker/build-push-action@v6
with:
context: .
file: ./_docker/Dockerfile.playwright-general
push: false
create_release_tag:
needs: [ test_playwright ]
name: Create Release
runs-on: ubuntu-24.04-arm
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
token: ${{ secrets.PAT }}
- name: Extract branch name
shell: bash
run: |
original_branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}
echo "branch_name=$transformed_branch" >> $GITHUB_OUTPUT
tag_name=$(echo "$original_branch" | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+')-beta
echo "tag_name=$tag_name" >> $GITHUB_OUTPUT
id: extract_branch
- uses: actions/setup-go@v5
with:
go-version: 'stable'
- name: Create Release
uses: softprops/action-gh-release@v2
with:
target_commitish: ${{ github.sha }}
token: ${{ secrets.PAT }}
tag_name: ${{ steps.extract_branch.outputs.tag_name }}
prerelease: false
make_latest: false
draft: false
generate_release_notes: true
name: ${{ steps.extract_branch.outputs.tag_name }}
+10
View File
@@ -2,6 +2,16 @@
All notable changes to this project will be documented in this file. For commit guidelines, please refer to [Standard Version](https://github.com/conventional-changelog/standard-version).
## v2.0.2
**Bugfixes**:
- OIDC: `groupsClaim` value is always included in requested scopes and falls back to the UserInfo endpoint when the ID token omits the groups claim.
- Windows: fix backslash duplication in navigation URLs, folder sizes showing 4 KB, and download/preview failures (#2815, #2816)
- Wrong extension in the 'new database was created popup (#2817) (#2824)
- External subtitles fail to load on public video shares due to authenticated subtitle endpoint (#2822) (#2827)
- OnlyOffice is inaccessible on password-protected shares (#2811)
- FFmpeg 9.0 incorrectly detected as below minimum 5.0.0 on Windows (#2820) -- thanks @yzxcj797
## v2.0.1
**Security**:
+6 -3
View File
@@ -238,11 +238,14 @@ func createConfig(configpath string, noInput bool) error {
}
for {
config.Server.DatabaseV2.Path = askQuestion(reader, "What should the file name and path be for the database?", "./database.db")
if strings.HasSuffix(config.Server.DatabaseV2.Path, ".db") {
// "database.db" is the reserved legacy-bolt filename and is rejected
// at startup (see backend/cmd/migrate.go), so the wizard must not
// suggest it as the default.
config.Server.DatabaseV2.Path = askQuestion(reader, "What should the file name and path be for the database?", "./filebrowser.sqlite")
if strings.HasSuffix(config.Server.DatabaseV2.Path, ".sqlite") {
break
}
fmt.Printf("Error: '%s' is not a valid path. Please enter a path to a file ending in .db", config.Server.DatabaseV2.Path)
fmt.Printf("Error: '%s' is not a valid path. Please enter a path to a file ending in .sqlite", config.Server.DatabaseV2.Path)
}
config.Frontend.Name = askQuestion(reader, "What should the application brand name be?", "FileBrowser Quantum")
config.Auth.AdminUsername = askQuestion(reader, "What should the default admin username be?", "admin")
+84 -87
View File
@@ -19,13 +19,13 @@ require (
github.com/google/go-cmp v0.7.0
github.com/google/uuid v1.6.0
github.com/gtsteffaniak/go-cache v1.1.0
github.com/gtsteffaniak/go-ffmpeg v0.5.1
github.com/gtsteffaniak/go-ffmpeg v0.5.2
github.com/gtsteffaniak/go-logger v1.1.0
github.com/kovidgoyal/imaging v1.8.23
github.com/mattn/go-sqlite3 v1.14.49
github.com/mattn/go-sqlite3 v1.14.50
github.com/pquerna/otp v1.5.0
github.com/spf13/afero v1.15.0
github.com/stretchr/testify v1.11.1
github.com/stretchr/testify v1.12.1
github.com/swaggo/http-swagger v1.3.4
github.com/swaggo/swag v1.16.6
golang.org/x/crypto v0.55.0
@@ -38,28 +38,29 @@ require (
golang.org/x/time v0.15.0
golang.org/x/tools v0.49.0
gopkg.in/yaml.v3 v3.0.1
modernc.org/sqlite v1.56.0
modernc.org/sqlite v1.57.0
)
require (
4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
4d63.com/gocheckcompilerdirectives v1.4.0 // indirect
4d63.com/gochecknoglobals v0.2.2 // indirect
charm.land/lipgloss/v2 v2.0.3 // indirect
codeberg.org/chavacava/garif v0.2.0 // indirect
charm.land/lipgloss/v2 v2.0.6 // indirect
codeberg.org/chavacava/garif v0.2.1 // indirect
codeberg.org/polyfloyd/go-errorlint v1.9.0 // indirect
dario.cat/mergo v1.0.2 // indirect
dev.gaijin.team/go/exhaustruct/v4 v4.0.0 // indirect
dev.gaijin.team/go/golib v0.6.0 // indirect
dev.gaijin.team/go/exhaustruct/v5 v5.0.3 // indirect
dev.gaijin.team/go/golib v0.8.1 // indirect
github.com/4meepo/tagalign v1.4.3 // indirect
github.com/Abirdcfly/dupword v0.1.7 // indirect
github.com/Abirdcfly/dupword v0.1.8 // indirect
github.com/AdminBenni/iota-mixing v1.0.0 // indirect
github.com/AlwxSin/noinlineerr v1.0.5 // indirect
github.com/Antonboom/errname v1.1.1 // indirect
github.com/Antonboom/nilnil v1.1.1 // indirect
github.com/AlwxSin/noinlineerr v1.0.6 // indirect
github.com/Antonboom/errname v1.1.2 // indirect
github.com/Antonboom/nilnil v1.1.2 // indirect
github.com/Antonboom/testifylint v1.6.4 // indirect
github.com/Azure/go-ntlmssp v0.1.1 // indirect
github.com/BurntSushi/toml v1.6.0 // indirect
github.com/ClickHouse/clickhouse-go-linter v1.2.0 // indirect
github.com/ClickHouse/clickhouse-go-linter v1.2.1 // indirect
github.com/Djarvur/go-err113 v0.1.1 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/Masterminds/semver/v3 v3.5.0 // indirect
@@ -73,42 +74,41 @@ require (
github.com/alfatraining/structtag v1.0.0 // indirect
github.com/alingse/asasalint v0.0.11 // indirect
github.com/alingse/nilnesserr v0.2.0 // indirect
github.com/andybalholm/brotli v1.2.0 // indirect
github.com/andybalholm/brotli v1.2.2 // indirect
github.com/ashanbrown/forbidigo/v2 v2.3.1 // indirect
github.com/ashanbrown/makezero/v2 v2.2.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bep/godartsass/v2 v2.5.0 // indirect
github.com/bep/golibsass v1.2.0 // indirect
github.com/bits-and-blooms/bitset v1.24.5 // indirect
github.com/bits-and-blooms/bitset v1.25.0 // indirect
github.com/bkielbasa/cyclop v1.2.3 // indirect
github.com/blizzy78/varnamelen v0.8.0 // indirect
github.com/bombsimon/wsl/v4 v4.7.0 // indirect
github.com/bombsimon/wsl/v5 v5.8.0 // indirect
github.com/bombsimon/wsl/v5 v5.9.0 // indirect
github.com/boombuler/barcode v1.1.0 // indirect
github.com/breml/bidichk v0.3.3 // indirect
github.com/breml/errchkjson v0.4.1 // indirect
github.com/butuzov/ireturn v0.4.1 // indirect
github.com/butuzov/mirror v1.3.0 // indirect
github.com/butuzov/mirror v1.3.3 // indirect
github.com/catenacyber/perfsprint v0.10.1 // indirect
github.com/ccojocar/zxcvbn-go v1.0.4 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/charithe/durationcheck v0.0.11 // indirect
github.com/charmbracelet/colorprofile v0.4.3 // indirect
github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318 // indirect
github.com/charmbracelet/x/ansi v0.11.7 // indirect
github.com/charmbracelet/ultraviolet v0.0.0-20260812204455-68fa937c71be // indirect
github.com/charmbracelet/x/ansi v0.11.8 // indirect
github.com/charmbracelet/x/term v0.2.2 // indirect
github.com/charmbracelet/x/termios v0.1.1 // indirect
github.com/charmbracelet/x/windows v0.2.2 // indirect
github.com/ckaznocha/intrange v0.3.1 // indirect
github.com/clipperhouse/displaywidth v0.11.0 // indirect
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/curioswitch/go-reassign v0.3.0 // indirect
github.com/daixiang0/gci v0.13.7 // indirect
github.com/dave/dst v0.27.3 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/daixiang0/gci v0.14.0 // indirect
github.com/dave/dst v0.27.4 // indirect
github.com/denis-tingaikin/go-header v0.5.0 // indirect
github.com/dlclark/regexp2/v2 v2.2.1 // indirect
github.com/dlclark/regexp2/v2 v2.7.1 // 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/dustin/go-humanize v1.0.1 // indirect
@@ -116,26 +116,26 @@ require (
github.com/ettle/strcase v0.2.0 // indirect
github.com/fatih/color v1.19.0 // indirect
github.com/fatih/structtag v1.2.0 // indirect
github.com/firefart/nonamedreturns v1.0.6 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.2 // indirect
github.com/firefart/nonamedreturns v1.0.8 // indirect
github.com/fsnotify/fsnotify v1.10.1 // indirect
github.com/fxamacker/cbor/v2 v2.9.3 // indirect
github.com/fzipp/gocyclo v0.6.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.15 // indirect
github.com/ghostiam/protogetter v0.3.20 // indirect
github.com/ghostiam/protogetter v0.3.21 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.8 // indirect
github.com/go-critic/go-critic v0.14.3 // indirect
github.com/go-critic/go-critic v0.14.4 // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/go-openapi/jsonpointer v1.0.0 // indirect
github.com/go-openapi/jsonreference v1.0.0 // indirect
github.com/go-openapi/spec v0.22.9 // indirect
github.com/go-openapi/swag/conv v0.28.0 // indirect
github.com/go-openapi/swag/jsonutils v0.28.0 // indirect
github.com/go-openapi/swag/loading v0.28.0 // indirect
github.com/go-openapi/swag/pools v0.28.0 // indirect
github.com/go-openapi/swag/stringutils v0.28.0 // indirect
github.com/go-openapi/swag/typeutils v0.28.0 // indirect
github.com/go-openapi/swag/yamlutils v0.28.0 // indirect
github.com/go-openapi/swag/conv v0.29.1 // indirect
github.com/go-openapi/swag/jsonutils v0.29.1 // indirect
github.com/go-openapi/swag/loading v0.29.1 // indirect
github.com/go-openapi/swag/pools v0.29.1 // indirect
github.com/go-openapi/swag/stringutils v0.29.1 // indirect
github.com/go-openapi/swag/typeutils v0.29.1 // indirect
github.com/go-openapi/swag/yamlutils v0.29.1 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-toolsmith/astcast v1.1.0 // indirect
@@ -146,26 +146,26 @@ require (
github.com/go-toolsmith/strparse v1.1.0 // indirect
github.com/go-toolsmith/typep v1.1.0 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/go-webauthn/x v0.2.8 // indirect
github.com/go-webauthn/x v0.3.0 // indirect
github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/godoc-lint/godoc-lint v0.11.2 // indirect
github.com/gofrs/flock v0.13.0 // indirect
github.com/gohugoio/hashstructure v0.6.0 // indirect
github.com/gohugoio/hugo v0.164.0 // indirect
github.com/gohugoio/hashstructure v1.0.0 // indirect
github.com/gohugoio/hugo v0.165.0 // indirect
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
github.com/golang/geo v0.0.0-20260810185319-42794aff7523 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/geo v0.0.0-20260818125358-b200a1149890 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golangci/asciicheck v0.5.0 // indirect
github.com/golangci/dupl v0.0.0-20260401084720-c99c5cf5c202 // indirect
github.com/golangci/go-printf-func-name v0.1.1 // indirect
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect
github.com/golangci/golangci-lint/v2 v2.12.2 // indirect
github.com/golangci/gofmt v0.0.0-20260820135601-e84e05053792 // indirect
github.com/golangci/golangci-lint/v2 v2.13.1 // indirect
github.com/golangci/golines v0.15.0 // indirect
github.com/golangci/misspell v0.8.0 // indirect
github.com/golangci/plugin-module-register v0.1.2 // indirect
github.com/golangci/revgrep v0.8.0 // indirect
github.com/golangci/rowserrcheck v0.0.0-20260419091836-c5f79b8a11ba // indirect
github.com/golangci/rowserrcheck v0.0.0-20260801150524-d2031e3af752 // indirect
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e // indirect
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e // indirect
github.com/google/go-tpm v0.9.8 // indirect
@@ -177,15 +177,14 @@ require (
github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
github.com/hashicorp/go-version v1.9.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jgautheron/goconst v1.10.0 // indirect
github.com/jgautheron/goconst v1.11.0 // indirect
github.com/jjti/go-spancheck v0.6.5 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/julz/importas v0.2.0 // indirect
github.com/karamaru-alpha/copyloopvar v1.2.2 // indirect
github.com/kisielk/errcheck v1.10.0 // indirect
github.com/kisielk/errcheck v1.20.0 // indirect
github.com/kkHAIKE/contextcheck v1.1.6 // indirect
github.com/kovidgoyal/go-parallel v1.1.1 // indirect
github.com/kovidgoyal/go-shm v1.0.0 // indirect
@@ -193,92 +192,90 @@ require (
github.com/kunwardeep/paralleltest v1.0.15 // indirect
github.com/lasiar/canonicalheader v1.1.2 // indirect
github.com/ldez/exptostd v0.4.5 // indirect
github.com/ldez/gomoddirectives v0.8.0 // indirect
github.com/ldez/gomoddirectives v0.9.0 // indirect
github.com/ldez/grignotin v0.10.1 // indirect
github.com/ldez/structtags v0.6.1 // indirect
github.com/ldez/tagliatelle v0.7.2 // indirect
github.com/ldez/usetesting v0.5.0 // indirect
github.com/leodido/go-urn v1.5.0 // indirect
github.com/leonklingele/grouper v1.1.2 // indirect
github.com/lucasb-eyer/go-colorful v1.4.0 // indirect
github.com/lucasb-eyer/go-colorful v1.4.1 // indirect
github.com/macabu/inamedparam v0.2.0 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/manuelarte/embeddedstructfieldcheck v0.4.0 // indirect
github.com/manuelarte/funcorder v0.6.0 // indirect
github.com/maratori/testableexamples v1.0.1 // indirect
github.com/maratori/testpackage v1.1.2 // indirect
github.com/matoous/godox v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-colorable v0.1.15 // indirect
github.com/mattn/go-isatty v0.0.24 // indirect
github.com/mattn/go-runewidth v0.0.23 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mgechev/revive v1.15.0 // indirect
github.com/mattn/go-runewidth v0.0.28 // indirect
github.com/mgechev/revive v1.16.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect
github.com/moricho/tparallel v0.3.2 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nakabonne/nestif v0.3.1 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/nishanths/exhaustive v0.12.0 // indirect
github.com/nishanths/predeclared v0.2.2 // indirect
github.com/nunnatsa/ginkgolinter v0.23.0 // indirect
github.com/nunnatsa/ginkgolinter v0.24.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.4.3 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.12.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/prometheus/client_golang v1.24.1 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.70.1 // indirect
github.com/prometheus/procfs v0.21.1 // indirect
github.com/quasilyte/go-ruleguard v0.4.5 // indirect
github.com/quasilyte/go-ruleguard/dsl v0.3.23 // indirect
github.com/quasilyte/gogrep v0.5.0 // indirect
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
github.com/raeperd/recvcheck v0.2.0 // indirect
github.com/raeperd/recvcheck v0.3.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.15.0 // indirect
github.com/rogpeppe/go-internal v1.16.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd // indirect
github.com/ryancurrah/gomodguard v1.4.1 // indirect
github.com/ryancurrah/gomodguard/v2 v2.1.3 // indirect
github.com/ryanrolds/sqlclosecheck v0.6.0 // indirect
github.com/sagikazarmark/locafero v0.12.0 // indirect
github.com/sanposhiho/wastedassign/v2 v2.1.0 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.3 // indirect
github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
github.com/sashamelentyev/usestdlibvars v1.29.0 // indirect
github.com/securego/gosec/v2 v2.26.1 // indirect
github.com/sirupsen/logrus v1.9.4 // indirect
github.com/securego/gosec/v2 v2.28.0 // indirect
github.com/sirupsen/logrus v1.10.1 // indirect
github.com/sivchari/containedctx v1.0.3 // indirect
github.com/sonatard/noctx v0.5.1 // indirect
github.com/sourcegraph/go-diff v0.8.0 // indirect
github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/cobra v1.10.2 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/spf13/viper v1.12.0 // indirect
github.com/spf13/viper v1.21.0 // indirect
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
github.com/stbenjam/no-sprintf-host-port v0.3.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/stretchr/objx v0.5.3 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/swaggo/files v1.0.1 // indirect
github.com/tdewolff/parse/v2 v2.8.12 // indirect
github.com/tdewolff/parse/v2 v2.8.16 // indirect
github.com/tetafro/godot v1.5.6 // indirect
github.com/timakin/bodyclose v0.0.0-20260129054331-73d1f95b84b4 // indirect
github.com/timakin/bodyclose v0.0.0-20260723120731-857993a2939c // indirect
github.com/timonwong/loggercheck v0.11.0 // indirect
github.com/tinylib/msgp v1.6.4 // indirect
github.com/tomarrell/wrapcheck/v2 v2.12.0 // indirect
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
github.com/ultraware/funlen v0.2.0 // indirect
github.com/ultraware/whitespace v0.2.0 // indirect
github.com/urfave/cli/v2 v2.3.0 // indirect
github.com/urfave/cli/v2 v2.27.7 // indirect
github.com/uudashr/gocognit v1.2.1 // indirect
github.com/uudashr/iface v1.4.2 // indirect
github.com/uudashr/iface v1.5.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xen0n/gosmopolitan v1.3.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/xo/terminfo v1.0.0 // indirect
github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect
github.com/yagipy/maintidx v1.0.0 // indirect
github.com/yeya24/promlinter v0.3.0 // indirect
github.com/ykadowak/zerologlint v0.1.5 // indirect
@@ -286,25 +283,25 @@ require (
go-simpler.org/musttag v0.14.0 // indirect
go-simpler.org/sloglint v0.12.0 // indirect
go.augendre.info/arangolint v0.4.0 // indirect
go.augendre.info/fatcontext v0.9.0 // indirect
go.augendre.info/fatcontext v0.10.0 // indirect
go.etcd.io/bbolt v1.5.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
go.uber.org/zap v1.27.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.28.0 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect
golang.org/x/exp/typeparams v0.0.0-20260209203927-2842357ff358 // indirect
golang.org/x/exp/typeparams v0.0.0-20260820142414-ca536658362e // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/text v0.41.0 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
google.golang.org/protobuf v1.36.12 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
honnef.co/go/tools v0.7.0 // indirect
modernc.org/libc v1.75.3 // indirect
honnef.co/go/tools v0.8.1 // indirect
modernc.org/libc v1.75.4 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.12.0 // indirect
mvdan.cc/gofumpt v0.9.2 // indirect
mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
modernc.org/memory v1.12.1 // indirect
mvdan.cc/gofumpt v0.11.0 // indirect
mvdan.cc/unparam v0.0.0-20260820064413-a201bf8e0538 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
)
tool (
+197 -592
View File
File diff suppressed because it is too large. Load diff
+1
View File
@@ -69,6 +69,7 @@ type FileOptions struct {
// SanitizePath cleans and validates a path or path-like filter (index paths, globs, etc.)
// to block traversal. Rule 1: Do Not Use Untrusted Input in File Paths (without validation).
func SanitizePath(inputPath string) (string, error) {
inputPath = strings.ReplaceAll(inputPath, `\`, `/`)
clean := path.Clean(inputPath)
// Split the path into segments to check for path traversal attempts.
-4
View File
@@ -34,10 +34,6 @@ func ParseSanitizedIndexPath(userPath string, isDir bool) (IndexPath, error) {
}
func parseIndexPath(path string, isDir bool, strict bool) (IndexPath, error) {
if strict && strings.Contains(path, `\`) {
return IndexPath{}, fmt.Errorf("invalid path: backslashes not allowed")
}
inner := strings.Trim(path, "/")
if inner == "" {
return IndexPath{IsDir: isDir}, nil
+11
View File
@@ -53,6 +53,9 @@ func TestSanitizePath_indexPaths(t *testing.T) {
{"traversal segment", "..", "", true},
{"resolved traversal", "/../secret", "/secret", false},
{"empty", "", "", true},
{"backslash traversal", `..\secret`, "", true},
{"backslash double traversal", `..\..\secret`, "", true},
{"backslash path normalized", `\foo\bar`, "/foo/bar", false},
}
for _, tt := range tests {
@@ -109,6 +112,14 @@ func TestParseSanitizedIndexPath(t *testing.T) {
if got.String() != "/secret/" {
t.Errorf("got %q want /secret/", got.String())
}
got, err = ParseSanitizedIndexPath(`\foo\bar\`, true)
if err != nil {
t.Fatalf("unexpected error for backslash path: %v", err)
}
if got.String() != "/foo/bar/" {
t.Errorf("got %q want /foo/bar/", got.String())
}
}
func TestIndexPath_Parent(t *testing.T) {
+3 -3
View File
@@ -14,9 +14,9 @@ import (
"github.com/golang-jwt/jwt/v4/request"
"golang.org/x/crypto/bcrypt"
"github.com/gtsteffaniak/filebrowser/backend/internal/auth"
"github.com/gtsteffaniak/filebrowser/backend/internal/adapters/fs/files"
"github.com/gtsteffaniak/filebrowser/backend/internal/activity"
"github.com/gtsteffaniak/filebrowser/backend/internal/adapters/fs/files"
"github.com/gtsteffaniak/filebrowser/backend/internal/auth"
activitydb "github.com/gtsteffaniak/filebrowser/backend/internal/database/activity"
"github.com/gtsteffaniak/filebrowser/backend/internal/database/share"
"github.com/gtsteffaniak/filebrowser/backend/internal/database/users"
@@ -228,7 +228,7 @@ func sessionCookieDomain(r *http.Request) string {
// @Success 200 {object} map[string]string "{"logoutUrl": "http://..."}"
// @Router /api/auth/logout [post]
func logoutHandler(w http.ResponseWriter, r *http.Request, d *Context) (int, error) {
if err := state.RevokeToken( d.Token); err != nil {
if err := state.RevokeToken(d.Token); err != nil {
logger.Errorf("Failed to revoke token on logout: %v", err)
}
+4 -3
View File
@@ -118,12 +118,12 @@ func configureHTTPRouter(router, api, publicRoutes, publicApi *http.ServeMux) {
api.HandleFunc("PUT /settings/analytics", withTimeout(time5s, withAdminHelper(settingsAnalyticsUpdateHandler)))
api.HandleFunc("PATCH /settings/analytics", withTimeout(time5s, withAdminHelper(settingsAnalyticsUpdateHandler)))
api.HandleFunc("GET /settings/analytics/preview", withTimeout(time30s, withAdminHelper(settingsAnalyticsPreviewHandler)))
api.HandleFunc("GET /settings/user-defaults", withTimeout(time5s, withUserHelper(settingsUserDefaultsGetHandler)))
api.HandleFunc("PATCH /settings/user-defaults", withTimeout(time5s, withAdminHelper(settingsUserDefaultsPatchHandler)))
publicApi.HandleFunc("GET /settings/user-defaults", withTimeout(time5s, withUserHelper(settingsUserDefaultsGetHandler)))
api.HandleFunc("GET /settings/source", withTimeout(time5s, withUserHelper(settingsSourceGetHandler)))
api.HandleFunc("PATCH /settings/source", withTimeout(time5s, withAdminHelper(settingsSourcePatchHandler)))
api.HandleFunc("GET /settings/sources", withUser(getSourceInfoHandler))
api.HandleFunc("GET /settings/user-defaults", withTimeout(time5s, withUserHelper(settingsUserDefaultsGetHandler)))
api.HandleFunc("PATCH /settings/user-defaults", withTimeout(time5s, withAdminHelper(settingsUserDefaultsPatchHandler)))
publicApi.HandleFunc("GET /settings/user-defaults", withTimeout(time5s, withUserHelper(settingsUserDefaultsGetHandler)))
// ========================================
// Tools Routes - /api/tools/
@@ -143,6 +143,7 @@ func configureHTTPRouter(router, api, publicRoutes, publicApi *http.ServeMux) {
api.HandleFunc("GET /media/metadata", withTimeout(time60s, withUserHelper(metadataHandler)))
api.HandleFunc("GET /media/lyrics", withTimeout(time60s, withUserHelper(lyricsHandler)))
api.HandleFunc("GET /media/stream", withTimeout(time60s, withUserHelper(streamHandler)))
publicApi.HandleFunc("GET /media/subtitles", withTimeout(time60s, withHashFileHelper(publicSubtitlesHandler)))
publicApi.HandleFunc("GET /media/metadata", withTimeout(time60s, withHashFileHelper(publicMetadataHandler)))
publicApi.HandleFunc("GET /media/lyrics", withTimeout(time60s, withHashFileHelper(publicLyricsHandler)))
publicApi.HandleFunc("GET /media/stream", withTimeout(time60s, withHashFileHelper(publicStreamHandler)))
+1 -5
View File
@@ -66,11 +66,7 @@ func authenticateLDAP(username, password string) ([]string, map[string]string, e
logger.Debugf("ldap: no service account bind (userPassword empty)")
}
// Build list of attributes to fetch
groupAttr := c.GroupsClaim
if groupAttr == "" {
groupAttr = "memberOf"
}
groupAttr := settings.ResolveGroupsClaim(c.GroupsClaim)
attributes := []string{"dn", groupAttr}
if c.UserIdentifier != "" {
attributes = append(attributes, c.UserIdentifier)
+63 -17
View File
@@ -13,7 +13,6 @@ import (
"github.com/gtsteffaniak/filebrowser/backend/internal/ffmpeg"
"github.com/gtsteffaniak/filebrowser/backend/internal/utils"
"github.com/gtsteffaniak/filebrowser/backend/pkg/settings"
)
// subtitlesHandler handles subtitle requests for both external files and embedded streams
@@ -33,17 +32,18 @@ import (
// @Failure 500 {object} map[string]string "Internal server error"
// @Router /api/media/subtitles [get]
func subtitlesHandler(w http.ResponseWriter, r *http.Request, d *Context) (int, error) {
name := r.URL.Query().Get("name")
path := r.URL.Query().Get("path")
source := r.URL.Query().Get("source")
name := r.URL.Query().Get("name")
embedded := r.URL.Query().Get("embedded") == "true"
if path == "" || source == "" {
return http.StatusBadRequest, fmt.Errorf("path and source are required")
}
if name == "" {
return http.StatusBadRequest, fmt.Errorf("name parameter is required")
}
if path == "" {
return http.StatusBadRequest, fmt.Errorf("path parameter is required")
}
filePerms, err := effectiveFilePerms(d, source)
if err != nil {
return http.StatusForbidden, err
@@ -52,18 +52,47 @@ func subtitlesHandler(w http.ResponseWriter, r *http.Request, d *Context) (int,
return http.StatusForbidden, fmt.Errorf("user is not allowed to view files in this source")
}
fileInfo, err := files.FileInfoFaster(utils.FileOptions{
FollowSymlinks: true,
Path: path,
Source: source,
Expand: true,
Content: false,
Metadata: true,
ExtractEmbeddedSubtitles: settings.Config.Integrations.Media.ExtractEmbeddedSubtitles,
ShowHidden: d.User.ShowHidden,
HideFileExt: d.User.HideFileExt,
SkipExtendedAttrs: false,
}, d.User)
fileUser := d.User
var fileOpts utils.FileOptions
if d.Share.Hash != "" {
source = d.Share.GetSourceName()
if source == "" {
return http.StatusNotFound, fmt.Errorf("source not found")
}
path = d.IndexPath
fileUser = d.ShareUser
fileOpts = utils.FileOptions{
Path: path,
Source: source,
Expand: true,
Content: false,
Metadata: true,
ExtractEmbeddedSubtitles: settings.Config.Integrations.Media.ExtractEmbeddedSubtitles && d.Share.ExtractEmbeddedSubtitles,
ShowHidden: d.Share.ShowHidden,
HideFileExt: d.User.HideFileExt,
FollowSymlinks: false,
SkipExtendedAttrs: false,
}
} else {
if source == "" {
return http.StatusBadRequest, fmt.Errorf("source is required")
}
fileOpts = utils.FileOptions{
FollowSymlinks: true,
Path: path,
Source: source,
Expand: true,
Content: false,
Metadata: true,
ExtractEmbeddedSubtitles: settings.Config.Integrations.Media.ExtractEmbeddedSubtitles,
ShowHidden: d.User.ShowHidden,
HideFileExt: d.User.HideFileExt,
SkipExtendedAttrs: false,
}
}
fileInfo, err := files.FileInfoFaster(fileOpts, fileUser)
if err != nil {
return ErrToStatus(err), err
}
@@ -289,3 +318,20 @@ func publicLyricsHandler(w http.ResponseWriter, r *http.Request, d *Context) (in
}
return RenderJSON(w, r, map[string]any{"lyrics": lyrics})
}
// publicSubtitlesHandler is the share-link variant of subtitlesHandler.
// @Summary Get subtitle content (public share)
// @Tags Media
// @Produce text/plain
// @Param hash query string true "Share hash"
// @Param path query string false "Path within the share"
// @Param name query string true "Subtitle track name"
// @Param embedded query bool false "Whether this is an embedded stream"
// @Success 200 {string} string "Raw subtitle content"
// @Router /public/api/media/subtitles [get]
func publicSubtitlesHandler(w http.ResponseWriter, r *http.Request, d *Context) (int, error) {
if d.Share.ShareType == "upload" {
return http.StatusNotImplemented, fmt.Errorf("browsing is disabled for upload shares")
}
return subtitlesHandler(w, r, d)
}
+1
View File
@@ -125,6 +125,7 @@ func withHashFileHelper(fn handleFunc) handleFunc {
(r.Method == "POST" && strings.Contains(r.URL.Path, "/resources/view-token")) ||
(r.Method == "GET" && strings.Contains(r.URL.Path, "/resources/items")) ||
(r.Method == "GET" && strings.Contains(r.URL.Path, "/media/metadata")) ||
(r.Method == "GET" && strings.Contains(r.URL.Path, "/media/subtitles")) ||
(r.Method == "GET" && strings.Contains(r.URL.Path, "/resources/download")) ||
(r.Method == "GET" && strings.Contains(r.URL.Path, "/resources/view")) ||
(r.Method == "GET" && strings.Contains(r.URL.Path, "/media/stream")) {
+5
View File
@@ -272,6 +272,11 @@ func oidcCallbackHandler(w http.ResponseWriter, r *http.Request, d *Context) (in
// Even if parsing succeeded, if essential claims are missing, use UserInfo
if _, ok := userdata.Claims[oidcCfg.UserIdentifier]; ok {
claimsFromIDToken = true
needsGroups := oidcCfg.AdminGroup != "" || len(oidcCfg.UserGroups) > 0
if needsGroups && len(userdata.Groups) == 0 {
logger.Debugf("OIDC: ID token missing groups claim (adminGroup/userGroups configured); fetching UserInfo")
claimsFromIDToken = false
}
}
}
}
+23 -6
View File
@@ -213,11 +213,13 @@ func onlyofficeClientConfigGetHandler(w http.ResponseWriter, r *http.Request, d
return http.StatusForbidden, err
}
shareToken := shareTokenForOnlyOffice(d)
// Build view URL that OnlyOffice server will use to fetch the file
documentURL := buildOnlyOfficeViewURL(r, source, providedPath, d.FileInfo.Hash, viewToken, d.Token)
documentURL := buildOnlyOfficeViewURL(r, source, providedPath, d.FileInfo.Hash, viewToken, d.Token, shareToken)
// Build callback URL for OnlyOffice to notify us of changes
callbackURL := buildOnlyOfficeCallbackURL(r, source, providedPath, d.FileInfo.Hash, d.Token)
callbackURL := buildOnlyOfficeCallbackURL(r, source, providedPath, d.FileInfo.Hash, d.Token, shareToken)
// Build OnlyOffice client configuration
clientConfig := map[string]interface{}{
@@ -296,14 +298,26 @@ func joinOnlyOfficeAPIURL(baseURL, apiPath string) string {
return base + "/" + path
}
// shareTokenForOnlyOffice returns the share download token for OnlyOffice server URLs.
// Only password-protected shares have a token; callers must already have passed share auth.
func shareTokenForOnlyOffice(d *Context) string {
if d.Share.Hash == "" || d.Share.PasswordHash == "" || d.Share.Token == "" {
return ""
}
return d.Share.Token
}
// buildOnlyOfficeViewURL constructs the view URL that OnlyOffice server uses to fetch the document.
func buildOnlyOfficeViewURL(r *http.Request, source, path, hash, viewToken, authToken string) string {
func buildOnlyOfficeViewURL(r *http.Request, source, path, hash, viewToken, authToken, shareToken string) string {
baseURL := onlyOfficeFileBrowserBaseURL(r)
params := url.Values{}
params.Set("file", path)
params.Set("viewToken", viewToken)
if hash != "" {
params.Set("hash", hash)
if shareToken != "" {
params.Set("token", shareToken)
}
return joinOnlyOfficeAPIURL(baseURL, "public/api/resources/view") + "?" + params.Encode()
}
params.Set("source", source)
@@ -312,7 +326,7 @@ func buildOnlyOfficeViewURL(r *http.Request, source, path, hash, viewToken, auth
}
// buildOnlyOfficeCallbackURL constructs the callback URL that OnlyOffice server will use to notify us of changes
func buildOnlyOfficeCallbackURL(r *http.Request, source, path, hash, token string) string {
func buildOnlyOfficeCallbackURL(r *http.Request, source, path, hash, authToken, shareToken string) string {
baseURL := onlyOfficeFileBrowserBaseURL(r)
params := url.Values{}
@@ -320,14 +334,17 @@ func buildOnlyOfficeCallbackURL(r *http.Request, source, path, hash, token strin
// Share callback URL - use public API and don't expose source, use path relative to share
params.Set("hash", hash)
params.Set("path", path)
params.Set("auth", token)
params.Set("auth", authToken)
if shareToken != "" {
params.Set("token", shareToken)
}
return joinOnlyOfficeAPIURL(baseURL, "public/api/office/callback") + "?" + params.Encode()
}
// Regular callback URL - include source for non-share requests
params.Set("source", source)
params.Set("path", path)
params.Set("auth", token)
params.Set("auth", authToken)
return joinOnlyOfficeAPIURL(baseURL, "api/office/callback") + "?" + params.Encode()
}
+80 -2
View File
@@ -5,6 +5,7 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"github.com/gtsteffaniak/filebrowser/backend/internal/adapters/fs/files"
@@ -60,19 +61,96 @@ func TestBuildOnlyOfficeViewURL(t *testing.T) {
settings.Config.Http.BaseURL = "/testing/"
req := httptest.NewRequest(http.MethodGet, "/", nil)
got := buildOnlyOfficeViewURL(req, "Downloads", "/doc.docx", "", "view-token", "session.jwt.token")
got := buildOnlyOfficeViewURL(req, "Downloads", "/doc.docx", "", "view-token", "session.jwt.token", "")
want := "http://filebrowser:8080/testing/api/resources/view?auth=session.jwt.token&file=%2Fdoc.docx&source=Downloads&viewToken=view-token"
if got != want {
t.Fatalf("buildOnlyOfficeViewURL() = %q, want %q", got, want)
}
shareGot := buildOnlyOfficeViewURL(req, "Downloads", "/doc.docx", "share-hash", "view-token", "session.jwt.token")
shareGot := buildOnlyOfficeViewURL(req, "Downloads", "/doc.docx", "share-hash", "view-token", "session.jwt.token", "")
shareWant := "http://filebrowser:8080/testing/public/api/resources/view?file=%2Fdoc.docx&hash=share-hash&viewToken=view-token"
if shareGot != shareWant {
t.Fatalf("buildOnlyOfficeViewURL(share) = %q, want %q", shareGot, shareWant)
}
}
func TestBuildOnlyOfficeShareURLs(t *testing.T) {
origHTTP := settings.Config.Http
t.Cleanup(func() { settings.Config.Http = origHTTP })
settings.Config.Http.BaseURL = "/files/"
settings.Config.Http.InternalUrl = ""
req := httptest.NewRequest(http.MethodGet, "http://example.com/files/public/api/office/config?hash=abc", nil)
t.Run("share view URL includes share token", func(t *testing.T) {
got := buildOnlyOfficeViewURL(req, "source", "/doc.docx", "shareHash", "view-token", "jwt-token", "share-download-token")
parsed, err := url.Parse(got)
if err != nil {
t.Fatalf("parse view URL: %v", err)
}
q := parsed.Query()
if q.Get("hash") != "shareHash" {
t.Errorf("hash = %q, want shareHash", q.Get("hash"))
}
if q.Get("viewToken") != "view-token" {
t.Errorf("viewToken = %q, want view-token", q.Get("viewToken"))
}
if q.Get("token") != "share-download-token" {
t.Errorf("token = %q, want share-download-token", q.Get("token"))
}
if q.Get("file") != "/doc.docx" {
t.Errorf("file = %q, want /doc.docx", q.Get("file"))
}
})
t.Run("share view URL omits token when empty", func(t *testing.T) {
got := buildOnlyOfficeViewURL(req, "source", "/doc.docx", "shareHash", "view-token", "jwt-token", "")
parsed, err := url.Parse(got)
if err != nil {
t.Fatalf("parse view URL: %v", err)
}
if parsed.Query().Get("token") != "" {
t.Errorf("expected no token param, got %q", parsed.Query().Get("token"))
}
})
t.Run("non-share view URL unchanged", func(t *testing.T) {
got := buildOnlyOfficeViewURL(req, "my-source", "/doc.docx", "", "view-token", "jwt-token", "share-download-token")
if strings.Contains(got, "token=") {
t.Errorf("non-share URL should not include share token: %q", got)
}
if !strings.Contains(got, "source=my-source") {
t.Errorf("expected source in URL, got %q", got)
}
})
t.Run("share callback URL includes share token", func(t *testing.T) {
got := buildOnlyOfficeCallbackURL(req, "source", "/doc.docx", "shareHash", "jwt-token", "share-download-token")
parsed, err := url.Parse(got)
if err != nil {
t.Fatalf("parse callback URL: %v", err)
}
q := parsed.Query()
if q.Get("token") != "share-download-token" {
t.Errorf("token = %q, want share-download-token", q.Get("token"))
}
if q.Get("auth") != "jwt-token" {
t.Errorf("auth = %q, want jwt-token", q.Get("auth"))
}
})
t.Run("share callback URL omits token when empty", func(t *testing.T) {
got := buildOnlyOfficeCallbackURL(req, "source", "/doc.docx", "shareHash", "jwt-token", "")
parsed, err := url.Parse(got)
if err != nil {
t.Fatalf("parse callback URL: %v", err)
}
if parsed.Query().Get("token") != "" {
t.Errorf("expected no token param, got %q", parsed.Query().Get("token"))
}
})
}
func TestJoinOnlyOfficeAPIURL(t *testing.T) {
tests := []struct {
base string
+3 -6
View File
@@ -149,6 +149,7 @@ func ValidateLdapAuth() error {
if ldapCfg.UserFilter == "" {
ldapCfg.UserFilter = "(&(cn=%s)(objectClass=user))"
}
applyAuthCommonDefaults(&ldapCfg.AuthCommon)
if err := verifyLdapConnection(); err != nil {
logger.Fatalf("LDAP connection check failed: %v", err)
}
@@ -158,9 +159,7 @@ func ValidateLdapAuth() error {
// ValidateOidcAuth processes the OIDC callback and retrieves user identity
func validateOidcAuth() error {
oidcCfg := &Config.Auth.Methods.OidcAuth // Use a pointer to modify the original config
if oidcCfg.GroupsClaim == "" {
oidcCfg.GroupsClaim = "groups"
}
applyAuthCommonDefaults(&oidcCfg.AuthCommon)
if oidcCfg.UserIdentifier == "" {
oidcCfg.UserIdentifier = "preferred_username"
}
@@ -289,9 +288,7 @@ func ValidateJwtAuth() error {
if jwtCfg.Algorithm == "" {
jwtCfg.Algorithm = "HS256"
}
if jwtCfg.GroupsClaim == "" {
jwtCfg.GroupsClaim = "groups"
}
applyAuthCommonDefaults(&jwtCfg.AuthCommon)
if jwtCfg.UserIdentifier == "" {
jwtCfg.UserIdentifier = "sub"
}
+16
View File
@@ -0,0 +1,16 @@
package settings
const defaultGroupsClaim = "groups"
// ResolveGroupsClaim returns the configured groups claim or the shared default when empty.
func ResolveGroupsClaim(claim string) string {
if claim == "" {
return defaultGroupsClaim
}
return claim
}
// applyAuthCommonDefaults sets shared defaults for external auth methods that support group claims.
func applyAuthCommonDefaults(c *AuthCommon) {
c.GroupsClaim = ResolveGroupsClaim(c.GroupsClaim)
}
+26
View File
@@ -0,0 +1,26 @@
package settings
import "testing"
func TestApplyAuthCommonDefaults(t *testing.T) {
empty := AuthCommon{}
applyAuthCommonDefaults(&empty)
if empty.GroupsClaim != "groups" {
t.Fatalf("default groupsClaim = %q, want groups", empty.GroupsClaim)
}
custom := AuthCommon{GroupsClaim: "memberOf"}
applyAuthCommonDefaults(&custom)
if custom.GroupsClaim != "memberOf" {
t.Fatalf("custom groupsClaim = %q, want memberOf", custom.GroupsClaim)
}
}
func TestResolveGroupsClaim(t *testing.T) {
if got := ResolveGroupsClaim(""); got != "groups" {
t.Fatalf("ResolveGroupsClaim(\"\") = %q, want groups", got)
}
if got := ResolveGroupsClaim("memberOf"); got != "memberOf" {
t.Fatalf("ResolveGroupsClaim(memberOf) = %q, want memberOf", got)
}
}
+1
View File
@@ -515,6 +515,7 @@ func setupAuth(generate bool) {
Config.Auth.AuthMethods = append(Config.Auth.AuthMethods, "password")
}
if Config.Auth.Methods.ProxyAuth.Enabled {
applyAuthCommonDefaults(&Config.Auth.Methods.ProxyAuth.AuthCommon)
Config.Auth.AuthMethods = append(Config.Auth.AuthMethods, "proxy")
}
if Config.Auth.Methods.NoAuth {
+47
View File
@@ -4003,6 +4003,53 @@ const docTemplate = `{
}
}
},
"/public/api/media/subtitles": {
"get": {
"produces": [
"text/plain"
],
"tags": [
"Media"
],
"summary": "Get subtitle content (public share)",
"parameters": [
{
"type": "string",
"description": "Share hash",
"name": "hash",
"in": "query",
"required": true
},
{
"type": "string",
"description": "Path within the share",
"name": "path",
"in": "query"
},
{
"type": "string",
"description": "Subtitle track name",
"name": "name",
"in": "query",
"required": true
},
{
"type": "boolean",
"description": "Whether this is an embedded stream",
"name": "embedded",
"in": "query"
}
],
"responses": {
"200": {
"description": "Raw subtitle content",
"schema": {
"type": "string"
}
}
}
}
},
"/public/api/resources": {
"get": {
"description": "Returns metadata for files or directories accessible via a public share link. Browsing is disabled for upload-only shares.",
+47
View File
@@ -3992,6 +3992,53 @@
}
}
},
"/public/api/media/subtitles": {
"get": {
"produces": [
"text/plain"
],
"tags": [
"Media"
],
"summary": "Get subtitle content (public share)",
"parameters": [
{
"type": "string",
"description": "Share hash",
"name": "hash",
"in": "query",
"required": true
},
{
"type": "string",
"description": "Path within the share",
"name": "path",
"in": "query"
},
{
"type": "string",
"description": "Subtitle track name",
"name": "name",
"in": "query",
"required": true
},
{
"type": "boolean",
"description": "Whether this is an embedded stream",
"name": "embedded",
"in": "query"
}
],
"responses": {
"200": {
"description": "Raw subtitle content",
"schema": {
"type": "string"
}
}
}
}
},
"/public/api/resources": {
"get": {
"description": "Returns metadata for files or directories accessible via a public share link. Browsing is disabled for upload-only shares.",
+31
View File
@@ -5074,6 +5074,37 @@ paths:
summary: Stream a single media file from a public share for inline viewing
tags:
- Resources
/public/api/media/subtitles:
get:
parameters:
- description: Share hash
in: query
name: hash
required: true
type: string
- description: Path within the share
in: query
name: path
type: string
- description: Subtitle track name
in: query
name: name
required: true
type: string
- description: Whether this is an embedded stream
in: query
name: embedded
type: boolean
produces:
- text/plain
responses:
"200":
description: Raw subtitle content
schema:
type: string
summary: Get subtitle content (public share)
tags:
- Media
/public/api/resources:
get:
consumes:
+166 -166
View File
@@ -946,9 +946,9 @@
}
},
"node_modules/@intlify/bundle-utils": {
"version": "11.2.4",
"resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-11.2.4.tgz",
"integrity": "sha512-eE18yR9eM9k5n8snCkHIYp2MuVTxa19aF8z9OMyxXWv0frz2HlBZDGIPFjA38pP3OJ1IlRBXC/dW5GILeLMSCQ==",
"version": "11.2.5",
"resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-11.2.5.tgz",
"integrity": "sha512-gl7CGygRALtuT4H8n/PNC0hubg4rnctPoT04//GZNsTemvJw0Q7i6jSaq0PZHxnH0cdGqyowNXmW4FYILbahzg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1155,14 +1155,14 @@
}
},
"node_modules/@intlify/unplugin-vue-i18n": {
"version": "11.2.4",
"resolved": "https://registry.npmjs.org/@intlify/unplugin-vue-i18n/-/unplugin-vue-i18n-11.2.4.tgz",
"integrity": "sha512-bY0ZOaVUvWTyvy4bRGCUKw4Brx5uH/ojjVKsZ1aWzY2drFKIJbeP8DpGMD2QZT8aLpZSUsHtiJlRGLQSZenrvw==",
"version": "11.2.5",
"resolved": "https://registry.npmjs.org/@intlify/unplugin-vue-i18n/-/unplugin-vue-i18n-11.2.5.tgz",
"integrity": "sha512-wLpS0cZTNAzaNL/STjjwSFhLunuoARKzEJh7jM/G00A40cVH+GEPhdo/WsvnesPvQVoN6JfjI/mGXwDNnTbvhg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@intlify/bundle-utils": "11.2.4",
"@intlify/bundle-utils": "11.2.5",
"@intlify/shared": "~11.4.2",
"@intlify/vue-i18n-extensions": "^8.0.0",
"@rollup/pluginutils": "^5.1.0",
@@ -1505,9 +1505,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz",
"integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.5.tgz",
"integrity": "sha512-jfkGfTwhQpsiSckPF8r9bU3pn3vyd72NlWaO+TgEO6WPSDnUhXzrNYCHBMOYj0ACaUgjm6eERLF+XV9a6RstoA==",
"cpu": [
"arm"
],
@@ -1519,9 +1519,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz",
"integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.5.tgz",
"integrity": "sha512-oGVqyQlxnrz9/ty89oHpU857VUHEl5/Xu4R2lS+aivCTrNnSsbiENzTnNaBsjxH0CNWGPhzHArOLFwo+oKXveA==",
"cpu": [
"arm64"
],
@@ -1533,9 +1533,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz",
"integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.5.tgz",
"integrity": "sha512-bW7B8xMEq8n99Q3ieEcPRGuphurdZAaFzQc9Efyyw3FL6DZO6pMy9xhdN+kBoD7Sy05xNXSr4OyPPnpkYriS/A==",
"cpu": [
"arm64"
],
@@ -1547,9 +1547,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz",
"integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.5.tgz",
"integrity": "sha512-YSwBS86QeHOGlrxJ1PSOIZSkzRL/JmKeunhc+lV6M1a6En8QuVCD/T/qIA0J4Gd2Y86RIOBYrLcOUtqGh9+/1w==",
"cpu": [
"x64"
],
@@ -1561,9 +1561,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz",
"integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.5.tgz",
"integrity": "sha512-2fST8lILgl7cKbme/1KDdPCmbXbG+gqoV3bHp19L0ypX/3akYMBVdOunPleRCwonoLnXOZ/0F+Mt/v8POFmfcQ==",
"cpu": [
"arm64"
],
@@ -1575,9 +1575,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz",
"integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.5.tgz",
"integrity": "sha512-cpIxQCP9J+EVad0a6LO1kY3ZGODlk80VlI+2I96B8xMcdHZ4pLVhfQ49JFpYqjPF91FFkQWftf57YlDcTiw9yQ==",
"cpu": [
"x64"
],
@@ -1589,9 +1589,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz",
"integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.5.tgz",
"integrity": "sha512-r9fGh3eFs3e/udWh5ZjXQtxiYK/xoFxQaYR/cELxac/Udkl5Th+IsFm0CX3Kl9hmUH/we7EoMpjJgeQNnE0+IA==",
"cpu": [
"arm"
],
@@ -1603,9 +1603,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz",
"integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.5.tgz",
"integrity": "sha512-xdvFdp7OM6KLJviJT2g/YuRSUjnZgGHk4RNgwIbN7X6cPugOucV60DdHXWzsBVCUdrGb6qSXnJQrrAKMmQuj3Q==",
"cpu": [
"arm"
],
@@ -1617,9 +1617,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz",
"integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.5.tgz",
"integrity": "sha512-rRqILAndyzHzP7T9NFQrq+4HFWNhqkqkKur7eiBpfLmz01PO0JKx5Vchu3YllE4YXI/Ftgq/szrDWg5GJ0mI8g==",
"cpu": [
"arm64"
],
@@ -1631,9 +1631,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz",
"integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.5.tgz",
"integrity": "sha512-Gf4X3qVMucayUvux6aXXPgXovocSFUC0rrffDuPI/S2nHhNMhjcZxsrAFYCOF350PRreW1XwzFj3CT/3bKsWCw==",
"cpu": [
"arm64"
],
@@ -1645,9 +1645,9 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz",
"integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.5.tgz",
"integrity": "sha512-+s5qA0TNM0qm8PK/a5gt/1Hpx+NV08uSuCncvhziIlQzT6AEV2fnUQo7eBtFTFO0nA9scauvoR2HusfXmQnO4w==",
"cpu": [
"loong64"
],
@@ -1659,9 +1659,9 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-musl": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz",
"integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.5.tgz",
"integrity": "sha512-ybb6QvWwWJCbBWqERpc8K3pYVGIrXlG8MEQ8IIuJY6Y9KdHQxoFoNyfkAOtKn1VHu3KuLidXvwrvGR1mEjeWCw==",
"cpu": [
"loong64"
],
@@ -1673,9 +1673,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz",
"integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.5.tgz",
"integrity": "sha512-nZb1DtnOyhCmYvsC8A2CwOkopVg+IS1+fPUa7rMOAXtNw5+lLCLLPqd6XAiNrGtoQKsbvIBOwsHnBH/3wnb4HQ==",
"cpu": [
"ppc64"
],
@@ -1687,9 +1687,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-musl": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz",
"integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.5.tgz",
"integrity": "sha512-yMbj63Sp89ryrXLWyz+sy+fYD2HpOnMCLGbe4Oa1smclFSUukdtD/BgdiHaAetJNb74URD8U4hM+qG5KVzMEkg==",
"cpu": [
"ppc64"
],
@@ -1701,9 +1701,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz",
"integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.5.tgz",
"integrity": "sha512-mhoan3OJw2kYV/e1jtIdmvUZgyBFeA6zGWsOswmR0Tg19TQbowZuR+JMLID6spbbBN7Zee2ejrgmy3+FxGrIdA==",
"cpu": [
"riscv64"
],
@@ -1715,9 +1715,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz",
"integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.5.tgz",
"integrity": "sha512-5ZTLmjWbb1VZdjuyhe83K/8QO0/h11midQCBP+X5OYn32ra7eOBoM0ZqtaY4nkgNsYgmdVhMYPoyVPTjUpHf3w==",
"cpu": [
"riscv64"
],
@@ -1729,9 +1729,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz",
"integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.5.tgz",
"integrity": "sha512-m53kG+br6PGxOTmgBEM2DHSDs9RVjsyEbUwjJPJGTFm1grWOG8EKJggDCTb60unD4Tjby8fi7/m9XfkEWasVWg==",
"cpu": [
"s390x"
],
@@ -1743,9 +1743,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz",
"integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.5.tgz",
"integrity": "sha512-6RHPJR1g/uvdYU8uXBnfq3nlqyZCP82Fr6NHgfGoaIeSh0YEqnX/x6uA9MmJJbnSH7swqX4F+CkGdUF+6doiQA==",
"cpu": [
"x64"
],
@@ -1757,9 +1757,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz",
"integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.5.tgz",
"integrity": "sha512-xs+OXQtEXgpXT0DmA5+U3qnRZHdCST/5HRQxS8wSPZTUZN/EMWeHuSIod32LQklTBZBV9DyfncKBQ8n5V3eFdw==",
"cpu": [
"x64"
],
@@ -1771,9 +1771,9 @@
]
},
"node_modules/@rollup/rollup-openbsd-x64": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz",
"integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.5.tgz",
"integrity": "sha512-e7hD+sl3s+mcLQDZ8pbudBVsdG6r5yN4w3LqG2TJ8sQHDpblWj5lrJs/3m01Cvlxbt4x13zu5thLjgypgtkYzw==",
"cpu": [
"x64"
],
@@ -1785,9 +1785,9 @@
]
},
"node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz",
"integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.5.tgz",
"integrity": "sha512-GiyJaCf+WpMub/17aPcKk27QMl5W6f+KhdPTjlFOn5akH5Wa/DCM9Stdx5cDfmasyKB08MqpVQ1uJE2RkkpbXg==",
"cpu": [
"arm64"
],
@@ -1799,9 +1799,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz",
"integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.5.tgz",
"integrity": "sha512-+OQ8U2DdoEfXl8T4Fb18AjmEwbXMerKDKCL8yCPAYhKCEEKoul7rkbeGCBFCbAlaGaa7pmtRTpkAJM2LE/i5FA==",
"cpu": [
"arm64"
],
@@ -1813,9 +1813,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz",
"integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.5.tgz",
"integrity": "sha512-KanvAZrPKbDBFwrgiU9yEVpQoox9QPV1WZOXX7HudJQY+eSlu82CtWxDU8WtuRRvtN5EGkLczkd6Y6DTcvm9wA==",
"cpu": [
"ia32"
],
@@ -1827,9 +1827,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz",
"integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.5.tgz",
"integrity": "sha512-1aC3UEWTtRl3RK3VpDJ/Tqk1XI4SLTmXIthAq6wRWo8XiSXJNd+VprJM4/1P4+i6HIaFEFlVi9sTTziniD2tOQ==",
"cpu": [
"x64"
],
@@ -1841,9 +1841,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz",
"integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.5.tgz",
"integrity": "sha512-/gDJaRs4gl0NPIwqCz+6PkpmhhjRAD2j6P4rSNHBzUkO3naEx2mIU0pRle1vUNRQ7mE/+8OOeXLTv/J56FKiQg==",
"cpu": [
"x64"
],
@@ -2196,16 +2196,16 @@
}
},
"node_modules/@vitest/expect": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz",
"integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==",
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz",
"integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@standard-schema/spec": "^1.1.0",
"@types/chai": "^5.2.2",
"@vitest/spy": "4.1.10",
"@vitest/utils": "4.1.10",
"@vitest/spy": "4.1.11",
"@vitest/utils": "4.1.11",
"chai": "^6.2.2",
"tinyrainbow": "^3.1.0"
},
@@ -2214,13 +2214,13 @@
}
},
"node_modules/@vitest/mocker": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz",
"integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==",
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz",
"integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/spy": "4.1.10",
"@vitest/spy": "4.1.11",
"estree-walker": "^3.0.3",
"magic-string": "^0.30.21"
},
@@ -2251,9 +2251,9 @@
}
},
"node_modules/@vitest/pretty-format": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz",
"integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==",
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz",
"integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2264,13 +2264,13 @@
}
},
"node_modules/@vitest/runner": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz",
"integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==",
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz",
"integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/utils": "4.1.10",
"@vitest/utils": "4.1.11",
"pathe": "^2.0.3"
},
"funding": {
@@ -2278,14 +2278,14 @@
}
},
"node_modules/@vitest/snapshot": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz",
"integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==",
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz",
"integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/pretty-format": "4.1.10",
"@vitest/utils": "4.1.10",
"@vitest/pretty-format": "4.1.11",
"@vitest/utils": "4.1.11",
"magic-string": "^0.30.21",
"pathe": "^2.0.3"
},
@@ -2294,9 +2294,9 @@
}
},
"node_modules/@vitest/spy": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz",
"integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==",
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz",
"integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==",
"dev": true,
"license": "MIT",
"funding": {
@@ -2304,13 +2304,13 @@
}
},
"node_modules/@vitest/utils": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz",
"integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==",
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz",
"integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/pretty-format": "4.1.10",
"@vitest/pretty-format": "4.1.11",
"convert-source-map": "^2.0.0",
"tinyrainbow": "^3.1.0"
},
@@ -2488,9 +2488,9 @@
"license": "MIT"
},
"node_modules/@xmldom/xmldom": {
"version": "0.8.14",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.14.tgz",
"integrity": "sha512-T4EDRUBVZYRldYApjEJiU0e1stYWaRAX7CuSnKzrpwdZKo53zGV8/pqfzV6FfwNl9YThD2OumQYvqtvjvgG7aQ==",
"version": "0.8.15",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.15.tgz",
"integrity": "sha512-/5NV/vDALVFDXgLmfsy9TRCBlKwO2LNBFzpzvb9iIj+jR+eSc6DLYYvVOdivT/jm7MtU6TebYuRmzEOI7w40UA==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
@@ -3011,9 +3011,9 @@
"license": "BSD-2-Clause"
},
"node_modules/dompurify": {
"version": "3.4.13",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.13.tgz",
"integrity": "sha512-2vmYIoqjze2d+kakP8S/nS5shfsl587kzwEjcGlTdiksUVgFHnFCsLYDVj/JNqJVOQZGSYBTmuycv0PodwmnMQ==",
"version": "3.4.14",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.14.tgz",
"integrity": "sha512-dVoH9z+MY+C9IilgGCk3YfFqjLi3fChm2OiKJMzh6axrJ5qwxqWaZamgmHrpv22CN/KdbZJuGEGgfQoL00LTdg==",
"license": "(MPL-2.0 OR Apache-2.0)",
"optionalDependencies": {
"@types/trusted-types": "^2.0.7"
@@ -3104,9 +3104,9 @@
}
},
"node_modules/es-module-lexer": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz",
"integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==",
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz",
"integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==",
"dev": true,
"license": "MIT"
},
@@ -3255,9 +3255,9 @@
}
},
"node_modules/eslint": {
"version": "10.8.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.8.1.tgz",
"integrity": "sha512-wqA7W2jbsC/BnV9Iv1UZpKVFkO1AdNoSmYW8NWG4HNOBbkAMvIqDZ27pI2f07dqn583NcIC44ckjAcOXDL1QbQ==",
"version": "10.9.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.9.0.tgz",
"integrity": "sha512-5KeEOJZBfEVA47boFiBsf+6MmmJpffM7qEBg4pLla2e4nlKgdKlqCW0oSLOGsT8Wl5uCGJptLV1bkaiShj90Gw==",
"dev": true,
"license": "MIT",
"workspaces": [
@@ -5176,9 +5176,9 @@
}
},
"node_modules/rollup": {
"version": "4.62.4",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz",
"integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==",
"version": "4.62.5",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.5.tgz",
"integrity": "sha512-/tqMfgP7GPA3PHhCmuiS4vIjrSVhHLgY++i+dhbG462euyAj7FpM4D9uq1X3BgjlqRdpcOrYhcQtfiQLNc8tqw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5193,31 +5193,31 @@
},
"optionalDependencies": {
"@napi-rs/lzma-linux-x64-gnu": "1.5.1",
"@rollup/rollup-android-arm-eabi": "4.62.4",
"@rollup/rollup-android-arm64": "4.62.4",
"@rollup/rollup-darwin-arm64": "4.62.4",
"@rollup/rollup-darwin-x64": "4.62.4",
"@rollup/rollup-freebsd-arm64": "4.62.4",
"@rollup/rollup-freebsd-x64": "4.62.4",
"@rollup/rollup-linux-arm-gnueabihf": "4.62.4",
"@rollup/rollup-linux-arm-musleabihf": "4.62.4",
"@rollup/rollup-linux-arm64-gnu": "4.62.4",
"@rollup/rollup-linux-arm64-musl": "4.62.4",
"@rollup/rollup-linux-loong64-gnu": "4.62.4",
"@rollup/rollup-linux-loong64-musl": "4.62.4",
"@rollup/rollup-linux-ppc64-gnu": "4.62.4",
"@rollup/rollup-linux-ppc64-musl": "4.62.4",
"@rollup/rollup-linux-riscv64-gnu": "4.62.4",
"@rollup/rollup-linux-riscv64-musl": "4.62.4",
"@rollup/rollup-linux-s390x-gnu": "4.62.4",
"@rollup/rollup-linux-x64-gnu": "4.62.4",
"@rollup/rollup-linux-x64-musl": "4.62.4",
"@rollup/rollup-openbsd-x64": "4.62.4",
"@rollup/rollup-openharmony-arm64": "4.62.4",
"@rollup/rollup-win32-arm64-msvc": "4.62.4",
"@rollup/rollup-win32-ia32-msvc": "4.62.4",
"@rollup/rollup-win32-x64-gnu": "4.62.4",
"@rollup/rollup-win32-x64-msvc": "4.62.4",
"@rollup/rollup-android-arm-eabi": "4.62.5",
"@rollup/rollup-android-arm64": "4.62.5",
"@rollup/rollup-darwin-arm64": "4.62.5",
"@rollup/rollup-darwin-x64": "4.62.5",
"@rollup/rollup-freebsd-arm64": "4.62.5",
"@rollup/rollup-freebsd-x64": "4.62.5",
"@rollup/rollup-linux-arm-gnueabihf": "4.62.5",
"@rollup/rollup-linux-arm-musleabihf": "4.62.5",
"@rollup/rollup-linux-arm64-gnu": "4.62.5",
"@rollup/rollup-linux-arm64-musl": "4.62.5",
"@rollup/rollup-linux-loong64-gnu": "4.62.5",
"@rollup/rollup-linux-loong64-musl": "4.62.5",
"@rollup/rollup-linux-ppc64-gnu": "4.62.5",
"@rollup/rollup-linux-ppc64-musl": "4.62.5",
"@rollup/rollup-linux-riscv64-gnu": "4.62.5",
"@rollup/rollup-linux-riscv64-musl": "4.62.5",
"@rollup/rollup-linux-s390x-gnu": "4.62.5",
"@rollup/rollup-linux-x64-gnu": "4.62.5",
"@rollup/rollup-linux-x64-musl": "4.62.5",
"@rollup/rollup-openbsd-x64": "4.62.5",
"@rollup/rollup-openharmony-arm64": "4.62.5",
"@rollup/rollup-win32-arm64-msvc": "4.62.5",
"@rollup/rollup-win32-ia32-msvc": "4.62.5",
"@rollup/rollup-win32-x64-gnu": "4.62.5",
"@rollup/rollup-win32-x64-msvc": "4.62.5",
"fsevents": "~2.3.2"
}
},
@@ -5992,19 +5992,19 @@
}
},
"node_modules/vitest": {
"version": "4.1.10",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz",
"integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==",
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.11.tgz",
"integrity": "sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/expect": "4.1.10",
"@vitest/mocker": "4.1.10",
"@vitest/pretty-format": "4.1.10",
"@vitest/runner": "4.1.10",
"@vitest/snapshot": "4.1.10",
"@vitest/spy": "4.1.10",
"@vitest/utils": "4.1.10",
"@vitest/expect": "4.1.11",
"@vitest/mocker": "4.1.11",
"@vitest/pretty-format": "4.1.11",
"@vitest/runner": "4.1.11",
"@vitest/snapshot": "4.1.11",
"@vitest/spy": "4.1.11",
"@vitest/utils": "4.1.11",
"es-module-lexer": "^2.0.0",
"expect-type": "^1.3.0",
"magic-string": "^0.30.21",
@@ -6032,12 +6032,12 @@
"@edge-runtime/vm": "*",
"@opentelemetry/api": "^1.9.0",
"@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
"@vitest/browser-playwright": "4.1.10",
"@vitest/browser-preview": "4.1.10",
"@vitest/browser-webdriverio": "4.1.10",
"@vitest/coverage-istanbul": "4.1.10",
"@vitest/coverage-v8": "4.1.10",
"@vitest/ui": "4.1.10",
"@vitest/browser-playwright": "4.1.11",
"@vitest/browser-preview": "4.1.11",
"@vitest/browser-webdriverio": "4.1.11",
"@vitest/coverage-istanbul": "4.1.11",
"@vitest/coverage-v8": "4.1.11",
"@vitest/ui": "4.1.11",
"happy-dom": "*",
"jsdom": "*",
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
+26 -7
View File
@@ -4,16 +4,35 @@ import { getApiPath, getPublicApiPath } from "@/utils/url.js";
import { adjustedData, fetchURL } from "./utils";
import { getCachedDirMetadata, setCachedDirMetadata } from "@/utils/metadataCache.js";
// GET /api/media/subtitles
// GET /api/media/subtitles or /public/api/media/subtitles
export async function getSubtitleContent(source, path, subtitleName, embedded = false) {
try {
const apiPath = getApiPath('media/subtitles', {
source: source,
path: path,
const hash = state.shareInfo?.hash || null
const baseParams = {
path,
name: subtitleName,
embedded: embedded.toString()
})
const res = await fetchURL(apiPath)
...(embedded && { embedded: 'true' }),
}
let res
if (hash) {
const apiPath = getPublicApiPath('media/subtitles', {
hash,
...baseParams,
...(state.shareInfo.token && { token: state.shareInfo.token }),
})
const sharePassword = localStorage.getItem(`sharepass:${hash}`) || ''
res = await fetchURL(apiPath, {
headers: { 'X-SHARE-PASSWORD': sharePassword },
})
} else {
const apiPath = getApiPath('media/subtitles', {
source,
...baseParams,
})
res = await fetchURL(apiPath)
}
const content = await res.text()
return content
} catch (err) {
+12 -2
View File
@@ -1,4 +1,5 @@
import { notify } from '@/notify'
import { state } from '@/store'
import { getApiPath, getPublicApiPath } from '@/utils/url.js'
import { fetchURL } from './utils'
@@ -8,7 +9,16 @@ export async function getConfig(req) {
const params = {
path: req.path,
...(req.hash && { hash: req.hash }),
...(req.source && { source: req.source })
...(req.source && { source: req.source }),
...(req.hash && state.shareInfo?.token && { token: state.shareInfo.token }),
}
const headers = {}
if (req.hash) {
const sharePassword = localStorage.getItem(`sharepass:${req.hash}`)
if (sharePassword) {
headers['X-SHARE-PASSWORD'] = sharePassword
}
}
let apiPath
@@ -18,7 +28,7 @@ export async function getConfig(req) {
apiPath = getApiPath('office/config', params)
}
const res = await fetchURL(apiPath)
const res = await fetchURL(apiPath, { headers })
return await res.json()
} catch (err) {
notify.showError(err.message || 'Error fetching OnlyOffice configuration')
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "مرحبًا بك في متصفح الملفات الكمي!",
"halloweenTitle": "عيد هالوين سعيد!",
"halloweenBody": "تم تطبيق سمة الهالوين. يمكنك تعطيله إذا لم يعجبك، أو تعطيله بشكل دائم في إعدادات الملف الشخصي عن طريق تحديد أي سمة أخرى.",
"firstLoadBody": "تم إنشاء قاعدة بيانات جديدة عند بدء التشغيل. إذا لم يكن هذا هو ما كنت تتوقعه، يرجى التحقق مرة أخرى من ملف التكوين الخاص بك لمسار 'server.database' والتأكد من وجوده. في docker، يمكن أن يكون مسار قاعدة البيانات \"./data/database.db\" أو \"./database.db\".",
"firstLoadBody": "تم إنشاء قاعدة بيانات جديدة عند بدء التشغيل. إذا لم يكن هذا هو ما كنت تتوقعه، يرجى التحقق مرة أخرى من ملف التكوين الخاص بك لمسار 'server.database' والتأكد من وجوده. في docker، يمكن أن يكون مسار قاعدة البيانات \"./data/filebrowser.sqlite\" أو \"./filebrowser.sqlite\".",
"selectPath": "تحديد المسار",
"renameSuccess": "تمت إعادة تسمية العنصر بنجاح!",
"newFileSuccess": "تم إنشاء الملف بنجاح!",
+1 -1
View File
@@ -450,7 +450,7 @@
"token": "Токен",
"onlyOfficeId": "OnlyOffice ID",
"firstLoadTitle": "Добре дошли във FileBrowser Quantum!",
"firstLoadBody": "Нова база данни беше създадена при стартиране. Ако това не е очакваното, моля, проверете конфигурационния файл за `server.database` път и се уверете, че съществува. В docker, пътят на базата данни може да бъде `./data/database.db` или `./database.db`.",
"firstLoadBody": "Нова база данни беше създадена при стартиране. Ако това не е очакваното, моля, проверете конфигурационния файл за `server.database` път и се уверете, че съществува. В docker, пътят на базата данни може да бъде `./data/filebrowser.sqlite` или `./filebrowser.sqlite`.",
"halloweenTitle": "Честит Хелоуин!",
"halloweenBody": "Темата за Хелоуин беше приложена. Можете да я изключите, ако не ви харесва, или да я изключите завинаги в настройките на профила, като изберете друга тема.",
"moveFailed": "Преместването не беше успешно",
+1 -1
View File
@@ -273,7 +273,7 @@
"firstLoadTitle": "Vítejte v aplikaci FileBrowser Quantum!",
"halloweenTitle": "Šťastný Halloween!",
"halloweenBody": "Bylo použito téma Halloween. Pokud se vám nelíbí, můžete jej vypnout nebo trvale zakázat v nastavení profilu výběrem jiného motivu.",
"firstLoadBody": "Při spuštění byla vytvořena nová databáze. Pokud to není to, co jste očekávali, překontrolujte prosím konfigurační soubor pro cestu `server.database` a ujistěte se, že existuje. V dockeru může být cesta k databázi `./data/database.db` nebo `./database.db`.",
"firstLoadBody": "Při spuštění byla vytvořena nová databáze. Pokud to není to, co jste očekávali, překontrolujte prosím konfigurační soubor pro cestu `server.database` a ujistěte se, že existuje. V dockeru může být cesta k databázi `./data/filebrowser.sqlite` nebo `./filebrowser.sqlite`.",
"selectPath": "Vybrat cestu",
"renameSuccess": "Položka byla úspěšně přejmenována!",
"newFileSuccess": "Soubor byl úspěšně vytvořen!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "Willkommen bei FileBrowser Quantum!",
"halloweenTitle": "Fröhliches Halloween!",
"halloweenBody": "Das Halloween-Thema wurde angewendet. Sie können es deaktivieren, wenn es Ihnen nicht gefällt, oder es in den Profileinstellungen dauerhaft deaktivieren, indem Sie ein anderes Thema auswählen.",
"firstLoadBody": "Beim Starten wurde eine neue Datenbank erstellt. Wenn dies nicht das ist, was Sie erwartet haben, überprüfen Sie bitte Ihre Konfigurationsdatei auf den Pfad `server.database` und stellen Sie sicher, dass er existiert. Bei Docker kann der Datenbankpfad `./data/database.db` oder `./database.db` sein.",
"firstLoadBody": "Beim Starten wurde eine neue Datenbank erstellt. Wenn dies nicht das ist, was Sie erwartet haben, überprüfen Sie bitte Ihre Konfigurationsdatei auf den Pfad `server.database` und stellen Sie sicher, dass er existiert. Bei Docker kann der Datenbankpfad `./data/filebrowser.sqlite` oder `./filebrowser.sqlite` sein.",
"selectPath": "Pfad auswählen",
"renameSuccess": "Artikel erfolgreich umbenannt!",
"newFileSuccess": "Datei erfolgreich erstellt!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "Καλώς ήρθατε στο FileBrowser Quantum!",
"halloweenTitle": "Καλές Απόκριες!",
"halloweenBody": "Το θέμα των αποκριών έχει εφαρμοστεί. Μπορείτε να το απενεργοποιήσετε αν δεν σας αρέσει ή να το απενεργοποιήσετε μόνιμα στις ρυθμίσεις προφίλ επιλέγοντας οποιοδήποτε άλλο θέμα.",
"firstLoadBody": "Κατά την εκκίνηση δημιουργήθηκε μια νέα βάση δεδομένων. Αν αυτό δεν είναι αυτό που περιμένατε, ελέγξτε ξανά το αρχείο ρυθμίσεων για τη διαδρομή `server.database` και βεβαιωθείτε ότι υπάρχει. Στο docker, η διαδρομή της βάσης δεδομένων μπορεί να είναι `./data/database.db` ή `./database.db`.",
"firstLoadBody": "Κατά την εκκίνηση δημιουργήθηκε μια νέα βάση δεδομένων. Αν αυτό δεν είναι αυτό που περιμένατε, ελέγξτε ξανά το αρχείο ρυθμίσεων για τη διαδρομή `server.database` και βεβαιωθείτε ότι υπάρχει. Στο docker, η διαδρομή της βάσης δεδομένων μπορεί να είναι `./data/filebrowser.sqlite` ή `./filebrowser.sqlite`.",
"selectPath": "Επιλέξτε διαδρομή",
"renameSuccess": "Το στοιχείο μετονομάστηκε επιτυχώς!",
"newFileSuccess": "Το αρχείο δημιουργήθηκε με επιτυχία!",
+1 -1
View File
@@ -450,7 +450,7 @@
"token": "Token",
"onlyOfficeId": "OnlyOffice ID",
"firstLoadTitle": "Welcome to FileBrowser Quantum!",
"firstLoadBody": "A new database was created on startup. If this is not what you expected, please double check your configuration file for `server.database` path and ensure it exists. On docker, database path could be `./data/database.db` or `./database.db`.",
"firstLoadBody": "A new database was created on startup. If this is not what you expected, please double check your configuration file for `server.database` path and ensure it exists. On docker, database path could be `./data/filebrowser.sqlite` or `./filebrowser.sqlite`.",
"halloweenTitle": "Happy Halloween!",
"halloweenBody": "The Halloween theme has been applied. You can disable it if you don't like it, or permanently disable it in profile settings by selecting any other theme.",
"moveFailed": "Move failed",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "¡Bienvenido a FileBrowser Quantum!",
"halloweenTitle": "¡Feliz Halloween!",
"halloweenBody": "¡Se aplicó el tema de Halloween! Puedes desactivarlo si no te gusta (temporal o permanentemente) en los ajustes seleccionando cualquier otro tema.",
"firstLoadBody": "Se creó una nueva base de datos al iniciar. Si esto no es lo que esperabas, aseguráte de que en tu configuración (config.yaml) tienes una ruta para la base de datos en `server.database`, y verifica si existe. Si usas Docker, la ubicación de la base de datos se encuentra en `./data/database.db`.",
"firstLoadBody": "Se creó una nueva base de datos al iniciar. Si esto no es lo que esperabas, aseguráte de que en tu configuración (config.yaml) tienes una ruta para la base de datos en `server.database`, y verifica si existe. Si usas Docker, la ubicación de la base de datos se encuentra en `./data/filebrowser.sqlite`.",
"selectPath": "Seleccionar ruta",
"renameSuccess": "El cambio de nombre se ha realizado correctamente",
"newFileSuccess": "¡Archivo creado con éxito!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "Bienvenue à FileBrowser Quantum !",
"halloweenTitle": "Joyeux Halloween !",
"halloweenBody": "Le thème Halloween a été appliqué. Vous pouvez le désactiver si vous ne l'aimez pas, ou le désactiver définitivement dans les paramètres du profil en sélectionnant un autre thème.",
"firstLoadBody": "Une nouvelle base de données a été créée au démarrage. Si ce n'est pas ce que vous attendiez, vérifiez que le chemin `server.database` existe dans votre fichier de configuration. Sur docker, le chemin de la base de données peut être `./data/database.db` ou `./database.db`.",
"firstLoadBody": "Une nouvelle base de données a été créée au démarrage. Si ce n'est pas ce que vous attendiez, vérifiez que le chemin `server.database` existe dans votre fichier de configuration. Sur docker, le chemin de la base de données peut être `./data/filebrowser.sqlite` ou `./filebrowser.sqlite`.",
"selectPath": "Sélectionner un chemin",
"renameSuccess": "L'élément a été renommé avec succès !",
"newFileSuccess": "Fichier créé avec succès !",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "ברוכים הבאים ל-FileBrowser Quantum!",
"halloweenTitle": "חג ליל כל הקדושים שמח!",
"halloweenBody": "נושא ליל כל הקדושים הוחל. ניתן להשבית אותו אם אינו מוצא חן בעיניך, או להשבית אותו לצמיתות בהגדרות הפרופיל על ידי בחירת נושא אחר.",
"firstLoadBody": "במהלך ההפעלה נוצר מסד נתונים חדש. אם זה לא מה שציפית, אנא בדוק שוב את קובץ התצורה שלך עבור הנתיב `server.database` וודא שהוא קיים. ב-docker, נתיב מסד הנתונים יכול להיות `./data/database.db` או `./database.db`.",
"firstLoadBody": "במהלך ההפעלה נוצר מסד נתונים חדש. אם זה לא מה שציפית, אנא בדוק שוב את קובץ התצורה שלך עבור הנתיב `server.database` וודא שהוא קיים. ב-docker, נתיב מסד הנתונים יכול להיות `./data/filebrowser.sqlite` או `./filebrowser.sqlite`.",
"selectPath": "בחר נתיב",
"renameSuccess": "הפריט שונה בהצלחה!",
"newFileSuccess": "הקובץ נוצר בהצלחה!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "Üdvözöljük a FileBrowser Quantum-on!",
"halloweenTitle": "Boldog Halloweent!",
"halloweenBody": "A Halloween témát alkalmazták. Ha nem tetszik, letilthatja, vagy véglegesen letilthatja a profilbeállításokban bármely más téma kiválasztásával.",
"firstLoadBody": "Az indításkor új adatbázis jött létre. Ha ez nem az, amire számított, kérjük, ellenőrizze kétszer is a konfigurációs fájlban a `server.database` elérési útvonalát, és győződjön meg róla, hogy létezik. Dockeren az adatbázis elérési útja lehet `./data/database.db` vagy `./database.db`.",
"firstLoadBody": "Az indításkor új adatbázis jött létre. Ha ez nem az, amire számított, kérjük, ellenőrizze kétszer is a konfigurációs fájlban a `server.database` elérési útvonalát, és győződjön meg róla, hogy létezik. Dockeren az adatbázis elérési útja lehet `./data/filebrowser.sqlite` vagy `./filebrowser.sqlite`.",
"selectPath": "Útvonal kiválasztása",
"renameSuccess": "Az elem átnevezése sikeres volt!",
"newFileSuccess": "A fájl sikeresen létrehozva!",
+1 -1
View File
@@ -449,7 +449,7 @@
"token": "Token",
"onlyOfficeId": "ID OnlyOffice",
"firstLoadTitle": "Benvenuto in FileBrowser Quantum!",
"firstLoadBody": "È stato creato un nuovo database all'avvio. Se non è quello che ti aspettavi, controlla il percorso `server.database` nel file di configurazione. Su Docker, il percorso potrebbe essere `./data/database.db` o `./database.db`.",
"firstLoadBody": "È stato creato un nuovo database all'avvio. Se non è quello che ti aspettavi, controlla il percorso `server.database` nel file di configurazione. Su Docker, il percorso potrebbe essere `./data/filebrowser.sqlite` o `./filebrowser.sqlite`.",
"halloweenTitle": "Buon Halloween!",
"halloweenBody": "Il tema di Halloween è stato applicato. Puoi disabilitarlo o cambiarlo permanentemente nelle impostazioni del profilo.",
"moveFailed": "Spostamento fallito",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "FileBrowser Quantumへようこそ!",
"halloweenTitle": "ハッピー・ハロウィーン",
"halloweenBody": "ハロウィーンのテーマが適用されました。気に入らなければ無効にするか、プロフィール設定で他のテーマを選択して永久に無効にすることができます。",
"firstLoadBody": "起動時に新しいデータベースが作成されました。これが期待したものでない場合は、設定ファイルの `server.database` パスを再確認し、それが存在することを確認してください。docker では、データベースのパスは `./data/database.db` または `./database.db` になります。",
"firstLoadBody": "起動時に新しいデータベースが作成されました。これが期待したものでない場合は、設定ファイルの `server.database` パスを再確認し、それが存在することを確認してください。docker では、データベースのパスは `./data/filebrowser.sqlite` または `./filebrowser.sqlite` になります。",
"selectPath": "パスを選択",
"renameSuccess": "アイテム名の変更に成功しました!",
"newFileSuccess": "ファイルは正常に作成されました!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "Welkom bij FileBrowser Quantum!",
"halloweenTitle": "Gelukkig Halloween!",
"halloweenBody": "Het Halloween-thema is toegepast. Je kunt het uitschakelen als je het niet leuk vindt, of permanent uitschakelen in de profielinstellingen door een ander thema te selecteren.",
"firstLoadBody": "Er is een nieuwe database aangemaakt bij het opstarten. Als dit niet is wat je verwachtte, controleer dan je configuratiebestand voor het `server.database` pad en zorg ervoor dat het bestaat. Op docker kan het databasepad `./data/database.db` of `./database.db` zijn.",
"firstLoadBody": "Er is een nieuwe database aangemaakt bij het opstarten. Als dit niet is wat je verwachtte, controleer dan je configuratiebestand voor het `server.database` pad en zorg ervoor dat het bestaat. Op docker kan het databasepad `./data/filebrowser.sqlite` of `./filebrowser.sqlite` zijn.",
"selectPath": "Pad kiezen",
"renameSuccess": "Item hernoemd succesvol!",
"newFileSuccess": "Bestand succesvol aangemaakt!",
+1 -1
View File
@@ -450,7 +450,7 @@
"token": "Token",
"onlyOfficeId": "OnlyOffice-ID",
"firstLoadTitle": "Welkom bij FileBrowser Quantum!",
"firstLoadBody": "Er is een nieuwe database aangemaakt bij het opstarten. Als dit niet is wat u verwachtte, controleer dan het configuratiebestand voor het `server.database` pad en zorg ervoor dat het bestaat. Op docker kan het databasepad `./data/database.db` of `./database.db` zijn.",
"firstLoadBody": "Er is een nieuwe database aangemaakt bij het opstarten. Als dit niet is wat u verwachtte, controleer dan het configuratiebestand voor het `server.database` pad en zorg ervoor dat het bestaat. Op docker kan het databasepad `./data/filebrowser.sqlite` of `./filebrowser.sqlite` zijn.",
"halloweenTitle": "Happy Halloween!",
"halloweenBody": "Het Halloween-thema is toegepast. U kunt het uitschakelen als u dit niet prettig vindt, of permanent uitschakelen in de profielinstellingen door een ander thema te selecteren.",
"moveFailed": "Verplaatsen mislukt",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "Witamy w FileBrowser Quantum!",
"halloweenTitle": "Wesołego Halloween!",
"halloweenBody": "Motyw Halloween został zastosowany. Możesz go wyłączyć, jeśli Ci się nie podoba, lub wyłączyć go na stałe w ustawieniach profilu, wybierając inny motyw.",
"firstLoadBody": "Nowa baza danych została utworzona podczas uruchamiania. Jeśli nie jest to to, czego oczekiwałeś, sprawdź dokładnie plik konfiguracyjny pod kątem ścieżki `server.database` i upewnij się, że istnieje. W dockerze ścieżka bazy danych może być `./data/database.db` lub `./database.db`.",
"firstLoadBody": "Nowa baza danych została utworzona podczas uruchamiania. Jeśli nie jest to to, czego oczekiwałeś, sprawdź dokładnie plik konfiguracyjny pod kątem ścieżki `server.database` i upewnij się, że istnieje. W dockerze ścieżka bazy danych może być `./data/filebrowser.sqlite` lub `./filebrowser.sqlite`.",
"selectPath": "Wybierz ścieżkę",
"renameSuccess": "Nazwa elementu została zmieniona pomyślnie!",
"newFileSuccess": "Plik został utworzony pomyślnie!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "Bem-vindo ao FileBrowser Quantum!",
"halloweenTitle": "Feliz Dia das Bruxas!",
"halloweenBody": "O tema Halloween foi aplicado. Você pode desativá-lo se não gostar dele ou desativá-lo permanentemente nas configurações de perfil, selecionando qualquer outro tema.",
"firstLoadBody": "Um novo banco de dados foi criado na inicialização. Se isso não for o que você esperava, verifique novamente em seu arquivo de configuração o caminho `server.database` e certifique-se de que ele exista. No docker, o caminho do banco de dados pode ser `./data/database.db` ou `./database.db`.",
"firstLoadBody": "Um novo banco de dados foi criado na inicialização. Se isso não for o que você esperava, verifique novamente em seu arquivo de configuração o caminho `server.database` e certifique-se de que ele exista. No docker, o caminho do banco de dados pode ser `./data/filebrowser.sqlite` ou `./filebrowser.sqlite`.",
"selectPath": "Selecionar caminho",
"renameSuccess": "Item renomeado com sucesso!",
"newFileSuccess": "Arquivo criado com sucesso!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "Bem-vindo ao FileBrowser Quantum!",
"halloweenTitle": "Feliz Dia das Bruxas!",
"halloweenBody": "O tema do Dia das Bruxas foi aplicado. Pode desactivá-lo se não gostar dele, ou desactivá-lo permanentemente nas definições do perfil, selecionando qualquer outro tema.",
"firstLoadBody": "Foi criada uma nova base de dados no arranque. Se isso não for o que você esperava, verifique novamente seu arquivo de configuração para o caminho `server.database` e certifique-se de que ele existe. No docker, o caminho do banco de dados pode ser `./data/database.db` ou `./database.db`.",
"firstLoadBody": "Foi criada uma nova base de dados no arranque. Se isso não for o que você esperava, verifique novamente seu arquivo de configuração para o caminho `server.database` e certifique-se de que ele existe. No docker, o caminho do banco de dados pode ser `./data/filebrowser.sqlite` ou `./filebrowser.sqlite`.",
"selectPath": "Selecionar caminho",
"renameSuccess": "Item renomeado com sucesso!",
"newFileSuccess": "Ficheiro criado com sucesso!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "Bine ați venit la FileBrowser Quantum!",
"halloweenTitle": "Halloween fericit!",
"halloweenBody": "Tema Halloween a fost aplicată. Puteți să o dezactivați dacă nu vă place sau să o dezactivați permanent în setările profilului selectând orice altă temă.",
"firstLoadBody": "O nouă bază de date a fost creată la pornire. Dacă acest lucru nu este ceea ce vă așteptați, vă rugăm să verificați fișierul de configurare pentru calea `server.database` și asigurați-vă că există. Pe docker, calea bazei de date poate fi `./data/database.db` sau `./database.db`.",
"firstLoadBody": "O nouă bază de date a fost creată la pornire. Dacă acest lucru nu este ceea ce vă așteptați, vă rugăm să verificați fișierul de configurare pentru calea `server.database` și asigurați-vă că există. Pe docker, calea bazei de date poate fi `./data/filebrowser.sqlite` sau `./filebrowser.sqlite`.",
"selectPath": "Selectați calea",
"renameSuccess": "Element redenumit cu succes!",
"newFileSuccess": "Fișier creat cu succes!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "Добро пожаловать в FileBrowser Quantum!",
"halloweenTitle": "Счастливого Хэллоуина!",
"halloweenBody": "Тема Хэллоуина была применена. Вы можете отключить ее, если она вам не нравится, или навсегда отключить ее в настройках профиля, выбрав любую другую тему.",
"firstLoadBody": "При запуске была создана новая база данных. Если это не то, что вы ожидали, проверьте путь к базе данных `server.database в вашем конфигурационном файле и убедитесь, что он существует. В docker путь к базе данных может быть `./data/database.db` или `./database.db`.",
"firstLoadBody": "При запуске была создана новая база данных. Если это не то, что вы ожидали, проверьте путь к базе данных `server.database в вашем конфигурационном файле и убедитесь, что он существует. В docker путь к базе данных может быть `./data/filebrowser.sqlite` или `./filebrowser.sqlite`.",
"selectPath": "Выберите путь",
"renameSuccess": "Элемент успешно переименован!",
"newFileSuccess": "Файл создан успешно!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "Vitajte v programe FileBrowser Quantum!",
"halloweenTitle": "Šťastný Halloween!",
"halloweenBody": "Bola použitá téma Halloween. Ak sa vám nepáči, môžete ju vypnúť, alebo ju natrvalo zakázať v nastaveniach profilu výberom akejkoľvek inej témy.",
"firstLoadBody": "Pri spustení bola vytvorená nová databáza. Ak to nie je to, čo ste očakávali, dvakrát skontrolujte konfiguračný súbor pre cestu `server.database` a uistite sa, že existuje. V dockeri môže byť cesta k databáze `./data/database.db` alebo `./database.db`.",
"firstLoadBody": "Pri spustení bola vytvorená nová databáza. Ak to nie je to, čo ste očakávali, dvakrát skontrolujte konfiguračný súbor pre cestu `server.database` a uistite sa, že existuje. V dockeri môže byť cesta k databáze `./data/filebrowser.sqlite` alebo `./filebrowser.sqlite`.",
"selectPath": "Vyberte cestu",
"renameSuccess": "Položka bola úspešne premenovaná!",
"newFileSuccess": "Súbor bol úspešne vytvorený!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "Välkommen till FileBrowser Quantum!",
"halloweenTitle": "Glad Halloween!",
"halloweenBody": "Halloween-temat har lagts till. Du kan inaktivera det om du inte gillar det, eller inaktivera det permanent i profilinställningarna genom att välja ett annat tema.",
"firstLoadBody": "En ny databas skapades vid uppstart. Om detta inte är vad du förväntade dig, vänligen dubbelkolla din konfigurationsfil för `server.database` sökväg och se till att den finns. På docker kan databassökvägen vara `./data/database.db` eller `./database.db`.",
"firstLoadBody": "En ny databas skapades vid uppstart. Om detta inte är vad du förväntade dig, vänligen dubbelkolla din konfigurationsfil för `server.database` sökväg och se till att den finns. På docker kan databassökvägen vara `./data/filebrowser.sqlite` eller `./filebrowser.sqlite`.",
"selectPath": "Välj sökväg",
"renameSuccess": "Objektet har bytt namn framgångsrikt!",
"newFileSuccess": "Filen skapades framgångsrikt!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "FileBrowser Quantum'a hoş geldiniz!",
"halloweenTitle": "Mutlu Cadılar Bayramı!",
"halloweenBody": "Cadılar Bayramı teması uygulanmıştır. Beğenmediyseniz devre dışı bırakabilir veya profil ayarlarından başka bir tema seçerek kalıcı olarak devre dışı bırakabilirsiniz.",
"firstLoadBody": "Başlangıçta yeni bir veritabanı oluşturuldu. Beklediğiniz bu değilse, lütfen `server.database` yolu için yapılandırma dosyanızı iki kez kontrol edin ve var olduğundan emin olun. Docker üzerinde, veritabanı yolu `./data/database.db` veya `./database.db` olabilir.",
"firstLoadBody": "Başlangıçta yeni bir veritabanı oluşturuldu. Beklediğiniz bu değilse, lütfen `server.database` yolu için yapılandırma dosyanızı iki kez kontrol edin ve var olduğundan emin olun. Docker üzerinde, veritabanı yolu `./data/filebrowser.sqlite` veya `./filebrowser.sqlite` olabilir.",
"selectPath": "Yol Seçin",
"renameSuccess": "Öğe başarıyla yeniden adlandırıldı!",
"newFileSuccess": "Dosya başarıyla oluşturuldu!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "Ласкаво просимо до FileBrowser Quantum!",
"halloweenTitle": "Щасливого Гелловіну!",
"halloweenBody": "Застосовано тему Хеллоуїна. Ви можете вимкнути її, якщо вона вам не подобається, або назавжди вимкнути в налаштуваннях профілю, вибравши будь-яку іншу тему.",
"firstLoadBody": "Під час запуску було створено нову базу даних. Якщо це не те, що ви очікували, перевірте ваш конфігураційний файл на наявність шляху до `сервер.бази даних` і переконайтеся, що він існує. У докері шлях до бази даних може бути `./data/database.db` або `./database.db`.",
"firstLoadBody": "Під час запуску було створено нову базу даних. Якщо це не те, що ви очікували, перевірте ваш конфігураційний файл на наявність шляху до `сервер.бази даних` і переконайтеся, що він існує. У докері шлях до бази даних може бути `./data/filebrowser.sqlite` або `./filebrowser.sqlite`.",
"selectPath": "Виберіть шлях",
"renameSuccess": "Елемент перейменовано успішно!",
"newFileSuccess": "Файл успішно створено!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "欢迎访问 FileBrowser Quantum!",
"halloweenTitle": "万圣节快乐",
"halloweenBody": "万圣节主题已应用。如果不喜欢,可以将其禁用,或者在个人档案设置中选择其他主题将其永久禁用。",
"firstLoadBody": "启动时创建了一个新数据库。如果这与您的预期不符,请仔细检查配置文件中的 `server.database` 路径并确保其存在。在 docker 上,数据库路径可以是 `./data/database.db` 或 `./database.db`。",
"firstLoadBody": "启动时创建了一个新数据库。如果这与您的预期不符,请仔细检查配置文件中的 `server.database` 路径并确保其存在。在 docker 上,数据库路径可以是 `./data/filebrowser.sqlite` 或 `./filebrowser.sqlite`。",
"selectPath": "选择路径",
"renameSuccess": "项目重命名成功!",
"newFileSuccess": "文件创建成功!",
+1 -1
View File
@@ -203,7 +203,7 @@
"firstLoadTitle": "歡迎來到 FileBrowser Quantum!",
"halloweenTitle": "萬聖節快樂",
"halloweenBody": "已套用萬聖節主題。如果不喜歡,可以暫時停用,或在個人資料設定中改選其他主題來永久停用。",
"firstLoadBody": "系統啟動時已建立新的資料庫。如果這不是預期行為,請再次檢查設定檔中的 `server.database` 路徑,並確認該路徑存在。在 Docker 環境中,資料庫路徑可能是 `./data/database.db` 或 `./database.db`。",
"firstLoadBody": "系統啟動時已建立新的資料庫。如果這不是預期行為,請再次檢查設定檔中的 `server.database` 路徑,並確認該路徑存在。在 Docker 環境中,資料庫路徑可能是 `./data/filebrowser.sqlite` 或 `./filebrowser.sqlite`。",
"selectPath": "選擇路徑",
"renameSuccess": "項目已成功重新命名!",
"newFileSuccess": "檔案已成功建立!",
+1 -1
View File
@@ -466,7 +466,7 @@ export default {
state.req.source,
state.req.path,
subtitleTrack.name,
subtitleTrack.embedded
subtitleTrack.embedded,
);
if (!content || content.length === 0) {
console.warn("Subtitle track has no content:", subtitleTrack.name);
+1 -1
View File
@@ -37,7 +37,7 @@ setup-gofitz-cgo:
cd backend && go run ./scripts/setup-gofitz-cgo
update:
cd backend && go get -u ./... && go mod tidy
cd backend && go get -u ./... && go get -u tool && go mod tidy
cd frontend && npm update
build: build-frontend build-backend