Compare commits

...

58 Commits

Author SHA1 Message Date
Henrique Dias
56a0f9244b chore(release): 2.32.1 2025-06-16 20:18:42 +02:00
michioxd
56b80b6d9b feat: add Vietnamese translation (#3840) 2025-06-16 18:47:20 +02:00
Dev_Nergis
d9ebd65ffc feat: update translation ko.json (#3852) 2025-06-16 18:35:50 +02:00
SOMA
a882fb6c85 feat: improve pt-br translations with new keys and refinements (#4903) 2025-06-16 17:39:57 +02:00
Henrique Dias
5daae69a6d chore: revert only translated mode to transifex 2025-06-15 21:05:30 +02:00
Henrique Dias
54a1ae0fa0 chore: add only translated mode to transifex 2025-06-15 20:48:01 +02:00
Henrique Dias
b6b4fb5da7 ci: remove manual .tx config 2025-06-15 20:13:21 +02:00
Henrique Dias
6d82a27f9a ci: add transifex.yml 2025-06-15 20:13:03 +02:00
Henrique Dias
31a326606d chore: updated readme and template 2025-06-13 22:46:22 +02:00
Henrique Dias
abbf203bdd chore: updated readme and templates 2025-06-13 22:46:22 +02:00
Henrique Dias
e82e2392a4 chore: update Go dependencies 2025-06-11 18:51:01 +02:00
Henrique Dias
f4a8420bf3 docs: add maintenance warning to readme 2025-06-11 17:44:32 +02:00
Simon
71a8f5662c fix: set videojs locale (#3742)
Co-authored-by: Oleg Lobanov <oleg@lobanov.me>
2025-06-05 15:53:29 +02:00
Henrique Dias
48f894740f chore: remove stale bot 2025-06-04 19:08:43 +02:00
Henrique Dias
b883e287a0 chore: migrate transifex settings 2025-06-04 18:58:48 +02:00
Henrique Dias
5d9f0977d6 Merge pull request #3675 from bo0tzz/fix/random-password 2025-06-04 17:39:32 +02:00
bo0tzz
c606a01a2d fix: err shadowing lint 2025-06-04 17:36:55 +02:00
bo0tzz
54b91b8ff0 fix: imports lint 2025-06-04 17:36:55 +02:00
bo0tzz
a46acba5f9 fix: generate random admin password on quick setup
This should help mitigate issues like #3646
2025-06-04 17:36:55 +02:00
Henrique Dias
1d14798653 Merge pull request #3776 from Matthaiks/pl 2025-06-04 17:35:00 +02:00
Matthaiks
6d55cc59f7 chore: Update Polish translation 2025-06-04 17:32:41 +02:00
Matthaiks
495e731ee7 Update Polish translation 2025-06-04 17:32:41 +02:00
Henrique Dias
ff1579b950 Merge pull request #3793 from Kcchouette/patch-1 2025-06-04 17:24:12 +02:00
Kcchouette
7a48fd0c3e Merge branch 'master' into patch-1 2025-05-20 11:23:27 +00:00
dependabot[bot]
cfea84fd5e build(deps): bump golang.org/x/net from 0.33.0 to 0.38.0 (#3869) 2025-05-19 12:27:04 +00:00
dependabot[bot]
0ba9505a19 build(deps): bump golang.org/x/crypto from 0.31.0 to 0.35.0 (#3865)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.31.0 to 0.35.0.
- [Commits](https://github.com/golang/crypto/compare/v0.31.0...v0.35.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.35.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-19 14:24:09 +02:00
dependabot[bot]
5355629fd1 build(deps-dev): bump vite from 6.0.11 to 6.1.6 in /frontend (#3886)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.0.11 to 6.1.6.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v6.1.6/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.1.6/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.1.6
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-19 13:49:42 +02:00
Kcchouette
f8a16a6aca Merge branch 'master' into patch-1 2025-04-19 09:22:44 +00:00
dependabot[bot]
35d1c09243 build(deps): bump vue-i18n from 11.0.1 to 11.1.2 in /frontend (#3786)
Bumps [vue-i18n](https://github.com/intlify/vue-i18n/tree/HEAD/packages/vue-i18n) from 11.0.1 to 11.1.2.
- [Release notes](https://github.com/intlify/vue-i18n/releases)
- [Changelog](https://github.com/intlify/vue-i18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/intlify/vue-i18n/commits/v11.1.2/packages/vue-i18n)

---
updated-dependencies:
- dependency-name: vue-i18n
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 17:03:45 +01:00
Kcchouette
99c64c12ed Update french translation 2025-03-10 21:04:12 +00:00
Oleg Lobanov
3d6c5152fe chore(release): 2.32.0 2025-01-31 09:48:22 +01:00
Oleg Lobanov
ba797cda31 build: fix go releaser 2025-01-31 09:48:08 +01:00
Arran Hobson Sayers
5300d00d2e fix: Fix user creation on proxy auth (#3666)
* Fix user creation on proxy auth

* Refactoring

---------

Co-authored-by: Oleg Lobanov <oleg@lobanov.me>
2025-01-30 11:28:19 +01:00
elmodor
bbdd313705 fix: disk usage refreshing (#3692)
Co-authored-by: Oleg Lobanov <oleg@lobanov.me>
2025-01-30 10:32:05 +01:00
Eden Yemini
045064f8b8 fix: add proper healthcheck for S6 containers (#3691)
Co-authored-by: Oleg Lobanov <oleg@lobanov.me>
2025-01-30 10:29:14 +01:00
정성민
252f0a7533 chore: update ko.json (#3688) 2025-01-30 10:24:44 +01:00
dependabot[bot]
1194cfe009 build(deps): bump golang.org/x/net from 0.23.0 to 0.33.0 (#3712)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.23.0 to 0.33.0.
- [Commits](https://github.com/golang/net/compare/v0.23.0...v0.33.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-30 10:22:04 +01:00
kloon15
0201f9c5c4 refactor: Fix eslint warnings (#3698)
* Update dependencies and remove typescript version pinning (fixed upstream)

* Fix esling warnings (disabled any and script lang checks)
Rewrote clipboard copy (Fixes #3407)
Run prettier

---------

Co-authored-by: Oleg Lobanov <oleg@lobanov.me>
2025-01-30 10:18:48 +01:00
Juan Bernárdez
cc331383fb chore: add translation for the "Hide dot files setting" in "es" (Spanish) language (#3704) 2025-01-30 10:16:40 +01:00
Ryan
d1c84a8412 fix: prompts disappearing on copy / move / upload (#3537)
---------

Co-authored-by: Ryan Miller <ryan.miller@infinitetactics.com>
Co-authored-by: Oleg Lobanov <oleg@lobanov.me>
2025-01-21 00:05:59 +01:00
dependabot[bot]
e92dbb4bb8 build(deps): bump golang.org/x/crypto from 0.26.0 to 0.31.0 (#3634)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.26.0 to 0.31.0.
- [Commits](https://github.com/golang/crypto/compare/v0.26.0...v0.31.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-16 22:07:57 +01:00
Arran Hobson Sayers
209acf2429 feat: create user on proxy authentication if user does not exist (#3569)
---------

Co-authored-by: Oleg Lobanov <oleg@lobanov.me>
2024-12-16 22:05:13 +01:00
dependabot[bot]
25372edb5c build(deps): bump cross-spawn from 7.0.3 to 7.0.6 in /tools (#3601)
Bumps [cross-spawn](https://github.com/moxystudio/node-cross-spawn) from 7.0.3 to 7.0.6.
- [Changelog](https://github.com/moxystudio/node-cross-spawn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/moxystudio/node-cross-spawn/compare/v7.0.3...v7.0.6)

---
updated-dependencies:
- dependency-name: cross-spawn
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-12 18:02:05 +01:00
kloon15
d51a343820 build: update to node 22 and pnpm (#3616)
This commit brings the project to support node 22 which became LTS and
fixes broken builds with typescript 5.7+ until vue-tsc is updated and
replaces npm with pnpm.

- Update tsconfig for node 22
- Pin typescript to 5.6.x to not break vue-tsc
- Replace npm with pnpm (corepack recommended)
- Update Makefile and main workflow for pnpm
- Migrate to eslint 9 flat config
- Fix broken imports
- Exclude non-TS vue files for vue-tsc
2024-12-09 12:27:18 +01:00
dependabot[bot]
065959451d build(deps): bump vue-i18n from 9.10.2 to 9.14.2 in /frontend (#3618)
Bumps [vue-i18n](https://github.com/intlify/vue-i18n/tree/HEAD/packages/vue-i18n) from 9.10.2 to 9.14.2.
- [Release notes](https://github.com/intlify/vue-i18n/releases)
- [Changelog](https://github.com/intlify/vue-i18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/intlify/vue-i18n/commits/v9.14.2/packages/vue-i18n)

---
updated-dependencies:
- dependency-name: vue-i18n
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-03 12:54:38 +01:00
dependabot[bot]
2fdea73430 build(deps): bump github.com/golang-jwt/jwt/v4 from 4.5.0 to 4.5.1 (#3574) 2024-11-05 06:49:45 +01:00
Oleg Lobanov
129a4fd39d chore(release): 2.31.2 2024-10-03 15:11:19 +02:00
Elisabeth Ryder
64400ffda8 fix: files list alignment (#3494) 2024-09-30 11:40:20 +02:00
dependabot[bot]
03d74ee758 build(deps): bump rollup from 4.21.3 to 4.22.4 in /frontend (#3504)
Bumps [rollup](https://github.com/rollup/rollup) from 4.21.3 to 4.22.4.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.21.3...v4.22.4)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-30 11:05:41 +02:00
Angelfisch
2b37e696c9 fix: added whitespace before version (#3510) 2024-09-30 11:05:23 +02:00
Andreas Deininger
21d5ee1b97 chore: bump 'actions/stale' to latest version (#3489) 2024-09-30 11:01:43 +02:00
dependabot[bot]
ec7b643e8e build(deps-dev): bump vite from 5.2.7 to 5.4.6 in /frontend (#3496)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.2.7 to 5.4.6.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.6/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.6/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-23 19:29:28 +02:00
Andreas Deininger
d729701bd4 chore: fix typos (#3490) 2024-09-23 11:55:07 +02:00
Marek Ištok
406d4f7884 fix: change location of custom init scripts (#3493)
Co-authored-by: niraami <contact@niraami.com>
2024-09-23 11:34:39 +02:00
knrdl
1e7c41505f fix: german translation spelling typos (#3469) 2024-09-23 11:25:53 +02:00
Oleg Lobanov
bb5d192095 chore(release): 2.31.1 2024-08-30 21:25:29 +02:00
n-i-x
121d9abecd fix: command not found in shell (#3438) 2024-08-30 21:24:45 +02:00
Oleg Lobanov
7de6bc4a91 build: update to alpine 3.20 (#3447)
* add execute permission to s6 scripts

* update s6 base image to 3.20

* Update aarch64 docker image

---------

Co-authored-by: Ryan Winter <ryanwinter@outlook.com>
2024-08-30 21:18:19 +02:00
92 changed files with 6830 additions and 8760 deletions

View File

@@ -1,22 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
---
**Description**
<!-- A clear and concise description of what the issue is about. What are you trying to do? -->
**Expected behaviour**
<!-- What did you expect to happen? -->
**What is happening instead?**
<!-- Please, give full error messages and/or log. -->
**Additional context**
<!-- Add any other context about the problem here. If applicable, add screenshots to help explain your problem. -->
**How to reproduce?**
<!-- Tell us how to reproduce this issue. How can someone who is starting from scratch reproduce this behaviour as minimally as possible? -->
**Files**
<!-- A list of relevant files for this issue. Large files can be uploaded one-by-one or in a tarball/zipfile. -->

43
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
name: Bug Report
description: Report a bug in FileBrowser.
labels: [bug, triage]
body:
- type: checkboxes
attributes:
label: Checklist
description: Please verify that you've followed these steps
options:
- label: This is a bug report, not a question.
required: true
- label: I have searched on the [issue tracker](https://github.com/filebrowser/filebrowser/issues?q=is%3Aissue) for my bug.
required: true
- label: I am running the latest [FileBrowser version](https://github.com/filebrowser/filebrowser/releases) or have an issue updating.
required: true
- type: textarea
id: version
attributes:
label: Version
render: Text
description: |
Enter the version of FileBrowser you are using.
- type: textarea
attributes:
label: Description
description: |
A clear and concise description of what the issue is about. What are you trying to do?
- type: textarea
attributes:
label: What did you expect to happen?
- type: textarea
attributes:
label: What actually happened?
- type: textarea
attributes:
label: Reproduction Steps
description: |
Tell us how to reproduce this issue. How can someone who is starting from scratch reproduce this behavior as minimally as possible?
- type: textarea
attributes:
label: Files
description: |
A list of relevant files for this issue. Large files can be uploaded one-by-one or in a tarball/zipfile.

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: GitHub Discussions
url: https://github.com/filebrowser/filebrowser/discussions
about: Please ask questions and discuss features here.

View File

@@ -1,16 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
---
**Is your feature request related to a problem? Please describe.**
<!-- Add a clear and concise description of what the problem is. E.g. *I'm always frustrated when [...]* -->
**Describe the solution you'd like**
<!-- Add a clear and concise description of what you want to happen. -->
**Describe alternatives you've considered**
<!-- Add a clear and concise description of any alternative solutions or features you've considered. -->
**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->

View File

@@ -1,19 +1,15 @@
**Description**
<!--
Please explain the changes you made here.
If the feature changes current behaviour, explain why your solution is better.
-->
## Description
:rotating_light: Before submitting your PR, please indicate which issues are either fixed or closed by this PR. See [GitHub Help: Closing issues using keywords](https://help.github.com/articles/closing-issues-via-commit-messages/).
<!-- Please explain the changes you made here. -->
- [ ] DO make sure you are requesting to **pull a topic/feature/bugfix branch** (right side). Don't request your master!
- [ ] DO make sure you are making a pull request against the **master branch** (left side). Also you should start *your branch* off *our master*.
- [ ] DO make sure that File Browser can be successfully built. See [builds](https://github.com/filebrowser/community/blob/master/builds.md) and [development](https://github.com/filebrowser/community/blob/master/development.md).
- [ ] AVOID breaking the continuous integration build.
## Additional Information
**Further comments**
<!--
If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did, what alternatives you considered, etc.
<!-- If it is a relatively large or complex change, please add more information to explain what you did, how you did it, if you considered any alternatives, etc. -->
:heart: Thank you!
-->
## Checklist
Before submitting your PR, please indicate which issues are either fixed or closed by this PR. See [GitHub Help: Closing issues using keywords](https://help.github.com/articles/closing-issues-via-commit-messages/).
- [ ] I am aware the project is currently in maintenance-only mode. See [README](https://github.com/filebrowser/community/blob/master/README.md)
- [ ] I am making a PR against the `master` branch.
- [ ] I am sure File Browser can be successfully built. See [builds](https://github.com/filebrowser/community/blob/master/builds.md) and [development](https://github.com/filebrowser/community/blob/master/development.md).

View File

@@ -3,20 +3,25 @@ name: main
on:
push:
branches:
- 'master'
- "master"
tags:
- 'v*'
- "v*"
pull_request:
jobs:
# linters
# linters
lint-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
package_json_file: "frontend/package.json"
- uses: actions/setup-node@v4
with:
node-version: '18'
node-version: "22.x"
cache: "pnpm"
cache-dependency-path: "frontend/pnpm-lock.yaml"
- run: make lint-frontend
lint-backend:
runs-on: ubuntu-latest
@@ -32,14 +37,19 @@ jobs:
steps:
- run: echo "done"
# tests
# tests
test-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
package_json_file: "frontend/package.json"
- uses: actions/setup-node@v4
with:
node-version: '18'
node-version: "22.x"
cache: "pnpm"
cache-dependency-path: "frontend/pnpm-lock.yaml"
- run: make test-frontend
test-backend:
runs-on: ubuntu-latest
@@ -55,7 +65,7 @@ jobs:
steps:
- run: echo "done"
# release
# release
release:
runs-on: ubuntu-latest
needs: [lint, test]
@@ -67,9 +77,14 @@ jobs:
- uses: actions/setup-go@v5
with:
go-version: 1.23.0
- uses: pnpm/action-setup@v4
with:
package_json_file: "frontend/package.json"
- uses: actions/setup-node@v4
with:
node-version: '18'
node-version: "22.x"
cache: "pnpm"
cache-dependency-path: "frontend/pnpm-lock.yaml"
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx

View File

@@ -1,24 +0,0 @@
name: 'Close stale issues and PRs'
permissions:
issues: write
pull-requests: write
on:
schedule:
- cron: '30 1 * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v5
with:
stale-pr-message: 'This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
close-pr-message: 'This PR was closed because it has been stalled for 5 days with no activity.'
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.'
days-before-stale: 30
days-before-close: 5
exempt-issue-labels: 'feature ☘,enhancement ⚙,bug 🐞'
exempt-pr-labels: 'need-help,wip'
operations-per-run: 100

View File

@@ -36,10 +36,10 @@ builds:
archives:
-
name_template: "{{.Os}}-{{.Arch}}{{if .Arm}}v{{.Arm}}{{end}}-{{ .ProjectName }}"
format: tar.gz
formats: [ 'tar.gz' ]
format_overrides:
- goos: windows
format: zip
formats: [ 'zip' ]
dockers:
-
@@ -139,6 +139,7 @@ dockers:
- "filebrowser/filebrowser:v{{ .Major }}-amd64-s6"
extra_files:
- docker/root
- healthcheck.sh
-
dockerfile: Dockerfile.s6.aarch64
use: buildx
@@ -157,6 +158,7 @@ dockers:
- "filebrowser/filebrowser:v{{ .Major }}-arm64-s6"
extra_files:
- docker/root
- healthcheck.sh
docker_manifests:
- name_template: "filebrowser/filebrowser:latest"
image_templates:

View File

@@ -1,10 +0,0 @@
[main]
host = https://www.transifex.com
lang_map = pt_BR: pt-br, zh_CN: zh-cn, zh_HK: zh-hk, zh_TW: zh-tw, nl_BE: nl-be, sv_SE: sv-se, cz-CS: cz_cs
[file-browser.file-browser]
file_filter = frontend/src/i18n/<lang>.json
minimum_perc = 50
source_file = frontend/src/i18n/en.json
source_lang = en
type = KEYVALUEJSON

View File

@@ -2,6 +2,90 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [2.32.1](https://github.com/filebrowser/filebrowser/compare/v2.32.0...v2.32.1) (2025-06-16)
### Features
* add Vietnamese translation ([#3840](https://github.com/filebrowser/filebrowser/issues/3840)) ([56b80b6](https://github.com/filebrowser/filebrowser/commit/56b80b6d9b4710538765ba7df5da1f03898f6b81))
* improve pt-br translations with new keys and refinements ([#4903](https://github.com/filebrowser/filebrowser/issues/4903)) ([a882fb6](https://github.com/filebrowser/filebrowser/commit/a882fb6c85ab6ccc845ed0bf3908d8e5e60ce346))
* update translation ko.json ([#3852](https://github.com/filebrowser/filebrowser/issues/3852)) ([d9ebd65](https://github.com/filebrowser/filebrowser/commit/d9ebd65ffcf9b2166fec708d51849796d12b16e0))
### Bug Fixes
* err shadowing lint ([c606a01](https://github.com/filebrowser/filebrowser/commit/c606a01a2d20932fb32ee896234d57631f8c47e4))
* generate random admin password on quick setup ([a46acba](https://github.com/filebrowser/filebrowser/commit/a46acba5f92ee044661880d6ae349e289d984328)), closes [#3646](https://github.com/filebrowser/filebrowser/issues/3646)
* imports lint ([54b91b8](https://github.com/filebrowser/filebrowser/commit/54b91b8ff0b8ee1f02f72425ab97d27a5d942fc3))
* set videojs locale ([#3742](https://github.com/filebrowser/filebrowser/issues/3742)) ([71a8f56](https://github.com/filebrowser/filebrowser/commit/71a8f5662c207e3cd4ee714a5b5a961121f510cd))
### Build
* **deps-dev:** bump vite from 6.0.11 to 6.1.6 in /frontend ([#3886](https://github.com/filebrowser/filebrowser/issues/3886)) ([5355629](https://github.com/filebrowser/filebrowser/commit/5355629fd1e7bd85ee3222fca22da899ba23ea95))
* **deps:** bump golang.org/x/crypto from 0.31.0 to 0.35.0 ([#3865](https://github.com/filebrowser/filebrowser/issues/3865)) ([0ba9505](https://github.com/filebrowser/filebrowser/commit/0ba9505a19cb369653fc9f8260dc02fcc6587629))
* **deps:** bump golang.org/x/net from 0.33.0 to 0.38.0 ([#3869](https://github.com/filebrowser/filebrowser/issues/3869)) ([cfea84f](https://github.com/filebrowser/filebrowser/commit/cfea84fd5e7ec9c1d2366293e5db12baaa4e3a81))
* **deps:** bump vue-i18n from 11.0.1 to 11.1.2 in /frontend ([#3786](https://github.com/filebrowser/filebrowser/issues/3786)) ([35d1c09](https://github.com/filebrowser/filebrowser/commit/35d1c092434b80b22c89a614a02122e9f5965b39))
## [2.32.0](https://github.com/filebrowser/filebrowser/compare/v2.31.2...v2.32.0) (2025-01-31)
### Features
* create user on proxy authentication if user does not exist ([#3569](https://github.com/filebrowser/filebrowser/issues/3569)) ([209acf2](https://github.com/filebrowser/filebrowser/commit/209acf2429b06e2e8d78218937c59fd7e7edd1be))
### Bug Fixes
* add proper healthcheck for S6 containers ([#3691](https://github.com/filebrowser/filebrowser/issues/3691)) ([045064f](https://github.com/filebrowser/filebrowser/commit/045064f8b8bf9f86058e877448085e38da8b3f2e))
* disk usage refreshing ([#3692](https://github.com/filebrowser/filebrowser/issues/3692)) ([bbdd313](https://github.com/filebrowser/filebrowser/commit/bbdd313705b8d253f0c47ad717a6e47b2f46e719))
* Fix user creation on proxy auth ([#3666](https://github.com/filebrowser/filebrowser/issues/3666)) ([5300d00](https://github.com/filebrowser/filebrowser/commit/5300d00d2e7dbb80a252aff57e100113f02506c3))
* prompts disappearing on copy / move / upload ([#3537](https://github.com/filebrowser/filebrowser/issues/3537)) ([d1c84a8](https://github.com/filebrowser/filebrowser/commit/d1c84a84123c77dede05c023b3697a432b56122c))
### Refactorings
* Fix eslint warnings ([#3698](https://github.com/filebrowser/filebrowser/issues/3698)) ([0201f9c](https://github.com/filebrowser/filebrowser/commit/0201f9c5c4dd2a4d5a3503e59cdb8045e8d3a91f)), closes [#3407](https://github.com/filebrowser/filebrowser/issues/3407)
### Build
* **deps:** bump cross-spawn from 7.0.3 to 7.0.6 in /tools ([#3601](https://github.com/filebrowser/filebrowser/issues/3601)) ([25372ed](https://github.com/filebrowser/filebrowser/commit/25372edb5c0e616e82b76b5f523633af57d347e0))
* **deps:** bump github.com/golang-jwt/jwt/v4 from 4.5.0 to 4.5.1 ([#3574](https://github.com/filebrowser/filebrowser/issues/3574)) ([2fdea73](https://github.com/filebrowser/filebrowser/commit/2fdea73430011846276a1cda52458f1d670f5ea7))
* **deps:** bump golang.org/x/crypto from 0.26.0 to 0.31.0 ([#3634](https://github.com/filebrowser/filebrowser/issues/3634)) ([e92dbb4](https://github.com/filebrowser/filebrowser/commit/e92dbb4bb8b7894264fbf0a48a641712c3b68766))
* **deps:** bump golang.org/x/net from 0.23.0 to 0.33.0 ([#3712](https://github.com/filebrowser/filebrowser/issues/3712)) ([1194cfe](https://github.com/filebrowser/filebrowser/commit/1194cfe0097a70399c1f06cf0f514b9d70fa463c))
* **deps:** bump vue-i18n from 9.10.2 to 9.14.2 in /frontend ([#3618](https://github.com/filebrowser/filebrowser/issues/3618)) ([0659594](https://github.com/filebrowser/filebrowser/commit/065959451d3ba12019c6151274aa4e6904cdca99))
* fix go releaser ([ba797cd](https://github.com/filebrowser/filebrowser/commit/ba797cda3135eddb9b7165dc5ceb932399cb54df))
* update to node 22 and pnpm ([#3616](https://github.com/filebrowser/filebrowser/issues/3616)) ([d51a343](https://github.com/filebrowser/filebrowser/commit/d51a3438201274a1b826be1b775ca1035ade20c5))
### [2.31.2](https://github.com/filebrowser/filebrowser/compare/v2.31.1...v2.31.2) (2024-10-03)
### Bug Fixes
* added whitespace before version ([#3510](https://github.com/filebrowser/filebrowser/issues/3510)) ([2b37e69](https://github.com/filebrowser/filebrowser/commit/2b37e696c9bde4d0c453de236a3555d982346bbb))
* change location of custom init scripts ([#3493](https://github.com/filebrowser/filebrowser/issues/3493)) ([406d4f7](https://github.com/filebrowser/filebrowser/commit/406d4f78845a1684df7c9c457b208f4dd9b2a930))
* files list alignment ([#3494](https://github.com/filebrowser/filebrowser/issues/3494)) ([64400ff](https://github.com/filebrowser/filebrowser/commit/64400ffda8b09f66b8662a3c9400235139800a4d))
* german translation spelling typos ([#3469](https://github.com/filebrowser/filebrowser/issues/3469)) ([1e7c415](https://github.com/filebrowser/filebrowser/commit/1e7c41505fb6a3b9baa1534787492a186e09bcfb))
### Build
* **deps-dev:** bump vite from 5.2.7 to 5.4.6 in /frontend ([#3496](https://github.com/filebrowser/filebrowser/issues/3496)) ([ec7b643](https://github.com/filebrowser/filebrowser/commit/ec7b643e8e9499f7ff226ec7f8e63a9df9890352))
* **deps:** bump rollup from 4.21.3 to 4.22.4 in /frontend ([#3504](https://github.com/filebrowser/filebrowser/issues/3504)) ([03d74ee](https://github.com/filebrowser/filebrowser/commit/03d74ee7582196c09720f8d488056339f06c446c))
### [2.31.1](https://github.com/filebrowser/filebrowser/compare/v2.31.0...v2.31.1) (2024-08-30)
### Bug Fixes
* command not found in shell ([#3438](https://github.com/filebrowser/filebrowser/issues/3438)) ([121d9ab](https://github.com/filebrowser/filebrowser/commit/121d9abecdc7d4e923cfc5023519995938a6ccae))
### Build
* update to alpine 3.20 ([#3447](https://github.com/filebrowser/filebrowser/issues/3447)) ([7de6bc4](https://github.com/filebrowser/filebrowser/commit/7de6bc4a912b5734dd0df02ed8391e78619e2615))
## [2.31.0](https://github.com/filebrowser/filebrowser/compare/v2.30.0...v2.31.0) (2024-08-29)
@@ -87,7 +171,7 @@ All notable changes to this project will be documented in this file. See [standa
* close editor when click escape key ([#2947](https://github.com/filebrowser/filebrowser/issues/2947)) ([70c8261](https://github.com/filebrowser/filebrowser/commit/70c826133b8578b8712e6db8f762a15a076cd9a9))
* enable preview in shared folder ([#3055](https://github.com/filebrowser/filebrowser/issues/3055)) ([4c233c3](https://github.com/filebrowser/filebrowser/commit/4c233c3db39ea5a00d6e602ec0ecbddecb590877))
* focus editor when opened ([#2946](https://github.com/filebrowser/filebrowser/issues/2946)) ([b19710e](https://github.com/filebrowser/filebrowser/commit/b19710efca6daa7af56dc211d0051d500d2eea22))
* freezing the list in the backgroud while previewing a file ([#3004](https://github.com/filebrowser/filebrowser/issues/3004)) ([e167c3e](https://github.com/filebrowser/filebrowser/commit/e167c3e1efed8b16be45d994a8d443fda1d8cf49))
* freezing the list in the background while previewing a file ([#3004](https://github.com/filebrowser/filebrowser/issues/3004)) ([e167c3e](https://github.com/filebrowser/filebrowser/commit/e167c3e1efed8b16be45d994a8d443fda1d8cf49))
* prompt to confirm discard editor changes ([#2948](https://github.com/filebrowser/filebrowser/issues/2948)) ([fb1a09c](https://github.com/filebrowser/filebrowser/commit/fb1a09c7c172b913c12b30975ca545e505df0c05))
* select multiple files with ctrl even with singleClick option ([#2953](https://github.com/filebrowser/filebrowser/issues/2953)) ([d49c3df](https://github.com/filebrowser/filebrowser/commit/d49c3dfacfc0ff07e620b3ad2700e64927b06235))

View File

@@ -1,16 +1,21 @@
FROM ghcr.io/linuxserver/baseimage-alpine:3.17
FROM ghcr.io/linuxserver/baseimage-alpine:3.20
RUN apk --update add ca-certificates \
mailcap \
curl
curl \
jq
COPY healthcheck.sh /healthcheck.sh
RUN chmod +x /healthcheck.sh # Make the script executable
HEALTHCHECK --start-period=2s --interval=5s --timeout=3s \
CMD curl -f http://localhost/health || exit 1
CMD /healthcheck.sh || exit 1
# copy local files
COPY docker/root/ /
RUN ln -s /config/settings.json /.filebrowser.json
COPY filebrowser /usr/bin/filebrowser
# ports and volumes
VOLUME /srv /config /database
EXPOSE 80
EXPOSE 80

View File

@@ -1,16 +1,21 @@
FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.17
FROM ghcr.io/linuxserver/baseimage-alpine:arm64v8-3.20
RUN apk --update add ca-certificates \
mailcap \
curl
curl \
jq
COPY healthcheck.sh /healthcheck.sh
RUN chmod +x /healthcheck.sh # Make the script executable
HEALTHCHECK --start-period=2s --interval=5s --timeout=3s \
CMD curl -f http://localhost/health || exit 1
CMD /healthcheck.sh || exit 1
# copy local files
COPY docker/root/ /
RUN ln -s /config/settings.json /.filebrowser.json
COPY filebrowser /usr/bin/filebrowser
# ports and volumes
VOLUME /srv /config /database
EXPOSE 80
EXPOSE 80

View File

@@ -1,16 +0,0 @@
FROM ghcr.io/linuxserver/baseimage-alpine:arm32v7-3.17
RUN apk --update add ca-certificates \
mailcap \
curl
HEALTHCHECK --start-period=2s --interval=5s --timeout=3s \
CMD curl -f http://localhost/health || exit 1
# copy local files
COPY docker/root/ /
COPY filebrowser /usr/bin/filebrowser
# ports and volumes
VOLUME /srv /config /database
EXPOSE 80

View File

@@ -10,7 +10,7 @@ build: | build-frontend build-backend ## Build binary
.PHONY: build-frontend
build-frontend: ## Build frontend
$Q cd frontend && npm ci && npm run build
$Q cd frontend && pnpm install --frozen-lockfile && pnpm run build
.PHONY: build-backend
build-backend: ## Build backend
@@ -21,6 +21,7 @@ test: | test-frontend test-backend ## Run all tests
.PHONY: test-frontend
test-frontend: ## Run frontend tests
$Q cd frontend && pnpm install --frozen-lockfile && pnpm run typecheck
.PHONY: test-backend
test-backend: ## Run backend tests
@@ -31,7 +32,7 @@ lint: lint-frontend lint-backend ## Run all linters
.PHONY: lint-frontend
lint-frontend: ## Run frontend linters
$Q cd frontend && npm ci && npm run lint
$Q cd frontend && pnpm install --frozen-lockfile && pnpm run lint
.PHONY: lint-backend
lint-backend: | $(golangci-lint) ## Run backend linters
@@ -65,4 +66,4 @@ help: ## Show this help
@awk 'BEGIN {FS = ":.*?## "} { \
if (/^[a-zA-Z_-]+:.*?##.*$$/) {printf " ${YELLOW}%-20s${GREEN}%s${RESET}\n", $$1, $$2} \
else if (/^## .*$$/) {printf " ${CYAN}%s${RESET}\n", substr($$1,4)} \
}' $(MAKEFILE_LIST)
}' $(MAKEFILE_LIST)

View File

@@ -12,11 +12,24 @@
filebrowser provides a file managing interface within a specified directory and it can be used to upload, delete, preview, rename and edit your files. It allows the creation of multiple users and each user can have its own directory. It can be used as a standalone app.
> [!WARNING]
>
> This project is currently on **maintenance-only** mode, and is looking for new maintainers. For more information, please read the [discussion #4906](https://github.com/filebrowser/filebrowser/discussions/4906). Therefore, please note the following:
>
> - It can take a while until someone gets back to you. Please be patient.
> - [Issues][issues] are only being used to track bugs. Any unrelated issues will be converted into a [discussion][discussions].
> - No new features will be implemented until further notice. The priority is on triaging issues and merge bug fixes.
>
> If you're interested in maintaining this project, please reach out via the discussion above.
[issues]: https://github.com/filebrowser/filebrowser/issues
[discussions]: https://github.com/filebrowser/filebrowser/discussions
## Demo
url: https://demo.filebrowser.org/
URL: https://demo.filebrowser.org/
credentials: `demo`/`demo`
Credentials: `demo`/`demo`
## Features

View File

@@ -1,9 +1,9 @@
package auth
import (
"crypto/rand"
"errors"
"net/http"
"os"
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/settings"
@@ -19,14 +19,49 @@ type ProxyAuth struct {
}
// Auth authenticates the user via an HTTP header.
func (a ProxyAuth) Auth(r *http.Request, usr users.Store, _ *settings.Settings, srv *settings.Server) (*users.User, error) {
func (a ProxyAuth) Auth(r *http.Request, usr users.Store, setting *settings.Settings, srv *settings.Server) (*users.User, error) {
username := r.Header.Get(a.Header)
user, err := usr.Get(srv.Root, username)
if errors.Is(err, fbErrors.ErrNotExist) {
return nil, os.ErrPermission
return a.createUser(usr, setting, srv, username)
}
return user, err
}
func (a ProxyAuth) createUser(usr users.Store, setting *settings.Settings, srv *settings.Server, username string) (*users.User, error) {
const passwordSize = 32
randomPasswordBytes := make([]byte, passwordSize)
_, err := rand.Read(randomPasswordBytes)
if err != nil {
return nil, err
}
return user, err
var hashedRandomPassword string
hashedRandomPassword, err = users.HashPwd(string(randomPasswordBytes))
if err != nil {
return nil, err
}
user := &users.User{
Username: username,
Password: hashedRandomPassword,
LockPassword: true,
}
setting.Defaults.Apply(user)
var userHome string
userHome, err = setting.MakeUserDir(user.Username, user.Scope, srv.Root)
if err != nil {
return nil, err
}
user.Scope = userHome
err = usr.Save(user)
if err != nil {
return nil, err
}
return user, nil
}
// LoginPage tells that proxy auth doesn't require a login page.

View File

@@ -76,7 +76,7 @@ var rootCmd = &cobra.Command{
Use: "filebrowser",
Short: "A stylish web-based file browser",
Long: `File Browser CLI lets you create the database to use with File Browser,
manage your users and all the configurations without acessing the
manage your users and all the configurations without accessing the
web interface.
If you've never run File Browser, you'll need to have a database for
@@ -108,7 +108,7 @@ name in caps. So to set "database" via an env variable, you should
set FB_DATABASE.
Also, if the database path doesn't exist, File Browser will enter into
the quick setup mode and a new database will be bootstraped and a new
the quick setup mode and a new database will be bootstrapped and a new
user created with the credentials from options "username" and "password".`,
Run: python(func(cmd *cobra.Command, _ []string, d pythonData) {
log.Println(cfgFile)
@@ -378,7 +378,13 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
password := getParam(flags, "password")
if password == "" {
password, err = users.HashPwd("admin")
var pwd string
pwd, err = users.RandomPwd()
checkErr(err)
log.Println("Generated random admin password for quick setup:", pwd)
password, err = users.HashPwd(pwd)
checkErr(err)
}

View File

@@ -188,7 +188,7 @@ func cleanUpMapValue(v interface{}) interface{} {
}
// convertCmdStrToCmdArray checks if cmd string is blank (whitespace included)
// then returns empty string array, else returns the splitted word array of cmd.
// then returns empty string array, else returns the split word array of cmd.
// This is to ensure the result will never be []string{""}
func convertCmdStrToCmdArray(cmd string) []string {
var cmdArray []string

View File

@@ -12,4 +12,4 @@ fi
chown abc:abc \
/config/settings.json \
/database \
/srv
/srv

0
docker/root/etc/services.d/filebrowser/run Normal file → Executable file
View File

View File

@@ -28,7 +28,7 @@ const (
ContentTextHeaderValue = "text/plain"
// ContentXMLHeaderValue header value for XML data.
ContentXMLHeaderValue = "text/xml"
// ContentXMLUnreadableHeaderValue obselete header value for XML.
// ContentXMLUnreadableHeaderValue obsolete header value for XML.
ContentXMLUnreadableHeaderValue = "application/xml"
// ContentMarkdownHeaderValue custom key/content type, the real is the text/html.
ContentMarkdownHeaderValue = "text/markdown"

View File

@@ -98,7 +98,7 @@ func CommonPrefix(sep byte, paths ...string) string {
// (e.g. /home/user1, /home/user1/foo, /home/user1/bar).
// path.Clean will have cleaned off trailing / separators with
// the exception of the root directory, "/" (in which case we
// make it "//", but this will get fixed up to "/" bellow).
// make it "//", but this will get fixed up to "/" below).
c = append(c, sep)
// Ignore the first path since it's already in c

View File

@@ -1,27 +0,0 @@
{
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/eslint-config-typescript",
"@vue/eslint-config-prettier"
],
"rules": {
"vue/multi-word-component-names": "off",
"vue/no-mutating-props": [
"error",
{
"shallowOnly": true
}
]
// no-undef is already included in
// @vue/eslint-config-typescript
},
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
}
}

View File

@@ -1,2 +1,3 @@
# Ignore artifacts:
dist
dist
pnpm-lock.yaml

38
frontend/eslint.config.js Normal file
View File

@@ -0,0 +1,38 @@
import pluginVue from "eslint-plugin-vue";
import vueTsEslintConfig from "@vue/eslint-config-typescript";
import prettierConfig from "@vue/eslint-config-prettier";
export default [
{
name: "app/files-to-lint",
files: ["**/*.{ts,mts,tsx,vue}"],
},
{
name: "app/files-to-ignore",
ignores: ["**/dist/**", "**/dist-ssr/**", "**/coverage/**"],
},
...pluginVue.configs["flat/essential"],
...vueTsEslintConfig(),
prettierConfig,
{
rules: {
// Note: you must disable the base rule as it can report incorrect errors
"no-unused-expressions": "off",
"@typescript-eslint/no-unused-expressions": "off",
// TODO: theres too many of these from before ts
"@typescript-eslint/no-explicit-any": "off",
// TODO: finish the ts conversion
"vue/block-lang": "off",
"vue/multi-word-component-names": "off",
"vue/no-mutating-props": [
"error",
{
shallowOnly: true,
},
],
},
},
];

View File

@@ -1,10 +0,0 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}

File diff suppressed because it is too large Load Diff

View File

@@ -4,70 +4,74 @@
"private": true,
"type": "module",
"engines": {
"npm": ">=7.0.0",
"node": ">=18.0.0"
"node": ">=22.0.0",
"pnpm": ">=9.0.0"
},
"scripts": {
"dev": "vite dev",
"build": "npm run typecheck && vite build",
"build": "pnpm run typecheck && vite build",
"clean": "find ./dist -maxdepth 1 -mindepth 1 ! -name '.gitkeep' -exec rm -r {} +",
"typecheck": "vue-tsc -p ./tsconfig.json --noEmit",
"lint": "npm run typecheck && eslint --ext .vue,.ts src/",
"lint:fix": "eslint --ext .vue,.ts --fix src/",
"typecheck": "vue-tsc -p ./tsconfig.tsc.json --noEmit",
"lint": "eslint src/",
"lint:fix": "eslint --fix src/",
"format": "prettier --write .",
"test": "playwright test"
},
"dependencies": {
"@chenfengyuan/vue-number-input": "^2.0.1",
"@vueuse/core": "^10.9.0",
"@vueuse/integrations": "^10.9.0",
"ace-builds": "^1.32.9",
"core-js": "^3.36.1",
"@vueuse/core": "^12.5.0",
"@vueuse/integrations": "^12.5.0",
"ace-builds": "^1.37.5",
"core-js": "^3.40.0",
"dayjs": "^1.11.10",
"epubjs": "^0.3.93",
"filesize": "^10.1.1",
"js-base64": "^3.7.7",
"jwt-decode": "^4.0.0",
"lodash-es": "^4.17.21",
"material-icons": "^1.13.12",
"marked": "^14.1.0",
"marked": "^15.0.6",
"material-icons": "^1.13.13",
"normalize.css": "^8.0.1",
"pinia": "^2.1.7",
"pinia": "^2.3.1",
"pretty-bytes": "^6.1.1",
"qrcode.vue": "^3.4.1",
"tus-js-client": "^4.1.0",
"tus-js-client": "^4.3.1",
"utif": "^3.1.0",
"video.js": "^8.10.0",
"video.js": "^8.21.0",
"videojs-hotkeys": "^0.2.28",
"videojs-mobile-ui": "^1.1.1",
"vue": "^3.4.21",
"vue-final-modal": "^4.5.4",
"vue-i18n": "^9.10.2",
"vue-i18n": "^11.1.2",
"vue-lazyload": "^3.0.0",
"vue-reader": "^1.2.14",
"vue-reader": "^1.2.17",
"vue-router": "^4.3.0",
"vue-toastification": "^2.0.0-rc.5"
},
"devDependencies": {
"@intlify/unplugin-vue-i18n": "^4.0.0",
"@playwright/test": "^1.42.1",
"@intlify/unplugin-vue-i18n": "^6.0.3",
"@playwright/test": "^1.50.0",
"@tsconfig/node22": "^22.0.0",
"@types/lodash-es": "^4.17.12",
"@types/node": "^20.12.2",
"@typescript-eslint/eslint-plugin": "^7.4.0",
"@vitejs/plugin-legacy": "^5.3.2",
"@types/node": "^22.10.10",
"@typescript-eslint/eslint-plugin": "^8.21.0",
"@vitejs/plugin-legacy": "^6.0.0",
"@vitejs/plugin-vue": "^5.0.4",
"@vue/eslint-config-prettier": "^9.0.0",
"@vue/eslint-config-typescript": "^13.0.0",
"@vue/eslint-config-prettier": "^10.2.0",
"@vue/eslint-config-typescript": "^14.3.0",
"@vue/tsconfig": "^0.7.0",
"autoprefixer": "^10.4.19",
"concurrently": "^8.2.2",
"eslint": "^8.57.0",
"eslint-plugin-prettier": "^5.1.3",
"concurrently": "^9.1.2",
"eslint": "^9.19.0",
"eslint-plugin-prettier": "^5.2.3",
"eslint-plugin-vue": "^9.24.0",
"jsdom": "^24.0.0",
"postcss": "^8.4.38",
"prettier": "^3.2.5",
"terser": "^5.30.0",
"vite": "^5.2.7",
"jsdom": "^26.0.0",
"postcss": "^8.5.1",
"prettier": "^3.4.2",
"terser": "^5.37.0",
"vite": "^6.1.6",
"vite-plugin-compression2": "^1.0.0",
"vue-tsc": "^2.0.7"
}
"vue-tsc": "^2.2.0"
},
"packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0"
}

5426
frontend/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
import { createURL, fetchURL, removePrefix } from "./utils";
import { baseURL } from "@/utils/constants";
import { useAuthStore } from "@/stores/auth";
import { useLayoutStore } from "@/stores/layout";
import { baseURL } from "@/utils/constants";
import { upload as postTus, useTus } from "./tus";
import { createURL, fetchURL, removePrefix } from "./utils";
export async function fetch(url: string) {
url = removePrefix(url);
@@ -156,6 +157,7 @@ function moveCopy(
overwrite = false,
rename = false
) {
const layoutStore = useLayoutStore();
const promises = [];
for (const item of items) {
@@ -166,7 +168,7 @@ function moveCopy(
}&destination=${to}&override=${overwrite}&rename=${rename}`;
promises.push(resourceAction(url, "PATCH"));
}
layoutStore.closeHovers();
return Promise.all(promises);
}

View File

@@ -25,7 +25,7 @@ export async function create(user: IUser) {
throw new StatusError(await res.text(), res.status);
}
export async function update(user: IUser, which = ["all"]) {
export async function update(user: Partial<IUser>, which = ["all"]) {
await fetchURL(`/api/users/${user.id}`, {
method: "PUT",
body: JSON.stringify({

View File

@@ -34,7 +34,7 @@ const props = defineProps<{
const items = computed(() => {
const relativePath = route.path.replace(props.base, "");
let parts = relativePath.split("/");
const parts = relativePath.split("/");
if (parts[0] === "") {
parts.shift();
@@ -44,7 +44,7 @@ const items = computed(() => {
parts.pop();
}
let breadcrumbs: BreadCrumb[] = [];
const breadcrumbs: BreadCrumb[] = [];
for (let i = 0; i < parts.length; i++) {
if (i === 0) {

View File

@@ -46,7 +46,7 @@ https://raw.githubusercontent.com/dzwillia/vue-simple-progress/master/src/compon
<script>
// We're leaving this untouched as you can read in the beginning
var isNumber = function (n) {
const isNumber = function (n) {
return !isNaN(parseFloat(n)) && isFinite(n);
};
@@ -107,7 +107,7 @@ export default {
},
computed: {
pct() {
var pct = (this.val / this.max) * 100;
let pct = (this.val / this.max) * 100;
pct = pct.toFixed(2);
return Math.min(pct, this.max);
},
@@ -160,7 +160,7 @@ export default {
return isNumber(this.fontSize) ? this.fontSize : 13;
},
progress_style() {
var style = {
const style = {
background: this.bgColor,
};
@@ -177,7 +177,7 @@ export default {
return style;
},
bar_style() {
var style = {
const style = {
background: this.barColor,
width: this.pct + "%",
height: this.size_px + "px",
@@ -198,7 +198,7 @@ export default {
return style;
},
text_style() {
var style = {
const style = {
color: this.textFgColor,
"font-size": this.text_font_size + "px",
"text-align": this.textAlign,

View File

@@ -50,7 +50,7 @@ import { useFileStore } from "@/stores/file";
import { useLayoutStore } from "@/stores/layout";
import { commands } from "@/api";
import { throttle } from "lodash";
import { throttle } from "lodash-es";
import { theme } from "@/utils/constants";
export default {
@@ -163,7 +163,7 @@ export default {
this.canInput = false;
event.target.innerHTML = "";
let results = {
const results = {
text: `${cmd}\n\n`,
};
@@ -180,7 +180,7 @@ export default {
},
() => {
results.text = results.text
// eslint-disable-next-line no-control-regex
.replace(/\u001b\[[0-9;]+m/g, "") // Filter ANSI color for now
.trimEnd();
this.canInput = true;

View File

@@ -101,7 +101,7 @@
href="https://github.com/filebrowser/filebrowser"
>File Browser</a
>
<span> {{ version }}</span>
<span> {{ " " }} {{ version }}</span>
</span>
<span>
<a @click="help">{{ $t("sidebar.help") }}</a>
@@ -158,7 +158,7 @@ export default {
methods: {
...mapActions(useLayoutStore, ["closeHovers", "showHover"]),
async fetchUsage() {
let path = this.$route.path.endsWith("/")
const path = this.$route.path.endsWith("/")
? this.$route.path
: this.$route.path + "/";
let usageStats = USAGE_DEFAULT;
@@ -166,7 +166,7 @@ export default {
return Object.assign(this.usage, usageStats);
}
try {
let usage = await api.usage(path);
const usage = await api.usage(path);
usageStats = {
used: prettyBytes(usage.used, { binary: true }),
total: prettyBytes(usage.total, { binary: true }),
@@ -191,8 +191,13 @@ export default {
logout: auth.logout,
},
watch: {
isFiles(newValue) {
newValue && this.fetchUsage();
$route: {
handler(to) {
if (to.path.includes("/files")) {
this.fetchUsage();
}
},
immediate: true,
},
},
};

View File

@@ -14,15 +14,15 @@
</div>
</template>
<script setup lang="ts">
import throttle from "lodash/throttle";
import { throttle } from "lodash-es";
import UTIF from "utif";
import { onBeforeUnmount, onMounted, ref, watch } from "vue";
interface IProps {
src: string;
moveDisabledTime: number;
classList: any[];
zoomStep: number;
moveDisabledTime?: number;
classList?: any[];
zoomStep?: number;
}
const props = withDefaults(defineProps<IProps>(), {
@@ -102,10 +102,11 @@ const decodeUTIF = () => {
if (document?.location?.pathname === undefined) {
return;
}
let suff = document.location.pathname.split(".")?.pop()?.toLowerCase() ?? "";
const suff =
document.location.pathname.split(".")?.pop()?.toLowerCase() ?? "";
if (sufs.indexOf(suff) == -1) return false;
let xhr = new XMLHttpRequest();
const xhr = new XMLHttpRequest();
UTIF._xhrs.push(xhr);
UTIF._imgs.push(imgex.value);
xhr.open("GET", props.src);
@@ -230,7 +231,7 @@ const touchMove = (event: TouchEvent) => {
if (imgex.value === null) {
return;
}
let step = imgex.value.width / 5;
const step = imgex.value.width / 5;
if (event.targetTouches.length === 2) {
moveDisabled.value = true;
if (disabledTimer.value) clearTimeout(disabledTimer.value);
@@ -239,9 +240,9 @@ const touchMove = (event: TouchEvent) => {
props.moveDisabledTime
);
let p1 = event.targetTouches[0];
let p2 = event.targetTouches[1];
let touchDistance = Math.sqrt(
const p1 = event.targetTouches[0];
const p2 = event.targetTouches[1];
const touchDistance = Math.sqrt(
Math.pow(p2.pageX - p1.pageX, 2) + Math.pow(p2.pageY - p1.pageY, 2)
);
if (!lastTouchDistance.value) {
@@ -253,8 +254,8 @@ const touchMove = (event: TouchEvent) => {
setZoom();
} else if (event.targetTouches.length === 1) {
if (moveDisabled.value) return;
let x = event.targetTouches[0].pageX - (lastX.value ?? 0);
let y = event.targetTouches[0].pageY - (lastY.value ?? 0);
const x = event.targetTouches[0].pageX - (lastX.value ?? 0);
const y = event.targetTouches[0].pageY - (lastY.value ?? 0);
if (Math.abs(x) >= step && Math.abs(y) >= step) return;
lastX.value = event.targetTouches[0].pageX;
lastY.value = event.targetTouches[0].pageY;
@@ -268,8 +269,8 @@ const doMove = (x: number, y: number) => {
}
const style = imgex.value.style;
let posX = pxStringToNumber(style.left) + x;
let posY = pxStringToNumber(style.top) + y;
const posX = pxStringToNumber(style.left) + x;
const posY = pxStringToNumber(style.top) + y;
style.left = posX + "px";
style.top = posY + "px";

View File

@@ -82,7 +82,7 @@ const isDraggable = computed(
const canDrop = computed(() => {
if (!props.isDir || props.readOnly) return false;
for (let i of fileStore.selected) {
for (const i of fileStore.selected) {
if (fileStore.req?.items[i].url === props.url) {
return false;
}
@@ -156,9 +156,9 @@ const drop = async (event: Event) => {
}
}
let items: any[] = [];
const items: any[] = [];
for (let i of fileStore.selected) {
for (const i of fileStore.selected) {
if (fileStore.req) {
items.push({
from: fileStore.req?.items[i].url,
@@ -172,10 +172,10 @@ const drop = async (event: Event) => {
if (el === null) {
return;
}
let path = el.__vue__.url;
let baseItems = (await api.fetch(path)).items;
const path = el.__vue__.url;
const baseItems = (await api.fetch(path)).items;
let action = (overwrite: boolean, rename: boolean) => {
const action = (overwrite: boolean, rename: boolean) => {
api
.move(items, overwrite, rename)
.then(() => {
@@ -184,7 +184,7 @@ const drop = async (event: Event) => {
.catch($showError);
};
let conflict = upload.checkConflict(items, baseItems);
const conflict = upload.checkConflict(items, baseItems);
let overwrite = false;
let rename = false;

View File

@@ -62,7 +62,8 @@ const initVideoPlayer = async () => {
const languagePack = await (
languageImports[lang] || languageImports.en
)?.();
videojs.addLanguage("videoPlayerLocal", languagePack.default);
const code = languageImports[lang] ? lang : "en";
videojs.addLanguage(code, languagePack.default);
sourceType.value = "";
//
@@ -70,14 +71,19 @@ const initVideoPlayer = async () => {
const srcOpt = { sources: { src: props.source, type: sourceType.value } };
//Supporting localized language display.
const langOpt = { language: "videoPlayerLocal" };
const langOpt = { language: code };
// support for playback at different speeds.
const playbackRatesOpt = { playbackRates: [0.5, 1, 1.5, 2, 2.5, 3] };
let options = getOptions(props.options, langOpt, srcOpt, playbackRatesOpt);
const options = getOptions(
props.options,
langOpt,
srcOpt,
playbackRatesOpt
);
player.value = videojs(videoPlayer.value!, options, () => {});
// TODO: need to test on mobile
// @ts-ignore
// @ts-expect-error no ts definition for mobileUi
player.value!.mobileUi();
} catch (error) {
console.error("Error initializing video player:", error);
@@ -120,7 +126,7 @@ const subLabel = (subUrl: string) => {
let url: URL;
try {
url = new URL(subUrl);
} catch (_) {
} catch {
// treat it as a relative url
// we only need this for filename
url = new URL(subUrl, window.location.origin);

View File

@@ -82,10 +82,10 @@ export default {
...mapActions(useLayoutStore, ["showHover", "closeHovers"]),
copy: async function (event) {
event.preventDefault();
let items = [];
const items = [];
// Create a new promise for each file.
for (let item of this.selected) {
for (const item of this.selected) {
items.push({
from: this.req.items[item].url,
to: this.dest + encodeURIComponent(this.req.items[item].name),
@@ -93,7 +93,7 @@ export default {
});
}
let action = async (overwrite, rename) => {
const action = async (overwrite, rename) => {
buttons.loading("copy");
await api
@@ -122,8 +122,8 @@ export default {
return;
}
let dstItems = (await api.fetch(this.dest)).items;
let conflict = upload.checkConflict(items, dstItems);
const dstItems = (await api.fetch(this.dest)).items;
const conflict = upload.checkConflict(items, dstItems);
let overwrite = false;
let rename = false;

View File

@@ -74,8 +74,8 @@ export default {
return;
}
let promises = [];
for (let index of this.selected) {
const promises = [];
for (const index of this.selected) {
promises.push(api.remove(this.req.items[index].url));
}

View File

@@ -43,7 +43,7 @@ export default {
submit: async function () {
this.updateRequest(null);
let uri = url.removeLastDir(this.$route.path) + "/";
const uri = url.removeLastDir(this.$route.path) + "/";
this.$router.push({ path: uri });
},
},

View File

@@ -80,7 +80,7 @@ export default {
// Otherwise we add every directory to the
// move options.
for (let item of req.items) {
for (const item of req.items) {
if (!item.isDir) continue;
this.items.push({
@@ -93,12 +93,12 @@ export default {
// Retrieves the URL of the directory the user
// just clicked in and fill the options with its
// content.
let uri = event.currentTarget.dataset.url;
const uri = event.currentTarget.dataset.url;
files.fetch(uri).then(this.fillOptions).catch(this.$showError);
},
touchstart(event) {
let url = event.currentTarget.dataset.url;
const url = event.currentTarget.dataset.url;
// In 300 milliseconds, we shall reset the count.
setTimeout(() => {

View File

@@ -124,7 +124,7 @@ export default {
let sum = 0;
for (let selected of this.selected) {
for (const selected of this.selected) {
sum += this.req.items[selected].size;
}

View File

@@ -81,9 +81,9 @@ export default {
...mapActions(useLayoutStore, ["showHover", "closeHovers"]),
move: async function (event) {
event.preventDefault();
let items = [];
const items = [];
for (let item of this.selected) {
for (const item of this.selected) {
items.push({
from: this.req.items[item].url,
to: this.dest + encodeURIComponent(this.req.items[item].name),
@@ -91,7 +91,7 @@ export default {
});
}
let action = async (overwrite, rename) => {
const action = async (overwrite, rename) => {
buttons.loading("move");
await api
@@ -106,8 +106,8 @@ export default {
});
};
let dstItems = (await api.fetch(this.dest)).items;
let conflict = upload.checkConflict(items, dstItems);
const dstItems = (await api.fetch(this.dest)).items;
const conflict = upload.checkConflict(items, dstItems);
let overwrite = false;
let rename = false;

View File

@@ -3,7 +3,7 @@
</template>
<script setup lang="ts">
import { ref, watch } from "vue";
import { watch } from "vue";
import { ModalsContainer, useModal } from "vue-final-modal";
import { storeToRefs } from "pinia";
import { useLayoutStore } from "@/stores/layout";
@@ -30,8 +30,6 @@ const layoutStore = useLayoutStore();
const { currentPromptName } = storeToRefs(layoutStore);
const closeModal = ref<() => Promise<string>>();
const components = new Map<string, any>([
["info", Info],
["help", Help],
@@ -52,11 +50,6 @@ const components = new Map<string, any>([
]);
watch(currentPromptName, (newValue) => {
if (closeModal.value) {
closeModal.value();
closeModal.value = undefined;
}
const modal = components.get(newValue!);
if (!modal) return;
@@ -67,7 +60,7 @@ watch(currentPromptName, (newValue) => {
},
});
closeModal.value = close;
layoutStore.setCloseOnPrompt(close, newValue!);
open();
});

View File

@@ -196,13 +196,23 @@ export default {
methods: {
...mapActions(useLayoutStore, ["closeHovers"]),
copyToClipboard: function (text) {
copy(text).then(
copy({ text }).then(
() => {
// clipboard successfully set
this.$showSuccess(this.$t("success.linkCopied"));
},
() => {
// clipboard write failed
copy({ text }, { permission: true }).then(
() => {
// clipboard successfully set
this.$showSuccess(this.$t("success.linkCopied"));
},
(e) => {
// clipboard write failed
this.$showError(e);
}
);
}
);
},

View File

@@ -48,12 +48,10 @@ const layoutStore = useLayoutStore();
// TODO: this is a copy of the same function in FileListing.vue
const uploadInput = (event: Event) => {
layoutStore.closeHovers();
let files = (event.currentTarget as HTMLInputElement)?.files;
const files = (event.currentTarget as HTMLInputElement)?.files;
if (files === null) return;
let folder_upload = !!files[0].webkitRelativePath;
const folder_upload = !!files[0].webkitRelativePath;
const uploadFiles: UploadList = [];
for (let i = 0; i < files.length; i++) {
@@ -68,8 +66,8 @@ const uploadInput = (event: Event) => {
});
}
let path = route.path.endsWith("/") ? route.path : route.path + "/";
let conflict = upload.checkConflict(uploadFiles, fileStore.req!.items);
const path = route.path.endsWith("/") ? route.path : route.path + "/";
const conflict = upload.checkConflict(uploadFiles, fileStore.req!.items);
if (conflict) {
layoutStore.showHover({

View File

@@ -13,7 +13,7 @@ export default {
name: "languages",
props: ["locale"],
data() {
let dataObj = {};
const dataObj = {};
const locales = {
he: "עברית",
hu: "Magyar",
@@ -38,6 +38,7 @@ export default {
"sv-se": "Swedish (Sweden)",
tr: "Türkçe",
uk: "Українська",
vi: "Tiếng Việt",
"zh-cn": "中文 (简体)",
"zh-tw": "中文 (繁體)",
};

View File

@@ -39,7 +39,7 @@ export default {
methods: {
remove(event, index) {
event.preventDefault();
let rules = [...this.rules];
const rules = [...this.rules];
rules.splice(index, 1);
this.$emit("update:rules", [...rules]);
},

View File

@@ -7,7 +7,7 @@
</template>
<script setup lang="ts">
import { SelectHTMLAttributes } from "vue";
import type { SelectHTMLAttributes } from "vue";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
@@ -17,7 +17,6 @@ defineProps<{
}>();
const emit = defineEmits<{
// eslint-disable-next-line @typescript-eslint/no-unused-vars
(e: "update:theme", val: string | null): void;
}>();

View File

@@ -116,7 +116,7 @@ watch(createUserDirData, () => {
if (props.user?.scope) {
props.user.scope = createUserDirData.value
? ""
: originalUserScope.value ?? "";
: (originalUserScope.value ?? "");
}
});
</script>

View File

@@ -63,8 +63,8 @@
local("Roboto"),
local("Roboto-Regular"),
url(../assets/fonts/roboto/normal-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
U+A720-A7FF;
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF,
U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
@@ -142,8 +142,8 @@
local("Roboto Medium"),
local("Roboto-Medium"),
url(../assets/fonts/roboto/medium-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
U+A720-A7FF;
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF,
U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
@@ -221,8 +221,8 @@
local("Roboto Bold"),
local("Roboto-Bold"),
url(../assets/fonts/roboto/bold-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
U+A720-A7FF;
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF,
U+2C60-2C7F, U+A720-A7FF;
}
@font-face {

View File

@@ -195,6 +195,10 @@ html[dir="rtl"] #listing {
align-items: center;
}
#listing.list .item p.name:not(#listing.list .item.header .name) {
margin-right: -3em;
}
#listing.list .item .name {
width: 50%;
}
@@ -227,10 +231,6 @@ html[dir="rtl"] #listing {
width: 0;
}
#listing.list .item.header .name {
margin-right: 3em;
}
#listing.list .header a {
color: inherit;
}
@@ -246,10 +246,6 @@ html[dir="rtl"] #listing {
white-space: pre-wrap;
}
#listing.list .item.header .name {
margin-right: 3em;
}
#listing.list .header span {
vertical-align: middle;
}

View File

@@ -46,7 +46,7 @@
},
"errors": {
"forbidden": "Sie haben keine Berechtigung dies abzurufen.",
"internal": "Etwas ist schief gelaufen.",
"internal": "Etwas ist schiefgelaufen.",
"notFound": "Dieser Ort kann nicht angezeigt werden.",
"connection": "Der Server ist nicht erreichbar."
},
@@ -73,7 +73,7 @@
"ctrl": {
"click": "Markiere mehrere Dateien oder Ordner",
"f": "Öffnet eine neue Suche",
"s": "Speichert eine Datei oder einen Ordner am akutellen Ort"
"s": "Speichert eine Datei oder einen Ordner am aktuellen Ort"
},
"del": "Löscht die ausgewählten Elemente",
"doubleClick": "Öffnet eine Datei oder einen Ordner",
@@ -106,7 +106,7 @@
"displayName": "Anzeigename:",
"download": "Lade Dateien",
"downloadMessage": "Wählen Sie ein Format zum Herunterladen aus.",
"error": "Etwas ist schief gelaufen",
"error": "Etwas ist schiefgelaufen",
"fileInfo": "Dateiinformation",
"filesSelected": "{count} Dateien ausgewählt.",
"lastModified": "Zuletzt geändert",
@@ -150,13 +150,13 @@
"allowNew": "Erstellen neuer Dateien und Ordner",
"allowPublish": "Veröffentlichen von neuen Beiträgen und Seiten",
"allowSignup": "Erlaube Benutzern sich zu registrieren",
"avoidChanges": "(leer lassen um Änderungen zu vermeiden)",
"avoidChanges": "(leer lassen, um Änderungen zu vermeiden)",
"branding": "Design",
"brandingDirectoryPath": "Designverzeichnispfad",
"brandingHelp": "Sie können das Erscheinungsbild Ihres File Browser anpassen, in dem Sie den Namen ändern, das Logo austauchsen oder eigene Stile definieren und sogar externe Links zu GitHub deaktivieren.\nUm mehr Informationen zum Anpassen des Designs zu bekommen, gehen Sie bitte zu {0}.",
"brandingHelp": "Sie können das Erscheinungsbild Ihres File Browser anpassen, in dem Sie den Namen ändern, das Logo austauschen oder eigene Stile definieren und sogar externe Links zu GitHub deaktivieren.\nUm mehr Informationen zum Anpassen des Designs zu bekommen, gehen Sie bitte zu {0}.",
"changePassword": "Passwort ändern",
"commandRunner": "Befehlseingabe",
"commandRunnerHelp": "Hier könne Sie Befehle eintragen, welche bei den benannten Aktionen ausgeführt werden. Sie müssen pro Zeile jeweils einen Befehl eingeben. Die Umgebungsvariable {0} und {1} sind verfügbar, wobei {0} relative zu {1} ist. Für mehr Informationen über diese Funktion und die verfügbaren Umgebungsvariablen, lesen Sie bitte die {2}.",
"commandRunnerHelp": "Hier könne Sie Befehle eintragen, welche bei den benannten Aktionen ausgeführt werden. Sie müssen pro Zeile jeweils einen Befehl eingeben. Die Umgebungsvariable {0} und {1} sind verfügbar, wobei {0} relative zu {1} ist. Für mehr Informationen über diese Funktion und die verfügbaren Umgebungsvariablen lesen Sie bitte die {2}.",
"commandsUpdated": "Befehle aktualisiert!",
"createUserDir": "Automatisches Erstellen des Home-Verzeichnisses beim Anlegen neuer Benutzer",
"tusUploads": "Gestückelter Upload",
@@ -170,7 +170,7 @@
"documentation": "Dokumentation",
"examples": "Beispiele",
"executeOnShell": "In Shell ausführen",
"executeOnShellDescription": "Es ist voreingestellt das der File Brower Befehle ausführt in dem er die Befehlsdateien direkt aufruft. Wenn Sie wollen, dass sie über einer Kommandozeile (wie Bash oder PowerShell) laufen, könne Sie diese hier definieren mit allen bennötigten Argumenten und Optionen. Wenn gesetzt, wird das Kommando das ausgeführt werden soll als Parameter angehängt. Das gilt für Benuzerkommandos sowie auch für Ereignisse.",
"executeOnShellDescription": "Es ist voreingestellt, dass der File Brower Befehle ausführt, indem er die Befehlsdateien direkt aufruft. Wenn Sie wollen, dass sie über einer Kommandozeile (wie Bash oder PowerShell) laufen, könne Sie diese hier definieren mit allen benötigten Argumenten und Optionen. Wenn gesetzt, wird das Kommando das ausgeführt werden soll als Parameter angehängt. Das gilt für Benutzerkommandos sowie auch für Ereignisse.",
"globalRules": "Das ist ein globales Set von Regeln die erlauben oder nicht erlauben. Die sind für alle Benutzer zutreffend. Es können spezielle Regeln in den Einstellungen der Benutzer definiert werden, die diese überschreiben.",
"globalSettings": "Globale Einstellungen",
"hideDotfiles": "Versteckte Dateien ausblenden",
@@ -195,7 +195,7 @@
"share": "Datei teilen"
},
"permissions": "Berechtigungen",
"permissionsHelp": "Sie können einem Benutzer Administratorrechte einräumen oder die Berechtigunen individuell festlegen. Wenn Sie \"Administrator\" auswählen, werden alle anderen Rechte automatisch vergeben. Die Nutzerverwaltung kann nur durch einen Administrator erfolgen.\n",
"permissionsHelp": "Sie können einem Benutzer Administratorrechte einräumen oder die Berechtigungen individuell festlegen. Wenn Sie \"Administrator\" auswählen, werden alle anderen Rechte automatisch vergeben. Die Nutzerverwaltung kann nur durch einen Administrator erfolgen.\n",
"profileSettings": "Profileinstellungen",
"ruleExample1": "Verhindert den Zugang zu versteckten Dateien (dot-Files, wie .git, .gitignore) in allen Ordnern\n",
"ruleExample2": "blockiert den Zugang auf Dateien mit dem Namen Caddyfile in der Wurzel/Basis des Scopes.",

View File

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

View File

@@ -14,7 +14,7 @@
"file": "Fichier",
"folder": "Dossier",
"fullScreen": "Plein écran",
"hideDotfiles": "Masquer les dotfiles",
"hideDotfiles": "Masquer les fichiers cachés",
"info": "Info",
"more": "Plus",
"move": "Déplacer",
@@ -22,15 +22,16 @@
"new": "Nouveau",
"next": "Suivant",
"ok": "OK",
"permalink": "Obtenir un lien permanent",
"permalink": "Obtenir le lien permanent",
"previous": "Précédent",
"preview": "Prévisualiser",
"publish": "Publier",
"rename": "Renommer",
"replace": "Remplacer",
"reportIssue": "Rapport d'erreur",
"reportIssue": "Signaler un problème",
"save": "Enregistrer",
"schedule": "Fixer la date",
"search": "Chercher",
"schedule": "Planifier",
"search": "Rechercher",
"select": "Sélectionner",
"selectMultiple": "Sélection multiple",
"share": "Partager",
@@ -40,18 +41,22 @@
"toggleSidebar": "Afficher/Masquer la barre latérale",
"update": "Mettre à jour",
"upload": "Importer",
"openFile": "Ouvrir le fichier"
"openFile": "Ouvrir le fichier",
"discardChanges": "Annuler"
},
"download": {
"downloadFile": "Télécharger le fichier",
"downloadFolder": "Télécharger le dossier",
"downloadSelected": "Télécharger la selection"
"downloadSelected": "Télécharger la sélection"
},
"upload": {
"abortUpload": "Êtes-vous sûr de vouloir annuler ?"
},
"errors": {
"forbidden": "Vous n'avez pas la permission d'accéder à cela.",
"internal": "Aïe ! Quelque chose s'est mal passé.",
"notFound": "Impossible d'accéder à cet emplacement.",
"connection": "Le serveur n'est pas accessible."
"connection": "Le serveur est injoignable."
},
"files": {
"body": "Corps",
@@ -61,15 +66,15 @@
"home": "Accueil",
"lastModified": "Dernière modification",
"loading": "Chargement...",
"lonely": "Il semble qu'il n'y ait rien par ici...",
"metadata": "Metadonnées",
"lonely": "C'est un peu désert ici...",
"metadata": "Métadonnées",
"multipleSelectionEnabled": "Sélection multiple activée",
"name": "Nom",
"size": "Taille",
"sortByLastModified": "Trier par date de dernière modification",
"sortByLastModified": "Trier par date de modification",
"sortByName": "Trier par nom",
"sortBySize": "Trier par taille",
"noPreview": "Il n'y a pas de prévisualisation pour ce fichier."
"noPreview": "L'aperçu n'est pas disponible pour ce fichier."
},
"help": {
"click": "Sélectionner un élément",
@@ -105,6 +110,7 @@
"deleteMessageMultiple": "Êtes-vous sûr de vouloir supprimer ces {count} élément(s) ?",
"deleteMessageSingle": "Êtes-vous sûr de vouloir supprimer cet élément ?",
"deleteMessageShare": "Êtes-vous sûr de vouloir supprimer ce partage ({path}) ?",
"deleteUser": "Êtes-vous sûr de vouloir supprimer cet utilisateur ?",
"deleteTitle": "Supprimer",
"displayName": "Nom :",
"download": "Télécharger",
@@ -125,31 +131,33 @@
"rename": "Renommer",
"renameMessage": "Nouveau nom pour",
"replace": "Remplacer",
"replaceMessage": "Un des fichiers que vous êtes en train d'importer a le même nom qu'un autre déjà présent. Voulez-vous remplacer le fichier actuel par le nouveau ?\n",
"schedule": "Fixer la date",
"replaceMessage": "L'un des fichiers que vous êtes en train d'importer a le même nom qu'un autre déjà présent. Voulez-vous remplacer le fichier actuel par le nouveau ?\n",
"schedule": "Planifier",
"scheduleMessage": "Choisissez une date pour planifier la publication de ce post",
"show": "Montrer",
"size": "Taille",
"upload": "Importer",
"uploadFiles": "Importation de {files} fichiers...",
"uploadMessage": "Séléctionnez une option d'import.",
"optionalPassword": "Mot de passe optionnel"
"uploadMessage": "Sélectionnez une option d'import.",
"optionalPassword": "Mot de passe optionnel",
"resolution": "Résolution",
"discardEditorChanges": "Êtes-vous sûr de vouloir annuler les modifications apportées ?"
},
"search": {
"images": "Images",
"music": "Musique",
"pdf": "PDF",
"pressToSearch": "Appuyez du entrée pour chercher...",
"pressToSearch": "Appuyez sur Entrée pour rechercher...",
"search": "Recherche en cours...",
"typeToSearch": "Écrivez pour chercher...",
"typeToSearch": "Écrivez pour rechercher...",
"types": "Types",
"video": "Video"
"video": "Vidéo"
},
"settings": {
"admin": "Admin",
"administrator": "Administrateur",
"allowCommands": "Exécuter des commandes",
"allowEdit": "Editer, renommer et supprimer des fichiers ou des dossiers",
"allowEdit": "Éditer, renommer et supprimer des fichiers ou des dossiers",
"allowNew": "Créer de nouveaux fichiers et dossiers",
"allowPublish": "Publier de nouveaux posts et pages",
"allowSignup": "Autoriser les utilisateurs à s'inscrire",
@@ -158,32 +166,39 @@
"brandingDirectoryPath": "Chemin du dossier d'image de marque",
"brandingHelp": "Vous pouvez personnaliser l'apparence de votre instance de File Browser en changeant son nom, en remplaçant le logo, en ajoutant des styles personnalisés et même en désactivant les liens externes vers GitHub.\nPour plus d'informations sur la personnalisation de l'image de marque, veuillez consulter la {0}.",
"changePassword": "Modifier le mot de passe",
"commandRunner": "Command runner",
"commandRunnerHelp": "Ici, vous pouvez définir les commandes qui sont exécutées pour les événements nommés précédemments. Vous devez en écrire une par ligne. Les variables d'environnement {0} et {1} seront disponibles, {0} étant relatif à {1}. Pour plus d'informations sur cette fonctionnalité et les variables d'environnement disponibles, veuillez lire la {2}.",
"commandRunner": "Exécuteur de commandes",
"commandRunnerHelp": "Ici, vous pouvez définir les commandes qui seront exécutées lors des événements nommés précédemments. Vous devez en écrire une par ligne. Les variables d'environnement {0} et {1} seront disponibles, {0} étant relatif à {1}. Pour plus d'informations sur cette fonctionnalité et les variables d'environnement disponibles, veuillez lire la {2}.",
"commandsUpdated": "Commandes mises à jour !",
"createUserDir": "Créer automatiquement un dossier pour l'utilisateur",
"tusUploads": "Uploads segmentés",
"tusUploadsHelp": "File Browser prend en charge les uploads segmentés afin de permettre une gestion efficace, fiable et reprenable sur des réseaux instables.",
"tusUploadsChunkSize": "Taille maximale autorisée par segment (les uploads directs seront utilisés pour les fichiers plus petits). Vous pouvez entrer un entier en octets ou une chaîne telle que 10MB, 1GB, etc.",
"tusUploadsRetryCount": "Nombre de tentatives en cas d'échec d'un segment.",
"userHomeBasePath": "Chemin de base pour les répertoires personnels des utilisateurs",
"userScopeGenerationPlaceholder": "Le périmètre sera généré automatiquement",
"createUserHomeDirectory": "Créer le répertoire personnel de l'utilisateur",
"customStylesheet": "Feuille de style personnalisée",
"defaultUserDescription": "Paramètres par défaut pour les nouveaux utilisateurs.",
"disableExternalLinks": "Désactiver les liens externes (sauf la documentation)",
"disableUsedDiskPercentage": "Disable used disk percentage graph",
"disableUsedDiskPercentage": "Désactiver le graphique de pourcentage d'utilisation du disque",
"documentation": "documentation",
"examples": "Exemples",
"executeOnShell": "Exécuter dans le shell",
"executeOnShellDescription": "Par défaut, File Browser exécute les commandes en appelant directement leurs binaires. Si vous voulez les exécuter sur un shell à la place (comme Bash ou PowerShell), vous pouvez le définir ici avec les arguments et les drapeaux requis. S'il est défini, la commande que vous exécutez sera ajoutée en tant qu'argument. Cela s'applique à la fois aux commandes utilisateur et aux crochets d'événements.",
"globalRules": "Il s'agit d'un ensemble global de règles d'autorisation et d'interdiction. Elles s'appliquent à tous les utilisateurs. Vous pouvez définir des règles spécifiques sur les paramètres de chaque utilisateur pour remplacer celles-ci.",
"globalSettings": "Paramètres généraux",
"globalSettings": "Paramètres globaux",
"hideDotfiles": "Cacher les fichiers de configuration utilisateur (dotfiles)",
"insertPath": "Insérez le chemin",
"insertRegex": "Insérez l'expression régulière",
"insertPath": "Insérer le chemin",
"insertRegex": "Insérer une expression régulière",
"instanceName": "Nom de l'instance",
"language": "Langue",
"lockPassword": "Empêcher l'utilisateur de changer son mot de passe",
"newPassword": "Votre nouveau mot de passe",
"newPasswordConfirm": "Confirmation du nouveau mot de passe",
"newUser": "Nouvel Utilisateur",
"newUser": "Nouvel utilisateur",
"password": "Mot de passe",
"passwordUpdated": "Mot de passe mis à jour !",
"path": "",
"path": "Chemin",
"perm": {
"create": "Créer des fichiers et des dossiers",
"delete": "Supprimer des fichiers et des dossiers",
@@ -209,14 +224,14 @@
"singleClick": "Utiliser un simple clic pour ouvrir les fichiers et les dossiers",
"themes": {
"dark": "Sombre",
"light": "Lumineux",
"light": "Clair",
"title": "Thème"
},
"user": "Utilisateur",
"userCommands": "Commandes",
"userCommandsHelp": "Une liste séparée par des espaces des commandes permises pour l'utilisateur. Exemple :",
"userCommandsHelp": "Une liste séparée par des espaces des commandes permises pour l'utilisateur. Exemple :\n",
"userCreated": "Utilisateur créé !",
"userDefaults": "User default settings",
"userDefaults": "Paramètres par défaut de l'utilisateur",
"userDeleted": "Utilisateur supprimé !",
"userManagement": "Gestion des utilisateurs",
"userUpdated": "Utilisateur mis à jour !",
@@ -237,7 +252,7 @@
"siteSettings": "Paramètres du site"
},
"success": {
"linkCopied": "Lien copié!"
"linkCopied": "Lien copié !"
},
"time": {
"days": "Jours",

View File

@@ -23,6 +23,7 @@ import("dayjs/locale/sk");
import("dayjs/locale/sv");
import("dayjs/locale/tr");
import("dayjs/locale/uk");
import("dayjs/locale/vi");
import("dayjs/locale/zh-cn");
import("dayjs/locale/zh-tw");
@@ -103,6 +104,9 @@ export function detectLocale() {
case /^uk\b/.test(locale):
locale = "uk";
break;
case /^vi\b/.test(locale):
locale = "vi";
break;
case /^sv-se\b/.test(locale):
case /^sv\b/.test(locale):
locale = "sv";
@@ -142,7 +146,7 @@ export const i18n = createI18n({
export const isRtl = (locale?: string) => {
// see below
// @ts-ignore
// @ts-expect-error incorrect type when legacy
return rtlLanguages.includes(locale || i18n.global.locale.value);
};
@@ -150,7 +154,7 @@ export function setLocale(locale: string) {
dayjs.locale(locale);
// according to doc u only need .value if legacy: false but they lied
// https://vue-i18n.intlify.dev/guide/essentials/scope.html#local-scope-1
//@ts-ignore
// @ts-expect-error incorrect type when legacy
i18n.global.locale.value = locale;
}

View File

@@ -3,47 +3,60 @@
"cancel": "취소",
"clear": "지우기",
"close": "닫기",
"continue": "계속",
"copy": "복사",
"copyFile": "파일 복사",
"copyToClipboard": "클립보드 복사",
"copyToClipboard": "클립보드 복사",
"copyDownloadLinkToClipboard": "다운로드 링크 클립보드에 복사",
"create": "생성",
"delete": "삭제",
"download": "다운로드",
"hideDotfiles": "",
"file": "파일",
"folder": "폴더",
"fullScreen": "전체 화면 전환",
"hideDotfiles": "숨김 파일 숨기기",
"info": "정보",
"more": "더보기",
"more": "더 보기",
"move": "이동",
"moveFile": "파일 이동",
"new": "신규",
"new": "새로 만들기",
"next": "다음",
"ok": "확인",
"permalink": "링크 기",
"permalink": "영구 링크 기",
"previous": "이전",
"preview": "미리보기",
"publish": "게시",
"rename": "이름 바꾸기",
"replace": "대체",
"reportIssue": "이슈 보내기",
"replace": "바꾸기",
"reportIssue": "문제 보고",
"save": "저장",
"schedule": "일정",
"schedule": "예약",
"search": "검색",
"select": "선택",
"selectMultiple": "다중 선택",
"share": "공유",
"shell": " 전환",
"shell": " 전환",
"submit": "제출",
"switchView": "보기 전환",
"toggleSidebar": "사이드바 전환",
"update": "업데이트",
"upload": "업로드"
"upload": "업로드",
"openFile": "파일 열기",
"discardChanges": "변경 사항 취소"
},
"download": {
"downloadFile": "파일 다운로드",
"downloadFolder": "폴더 다운로드",
"downloadSelected": ""
"downloadSelected": "선택 항목 다운로드"
},
"upload": {
"abortUpload": "업로드를 중단하시겠습니까?"
},
"errors": {
"forbidden": "접근 권한이 없습니다.",
"internal": "오류가 발생하였습니다.",
"notFound": "해당 경로를 찾을 수 없습니다."
"forbidden": "이곳에 접근 권한이 없습니다.",
"internal": "문제가 발생습니다.",
"notFound": "이 위치에 접근할 수 없습니다.",
"connection": "서버에 연결할 수 없습니다."
},
"files": {
"body": "본문",
@@ -51,175 +64,192 @@
"files": "파일",
"folders": "폴더",
"home": "홈",
"lastModified": "최종 수정",
"loading": "로딩중...",
"lonely": "폴더가 비어 있습니다...",
"lastModified": "마지막 수정",
"loading": "로딩 중...",
"lonely": "여기에 아무것도 없네요...",
"metadata": "메타데이터",
"multipleSelectionEnabled": "다중 선택 켜짐",
"multipleSelectionEnabled": "다중 선택 활성화됨",
"name": "이름",
"size": "크기",
"sortByLastModified": "수정시간순 정렬",
"sortByName": "이름",
"sortBySize": "크기순"
"sortByLastModified": "마지막 수정일 순 정렬",
"sortByName": "이름 순 정렬",
"sortBySize": "크기 순 정렬",
"noPreview": "이 파일은 미리보기를 사용할 수 없습니다."
},
"help": {
"click": "파일이나 디렉토리를 선택해주세요.",
"click": "파일 또는 디렉터리 선택",
"ctrl": {
"click": "여러 개의 파일이나 디렉토리를 선택해주세요.",
"f": "검색 열기",
"s": "파일 또는 디렉리 다운로드"
"click": "여러 파일 또는 디렉터리 선택",
"f": "검색 열기",
"s": "파일 저장 또는 현재 디렉리 다운로드"
},
"del": "선택된 파일 삭제",
"doubleClick": "파일 또는 디렉리 열기",
"esc": "선택 취소/프롬프트 닫기",
"f1": "정보",
"f2": "파일 이름 변경",
"del": "선택한 항목 삭제",
"doubleClick": "파일 또는 디렉리 열기",
"esc": "선택 취소 및/또는 프롬프트 닫기",
"f1": "정보",
"f2": "파일 이름 바꾸기",
"help": "도움말"
},
"login": {
"createAnAccount": "계정 생성",
"createAnAccount": "계정 만들기",
"loginInstead": "이미 계정이 있습니다",
"password": "비밀번호",
"passwordConfirm": "비밀번호 확인",
"passwordsDontMatch": "비밀번호가 일치하지 않습니다",
"signup": "가입하기",
"signup": "가입",
"submit": "로그인",
"username": "사용자 이름",
"usernameTaken": "사용자 이름이 존재합니다",
"wrongCredentials": "사용자 이름 또는 비밀번호를 확인하십시오"
"usernameTaken": "이미 사용 중인 사용자 이름니다",
"wrongCredentials": "잘못된 자격 증명"
},
"permanent": "영구",
"prompts": {
"copy": "복사",
"copyMessage": "복사할 디렉토리:",
"currentlyNavigating": "현재 위치:",
"deleteMessageMultiple": "{count} 개의 파일을 삭제하시겠습니까?",
"deleteMessageSingle": "파일 혹은 디렉토리를 삭제하시겠습니까?",
"copyMessage": "파일을 복사할 위치를 선택하세요:",
"currentlyNavigating": "현재 탐색 중:",
"deleteMessageMultiple": "{count}개의 파일을 삭제하시겠습니까?",
"deleteMessageSingle": "이 파일/폴더를 삭제하시겠습니까?",
"deleteMessageShare": "이 공유({path})를 삭제하시겠습니까?",
"deleteUser": "이 사용자를 삭제하시겠습니까?",
"deleteTitle": "파일 삭제",
"displayName": "시 이름:",
"displayName": "시 이름:",
"download": "파일 다운로드",
"downloadMessage": "다운로드 포맷 설정.",
"error": "에러 발생!",
"downloadMessage": "다운로드할 형식을 선택하세요.",
"error": "문제가 발생했습니다",
"fileInfo": "파일 정보",
"filesSelected": "{count} 개의 파일 선택되었습니다.",
"lastModified": "최종 수정",
"filesSelected": "{count}개의 파일 선택.",
"lastModified": "마지막 수정",
"move": "이동",
"moveMessage": "이동할 화일 또는 디렉토리를 선택하세요:",
"newArchetype": "원형을 유지하는 포스트를 생성합니다. 파일은 컨텐트 폴더에 생성됩니다.",
"newDir": "새 디렉리",
"newDirMessage": "새 디렉리 이름을 입력해주세요.",
"moveMessage": "파일/폴더의 새 위치를 선택하세요:",
"newArchetype": "아키타입을 기반으로 새 게시물을 만듭니다. 파일은 content 폴더에 생성됩니다.",
"newDir": "새 디렉리",
"newDirMessage": "새 디렉리 이름을 지정하세요.",
"newFile": "새 파일",
"newFileMessage": "새 파일 이름을 입력해주세요.",
"numberDirs": "디렉리 수",
"newFileMessage": "새 파일 이름을 지정하세요.",
"numberDirs": "디렉리 수",
"numberFiles": "파일 수",
"rename": "이름 변경",
"renameMessage": "새로운 이름을 입력하세요.",
"replace": "대체하기",
"replaceMessage": "동일한 파일 이름이 존재합니다. 현재 파일을 덮어쓸까요?\n",
"schedule": "일정",
"scheduleMessage": "이 글을 공개할 시간을 알려주세요.",
"show": "보기",
"rename": "이름 바꾸기",
"renameMessage": "새 이름을 입력하세요:",
"replace": "바꾸기",
"replaceMessage": "업로드하려는 파일 이름이 충돌하는 파일이 있습니다. 이 파일을 건너뛰고 업로드를 계속하거나 기존 파일을 바꾸시겠습니까?\n",
"schedule": "예약",
"scheduleMessage": "이 게시물의 게시를 예약할 날짜와 시간을 선택하세요.",
"show": "표시",
"size": "크기",
"upload": "",
"uploadMessage": ""
"upload": "업로드",
"uploadFiles": "{files}개의 파일 업로드 중...",
"uploadMessage": "업로드할 옵션을 선택하세요.",
"optionalPassword": "선택적 비밀번호",
"resolution": "해상도",
"discardEditorChanges": "변경 사항을 취소하시겠습니까?"
},
"search": {
"images": "이미지",
"music": "음악",
"pdf": "PDF",
"pressToSearch": "검색하려면 엔터를 입력하세요",
"pressToSearch": "Enter 키를 눌러 검색...",
"search": "검색...",
"typeToSearch": "검색어 입력...",
"types": "Types",
"types": "유형",
"video": "비디오"
},
"settings": {
"admin": "관리자",
"administrator": "관리자",
"allowCommands": "명령 실행",
"allowEdit": "파일/디렉토리의 수정/변경/삭제 허용",
"allowNew": "파일/디렉리 생성 허용",
"allowPublish": "새 포스트/페이지 생성 허용",
"allowCommands": "명령 실행 허용",
"allowEdit": "파일 또는 디렉터리 편집, 이름 바꾸기, 삭제 허용",
"allowNew": "새 파일 및 디렉리 생성 허용",
"allowPublish": "새 게시물 및 페이지 게시 허용",
"allowSignup": "사용자 가입 허용",
"avoidChanges": "(수정하지 않으면 비워두세요)",
"avoidChanges": "(변경하지 않으면 비워두세요)",
"branding": "브랜딩",
"brandingDirectoryPath": "브랜 디렉리 경로",
"brandingHelp": "File Browser 인스턴스 이름, 로고, 스타일 등을 변경할 수 있습니다. 자세한 사항은 여기{0}에서 확인하세요.",
"brandingDirectoryPath": "브랜 디렉리 경로",
"brandingHelp": "File Browser 인스턴스 이름 변경, 로고 교체, 사용자 정의 스타일 추가, GitHub 외부 링크 비활성화를 통해 모양과 느낌을 사용자 지정할 수 있습니다.\n사용자 정의 브랜딩에 대한 자세한 내용은 {0}을(를) 확인하세요.",
"changePassword": "비밀번호 변경",
"commandRunner": "명령 실행기",
"commandRunnerHelp": "이벤트에 해당하는 명령 설정하세요. 줄당 1개의 명령을 적으세요. 환경 변수{0} {1}이 사용가능하며, {0} 은 {1}에 상대 경로 입니다. 자세한 사항은 {2} 를 참조하세요.",
"commandsUpdated": "명령 수정됨!",
"createUserDir": "Auto create user home dir while adding new user",
"customStylesheet": "커스텀 스타일시트",
"defaultUserDescription": "아래 사항은 신규 사용자들에 대한 기본 설정입니다.",
"disableExternalLinks": "외부 링크 감추기",
"disableUsedDiskPercentage": "Disable used disk percentage graph",
"commandRunner": "명령 실행기",
"commandRunnerHelp": "여기서 지정된 이벤트에서 실행될 명령어를 설정할 수 있습니다. 한 줄에 하나씩 작성해야 합니다. 환경 변수 {0} {1}을(를) 사용할 수 있으며, {0}은(는) {1}에 상대입니다. 이 기능과 사용 가능한 환경 변수에 대한 자세한 내용은 {2}을(를) 읽어보세요.",
"commandsUpdated": "명령어가 업데이트되었습니다!",
"createUserDir": "새 사용자 추가 시 사용자 홈 디렉터리 자동 생성",
"tusUploads": "청크 업로드",
"tusUploadsHelp": "File Browser는 청크 파일 업로드를 지원하여 불안정한 네트워크에서도 효율적이고 안정적이며 재개 가능하고 분할된 파일 업로드를 가능하게 합니다.",
"tusUploadsChunkSize": "요청의 최대 크기를 나타냅니다 (더 작은 업로드에는 직접 업로드가 사용됩니다). 바이트 크기를 나타내는 일반 정수 또는 10MB, 1GB 등과 같은 문자열을 입력할 수 있습니다.",
"tusUploadsRetryCount": "청크 업로드 실패 시 재시도 횟수.",
"userHomeBasePath": "사용자 홈 디렉터리의 기본 경로",
"userScopeGenerationPlaceholder": "범위가 자동으로 생성됩니다",
"createUserHomeDirectory": "사용자 홈 디렉터리 생성",
"customStylesheet": "사용자 정의 스타일시트",
"defaultUserDescription": "새 사용자의 기본 설정입니다.",
"disableExternalLinks": "외부 링크 비활성화 (문서 제외)",
"disableUsedDiskPercentage": "사용된 디스크 비율 그래프 비활성화",
"documentation": "문서",
"examples": "예",
"executeOnShell": "에서 실행",
"executeOnShellDescription": "기본적으로 File Browser 는 바이너리를 명령어로 호출하여 실행합니다. 쉘을 통해 실행하기를 원한다면, Bash 또는 PowerShell 필요한 인수 플래그를 설정하세요. 사용자 명령어와 이벤트 훅에 모두 적용됩니다.",
"globalRules": "규칙에 대한 전역설정으로 모든 사용자에게 적용됩니다. 지정된 규칙은 사용자 설정을 덮어쓰기 합니다.",
"examples": "예",
"executeOnShell": "에서 실행",
"executeOnShellDescription": "기본적으로 File Browser는 바이너리를 직접 호출하여 명령을 실행합니다. 대신 셸(예: Bash 또는 PowerShell)에서 실행하려면 필요한 인수 플래그와 함께 여기에 정의할 수 있습니다. 설정된 경우 실행하는 명령이 인수로 추가됩니다. 이는 사용자 명령 이벤트 후크 모두 적용됩니다.",
"globalRules": "이것은 전역 허용 및 차단 규칙 세트입니다. 모든 사용자에게 적용됩니다. 각 사용자 설정에서 특정 규칙을 정의하여 이 규칙을 재정의할 수 있습니다.",
"globalSettings": "전역 설정",
"hideDotfiles": "",
"insertPath": "경로 입",
"insertRegex": "정규식 입",
"hideDotfiles": "숨김 파일 숨기기",
"insertPath": "경로 입",
"insertRegex": "정규식 표현 삽입",
"instanceName": "인스턴스 이름",
"language": "언어",
"lockPassword": "사용자에 의한 비밀번호 변경을 허용하지 않음",
"newPassword": "새로운 비밀번호",
"newPasswordConfirm": "새로운 비밀번호 확인",
"newUser": "새로운 사용자",
"lockPassword": "사용자 비밀번호 변경하지 못하도록 잠금",
"newPassword": "새 비밀번호",
"newPasswordConfirm": "새 비밀번호 확인",
"newUser": "새 사용자",
"password": "비밀번호",
"passwordUpdated": "비밀번호 수정 완료!",
"path": "",
"passwordUpdated": "비밀번호가 업데이트되었습니다!",
"path": "경로",
"perm": {
"create": "파일이나 디렉리 생성하기",
"delete": "화일이나 디렉리 삭제하기",
"create": "파일 디렉리 생성",
"delete": "파일 및 디렉리 삭제",
"download": "다운로드",
"execute": "명령 실행",
"modify": "파일 편집",
"rename": "파일 이름 변경 또는 디렉토리 이동",
"share": "파일 공유하기"
"rename": "파일 및 디렉터리 이름 바꾸기 또는 이동",
"share": "파일 공유"
},
"permissions": "권한",
"permissionsHelp": "사용자를 관리자로 만들거나 권한을 부여할 수 있습니다. 관리자를 선택하면, 모든 옵션이 자동으로 선택됩니다. 사용자 관리는 현재 관리자만 할 수 있습니다.\n",
"permissionsHelp": "사용자를 관리자로 설정하거나 개별적으로 권한을 선택할 수 있습니다. \"관리자\"를 선택하면 다른 모든 옵션이 자동으로 선택됩니다. 사용자 관리는 관리자의 권한으로 유지됩니다.\n",
"profileSettings": "프로필 설정",
"ruleExample1": "점(.)으로 시작하는 모든 파일의 접근을 방지합니다.(예 .git, .gitignore)\n",
"ruleExample2": "Caddyfile파일의 접근을 방지합니다.",
"rules": "",
"rulesHelp": "사용자별로 규칙을 허용/방지를 지정할 수 있습니다. 방지된 파일은 보이지 않 사용자들은 접근할 수 없습니다. 사용자의 접근 허용 범위와 관련해 정규표현식(regex)과 경로를 지원합니다.\n",
"ruleExample1": "모든 폴더에서 모든 숨김 파일(예: .git, .gitignore)에 대한 액세스를 방지합니다.\n",
"ruleExample2": "범위의 루트에 있는 Caddyfile이라는 파일에 대한 액세스를 차단합니다.",
"rules": "규칙",
"rulesHelp": "여기서 이 특정 사용자에 대한 허용 및 차단 규칙 세트를 정의할 수 있습니다. 차단된 파일은 목록에 표시되지 않으며 사용자가 액세스할 수 없습니다. 사용자의 범위에 상대적인 정규식 및 경로를 지원합니다.\n",
"scope": "범위",
"settingsUpdated": "설정 수정됨!",
"shareDuration": "",
"shareManagement": "",
"singleClick": "",
"setDateFormat": "정확한 날짜 형식 설정",
"settingsUpdated": "설정이 업데이트되었습니다!",
"shareDuration": "공유 기간",
"shareManagement": "공유 관리",
"shareDeleted": "공유가 삭제되었습니다!",
"singleClick": "파일 및 디렉터리를 열 때 한 번 클릭 사용",
"themes": {
"dark": "",
"light": "",
"title": ""
"default": "시스템 기본값",
"dark": "어둡게",
"light": "밝게",
"title": "테마"
},
"user": "사용자",
"userCommands": "명령어",
"userCommandsHelp": "사용에게 허용할 명령어를 공백으로 구분하여 입력하세요. 예:\n",
"userCreated": "사용자 생성!",
"userCommandsHelp": "이 사용자가 사용할 수 있는 명령어 목록 (공백으로 구분). 예:\n",
"userCreated": "사용자 생성되었습니다!",
"userDefaults": "사용자 기본 설정",
"userDeleted": "사용자 삭제!",
"userDeleted": "사용자 삭제되었습니다!",
"userManagement": "사용자 관리",
"userUpdated": "사용자 수정됨!",
"userUpdated": "사용자가 업데이트되었습니다!",
"username": "사용자 이름",
"users": "사용자"
},
"sidebar": {
"help": "도움말",
"hugoNew": "Hugo New",
"hugoNew": "Hugo 새로 만들기",
"login": "로그인",
"logout": "로그아웃",
"myFiles": "내 파일",
"newFile": "새로운 파일",
"newFolder": "새로운 폴더",
"newFile": "새 파일",
"newFolder": "새 폴더",
"preview": "미리보기",
"settings": "설정",
"signup": "가입하기",
"signup": "가입",
"siteSettings": "사이트 설정"
},
"success": {
@@ -227,9 +257,9 @@
},
"time": {
"days": "일",
"hours": "시",
"hours": "시",
"minutes": "분",
"seconds": "초",
"unit": "Time Unit"
"unit": "시간 단위"
}
}

View File

@@ -3,133 +3,153 @@
"cancel": "Anuluj",
"clear": "Wyczyść",
"close": "Zamknij",
"continue": "Kontynuuj",
"copy": "Kopiuj",
"copyFile": "Kopiuj plik",
"copyToClipboard": "kopiuj do schowka",
"copyToClipboard": "Kopiuj do schowka",
"copyDownloadLinkToClipboard": "Kopiuj link pobierania do schowka",
"create": "Utwórz",
"delete": "Usuń",
"download": "Pobierz",
"hideDotfiles": "",
"info": "Informacja",
"more": "Więce",
"file": "Plik",
"folder": "Folder",
"fullScreen": "Przełącz tryb pełnoekranowy",
"hideDotfiles": "Ukryj pliki poprzedzone kropką",
"info": "Informacje",
"more": "Więcej",
"move": "Przenieś",
"moveFile": "Przenieś plik",
"new": "Nowy",
"next": "Następny",
"ok": "OK",
"permalink": "Uzyskaj link bezpośredni (permalink)",
"permalink": "Uzyskaj stały link",
"previous": "Poprzedni",
"preview": "Podgląd",
"publish": "Opublikuj",
"rename": "Zmień nazwę",
"replace": "Zamień",
"reportIssue": "Zgłoś problem",
"save": "Zapisz",
"schedule": "Grafik",
"schedule": "Harmonogram",
"search": "Szukaj",
"select": "Wybierz",
"select": "Zaznacz",
"selectMultiple": "Zaznacz wiele",
"share": "Udostępnij",
"shell": "Pokaż/ukryj powłokę",
"shell": "Przełącz powłokę",
"submit": "Prześlij",
"switchView": "Zmień widok",
"toggleSidebar": "Pokaż/ukryj panel boczny",
"toggleSidebar": "Przełącz pasek boczny",
"update": "Aktualizuj",
"upload": "Wgraj"
"upload": "Wyślij",
"openFile": "Otwórz plik",
"discardChanges": "Odrzuć"
},
"download": {
"downloadFile": "Pobierz plik",
"downloadFolder": "Pobierz folder",
"downloadSelected": "Pobierz zaznaczone"
},
"upload": {
"abortUpload": "Czy na pewno chcesz przerwać?"
},
"errors": {
"forbidden": "Nie posiadasz uprawnień potrzebnych, by uzyskać do tego dostęp.",
"forbidden": "Nie masz zezwolenia na dostęp do tego.",
"internal": "Pojawił się poważny problem.",
"notFound": "Ten adres nie jest poprawny."
"notFound": "Ta lokalizacja jest nieosiągalna.",
"connection": "Serwer jest nieosiągalny."
},
"files": {
"body": "Body",
"closePreview": "Zamknij poprzednie",
"body": "Zawartość",
"closePreview": "Zamknij podgląd",
"files": "Pliki",
"folders": "Foldery",
"home": "Katalog domowy",
"lastModified": "Ostatnio modyfikowane",
"home": "Główny",
"lastModified": "Ostatnio zmodyfikowano",
"loading": "Ładowanie...",
"lonely": "Smutno gdy tak pusto...",
"lonely": "Smutno, gdy tak pusto...",
"metadata": "Metadane",
"multipleSelectionEnabled": "Zaznaczenie wielu włączone",
"multipleSelectionEnabled": "Włączono zaznaczenie wielokrotne",
"name": "Nazwa",
"size": "Rozmiar",
"sortByLastModified": "Sortuj wg. daty modyfikacji",
"sortByName": "Sortuj wg. nazwy",
"sortBySize": "Sortuj wg. rozmiaru"
"sortByLastModified": "Sortuj wg ostatniej modyfikacji",
"sortByName": "Sortuj wg nazwy",
"sortBySize": "Sortuj wg rozmiaru",
"noPreview": "Podgląd tego pliku jest niedostępny."
},
"help": {
"click": "wybierz plik lub foler",
"click": "zaznacz plik lub folder",
"ctrl": {
"click": "wybierz wiele plików lub folderów",
"click": "zaznacz wiele plików lub folderów",
"f": "otwórz wyszukiwarkę",
"s": "pobierz aktywny plik lub folder"
},
"del": "usuń zaznaczone",
"del": "usuń zaznaczone elementy",
"doubleClick": "otwórz plik lub folder",
"esc": "wyczyść zaznaczenie i/lub zamknij okno z powiadomieniem",
"f1": "ta informacja",
"esc": "wyczyść zaznaczenie i/lub zamknij monit",
"f1": "te informacje",
"f2": "zmień nazwę pliku",
"help": "Pomoc"
},
"login": {
"createAnAccount": "Utwórz konto",
"loginInstead": "Takie konto już istnieje",
"loginInstead": "Mam już konto",
"password": "Hasło",
"passwordConfirm": "Potwierdzenie hasła",
"passwordsDontMatch": "Hasła różnią się",
"passwordsDontMatch": "Hasła nie pasują do siebie",
"signup": "Rejestracja",
"submit": "Logowanie",
"submit": "Zaloguj",
"username": "Nazwa użytkownika",
"usernameTaken": "Nazwa użytkownika j zajęta",
"usernameTaken": "Ta nazwa użytkownika jest zajęta",
"wrongCredentials": "Błędne dane logowania"
},
"permanent": "Permanentny",
"prompts": {
"copy": "Kopiuj",
"copyMessage": "Wybierz lokalizację do której mają być skopiowane wybrane pliki",
"currentlyNavigating": "Obecnie przeglądasz:",
"deleteMessageMultiple": "Czy jesteś pewien że chcesz usunąć {count} plik(ów)?",
"deleteMessageSingle": "Czy jesteś pewien, że chcesz usunąć ten plik/folder?",
"copyMessage": "Wybierz lokalizację docelową:",
"currentlyNavigating": "Aktualnie poruszasz się po:",
"deleteMessageMultiple": "Czy na pewno chcesz usunąć pliki: {count}?",
"deleteMessageSingle": "Czy na pewno chcesz usunąć ten plik/folder?",
"deleteMessageShare": "Czy na pewno chcesz usunąć ten udział ({path})?",
"deleteUser": "Czy na pewno chcesz usunąć tego użytkownika?",
"deleteTitle": "Usuń pliki",
"displayName": "Wyświetlana Nazwa:",
"displayName": "Wyświetlana nazwa:",
"download": "Pobierz pliki",
"downloadMessage": "Wybierz format, jaki chesz pobrać.",
"error": "Pojawił się nieznany błąd",
"fileInfo": "Informacje o pliku",
"filesSelected": "{count} plików zostało zaznaczonych.",
"lastModified": "Osatnio Zmodyfikowane",
"downloadMessage": "Wybierz format, w którym chcesz pobrać.",
"error": "Pojawił się jakiś błąd",
"fileInfo": "Informacje o pliku",
"filesSelected": "Zaznaczone pliki: {count}",
"lastModified": "Ostatnio zmodyfikowano",
"move": "Przenieś",
"moveMessage": "Wybierz nową lokalizację dla swoich plik(ów)/folder(ów):",
"newArchetype": "Utwórz nowy wpis na bazie wybranego wzorca. Twój plik będzie utworzony w wybranym folderze.",
"moveMessage": "Wybierz nową lokalizację dla swoich plików/folderów:",
"newArchetype": "Utwórz nowy wpis na bazie wybranego wzorca. Twój plik będzie utworzony w wybranym folderze.",
"newDir": "Nowy folder",
"newDirMessage": "Podaj nazwę tworzonego folderu.",
"newDirMessage": "Nazwij nowy folder.",
"newFile": "Nowy plik",
"newFileMessage": "Podaj nazwętworzonego pliku.",
"numberDirs": "Ilość katalogów",
"numberFiles": "Ilość plików",
"newFileMessage": "Nazwij nowy plik.",
"numberDirs": "Liczba folderów",
"numberFiles": "Liczba plików",
"rename": "Zmień nazwę",
"renameMessage": "Podaj nową nazwę dla",
"replace": "Zamień",
"replaceMessage": "Jednen z plików który próbujesz wrzucić próbje nadpisać plik o tej samej nazwie. Czy chcesz nadpisać poprzedni plik?\n",
"schedule": "Grafi",
"scheduleMessage": "Wybierz datę i czas dla publikacji tego wpisu.",
"replaceMessage": "Jeden z przesyłanych plików chce nadpisać istniejący plik o tej samej nazwie. Chcesz pominąć ten plik i kontynuować przesyłanie reszty plików, czy nadpisać istniejący plik?\n",
"schedule": "Grafik",
"scheduleMessage": "Wybierz datę i czas dla publikacji tego wpisu.",
"show": "Pokaż",
"size": "Rozmiar",
"upload": "Prześlij",
"uploadMessage": "Proszę wybrać metodę przesyłania"
"upload": "Wyślij",
"uploadFiles": "Wysyłam pliki: {files}...",
"uploadMessage": "Wybierz opcję przesyłania.",
"optionalPassword": "Opcjonalne hasło",
"resolution": "Rozdzielczość",
"discardEditorChanges": "Czy na pewno chcesz odrzucić wprowadzone zmiany?"
},
"search": {
"images": "Zdjęcia",
"images": "Obrazy",
"music": "Muzyka",
"pdf": "PDF",
"pressToSearch": "Wciśnij enter, aby wyszukać...",
"pressToSearch": "Naciśnij Enter, aby wyszukać...",
"search": "Szukaj...",
"typeToSearch": "Zacznij pisać, aby wyszukać...",
"typeToSearch": "Typ plików do wyszukania...",
"types": "Typy",
"video": "Wideo"
},
@@ -137,70 +157,80 @@
"admin": "Admin",
"administrator": "Administrator",
"allowCommands": "Wykonaj polecenie",
"allowEdit": "Edycja, zmiana nazwy i usuniecie plików lub folderów",
"allowEdit": "Edycja, zmiana nazwy i usuniecie plików lub folderów",
"allowNew": "Tworzenie nowych plików lub folderów",
"allowPublish": "Tworzenie nowych wpisów i stron",
"allowSignup": "Zezwól na rejestrację użytkowników",
"avoidChanges": "(pozostaw puste aby nie zosatało zmienione)",
"branding": "Branding",
"brandingDirectoryPath": "Folder brandingowy",
"brandingHelp": "Możesz dostosować wygląd i doznania użytkownika swojej instancji File Browser poprzez zmianę jej nazwy, zmianę logo, dodanie własnych stylów, a nawet wyłączyć linki zewnętrzne do GitHuba.\nW celu pozyskania większej ilości informacji nt. osobistego brandingu, zapoznaj się z {0}.",
"changePassword": "Zmień Hasło",
"allowPublish": "Tworzenie nowych wpisów i stron",
"allowSignup": "Pozwól użytkownikom na rejestrację",
"avoidChanges": "(pozostaw puste, aby uniknąć zmian)",
"branding": "Personalizacja",
"brandingDirectoryPath": "Ścieżka do folderu personalizacji",
"brandingHelp": "Możesz zmodyfikować wygląd instancji File Browser poprzez zmianę nazwy, logo, dodanie własnych stylów graficznych, a nawet usunięcia linków do serwisu GitHub. Więcej informacji o modyfikacji wyglądu znajdziesz w {0}.",
"changePassword": "Zmień hasło",
"commandRunner": "Narzędzie do wykonywania poleceń",
"commandRunnerHelp": "Tu możesz ustawić komendy, które będą wykonywane przy danych zdarzeniach. Musisz wpisywać po jednej na linjkę. Zmienne środowiskowe {0} i {1} będą dostępne, gdzie {0} jest względne wobec {1}. Więcej informacji o tej funkcji i dostępnych zmiennych środowiskowych znajdziesz tutaj: {2}.",
"commandRunnerHelp": "Tu możesz ustawić polecenia, które będą wykonywane przy danych zdarzeniach. Musisz wpisywać po jednym na wiersz. Zmienne środowiskowe {0} i {1} będą dostępne, gdzie {0} jest względne wobec {1}. Więcej informacji o tej funkcji i dostępnych zmiennych środowiskowych znajdziesz w {2}.",
"commandsUpdated": "Polecenie zaktualizowane!",
"createUserDir": "Automatycznie utwórz katalog domowy użytkownika podczas dodania nowego użytkownika",
"customStylesheet": "Własny arkusz stylów",
"defaultUserDescription": "Oto domyślne ustawienia dla nowych użytkowników.",
"disableExternalLinks": "Wyłącz linki zewnętrzne (z wyjątkiem dokumentacji)",
"disableUsedDiskPercentage": "Disable used disk percentage graph",
"documentation": "dokumentacja",
"createUserDir": "Automatycznie twórz katalog domowy podczas dodawania użytkownika",
"tusUploads": "Przesyłanie we fragmentach",
"tusUploadsHelp": "File Browser wspiera przesyłanie plików we fragmentach, co pozwala na proces przesyłania, który jest wydajny, pewny i możliwy do wznowienia nawet w sieciach o wątpliwej stabilności przesyłu danych.",
"tusUploadsChunkSize": "Oznacza maksymalny rozmiar przesyłanych plików (dla mniejszych plików użyte zostanie przesyłanie bezpośrednie). Możesz ustawić tę wartość zarówno zapisaną samymi cyframi w bajtach, jak i podać ją w formie skróconej, np. poprzez 10MB, 1GB itp.",
"tusUploadsRetryCount": "Liczba prób ponowienia transferu w przypadku wystapienia problemu z przesyłem.",
"userHomeBasePath": "Ścieżka podstawowa dla katalogów domowych użytkowników",
"userScopeGenerationPlaceholder": "Zakres zostanie wygenerowany automatycznie",
"createUserHomeDirectory": "Utwórz katalog domowy użytkownika",
"customStylesheet": "Własny arkusz stylu",
"defaultUserDescription": "To są domyślne ustawienia dla nowych użytkowników.",
"disableExternalLinks": "Wyłącz linki zewnętrzne (z wyjątkiem dokumentacji)",
"disableUsedDiskPercentage": "Wyłącz wykres procentowy używanego dysku",
"documentation": "dokumentacji",
"examples": "Przykłady",
"executeOnShell": "Wykonaj w powłoce",
"executeOnShellDescription": "Domyślnie File Browser wykonuje polecenia wywołując ich pliki binarne bezpośrednio. Jesli preferujesz wykonywanie ich w powłoce (jak np. Bash czy PowerShell), możesz zdefiniować to tutaj wraz z wymaganymi flagami i argumentami. Jeśli to ustawienie jest aktywne, polecenie które wykonarz zostanie dodane jako argument. Stosuje się to zarówno do poleceń użytkownika jak i zaczepów zdarzeń.",
"globalRules": "To jest globalne zestawienie reguł zezwalających i zabraniających. Stosują się one do każdego użytkownika. Możesz zdefiniować indywidualne zasady w ustawieniach każdego użytkownika, by zignorować te reguły.",
"globalSettings": "Ustawienia Globalne",
"hideDotfiles": "Ukryj ukryte pliki",
"executeOnShell": "Wykonaj w powłoce",
"executeOnShellDescription": "Domyślnie File Browser wykonuje polecenia poprzez bezpośrednie uruchomienie odpowiednich plików binarnych. Jeśli chcesz uruchamiać polecenia z poziomu powłoki (np. Bash lub PowerShell), możesz zdefiniować je tutaj, z wykorzystaniem odpowiednich argumentów i flag. Gdy się na to zdecydujesz, wykonywane polecenie będzie załączone jako argument. Tyczy się to tak poleceń użytkownika, jak i zaczepów zdarzeń.",
"globalRules": "Globalny zestaw reguł zezwalających i zakazujących. Dotyczą każdego użytkownika. Aby zastąpić ustawienia globalne, możesz zdefiniować określone reguły indywidualnie dla każdego użytkownika.",
"globalSettings": "Ustawienia globalne",
"hideDotfiles": "Ukryj pliki poprzedzone kropką",
"insertPath": "Wstaw ścieżkę",
"insertRegex": "Wstaw wyrażenie regularne",
"instanceName": "Nazwa instancji",
"language": "Język",
"lockPassword": "Zablokuj użytkownikowi możliwość zmiany hasła",
"newPassword": "Twoje nowe hasło",
"newPasswordConfirm": "Potwierdź swoje hasło",
"newUser": "Nowy Użytkownik",
"newPassword": "Nowe hasło",
"newPasswordConfirm": "Potwierdź nowe hasło",
"newUser": "Nowy użytkownik",
"password": "Hasło",
"passwordUpdated": "Hasło zostało zapisane!",
"passwordUpdated": "Hasło zostało zaktualizowane!",
"path": "Ścieżka",
"perm": {
"create": "Tworzenie plików i katalogów",
"delete": "Usuwanie plików i katalogów",
"create": "Tworzenie plików i folderów",
"delete": "Usuwanie plików i folderów",
"download": "Pobieranie",
"execute": "Wykonywanie poleceń",
"modify": "Edycja plików",
"rename": "Zmiana nazw lub przenoszenie plików i katalogów",
"modify": "Edytowanie plików",
"rename": "Zmienianie nazwy lub przenoszenie plików i katalogów",
"share": "Udostępnianie plików"
},
"permissions": "Uprawnienia",
"permissionsHelp": "Możesz uczynić użytkownika administratorem, lub wybrać uprawnienia indywidualnie. Jeśli zaznaczysz opcję \"Administrator\", wszystkie pozostałe opcje zostaną automatycznie zaznaczone. Zarządzanie użytkownikami pozostaje przywilejem administratora.\n",
"permissionsHelp": "Możesz ustawić użytkownika jako administratora lub wybrać uprawnienia indywidualnie. Jeśli wybierzesz „Administrator, wszystkie pozostałe opcje zostaną automatycznie zaznaczone. Zarządzanie użytkownikami pozostaje przywilejem administratora.\n",
"profileSettings": "Twój profil",
"ruleExample1": "uniemożliwia dostęp do któregokolwiek z ukrytych plików (takich jak .git, .gitignore) w każdym folderze.\n",
"ruleExample2": "blokuje dostęp do pliku Caddyfile w głównym katalogu zakresu.",
"ruleExample1": "uniemożliwia dostęp do plików poprzedzonych kropką (takich jak .git, .gitignore) we wszystkich folderach.\n",
"ruleExample2": "blokuje dostęp do pliku o nazwie Caddyfile w katalogu głównym zakresu.",
"rules": "Uprawnienia",
"rulesHelp": "Tu możesz zdefiniować zestawienie reguł zezwalających i zabraniających dla tego konkretnego użytkownika. Zablokowane pliki nie będą widoczne na listach i nie będą dostępne dla użytkownika. Wspierane są wyrażenia regularne i ścieżki względne wobec zakresu użytkownika.\n",
"rulesHelp": "Tutaj możesz zdefiniować zestaw reguł zezwalających i zakazujących dla tego użytkownika. Zablokowane pliki nie pojawią się na listach i nie będą dostępne dla użytkownika. Obsługujemy wyrażenia regularne i ścieżki względne w stosunku do zakresu użytkownika.\n",
"scope": "Zakres",
"settingsUpdated": "Uprawnienia Zapisane!",
"setDateFormat": "Ustaw dokładny format daty",
"settingsUpdated": "Ustawienia zaktualizowane!",
"shareDuration": "Okres udostępniania",
"shareManagement": "Zarządzanie udostępnianiem",
"singleClick": "Pojedyncze kliknięcie",
"shareDeleted": "Udostępnienie usunięte!",
"singleClick": "Używaj pojedynczych kliknięć, aby otwierać pliki i foldery",
"themes": {
"dark": "ciemny",
"light": "jasny",
"title": "Motywy"
"default": "Domyślny systemowy",
"dark": "Ciemny",
"light": "Jasny",
"title": "Motyw"
},
"user": "Użytkownik",
"userCommands": "Polecenia",
"userCommandsHelp": "Lista oddzielonych spacjami poleceń dostępnych dla tego użytkownika. Przykład:\n",
"userCommandsHelp": "Oddzielona spacjami lista z dostępnymi poleceniami dla tego użytkownika. Przykład:\n",
"userCreated": "Użytkownik zapisany!",
"userDefaults": "Domyślne ustawienia użytkownika",
"userDeleted": "Użytkownik usunięty!",
@@ -211,8 +241,8 @@
},
"sidebar": {
"help": "Pomoc",
"hugoNew": "Hugo New",
"login": "Login",
"hugoNew": "Nowy Hugo",
"login": "Zaloguj",
"logout": "Wyloguj",
"myFiles": "Moje pliki",
"newFile": "Nowy plik",
@@ -220,10 +250,10 @@
"preview": "Podgląd",
"settings": "Ustawienia",
"signup": "Rejestracja",
"siteSettings": "Ustawienia Strony"
"siteSettings": "Ustawienia strony"
},
"success": {
"linkCopied": "Link Skopiowany!"
"linkCopied": "Link skopiowany!"
},
"time": {
"days": "Dni",

View File

@@ -38,13 +38,20 @@
"toggleSidebar": "Alternar barra lateral",
"update": "Atualizar",
"upload": "Enviar",
"openFile": "Abrir"
"openFile": "Abrir",
"copyDownloadLinkToClipboard": "Copiar link de download para a área de transferência",
"fullScreen": "Alternar tela cheia",
"preview": "Pré-visualizar",
"discardChanges": "Descartar"
},
"download": {
"downloadFile": "Baixar arquivo",
"downloadFolder": "Baixar pasta",
"downloadSelected": "Baixar selecionado"
},
"upload": {
"abortUpload": "Tem certeza de que deseja abortar o upload?"
},
"errors": {
"forbidden": "Você não tem permissões para acessar isto.",
"internal": "Ops! Algum erro ocorreu.",
@@ -58,8 +65,8 @@
"folders": "Pastas",
"home": "Início",
"lastModified": "Última modificação",
"loading": "Carregando. Aguarde, por favor.",
"lonely": "Não existe nada aqui.",
"loading": "Carregando...",
"lonely": "Não nada aqui...",
"metadata": "Metadados",
"multipleSelectionEnabled": "Seleção múltipla ativada",
"name": "Nome",
@@ -73,12 +80,12 @@
"click": "selecionar pasta ou arquivo",
"ctrl": {
"click": "selecionar várias pastas e arquivos",
"f": "pesquisar",
"f": "abrir pesquisa",
"s": "salvar um arquivo ou baixar a pasta que você está"
},
"del": "apagar os arquivos selecionados",
"doubleClick": "abrir pasta ou arquivo",
"esc": "limpar seleção e/ou fechar menu",
"esc": "limpar seleção e/ou fechar prompt",
"f1": "esta informação",
"f2": "renomear arquivo",
"help": "Ajuda"
@@ -123,7 +130,7 @@
"rename": "Renomear",
"renameMessage": "Insira um novo nome para",
"replace": "Substituir",
"replaceMessage": "Já existe um arquivo com nome igual a um dos que está tentando enviar. Deseja substituir?\n",
"replaceMessage": "Um dos arquivos que você está tentando enviar possui um nome conflitante. Deseja pular este arquivo e continuar o envio ou substituir o existente?\n",
"schedule": "Agendar",
"scheduleMessage": "Escolha uma data para agendar a publicação deste post.",
"show": "Mostrar",
@@ -131,7 +138,10 @@
"upload": "Enviar",
"uploadFiles": "Enviando {files} arquivos...",
"uploadMessage": "Selecione uma opção para enviar.",
"optionalPassword": "Senha opcional"
"optionalPassword": "Senha opcional",
"deleteUser": "Tem certeza de que deseja apagar este usuário?",
"resolution": "Resolução",
"discardEditorChanges": "Tem certeza de que deseja descartar as alterações feitas?"
},
"search": {
"images": "Imagens",
@@ -159,7 +169,7 @@
"commandRunner": "Execução de comandos",
"commandRunnerHelp": "Aqui você pode definir comandos que serão executados nos eventos descritos. Escreva um por linha. As variáveis de ambiente {0} e {1} estão disponíveis, sendo {0} relativo a {1}. Para mais informações sobre esta função e as variáveis de ambiente disponíveis, leia a {2}.",
"commandsUpdated": "Comandos atualizados!",
"createUserDir": "Criar diretório Home para novos usuários",
"createUserDir": "Criar diretório Home do usuário automaticamente ao adicionar novo usuário",
"userHomeBasePath": "Caminho base para diretórios de usuários",
"userScopeGenerationPlaceholder": "O escopo será gerado automaticamente",
"createUserHomeDirectory": "Criar diretório Home de usuário",
@@ -184,7 +194,7 @@
"newUser": "Novo usuário",
"password": "Senha",
"passwordUpdated": "Senha atualizada!",
"path": "",
"path": "Caminho",
"perm": {
"create": "Criar arquivos e diretórios",
"delete": "Apagar arquivos e diretórios",
@@ -209,6 +219,7 @@
"shareDeleted": "Compartilhamento apagado!",
"singleClick": "Usar clique único para abrir arquivos e diretórios",
"themes": {
"default": "Padrão do sistema",
"dark": "Escuro",
"light": "Claro",
"title": "Tema"
@@ -229,7 +240,7 @@
"hugoNew": "Hugo New",
"login": "Login",
"logout": "Sair",
"myFiles": "Arquivos",
"myFiles": "Meus arquivos",
"newFile": "Novo arquivo",
"newFolder": "Nova pasta",
"preview": "Pré-visualizar",
@@ -245,6 +256,6 @@
"hours": "Horas",
"minutes": "Minutos",
"seconds": "Segundos",
"unit": "Unidades de Tempo"
"unit": "Unidade de tempo"
}
}

265
frontend/src/i18n/vi.json Normal file
View File

@@ -0,0 +1,265 @@
{
"buttons": {
"cancel": "Hủy",
"clear": "Xóa",
"close": "Đóng",
"continue": "Tiếp tục",
"copy": "Sao chép",
"copyFile": "Sao chép tập tin",
"copyToClipboard": "Sao chép vào clipboard",
"copyDownloadLinkToClipboard": "Sao chép liên kết tải xuống vào clipboard",
"create": "Tạo",
"delete": "Xóa",
"download": "Tải xuống",
"file": "Tập tin",
"folder": "Thư mục",
"fullScreen": "Toàn màn hình",
"hideDotfiles": "Ẩn tập tin ẩn",
"info": "Thông tin",
"more": "Thêm",
"move": "Di chuyển",
"moveFile": "Di chuyển tập tin",
"new": "Mới",
"next": "Tiếp theo",
"ok": "OK",
"permalink": "Lấy liên kết vĩnh viễn",
"previous": "Trước",
"preview": "Xem trước",
"publish": "Xuất bản",
"rename": "Đổi tên",
"replace": "Thay thế",
"reportIssue": "Báo cáo sự cố",
"save": "Lưu",
"schedule": "Lên lịch",
"search": "Tìm kiếm",
"select": "Chọn",
"selectMultiple": "Chọn nhiều",
"share": "Chia sẻ",
"shell": "Chuyển đổi shell",
"submit": "Gửi",
"switchView": "Chuyển chế độ xem",
"toggleSidebar": "Thanh bên",
"update": "Cập nhật",
"upload": "Tải lên",
"openFile": "Mở tệp",
"discardChanges": "Hủy bỏ thay đổi"
},
"download": {
"downloadFile": "Tải xuống tệp tin",
"downloadFolder": "Tải xuống thư mục",
"downloadSelected": "Tải xuống đã chọn"
},
"upload": {
"abortUpload": "Bạn có chắc chắn muốn hủy tải lên không?"
},
"errors": {
"forbidden": "Bạn không có quyền truy cập vào nội dung này.",
"internal": "Đã xảy ra lỗi nghiêm trọng.",
"notFound": "Không thể truy cập vị trí này.",
"connection": "Không thể kết nối đến máy chủ."
},
"files": {
"body": "Nội dung",
"closePreview": "Đóng xem trước",
"files": "Tập tin",
"folders": "Thư mục",
"home": "Trang chủ",
"lastModified": "Sửa đổi lần cuối",
"loading": "Đang tải...",
"lonely": "Không có gì ở đây...",
"metadata": "Siêu dữ liệu",
"multipleSelectionEnabled": "Đã bật chọn nhiều",
"name": "Tên",
"size": "Kích thước",
"sortByLastModified": "Sắp xếp theo ngày sửa đổi",
"sortByName": "Sắp xếp theo tên",
"sortBySize": "Sắp xếp theo kích thước",
"noPreview": "Không có bản xem trước cho tập tin này."
},
"help": {
"click": "chọn tập tin hoặc thư mục",
"ctrl": {
"click": "chọn nhiều tập tin hoặc thư mục",
"f": "mở tìm kiếm",
"s": "lưu tập tin hoặc tải thư mục hiện tại"
},
"del": "xóa các mục đã chọn",
"doubleClick": "mở tập tin hoặc thư mục",
"esc": "hủy chọn và/hoặc đóng hộp thoại",
"f1": "mở trợ giúp này",
"f2": "đổi tên tập tin",
"help": "Trợ giúp"
},
"login": {
"createAnAccount": "Tạo tài khoản",
"loginInstead": "Đã có tài khoản",
"password": "Mật khẩu",
"passwordConfirm": "Xác nhận mật khẩu",
"passwordsDontMatch": "Mật khẩu không khớp",
"signup": "Đăng ký",
"submit": "Đăng nhập",
"username": "Tên người dùng",
"usernameTaken": "Tên người dùng đã tồn tại",
"wrongCredentials": "Thông tin đăng nhập không đúng"
},
"permanent": "Vĩnh viễn",
"prompts": {
"copy": "Sao chép",
"copyMessage": "Chọn vị trí để sao chép tệp của bạn:",
"currentlyNavigating": "Đang điều hướng tại:",
"deleteMessageMultiple": "Bạn có chắc chắn muốn xóa {count} tệp không?",
"deleteMessageSingle": "Bạn có chắc chắn muốn xóa tệp/thư mục này không?",
"deleteMessageShare": "Bạn có chắc chắn muốn xóa chia sẻ này ({path}) không?",
"deleteUser": "Bạn có chắc chắn muốn xóa người dùng này không?",
"deleteTitle": "Xóa tệp",
"displayName": "Tên hiển thị:",
"download": "Tải xuống tệp",
"downloadMessage": "Chọn định dạng bạn muốn tải xuống.",
"error": "Đã xảy ra lỗi",
"fileInfo": "Thông tin tệp",
"filesSelected": "{count} tệp đã được chọn.",
"lastModified": "Chỉnh sửa lần cuối",
"move": "Di chuyển",
"moveMessage": "Chọn vị trí mới cho tệp/thư mục của bạn:",
"newArchetype": "Tạo một bài viết mới dựa trên nguyên mẫu. Tệp của bạn sẽ được tạo trong thư mục nội dung.",
"newDir": "Thư mục mới",
"newDirMessage": "Đặt tên cho thư mục mới của bạn.",
"newFile": "Tệp mới",
"newFileMessage": "Đặt tên cho tệp mới của bạn.",
"numberDirs": "Số lượng thư mục",
"numberFiles": "Số lượng tệp",
"rename": "Đổi tên",
"renameMessage": "Nhập tên mới cho",
"replace": "Thay thế",
"replaceMessage": "Một trong những tệp bạn đang cố tải lên có tên trùng lặp. Bạn có muốn bỏ qua tệp này và tiếp tục tải lên hay thay thế tệp hiện có?\n",
"schedule": "Lên lịch",
"scheduleMessage": "Chọn ngày và giờ để lên lịch xuất bản bài viết này.",
"show": "Hiển thị",
"size": "Kích thước",
"upload": "Tải lên",
"uploadFiles": "Đang tải lên {files} tệp...",
"uploadMessage": "Chọn một tùy chọn để tải lên.",
"optionalPassword": "Mật khẩu tùy chọn",
"resolution": "Độ phân giải",
"discardEditorChanges": "Bạn có chắc chắn muốn hủy bỏ các thay đổi đã thực hiện không?"
},
"search": {
"images": "Hình ảnh",
"music": "Nhạc",
"pdf": "PDF",
"pressToSearch": "Nhấn Enter để tìm kiếm...",
"search": "Tìm kiếm...",
"typeToSearch": "Nhập để tìm kiếm...",
"types": "Loại",
"video": "Video"
},
"settings": {
"admin": "Quản trị viên",
"administrator": "Người quản trị",
"allowCommands": "Thực thi lệnh",
"allowEdit": "Chỉnh sửa, đổi tên và xóa tệp hoặc thư mục",
"allowNew": "Tạo tệp và thư mục mới",
"allowPublish": "Xuất bản bài viết và trang mới",
"allowSignup": "Cho phép người dùng đăng ký",
"avoidChanges": "(để trống để tránh thay đổi)",
"branding": "Thương hiệu",
"brandingDirectoryPath": "Đường dẫn thư mục thương hiệu",
"brandingHelp": "Bạn có thể tùy chỉnh giao diện và trải nghiệm của File Browser bằng cách thay đổi tên, thay thế logo, thêm kiểu tùy chỉnh và thậm chí vô hiệu hóa các liên kết bên ngoài đến GitHub.\nĐể biết thêm thông tin về tùy chỉnh thương hiệu, vui lòng xem {0}.",
"changePassword": "Đổi mật khẩu",
"commandRunner": "Trình chạy lệnh",
"commandRunnerHelp": "Tại đây, bạn có thể thiết lập các lệnh được thực thi trong các sự kiện đã định. Bạn phải viết một lệnh trên mỗi dòng. Các biến môi trường {0} và {1} sẽ có sẵn, trong đó {0} tương đối với {1}. Để biết thêm thông tin về tính năng này và các biến môi trường có sẵn, vui lòng đọc {2}.",
"commandsUpdated": "Lệnh đã được cập nhật!",
"createUserDir": "Tự động tạo thư mục chính của người dùng khi thêm người dùng mới",
"tusUploads": "Tải lên theo phân đoạn",
"tusUploadsHelp": "File Browser hỗ trợ tải lên tệp theo phân đoạn, giúp việc tải lên trở nên hiệu quả, đáng tin cậy, có thể tiếp tục và phù hợp với mạng không ổn định.",
"tusUploadsChunkSize": "Kích thước tối đa của một yêu cầu (tải lên trực tiếp sẽ được sử dụng cho các tệp nhỏ hơn). Bạn có thể nhập một số nguyên biểu thị kích thước theo byte hoặc một chuỗi như 10MB, 1GB, v.v.",
"tusUploadsRetryCount": "Số lần thử lại nếu một phân đoạn tải lên thất bại.",
"userHomeBasePath": "Đường dẫn cơ bản của thư mục chính người dùng",
"userScopeGenerationPlaceholder": "Phạm vi sẽ được tạo tự động",
"createUserHomeDirectory": "Tạo thư mục chính của người dùng",
"customStylesheet": "Bảng định dạng tùy chỉnh",
"defaultUserDescription": "Đây là cài đặt mặc định cho người dùng mới.",
"disableExternalLinks": "Vô hiệu hóa các liên kết bên ngoài (trừ tài liệu)",
"disableUsedDiskPercentage": "Vô hiệu hóa biểu đồ phần trăm dung lượng đã sử dụng",
"documentation": "tài liệu",
"examples": "Ví dụ",
"executeOnShell": "Thực thi trên shell",
"executeOnShellDescription": "Theo mặc định, File Browser thực thi lệnh bằng cách gọi trực tiếp các tệp nhị phân của chúng. Nếu bạn muốn chạy chúng trên shell (chẳng hạn như Bash hoặc PowerShell), bạn có thể định nghĩa tại đây cùng với các tham số và cờ cần thiết. Nếu được đặt, lệnh bạn thực thi sẽ được thêm làm đối số. Điều này áp dụng cho cả lệnh người dùng và hook sự kiện.",
"globalRules": "Đây là tập hợp quy tắc chung về quyền cho phép và từ chối. Chúng áp dụng cho mọi người dùng. Bạn có thể đặt quy tắc riêng cho từng người dùng để ghi đè các quy tắc chung này.",
"globalSettings": "Cài đặt chung",
"hideDotfiles": "Ẩn tệp ẩn (dotfiles)",
"insertPath": "Nhập đường dẫn",
"insertRegex": "Nhập biểu thức regex",
"instanceName": "Tên phiên bản",
"language": "Ngôn ngữ",
"lockPassword": "Ngăn người dùng thay đổi mật khẩu",
"newPassword": "Mật khẩu mới của bạn",
"newPasswordConfirm": "Xác nhận mật khẩu mới",
"newUser": "Người dùng mới",
"password": "Mật khẩu",
"passwordUpdated": "Mật khẩu đã được cập nhật!",
"path": "Đường dẫn",
"perm": {
"create": "Tạo tệp và thư mục",
"delete": "Xóa tệp và thư mục",
"download": "Tải xuống",
"execute": "Thực thi lệnh",
"modify": "Chỉnh sửa tệp",
"rename": "Đổi tên hoặc di chuyển tệp và thư mục",
"share": "Chia sẻ tệp"
},
"permissions": "Quyền",
"permissionsHelp": "Bạn có thể đặt người dùng làm quản trị viên hoặc chọn quyền riêng lẻ. Nếu chọn \"Người quản trị\", tất cả các tùy chọn khác sẽ tự động được chọn. Việc quản lý người dùng vẫn là đặc quyền của quản trị viên.\n",
"profileSettings": "Cài đặt hồ sơ",
"ruleExample1": "ngăn truy cập vào bất kỳ tệp ẩn nào (chẳng hạn như .git, .gitignore) trong mọi thư mục.\n",
"ruleExample2": "chặn truy cập vào tệp có tên Caddyfile trong thư mục gốc của phạm vi.",
"rules": "Quy tắc",
"rulesHelp": "Tại đây, bạn có thể xác định một tập hợp quy tắc cho phép hoặc từ chối cho người dùng cụ thể này. Các tệp bị chặn sẽ không hiển thị trong danh sách và người dùng không thể truy cập chúng. Chúng tôi hỗ trợ regex và đường dẫn tương đối với phạm vi của người dùng.\n",
"scope": "Phạm vi",
"setDateFormat": "Đặt định dạng ngày chính xác",
"settingsUpdated": "Cài đặt đã được cập nhật!",
"shareDuration": "Thời gian chia sẻ",
"shareManagement": "Quản lý chia sẻ",
"shareDeleted": "Chia sẻ đã bị xóa!",
"singleClick": "Dùng một lần nhấp để mở tệp và thư mục",
"themes": {
"default": "Mặc định hệ thống",
"dark": "Tối",
"light": "Sáng",
"title": "Chủ đề"
},
"user": "Người dùng",
"userCommands": "Lệnh",
"userCommandsHelp": "Danh sách lệnh được phân tách bằng khoảng trắng dành cho người dùng này. Ví dụ:\n",
"userCreated": "Người dùng đã được tạo!",
"userDefaults": "Cài đặt mặc định của người dùng",
"userDeleted": "Người dùng đã bị xóa!",
"userManagement": "Quản lý người dùng",
"userUpdated": "Người dùng đã được cập nhật!",
"username": "Tên người dùng",
"users": "Người dùng"
},
"sidebar": {
"help": "Trợ giúp",
"hugoNew": "Hugo New",
"login": "Đăng nhập",
"logout": "Đăng xuất",
"myFiles": "Tập tin của tôi",
"newFile": "Tập tin mới",
"newFolder": "Thư mục mới",
"preview": "Xem trước",
"settings": "Cài đặt",
"signup": "Đăng ký",
"siteSettings": "Cài đặt trang"
},
"success": {
"linkCopied": "Liên kết đã được sao chép!"
},
"time": {
"days": "Ngày",
"hours": "Giờ",
"minutes": "Phút",
"seconds": "Giây",
"unit": "Đơn vị"
}
}

View File

@@ -4,7 +4,7 @@ import VueNumberInput from "@chenfengyuan/vue-number-input";
import VueLazyload from "vue-lazyload";
import { createVfm } from "vue-final-modal";
import Toast, { POSITION, useToast } from "vue-toastification";
import {
import type {
ToastOptions,
PluginOptions,
} from "vue-toastification/dist/types/types";

View File

@@ -1,4 +1,5 @@
import { RouteLocation, createRouter, createWebHistory } from "vue-router";
import type { RouteLocation } from "vue-router";
import { createRouter, createWebHistory } from "vue-router";
import Login from "@/views/Login.vue";
import Layout from "@/views/Layout.vue";
import Files from "@/views/Files.vue";

View File

@@ -1,6 +1,6 @@
import { createPinia as _createPinia } from "pinia";
import { markRaw } from "vue";
import { Router } from "vue-router";
import type { Router } from "vue-router";
export default function createPinia(router: Router) {
const pinia = _createPinia();

View File

@@ -29,6 +29,12 @@ export const useLayoutStore = defineStore("layout", {
toggleShell() {
this.showShell = !this.showShell;
},
setCloseOnPrompt(closeFunction: () => Promise<string>, onPrompt: string) {
const prompt = this.prompts.find((prompt) => prompt.prompt === onPrompt);
if (prompt) {
prompt.close = closeFunction;
}
},
showHover(value: PopupProps | string) {
if (typeof value !== "object") {
this.prompts.push({
@@ -36,6 +42,7 @@ export const useLayoutStore = defineStore("layout", {
confirm: null,
action: undefined,
props: null,
close: null,
});
return;
}
@@ -45,6 +52,7 @@ export const useLayoutStore = defineStore("layout", {
confirm: value?.confirm,
action: value?.action,
props: value?.props,
close: value?.close,
});
},
showError() {
@@ -53,6 +61,7 @@ export const useLayoutStore = defineStore("layout", {
confirm: null,
action: undefined,
props: null,
close: null,
});
},
showSuccess() {
@@ -61,10 +70,11 @@ export const useLayoutStore = defineStore("layout", {
confirm: null,
action: undefined,
props: null,
close: null,
});
},
closeHovers() {
this.prompts.pop();
this.prompts.shift()?.close?.();
},
// easily reset state using `$reset`
clearLayout() {

View File

@@ -1,7 +1,7 @@
import { defineStore } from "pinia";
import { useFileStore } from "./file";
import { files as api } from "@/api";
import throttle from "lodash/throttle";
import { throttle } from "lodash-es";
import buttons from "@/utils/buttons";
// TODO: make this into a user setting
@@ -170,12 +170,12 @@ export const useUploadStore = defineStore("upload", {
async processUploads() {
const uploadsCount = Object.keys(this.uploads).length;
const isBellowLimit = uploadsCount < UPLOADS_LIMIT;
const isBelowLimit = uploadsCount < UPLOADS_LIMIT;
const isQueueEmpty = this.queue.length == 0;
const isUploadsEmpty = uploadsCount == 0;
const isFinished = isQueueEmpty && isUploadsEmpty;
const canProcess = isBellowLimit && !isQueueEmpty;
const canProcess = isBelowLimit && !isQueueEmpty;
if (isFinished) {
const fileStore = useFileStore();

View File

@@ -3,6 +3,7 @@ interface PopupProps {
confirm?: any;
action?: PopupAction;
props?: any;
close?: (() => Promise<string>) | null;
}
type PopupAction = (e: Event) => void;

View File

@@ -1,6 +1,7 @@
import { useAuthStore } from "@/stores/auth";
import router from "@/router";
import { JwtPayload, jwtDecode } from "jwt-decode";
import type { JwtPayload } from "jwt-decode";
import { jwtDecode } from "jwt-decode";
import { baseURL, noAuth } from "./constants";
import { StatusError } from "@/api/utils";
@@ -23,7 +24,7 @@ export async function validateLogin() {
await renew(<string>localStorage.getItem("jwt"));
}
} catch (error) {
console.warn("Invalid JWT token in storage"); // eslint-disable-line
console.warn("Invalid JWT token in storage");
throw error;
}
}

View File

@@ -4,7 +4,7 @@ function loading(button: string) {
);
if (el === undefined || el === null) {
console.log("Error getting button " + button); // eslint-disable-line
console.log("Error getting button " + button);
return;
}
@@ -30,7 +30,7 @@ function done(button: string) {
);
if (el === undefined || el === null) {
console.log("Error getting button " + button); // eslint-disable-line
console.log("Error getting button " + button);
return;
}
@@ -51,7 +51,7 @@ function success(button: string) {
);
if (el === undefined || el === null) {
console.log("Error getting button " + button); // eslint-disable-line
console.log("Error getting button " + button);
return;
}

View File

@@ -1,39 +1,36 @@
// Based on code by the following links:
// https://stackoverflow.com/a/74528564
// https://web.dev/articles/async-clipboard
export function copy(text: string) {
interface ClipboardArgs {
text?: string;
data?: ClipboardItems;
}
interface ClipboardOpts {
permission?: boolean;
}
export function copy(data: ClipboardArgs, opts?: ClipboardOpts) {
return new Promise<void>((resolve, reject) => {
if (
// Clipboard API requires secure context
window.isSecureContext &&
typeof navigator.clipboard !== "undefined" &&
// @ts-ignore
navigator.permissions !== "undefined"
typeof navigator.clipboard !== "undefined"
) {
navigator.permissions
// @ts-ignore
.query({ name: "clipboard-write" })
.then((permission) => {
if (permission.state === "granted" || permission.state === "prompt") {
// simple writeText should work for all modern browsers
navigator.clipboard.writeText(text).then(resolve).catch(reject);
} else {
reject(new Error("Permission not granted!"));
}
})
.catch((e) => {
// Firefox doesn't support clipboard-write permission
if (navigator.userAgent.indexOf("Firefox") != -1) {
navigator.clipboard.writeText(text).then(resolve).catch(reject);
} else {
reject(e);
}
});
if (opts?.permission) {
getPermission("clipboard-write")
.then(() => writeToClipboard(data).then(resolve).catch(reject))
.catch(reject);
} else {
writeToClipboard(data).then(resolve).catch(reject);
}
} else if (
document.queryCommandSupported &&
document.queryCommandSupported("copy")
document.queryCommandSupported("copy") &&
data.text // old method only supports text
) {
const textarea = createTemporaryTextarea(text);
const textarea = createTemporaryTextarea(data.text);
const body = document.activeElement || document.body;
try {
body.appendChild(textarea);
@@ -54,6 +51,35 @@ export function copy(text: string) {
});
}
function getPermission(name: string) {
return new Promise<void>((resolve, reject) => {
typeof navigator.permissions !== "undefined" &&
navigator.permissions
// @ts-expect-error chrome specific api
.query({ name })
.then((permission) => {
if (permission.state === "granted" || permission.state === "prompt") {
resolve();
} else {
reject(new Error("Permission denied!"));
}
});
});
}
function writeToClipboard(data: ClipboardArgs) {
if (data.text) {
return navigator.clipboard.writeText(data.text);
}
if (data.data) {
return navigator.clipboard.write(data.data);
}
return new Promise<void>((resolve, reject) => {
reject(new Error("No data was supplied!"));
});
}
const styles = {
fontSize: "12pt",
position: "fixed",
@@ -69,10 +95,10 @@ const styles = {
background: "transparent",
};
const createTemporaryTextarea = (text: string) => {
function createTemporaryTextarea(text: string) {
const textarea = document.createElement("textarea");
textarea.value = text;
textarea.setAttribute("readonly", "");
Object.assign(textarea.style, styles);
return textarea;
};
}

View File

@@ -6,13 +6,16 @@ export default function getRule(rules: string[]) {
let result = null;
const find = Array.prototype.find;
find.call(document.styleSheets, (styleSheet) => {
result = find.call(styleSheet.cssRules, (cssRule) => {
find.call(document.styleSheets, (styleSheet: CSSStyleSheet) => {
result = find.call(styleSheet.cssRules, (cssRule: CSSRule) => {
let found = false;
if (cssRule instanceof window.CSSStyleRule) {
// faster than checking instanceof for every element
if (cssRule.constructor.name === "CSSStyleRule") {
for (let i = 0; i < rules.length; i++) {
if (cssRule.selectorText.toLowerCase() === rules[i]) {
if (
(cssRule as CSSStyleRule).selectorText.toLowerCase() === rules[i]
) {
found = true;
}
}
@@ -24,5 +27,5 @@ export default function getRule(rules: string[]) {
return result != null;
});
return result;
return result as CSSStyleRule | null;
}

View File

@@ -1,3 +1,4 @@
import { useLayoutStore } from "@/stores/layout";
import { useUploadStore } from "@/stores/upload";
import url from "@/utils/url";
@@ -126,6 +127,9 @@ export function handleFiles(
overwrite = false
) {
const uploadStore = useUploadStore();
const layoutStore = useLayoutStore();
layoutStore.closeHovers();
for (const file of files) {
const id = uploadStore.id;

View File

@@ -325,6 +325,7 @@ const token = ref<string>("");
const audio = ref<HTMLAudioElement>();
const tag = ref<boolean>(false);
const $showError = inject<IToastError>("$showError")!;
const $showSuccess = inject<IToastSuccess>("$showSuccess")!;
const { t } = useI18n({});
@@ -463,9 +464,9 @@ const download = () => {
if (req.value === null) return false;
layoutStore.closeHovers();
let files: string[] = [];
const files: string[] = [];
for (let i of fileStore.selected) {
for (const i of fileStore.selected) {
files.push(req.value.items[i].path);
}
@@ -488,13 +489,23 @@ const linkSelected = () => {
};
const copyToClipboard = (text: string) => {
copy(text).then(
copy({ text }).then(
() => {
// clipboard successfully set
$showSuccess(t("success.linkCopied"));
},
() => {
// clipboard write failed
copy({ text }, { permission: true }).then(
() => {
// clipboard successfully set
$showSuccess(t("success.linkCopied"));
},
(e) => {
// clipboard write failed
$showError(e);
}
);
}
);
};

View File

@@ -108,7 +108,7 @@ onMounted(() => {
showPrintMargin: false,
readOnly: fileStore.req?.type === "textImmutable",
theme: "ace/theme/chrome",
mode: modelist.getModeForPath(fileStore.req?.name).mode,
mode: modelist.getModeForPath(fileStore.req!.name).mode,
wrap: true,
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
@@ -173,7 +173,7 @@ const close = () => {
fileStore.updateRequest(null);
let uri = url.removeLastDir(route.path) + "/";
const uri = url.removeLastDir(route.path) + "/";
router.push({ path: uri });
};

View File

@@ -285,7 +285,7 @@ import { users, files as api } from "@/api";
import { enableExec } from "@/utils/constants";
import * as upload from "@/utils/upload";
import css from "@/utils/css";
import throttle from "lodash/throttle";
import { throttle } from "lodash-es";
import { Base64 } from "js-base64";
import HeaderBar from "@/components/header/HeaderBar.vue";
@@ -523,12 +523,12 @@ const keyEvent = (event: KeyboardEvent) => {
break;
case "a":
event.preventDefault();
for (let file of items.value.files) {
for (const file of items.value.files) {
if (fileStore.selected.indexOf(file.index) === -1) {
fileStore.selected.push(file.index);
}
}
for (let dir of items.value.dirs) {
for (const dir of items.value.dirs) {
if (fileStore.selected.indexOf(dir.index) === -1) {
fileStore.selected.push(dir.index);
}
@@ -551,9 +551,9 @@ const copyCut = (event: Event | KeyboardEvent): void => {
if (fileStore.req === null) return;
let items = [];
const items = [];
for (let i of fileStore.selected) {
for (const i of fileStore.selected) {
items.push({
from: fileStore.req.items[i].url,
name: fileStore.req.items[i].name,
@@ -575,9 +575,9 @@ const paste = (event: Event) => {
if ((event.target as HTMLElement).tagName?.toLowerCase() === "input") return;
// TODO router location should it be
let items: any[] = [];
const items: any[] = [];
for (let item of clipboardStore.items) {
for (const item of clipboardStore.items) {
const from = item.from.endsWith("/") ? item.from.slice(0, -1) : item.from;
const to = route.path + encodeURIComponent(item.name);
items.push({ from, to, name: item.name });
@@ -614,7 +614,7 @@ const paste = (event: Event) => {
return;
}
let conflict = upload.checkConflict(items, fileStore.req!.items);
const conflict = upload.checkConflict(items, fileStore.req!.items);
let overwrite = false;
let rename = false;
@@ -640,14 +640,13 @@ const paste = (event: Event) => {
const colunmsResize = () => {
// Update the columns size based on the window width.
let items_ = css(["#listing.mosaic .item", ".mosaic#listing .item"]);
const items_ = css(["#listing.mosaic .item", ".mosaic#listing .item"]);
if (items_ === null) return;
let columns = Math.floor(
(document.querySelector("main")?.offsetWidth ?? 0) / columnWidth.value
);
if (columns === 0) columns = 1;
// @ts-ignore never type error
items_.style.width = `calc(${100 / columns}% - 1em)`;
};
@@ -677,11 +676,10 @@ const dragEnter = () => {
// When the user starts dragging an item, put every
// file on the listing with 50% opacity.
let items = document.getElementsByClassName("item");
const items = document.getElementsByClassName("item");
// @ts-ignore
Array.from(items).forEach((file: HTMLElement) => {
file.style.opacity = "0.5";
Array.from(items).forEach((file: Element) => {
(file as HTMLElement).style.opacity = "0.5";
});
};
@@ -698,7 +696,7 @@ const drop = async (event: DragEvent) => {
dragCounter.value = 0;
resetOpacity();
let dt = event.dataTransfer;
const dt = event.dataTransfer;
let el: HTMLElement | null = event.target as HTMLElement;
if (fileStore.req === null || dt === null || dt.files.length <= 0) return;
@@ -709,7 +707,7 @@ const drop = async (event: DragEvent) => {
}
}
let files: UploadList = (await upload.scanFiles(dt)) as UploadList;
const files: UploadList = (await upload.scanFiles(dt)) as UploadList;
let items = fileStore.req.items;
let path = route.path.endsWith("/") ? route.path : route.path + "/";
@@ -729,7 +727,7 @@ const drop = async (event: DragEvent) => {
}
}
let conflict = upload.checkConflict(files, items);
const conflict = upload.checkConflict(files, items);
if (conflict) {
layoutStore.showHover({
@@ -753,12 +751,10 @@ const drop = async (event: DragEvent) => {
};
const uploadInput = (event: Event) => {
layoutStore.closeHovers();
let files = (event.currentTarget as HTMLInputElement)?.files;
const files = (event.currentTarget as HTMLInputElement)?.files;
if (files === null) return;
let folder_upload = !!files[0].webkitRelativePath;
const folder_upload = !!files[0].webkitRelativePath;
const uploadFiles: UploadList = [];
for (let i = 0; i < files.length; i++) {
@@ -773,8 +769,8 @@ const uploadInput = (event: Event) => {
});
}
let path = route.path.endsWith("/") ? route.path : route.path + "/";
let conflict = upload.checkConflict(uploadFiles, fileStore.req!.items);
const path = route.path.endsWith("/") ? route.path : route.path + "/";
const conflict = upload.checkConflict(uploadFiles, fileStore.req!.items);
if (conflict) {
layoutStore.showHover({
@@ -798,7 +794,7 @@ const uploadInput = (event: Event) => {
};
const resetOpacity = () => {
let items = document.getElementsByClassName("item");
const items = document.getElementsByClassName("item");
Array.from(items).forEach((file: Element) => {
(file as HTMLElement).style.opacity = "1";
@@ -824,7 +820,6 @@ const sort = async (by: string) => {
try {
if (authStore.user?.id) {
// @ts-ignore
await users.update({ id: authStore.user?.id, sorting: { by, asc } }, [
"sorting",
]);
@@ -875,10 +870,10 @@ const download = () => {
confirm: (format: any) => {
layoutStore.closeHovers();
let files = [];
const files = [];
if (fileStore.selectedCount > 0 && fileStore.req !== null) {
for (let i of fileStore.selected) {
for (const i of fileStore.selected) {
files.push(fileStore.req.items[i].url);
}
} else {
@@ -901,13 +896,12 @@ const switchView = async () => {
const data = {
id: authStore.user?.id,
viewMode: modes[authStore.user?.viewMode ?? "list"] || "list",
viewMode: (modes[authStore.user?.viewMode ?? "list"] ||
"list") as ViewModeType,
};
// @ts-ignore
users.update(data, ["viewMode"]).catch($showError);
// @ts-ignore
authStore.updateUser(data);
setItemWeight();

View File

@@ -168,7 +168,7 @@ import { files as api } from "@/api";
import { createURL } from "@/api/utils";
import { resizePreview } from "@/utils/constants";
import url from "@/utils/url";
import throttle from "lodash/throttle";
import { throttle } from "lodash-es";
import HeaderBar from "@/components/header/HeaderBar.vue";
import Action from "@/components/header/Action.vue";
import ExtendedImage from "@/components/files/ExtendedImage.vue";
@@ -353,7 +353,7 @@ const updatePreview = async () => {
autoPlay.value = false;
}
let dirs = route.fullPath.split("/");
const dirs = route.fullPath.split("/");
name.value = decodeURIComponent(dirs[dirs.length - 1]);
if (!listing.value) {
@@ -422,7 +422,7 @@ const toggleNavigation = throttle(function () {
const close = () => {
fileStore.updateRequest(null);
let uri = url.removeLastDir(route.path) + "/";
const uri = url.removeLastDir(route.path) + "/";
router.push({ path: uri });
};

View File

@@ -282,11 +282,11 @@ const formattedChunkSize = computed({
// Define funcs
const capitalize = (name: string, where: string | RegExp = "_") => {
if (where === "caps") where = /(?=[A-Z])/;
let splitted = name.split(where);
const split = name.split(where);
name = "";
for (let i = 0; i < splitted.length; i++) {
name += splitted[i].charAt(0).toUpperCase() + splitted[i].slice(1) + " ";
for (let i = 0; i < split.length; i++) {
name += split[i].charAt(0).toUpperCase() + split[i].slice(1) + " ";
}
return name.slice(0, -1);
@@ -294,7 +294,7 @@ const capitalize = (name: string, where: string | RegExp = "_") => {
const save = async () => {
if (settings.value === null) return false;
let newSettings: ISettings = {
const newSettings: ISettings = {
...settings.value,
shell:
settings.value?.shell
@@ -376,7 +376,7 @@ onMounted(async () => {
try {
layoutStore.loading = true;
const original: ISettings = await api.get();
let newSettings: ISettings = { ...original, commands: {} };
const newSettings: ISettings = { ...original, commands: {} };
const keys = Object.keys(original.commands) as Array<keyof SettingsCommand>;
for (const key of keys) {

View File

@@ -87,12 +87,12 @@ onMounted(async () => {
layoutStore.loading = true;
try {
let newLinks = await api.list();
const newLinks = await api.list();
if (authStore.user?.perm.admin) {
let userMap = new Map<number, string>();
for (let user of await users.getAll())
const userMap = new Map<number, string>();
for (const user of await users.getAll())
userMap.set(user.id, user.username);
for (let link of newLinks) {
for (const link of newLinks) {
if (link.userID && userMap.has(link.userID))
link.username = userMap.get(link.userID);
}
@@ -108,13 +108,23 @@ onMounted(async () => {
});
const copyToClipboard = (text: string) => {
copy(text).then(
copy({ text }).then(
() => {
// clipboard successfully set
$showSuccess(t("success.linkCopied"));
},
() => {
// clipboard write failed
copy({ text }, { permission: true }).then(
() => {
// clipboard successfully set
$showSuccess(t("success.linkCopied"));
},
(e) => {
// clipboard write failed
$showError(e);
}
);
}
);
};

View File

@@ -90,7 +90,7 @@ const fetchData = async () => {
try {
if (isNew.value) {
let { defaults, createUserDir: _createUserDir } = await settings.get();
const { defaults, createUserDir: _createUserDir } = await settings.get();
createUserDir.value = _createUserDir;
user.value = {
...defaults,

View File

@@ -0,0 +1,13 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"types": ["vite/client", "@intlify/unplugin-vue-i18n/messages"],
"paths": {
"@/*": ["./src/*"]
}
}
}

View File

@@ -1,24 +1,11 @@
{
"compilerOptions": {
"baseUrl": ".",
"allowJs": true,
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"moduleResolution": "Node10",
"strict": true,
"sourceMap": true,
"noImplicitReturns": true,
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"lib": ["ESNext", "DOM"],
"skipLibCheck": true,
"types": ["vite/client", "@intlify/unplugin-vue-i18n/messages"],
"paths": {
"@/*": ["./src/*"]
"files": [],
"references": [
{
"path": "./tsconfig.node.json"
},
{
"path": "./tsconfig.app.json"
}
},
"include": ["src/**/*.ts", "src/**/*.vue"],
"exclude": ["node_modules", "dist"]
]
}

View File

@@ -0,0 +1,18 @@
{
"extends": "@tsconfig/node22/tsconfig.json",
"include": [
"vite.config.*",
"vitest.config.*",
"cypress.config.*",
"nightwatch.conf.*",
"playwright.config.*"
],
"compilerOptions": {
"composite": true,
"noEmit": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["node"]
}
}

View File

@@ -0,0 +1,14 @@
{
"extends": "./tsconfig.app.json",
// vue-tsc wont shut up about error TS9005
// in non-TS vue files so exclude them
"exclude": [
"src/components/Shell.vue",
"src/components/prompts/Copy.vue",
"src/components/prompts/Delete.vue",
"src/components/prompts/FileList.vue",
"src/components/prompts/Rename.vue",
"src/components/prompts/Share.vue",
"src/components/prompts/UploadFiles.vue"
]
}

61
go.mod
View File

@@ -1,72 +1,67 @@
module github.com/filebrowser/filebrowser/v2
go 1.23
go 1.23.0
require (
github.com/asdine/storm/v3 v3.2.1
github.com/asticode/go-astisub v0.26.2
github.com/asticode/go-astisub v0.34.0
github.com/disintegration/imaging v1.6.2
github.com/dsoprea/go-exif/v3 v3.0.1
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/golang-jwt/jwt/v4 v4.5.2
github.com/gorilla/mux v1.8.1
github.com/gorilla/websocket v1.5.3
github.com/maruel/natural v1.1.1
github.com/marusama/semaphore/v2 v2.5.0
github.com/mholt/archiver/v3 v3.5.1
github.com/mitchellh/go-homedir v1.1.0
github.com/pelletier/go-toml/v2 v2.2.3
github.com/pelletier/go-toml/v2 v2.2.4
github.com/shirou/gopsutil/v3 v3.24.5
github.com/spf13/afero v1.11.0
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0
github.com/spf13/afero v1.14.0
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
github.com/spf13/viper v1.20.1
github.com/stretchr/testify v1.10.0
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
go.etcd.io/bbolt v1.3.11
golang.org/x/crypto v0.26.0
golang.org/x/image v0.19.0
golang.org/x/text v0.17.0
go.etcd.io/bbolt v1.4.1
golang.org/x/crypto v0.39.0
golang.org/x/image v0.28.0
golang.org/x/text v0.26.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v2 v2.4.0
)
require (
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/asticode/go-astikit v0.42.0 // indirect
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/asticode/go-astikit v0.55.0 // indirect
github.com/asticode/go-astits v1.13.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // 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/fsnotify/fsnotify v1.7.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/golang/geo v0.0.0-20230421003525-6adc56603217 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/golang/geo v0.0.0-20250606134707-e8fe6a72b492 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.17.7 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/nwaples/rardecode v1.1.3 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/sagikazarmark/locafero v0.9.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/cast v1.9.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/ulikunitz/xz v0.5.11 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sys v0.23.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/sys v0.33.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

138
go.sum
View File

@@ -3,20 +3,20 @@ github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t
github.com/Sereal/Sereal v0.0.0-20190618215532-0b8ac451a863 h1:BRrxwOZBolJN4gIwvZMJY1tzqBvQgpaZiQRuIDD40jM=
github.com/Sereal/Sereal v0.0.0-20190618215532-0b8ac451a863/go.mod h1:D0JMgToj/WdxCgd30Kc1UcA9E+WdZoJqeVOuYW7iTBM=
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
github.com/asdine/storm/v3 v3.2.1 h1:I5AqhkPK6nBZ/qJXySdI7ot5BlXSZ7qvDY1zAn5ZJac=
github.com/asdine/storm/v3 v3.2.1/go.mod h1:LEpXwGt4pIqrE/XcTvCnZHT5MgZCV6Ub9q7yQzOFWr0=
github.com/asticode/go-astikit v0.20.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xblP7fCWbgwipF0=
github.com/asticode/go-astikit v0.30.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xblP7fCWbgwipF0=
github.com/asticode/go-astikit v0.42.0 h1:pnir/2KLUSr0527Tv908iAH6EGYYrYta132vvjXsH5w=
github.com/asticode/go-astikit v0.42.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xblP7fCWbgwipF0=
github.com/asticode/go-astisub v0.26.2 h1:cdEXcm+SUSmYCEPTQYbbfCECnmQoIFfH6pF8wDJhfVo=
github.com/asticode/go-astisub v0.26.2/go.mod h1:WTkuSzFB+Bp7wezuSf2Oxulj5A8zu2zLRVFf6bIFQK8=
github.com/asticode/go-astikit v0.55.0 h1:jdR6djfjAF2SwtFu1hzwkenCRejzOZUREsr3xPAPHeg=
github.com/asticode/go-astikit v0.55.0/go.mod h1:fV43j20UZYfXzP9oBn33udkvCvDvCDhzjVqoLFuuYZE=
github.com/asticode/go-astisub v0.34.0 h1:owKNj0A9pc7YVW/rNy2MJZ1mf0L8DTdklZVfyZDhTWI=
github.com/asticode/go-astisub v0.34.0/go.mod h1:WTkuSzFB+Bp7wezuSf2Oxulj5A8zu2zLRVFf6bIFQK8=
github.com/asticode/go-astits v1.8.0/go.mod h1:DkOWmBNQpnr9mv24KfZjq4JawCFX1FCqjLVGvO0DygQ=
github.com/asticode/go-astits v1.13.0 h1:XOgkaadfZODnyZRR5Y0/DWkA9vrkLLPLeeOvDwfKZ1c=
github.com/asticode/go-astits v1.13.0/go.mod h1:QSHmknZ51pf6KJdHKZHJTLlMegIrhega3LPWz3ND/iI=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@@ -47,48 +47,48 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjr
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
github.com/golang/geo v0.0.0-20230421003525-6adc56603217 h1:HKlyj6in2JV6wVkmQ4XmG/EIm+SCYlPZ+V4GWit7Z+I=
github.com/golang/geo v0.0.0-20230421003525-6adc56603217/go.mod h1:8wI0hitZ3a1IxZfeH3/5I97CI8i5cLGsYe7xNhQGs9U=
github.com/golang/geo v0.0.0-20250606134707-e8fe6a72b492 h1:8mHyM6CCmj/DQAhHXJVTgdkg/6hAH71N7qGEF+t4Bzg=
github.com/golang/geo v0.0.0-20250606134707-e8fe6a72b492/go.mod h1:Vaw7L5b+xa3Rj4/pRtrQkymn3lSBRB/NAEdbF9YEVLA=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
@@ -101,8 +101,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
github.com/marusama/semaphore/v2 v2.5.0 h1:o/1QJD9DBYOWRnDhPwDVAXQn6mQYD0gZaS1Tpx6DJGM=
@@ -111,76 +109,72 @@ github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Cl
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
github.com/nwaples/rardecode v1.1.3 h1:cWCaZwfM5H7nAD6PyEdcVnczzV8i/JtotnyW/dD9lEc=
github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/profile v1.4.0/go.mod h1:NWz/XGvpEW1FyYQ7fCx4dqYBLlfTcE+A9FLAkNKqjFE=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sagikazarmark/locafero v0.9.0 h1:GbgQGNtTrEmddYDSAH9QLRyfAHY12md+8YFTqyMTC9k=
github.com/sagikazarmark/locafero v0.9.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk=
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA=
github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo=
github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE=
github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc=
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
go.etcd.io/bbolt v1.4.1 h1:5mOV+HWjIPLEAlUGMsveaUvK2+byZMFOzojoi7bh7uI=
go.etcd.io/bbolt v1.4.1/go.mod h1:c8zu2BnXWTu2XM4XcICtbGSl9cFwsXtcf9zLt2OncM8=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw=
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ=
golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys=
golang.org/x/image v0.28.0 h1:gdem5JW1OLS4FbkWgLO+7ZeFzYtL3xClb97GaUzYMFE=
golang.org/x/image v0.28.0/go.mod h1:GUJYXtnGKEUgggyzh+Vxt+AviiCcyiwpsl8iQ8MvwGY=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20191105084925-a882066a44e0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -190,10 +184,10 @@ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -204,27 +198,23 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -47,7 +47,7 @@ func errToStatus(err error) int {
}
}
// This is an addaptation if http.StripPrefix in which we don't
// This is an adaptation if http.StripPrefix in which we don't
// return 404 if the page doesn't have the needed prefix.
func stripPrefix(prefix string, h http.Handler) http.Handler {
if prefix == "" || prefix == "/" {

View File

@@ -12,7 +12,7 @@ import (
func ParseCommand(s *settings.Settings, raw string) ([]string, error) {
var command []string
if len(s.Shell) == 0 {
if len(s.Shell) == 0 || s.Shell[0] == "" {
cmd, args, err := SplitCommandAndArgs(raw)
if err != nil {
return nil, err

View File

@@ -535,9 +535,9 @@ create-require@^1.1.0:
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
version "7.0.6"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"

16
transifex.yml Normal file
View File

@@ -0,0 +1,16 @@
filters:
- filter_type: file
file_format: KEYVALUEJSON
source_language: en
source_file: frontend/src/i18n/en.json
translation_files_expression: 'frontend/src/i18n/<lang>.json'
settings:
language_mapping:
sv_SE: sv-se
cz-CS: cz_cs
pt_BR: pt-br
zh_CN: zh-cn
zh_HK: zh-hk
zh_TW: zh-tw
nl_BE: nl-be

View File

@@ -1,9 +1,15 @@
package users
import (
"crypto/rand"
"encoding/base64"
"golang.org/x/crypto/bcrypt"
)
// randomPasswordBytesCount is chosen to fit in a base64 string without padding
const randomPasswordBytesCount = 9
// HashPwd hashes a password.
func HashPwd(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
@@ -15,3 +21,15 @@ func CheckPwd(password, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}
func RandomPwd() (string, error) {
randomPasswordBytes := make([]byte, randomPasswordBytesCount)
var _, err = rand.Read(randomPasswordBytes)
if err != nil {
return "", err
}
// This is done purely to make the password human-readable
var randomPasswordString = base64.URLEncoding.EncodeToString(randomPasswordBytes)
return randomPasswordString, nil
}

View File

@@ -3,6 +3,6 @@ package version
var (
// Version is the current File Browser version.
Version = "(untracked)"
// CommitSHA is the commmit sha.
// CommitSHA is the commit sha.
CommitSHA = "(unknown)"
)