Compare commits
1 Commits
v2.45.3
...
chore/upda
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03f2bcd9a0 |
6
.github/CODEOWNERS
vendored
@@ -1 +1,5 @@
|
||||
* @filebrowser/maintainers
|
||||
# These owners will be the default owners for everything in the repo.
|
||||
# Unless a later match takes precedence, @o1egl will be requested for
|
||||
# review when someone opens a pull request.
|
||||
|
||||
* @o1egl @hacdias
|
||||
|
||||
115
.github/workflows/ci.yaml
vendored
@@ -1,115 +0,0 @@
|
||||
name: Continuous Integration
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
tags:
|
||||
- "v*"
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
lint-frontend:
|
||||
name: Lint Frontend
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
package_json_file: "frontend/package.json"
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "24.x"
|
||||
cache: "pnpm"
|
||||
cache-dependency-path: "frontend/pnpm-lock.yaml"
|
||||
- working-directory: frontend
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm run lint
|
||||
|
||||
lint-backend:
|
||||
name: Lint Backend
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "1.25.x"
|
||||
- uses: golangci/golangci-lint-action@v9
|
||||
with:
|
||||
version: "latest"
|
||||
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "1.25.x"
|
||||
- run: go test --race ./...
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.25'
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
package_json_file: "frontend/package.json"
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "24.x"
|
||||
cache: "pnpm"
|
||||
cache-dependency-path: "frontend/pnpm-lock.yaml"
|
||||
- name: Install Task
|
||||
uses: go-task/setup-task@v1
|
||||
- run: task build
|
||||
|
||||
release:
|
||||
name: Release
|
||||
needs: ["lint-frontend", "lint-backend", "test", "build"]
|
||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.25'
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
package_json_file: "frontend/package.json"
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "24.x"
|
||||
cache: "pnpm"
|
||||
cache-dependency-path: "frontend/pnpm-lock.yaml"
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Install Task
|
||||
uses: go-task/setup-task@v1
|
||||
- run: task build-frontend
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
version: latest
|
||||
args: release --clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
|
||||
|
||||
|
||||
|
||||
52
.github/workflows/docs.yml
vendored
@@ -1,52 +0,0 @@
|
||||
name: Docs
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'www'
|
||||
- '*.md'
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build Docs
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Install Task
|
||||
uses: go-task/setup-task@v1
|
||||
- name: Build site
|
||||
run: task docs
|
||||
|
||||
build-and-release:
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||
name: Build and Release Docs
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Install Task
|
||||
uses: go-task/setup-task@v1
|
||||
- name: Build site
|
||||
run: task docs
|
||||
- name: Deploy to Cloudflare Pages
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: pages deploy www/public --project-name=${{ secrets.CLOUDFLARE_PROJECT_NAME }}
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
105
.github/workflows/main.yaml
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
name: main
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
tags:
|
||||
- "v*"
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
# 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: "22.x"
|
||||
cache: "pnpm"
|
||||
cache-dependency-path: "frontend/pnpm-lock.yaml"
|
||||
- run: make lint-frontend
|
||||
lint-backend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.24'
|
||||
- run: make lint-backend
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [lint-frontend, lint-backend]
|
||||
steps:
|
||||
- run: echo "done"
|
||||
|
||||
# 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: "22.x"
|
||||
cache: "pnpm"
|
||||
cache-dependency-path: "frontend/pnpm-lock.yaml"
|
||||
- run: make test-frontend
|
||||
test-backend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.24'
|
||||
- run: make test-backend
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test-frontend, test-backend]
|
||||
steps:
|
||||
- run: echo "done"
|
||||
|
||||
# release
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [lint, test]
|
||||
if: startsWith(github.event.ref, 'refs/tags/v')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23'
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
package_json_file: "frontend/package.json"
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
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
|
||||
uses: docker/setup-buildx-action@v1
|
||||
- name: Build frontend
|
||||
run: make build-frontend
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
with:
|
||||
version: latest
|
||||
args: release --clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
|
||||
@@ -13,10 +13,10 @@ permissions:
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Validate Title
|
||||
name: Validate PR title
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: amannn/action-semantic-pull-request@v6
|
||||
- uses: amannn/action-semantic-pull-request@v5
|
||||
id: lint_pr_title
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -43,4 +43,4 @@ jobs:
|
||||
uses: marocchino/sticky-pull-request-comment@v2
|
||||
with:
|
||||
header: pr-title-lint-error
|
||||
delete: true
|
||||
delete: true
|
||||
20
.github/workflows/site-pr.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: Build Site
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'www'
|
||||
- '*.md'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Build site
|
||||
run: make site
|
||||
32
.github/workflows/site-publish.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: Build and Deploy Site
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Build site
|
||||
run: make site
|
||||
|
||||
- name: Deploy to Cloudflare Pages
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: pages deploy www/public --project-name=${{ secrets.CLOUDFLARE_PROJECT_NAME }}
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
5
.gitignore
vendored
@@ -35,5 +35,10 @@ build/
|
||||
/frontend/dist/*
|
||||
!/frontend/dist/.gitkeep
|
||||
|
||||
# Playwright files
|
||||
/frontend/test-results/
|
||||
/frontend/playwright-report/
|
||||
/frontend/playwright/.cache/
|
||||
|
||||
default.nix
|
||||
Dockerfile.dev
|
||||
|
||||
171
.goreleaser.yml
@@ -40,144 +40,47 @@ archives:
|
||||
- goos: windows
|
||||
formats: ["zip"]
|
||||
|
||||
dockers:
|
||||
# Alpine docker images
|
||||
- dockerfile: Dockerfile
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--pull"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.name={{.ProjectName}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Version}}"
|
||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
||||
- "--platform=linux/amd64"
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-amd64"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-amd64"
|
||||
dockers_v2:
|
||||
- id: filebrowser
|
||||
images:
|
||||
- "filebrowser/filebrowser"
|
||||
dockerfile: Dockerfile
|
||||
tags:
|
||||
- "latest"
|
||||
- "{{ .Tag }}"
|
||||
- "v{{ .Major }}"
|
||||
labels:
|
||||
org.opencontainers.image.created: "{{.Date}}"
|
||||
org.opencontainers.image.name: "{{.ProjectName}}"
|
||||
org.opencontainers.image.revision: "{{.FullCommit}}"
|
||||
org.opencontainers.image.version: "{{.Version}}"
|
||||
org.opencontainers.image.source: "{{.GitURL}}"
|
||||
extra_files:
|
||||
- docker
|
||||
- dockerfile: Dockerfile
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--pull"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.name={{.ProjectName}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Version}}"
|
||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
||||
- "--platform=linux/arm64"
|
||||
goos: linux
|
||||
goarch: arm64
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-arm64"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-arm64"
|
||||
platforms:
|
||||
- linux/amd64
|
||||
- linux/arm64
|
||||
- linux/arm/v6
|
||||
- linux/arm/v7
|
||||
- id: filebrowser-s6
|
||||
images:
|
||||
- "filebrowser/filebrowser"
|
||||
dockerfile: Dockerfile.s6
|
||||
tags:
|
||||
- "s6"
|
||||
- "{{ .Tag }}-s6"
|
||||
- "v{{ .Major }}-s6"
|
||||
labels:
|
||||
org.opencontainers.image.created: "{{.Date}}"
|
||||
org.opencontainers.image.name: "{{.ProjectName}}"
|
||||
org.opencontainers.image.revision: "{{.FullCommit}}"
|
||||
org.opencontainers.image.version: "{{.Version}}"
|
||||
org.opencontainers.image.source: "{{.GitURL}}"
|
||||
extra_files:
|
||||
- docker
|
||||
- dockerfile: Dockerfile
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--pull"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.name={{.ProjectName}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Version}}"
|
||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
||||
- "--platform=linux/arm/v6"
|
||||
goos: linux
|
||||
goarch: arm
|
||||
goarm: "6"
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-armv6"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-armv6"
|
||||
extra_files:
|
||||
- docker
|
||||
- dockerfile: Dockerfile
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--pull"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.name={{.ProjectName}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Version}}"
|
||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
||||
- "--platform=linux/arm/v7"
|
||||
goos: linux
|
||||
goarch: arm
|
||||
goarm: "7"
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-armv7"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-armv7"
|
||||
extra_files:
|
||||
- docker
|
||||
|
||||
## s6-overlay docker images
|
||||
- dockerfile: Dockerfile.s6
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--pull"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.name={{.ProjectName}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Version}}"
|
||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
||||
- "--platform=linux/amd64"
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-amd64-s6"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-amd64-s6"
|
||||
extra_files:
|
||||
- docker
|
||||
- dockerfile: Dockerfile.s6
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--pull"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.name={{.ProjectName}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Version}}"
|
||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
||||
- "--platform=linux/arm64"
|
||||
goos: linux
|
||||
goarch: arm64
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-arm64-s6"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-arm64-s6"
|
||||
extra_files:
|
||||
- docker
|
||||
|
||||
docker_manifests:
|
||||
- name_template: "filebrowser/filebrowser:latest"
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-amd64"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-arm64"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-armv7"
|
||||
- name_template: "filebrowser/filebrowser:{{ .Tag }}"
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-amd64"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-arm64"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-armv7"
|
||||
- name_template: "filebrowser/filebrowser:v{{ .Major }}"
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-amd64"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-arm64"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-armv7"
|
||||
## s6 image manifests
|
||||
- name_template: "filebrowser/filebrowser:s6"
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-amd64-s6"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-arm64-s6"
|
||||
- name_template: "filebrowser/filebrowser:{{ .Tag }}-s6"
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-amd64-s6"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-arm64-s6"
|
||||
- name_template: "filebrowser/filebrowser:v{{ .Major }}-s6"
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-amd64-s6"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-arm64-s6"
|
||||
platforms:
|
||||
- linux/amd64
|
||||
- linux/arm64
|
||||
|
||||
homebrew_casks:
|
||||
- name: filebrowser
|
||||
|
||||
12
CHANGELOG.md
@@ -1,16 +1,6 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
||||
|
||||
## [2.45.3](https://github.com/filebrowser/filebrowser/compare/v2.45.2...v2.45.3) (2025-11-13)
|
||||
|
||||
## [2.45.2](https://github.com/filebrowser/filebrowser/compare/v2.45.1...v2.45.2) (2025-11-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps:** update module github.com/shirou/gopsutil/v3 to v4 ([#5536](https://github.com/filebrowser/filebrowser/issues/5536)) ([fdff7a3](https://github.com/filebrowser/filebrowser/commit/fdff7a38f4711f2b58dfdd60bebbb057bd3a478d))
|
||||
* **deps:** update module gopkg.in/yaml.v2 to v3 ([#5537](https://github.com/filebrowser/filebrowser/issues/5537)) ([f26a685](https://github.com/filebrowser/filebrowser/commit/f26a68587d8432b536453093f42dc255d19d10fa))
|
||||
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.45.1](https://github.com/filebrowser/filebrowser/compare/v2.45.0...v2.45.1) (2025-11-11)
|
||||
|
||||
|
||||
@@ -15,23 +15,11 @@ We encourage you to use git to manage your fork. To clone the main repository, j
|
||||
git clone https://github.com/filebrowser/filebrowser
|
||||
```
|
||||
|
||||
We use [Taskfile](https://taskfile.dev/) to manage the different processes (building, releasing, etc) automatically.
|
||||
|
||||
## Build
|
||||
|
||||
You can fully build the project in order to produce a binary by running:
|
||||
|
||||
```bash
|
||||
task build
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
For development, there are a few things to have in mind.
|
||||
|
||||
### Frontend
|
||||
|
||||
We use [Node.js](https://nodejs.org/en/) on the frontend to manage the build process. Prepare the frontend environment:
|
||||
We are using [Node.js](https://nodejs.org/en/) on the frontend to manage the build process. The steps to build it are:
|
||||
|
||||
```bash
|
||||
# From the root of the repo, go to frontend/
|
||||
@@ -39,62 +27,37 @@ cd frontend
|
||||
|
||||
# Install the dependencies
|
||||
pnpm install
|
||||
```
|
||||
|
||||
If you just want to develop the backend, you can create a static build of the frontend:
|
||||
|
||||
```bash
|
||||
# Build the frontend
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
If you want to develop the frontend, start a development server which watches for changes:
|
||||
This will install the dependencies and build the frontend so you can then embed it into the Go app. Although, if you want to play with it, you'll get bored of building it after every change you do. So, you can run the command below to watch for changes:
|
||||
|
||||
```bash
|
||||
pnpm run dev
|
||||
```
|
||||
|
||||
Please note that you need to access File Browser's interface through the development server of the frontend.
|
||||
|
||||
### Backend
|
||||
|
||||
First prepare the backend environment by downloading all required dependencies:
|
||||
First of all, you need to download the required dependencies. We are using the built-in `go mod` tool for dependency management. To get the modules, run:
|
||||
|
||||
```bash
|
||||
go mod download
|
||||
```
|
||||
|
||||
You can now build or run File Browser as any other Go project:
|
||||
The magic of File Browser is that the static assets are bundled into the final binary. For that, we use [Go embed.FS](https://golang.org/pkg/embed/). The files from `frontend/dist` will be embedded during the build process.
|
||||
|
||||
To build File Browser is just like any other Go program:
|
||||
|
||||
```bash
|
||||
# Build
|
||||
go build
|
||||
|
||||
# Run
|
||||
go run .
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
We rely on Docker to abstract all the dependencies required for building the documentation.
|
||||
|
||||
To build the documentation to `www/public`:
|
||||
To create a development build use the "dev" tag, this way the content inside the frontend folder will not be embedded in the binary but will be reloaded at every change:
|
||||
|
||||
```bash
|
||||
task docs
|
||||
```
|
||||
|
||||
To start a local server on port `8000` to view the built documentation:
|
||||
|
||||
```bash
|
||||
task docs-serve
|
||||
```
|
||||
|
||||
## Release
|
||||
|
||||
To make a release, just run:
|
||||
|
||||
```bash
|
||||
task release
|
||||
go build -tags dev
|
||||
```
|
||||
|
||||
## Translations
|
||||
|
||||
@@ -8,6 +8,7 @@ RUN apk update && \
|
||||
|
||||
## Second stage: Use lightweight BusyBox image for final runtime environment
|
||||
FROM busybox:1.37.0-musl
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
# Define non-root user UID and GID
|
||||
ENV UID=1000
|
||||
@@ -18,7 +19,7 @@ RUN addgroup -g $GID user && \
|
||||
adduser -D -u $UID -G user user
|
||||
|
||||
# Copy binary, scripts, and configurations into image with proper ownership
|
||||
COPY --chown=user:user filebrowser /bin/filebrowser
|
||||
COPY --chown=user:user $TARGETPLATFORM/filebrowser /bin/filebrowser
|
||||
COPY --chown=user:user docker/common/ /
|
||||
COPY --chown=user:user docker/alpine/ /
|
||||
COPY --chown=user:user --from=fetcher /sbin/tini-static /bin/tini
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
FROM ghcr.io/linuxserver/baseimage-alpine:3.22
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
RUN apk update && \
|
||||
apk --no-cache add ca-certificates mailcap jq libcap
|
||||
@@ -8,7 +9,7 @@ RUN mkdir -p /config /database /srv && \
|
||||
chown -R abc:abc /config /database /srv
|
||||
|
||||
# Copy files and set permissions
|
||||
COPY filebrowser /bin/filebrowser
|
||||
COPY $TARGETPLATFORM/filebrowser /bin/filebrowser
|
||||
COPY docker/common/ /
|
||||
COPY docker/s6/ /
|
||||
|
||||
|
||||
88
Makefile
Normal file
@@ -0,0 +1,88 @@
|
||||
include common.mk
|
||||
include tools.mk
|
||||
|
||||
LDFLAGS += -X "$(MODULE)/version.Version=$(VERSION)" -X "$(MODULE)/version.CommitSHA=$(VERSION_HASH)"
|
||||
|
||||
SITE_DOCKER_FLAGS = \
|
||||
-v $(CURDIR)/www:/docs \
|
||||
-v $(CURDIR)/LICENSE:/docs/docs/LICENSE \
|
||||
-v $(CURDIR)/SECURITY.md:/docs/docs/security.md \
|
||||
-v $(CURDIR)/CHANGELOG.md:/docs/docs/changelog.md \
|
||||
-v $(CURDIR)/CODE-OF-CONDUCT.md:/docs/docs/code-of-conduct.md \
|
||||
-v $(CURDIR)/CONTRIBUTING.md:/docs/docs/contributing.md
|
||||
|
||||
## Build:
|
||||
|
||||
.PHONY: build
|
||||
build: | build-frontend build-backend ## Build binary
|
||||
|
||||
.PHONY: build-frontend
|
||||
build-frontend: ## Build frontend
|
||||
$Q cd frontend && pnpm install --frozen-lockfile && pnpm run build
|
||||
|
||||
.PHONY: build-backend
|
||||
build-backend: ## Build backend
|
||||
$Q $(go) build -ldflags '$(LDFLAGS)' -o .
|
||||
|
||||
.PHONY: test
|
||||
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
|
||||
$Q $(go) test -v ./...
|
||||
|
||||
.PHONY: lint
|
||||
lint: lint-frontend lint-backend ## Run all linters
|
||||
|
||||
.PHONY: lint-frontend
|
||||
lint-frontend: ## Run frontend linters
|
||||
$Q cd frontend && pnpm install --frozen-lockfile && pnpm run lint
|
||||
|
||||
.PHONY: lint-backend
|
||||
lint-backend: | $(golangci-lint) ## Run backend linters
|
||||
$Q $(golangci-lint) run -v
|
||||
|
||||
.PHONY: lint-commits
|
||||
lint-commits: $(commitlint) ## Run commit linters
|
||||
$Q ./scripts/commitlint.sh
|
||||
|
||||
fmt: $(goimports) ## Format source files
|
||||
$Q $(goimports) -local $(MODULE) -w $$(find . -type f -name '*.go' -not -path "./vendor/*")
|
||||
|
||||
clean: clean-tools ## Clean
|
||||
|
||||
## Release:
|
||||
|
||||
.PHONY: bump-version
|
||||
bump-version: $(standard-version) ## Bump app version
|
||||
$Q ./scripts/bump_version.sh
|
||||
|
||||
.PHONY: site
|
||||
site: ## Build site
|
||||
@rm -rf www/public
|
||||
docker build -f www/Dockerfile --progress=plain -t filebrowser.site www
|
||||
docker run --rm $(SITE_DOCKER_FLAGS) filebrowser.site build -d "public"
|
||||
|
||||
.PHONY: site-serve
|
||||
site-serve: ## Serve site for development
|
||||
docker build -f www/Dockerfile --progress=plain -t filebrowser.site www
|
||||
docker run --rm -it -p 8000:8000 $(SITE_DOCKER_FLAGS) filebrowser.site
|
||||
|
||||
## Help:
|
||||
help: ## Show this help
|
||||
@echo ''
|
||||
@echo 'Usage:'
|
||||
@echo ' ${YELLOW}make${RESET} ${GREEN}<target> [options]${RESET}'
|
||||
@echo ''
|
||||
@echo 'Options:'
|
||||
@$(call global_option, "V [0|1]", "enable verbose mode (default:0)")
|
||||
@echo ''
|
||||
@echo 'Targets:'
|
||||
@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)
|
||||
22
README.md
@@ -1,10 +1,12 @@
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/filebrowser/filebrowser/master/branding/banner.png" width="550"/>
|
||||
<img src="https://raw.githubusercontent.com/filebrowser/logo/master/banner.png" width="550"/>
|
||||
</p>
|
||||
|
||||
[](https://github.com/filebrowser/filebrowser/actions/workflows/main.yaml)
|
||||
[](https://goreportcard.com/report/github.com/filebrowser/filebrowser/v2)
|
||||
[](https://goreportcard.com/report/github.com/filebrowser/filebrowser)
|
||||
[](http://godoc.org/github.com/filebrowser/filebrowser)
|
||||
[](https://github.com/filebrowser/filebrowser/releases/latest)
|
||||
[](http://webchat.freenode.net/?channels=%23filebrowser)
|
||||
|
||||
File Browser provides a file managing interface within a specified directory and it can be used to upload, delete, preview and edit your files. It is a **create-your-own-cloud**-kind of software where you can just install it on your server, direct it to a path and access your files through a nice web interface.
|
||||
|
||||
@@ -14,12 +16,18 @@ Documentation on how to install, configure, and contribute to this project is ho
|
||||
|
||||
## Project Status
|
||||
|
||||
This project is a finished product which fulfills its goal: be a single binary web File Browser which can be run by anyone anywhere. That means that File Browser is currently on **maintenance-only** mode. Therefore, please note the following:
|
||||
> [!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.
|
||||
|
||||
- It can take a while until someone gets back to you. Please be patient.
|
||||
- [Issues](https://github.com/filebrowser/filebrowser/issues) are meant to track bugs. Unrelated issues will be converted into [discussions](https://github.com/filebrowser/filebrowser/discussions).
|
||||
- No new features will be implemented by maintainers. Pull requests for new features will be reviewed on a case by case basis.
|
||||
- The priority is triaging issues, addressing security issues, and fixing bug fixes.
|
||||
[issues]: https://github.com/filebrowser/filebrowser/issues
|
||||
[discussions]: https://github.com/filebrowser/filebrowser/discussions
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
69
Taskfile.yml
@@ -1,69 +0,0 @@
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
SITE_DOCKER_FLAGS: >-
|
||||
-v ./www:/docs
|
||||
-v ./LICENSE:/docs/docs/LICENSE
|
||||
-v ./SECURITY.md:/docs/docs/security.md
|
||||
-v ./CHANGELOG.md:/docs/docs/changelog.md
|
||||
-v ./CODE-OF-CONDUCT.md:/docs/docs/code-of-conduct.md
|
||||
-v ./CONTRIBUTING.md:/docs/docs/contributing.md
|
||||
|
||||
tasks:
|
||||
build-frontend:
|
||||
desc: Build frontend assets
|
||||
dir: frontend
|
||||
cmds:
|
||||
- pnpm install --frozen-lockfile
|
||||
- pnpm run build
|
||||
|
||||
build-backend:
|
||||
desc: Build backend binary
|
||||
cmds:
|
||||
- go build -ldflags='-s -w -X "github.com/filebrowser/filebrowser/v2/version.Version={{.VERSION}}" -X "github.com/filebrowser/filebrowser/v2/version.CommitSHA={{.GIT_COMMIT}}"' -o filebrowser .
|
||||
vars:
|
||||
GIT_COMMIT:
|
||||
sh: git log -n 1 --format=%h
|
||||
VERSION:
|
||||
sh: git describe --tags --abbrev=0 --match=v* | cut -c 2-
|
||||
|
||||
build:
|
||||
desc: Build both frontend and backend
|
||||
cmds:
|
||||
- task: build-frontend
|
||||
- task: build-backend
|
||||
|
||||
release-make:
|
||||
internal: true
|
||||
prompt: Do you wish to proceed?
|
||||
cmds:
|
||||
- pnpm dlx commit-and-tag-version -s
|
||||
|
||||
release-dry-run:
|
||||
internal: true
|
||||
cmds:
|
||||
- pnpm dlx commit-and-tag-version --dry-run --skip
|
||||
|
||||
release:
|
||||
desc: Create a new release
|
||||
cmds:
|
||||
- task: release-dry-run
|
||||
- task: release-make
|
||||
|
||||
docs-image-make:
|
||||
internal: true
|
||||
cmds:
|
||||
- docker build -f www/Dockerfile --progress=plain -t filebrowser.site www
|
||||
|
||||
docs:
|
||||
desc: Generate documentation
|
||||
cmds:
|
||||
- rm -rf www/public
|
||||
- task: docs-image-make
|
||||
- docker run --rm {{.SITE_DOCKER_FLAGS}} filebrowser.site build -d "public"
|
||||
|
||||
docs-serve:
|
||||
desc: Serve documentation
|
||||
cmds:
|
||||
- task: docs-image-make
|
||||
- docker run --rm -it -p 8000:8000 {{.SITE_DOCKER_FLAGS}} filebrowser.site
|
||||
|
Before Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 39 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="700" height="700" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd"><defs><style>.prefix__fil1{fill:#fefefe}.prefix__fil6{fill:#006498}.prefix__fil5{fill:#bdeaff}</style></defs><g id="prefix__Layer_x0020_1"><path d="M80 0h540c44 0 80 36 80 80v540c0 44-36 80-80 80H80c-44 0-80-36-80-80V80C0 36 36 0 80 0z" fill="#455a64"/><path class="prefix__fil1" d="M350 71c154 0 279 125 279 279S504 629 350 629 71 504 71 350 196 71 350 71z"/><path d="M475 236l118 151c3 116-149 252-292 198l-76-99 114-156s138-95 136-94z" fill="#332c2b" fill-opacity=".149"/><path d="M231 211h208l38 24v246c0 5-3 8-8 8H231c-5 0-8-3-8-8V219c0-5 3-8 8-8z" fill="#2bbcff"/><path d="M231 211h208l38 24v2l-37-23H231c-4 0-7 3-7 7v263c-1-1-1-2-1-3V219c0-5 3-8 8-8z" fill="#53c6fc"/><path class="prefix__fil5" d="M305 212h113v98H305zM255 363h189c3 0 5 2 5 4v116H250V367c0-2 2-4 5-4z"/><path class="prefix__fil6" d="M250 470h199v13H250zM380 226h10c3 0 6 2 6 5v40c0 3-3 6-6 6h-10c-3 0-6-3-6-6v-40c0-3 3-5 6-5z"/><path class="prefix__fil1" d="M254 226c10 0 17 7 17 17 0 9-7 16-17 16-9 0-17-7-17-16 0-10 8-17 17-17z"/><path class="prefix__fil6" d="M267 448h165c2 0 3 1 3 3 0 1-1 3-3 3H267c-2 0-3-2-3-3 0-2 1-3 3-3zM267 415h165c2 0 3 1 3 3 0 1-1 2-3 2H267c-2 0-3-1-3-2 0-2 1-3 3-3zM267 381h165c2 0 3 2 3 3 0 2-1 3-3 3H267c-2 0-3-1-3-3 0-1 1-3 3-3z"/><path class="prefix__fil1" d="M236 472c3 0 5 2 5 5 0 2-2 4-5 4s-5-2-5-4c0-3 2-5 5-5zM463 472c3 0 5 2 5 5 0 2-2 4-5 4s-5-2-5-4c0-3 2-5 5-5z"/><path class="prefix__fil6" d="M305 212h-21v98h21z"/><path d="M477 479v2c0 5-3 8-8 8H231c-5 0-8-3-8-8v-2c0 4 3 8 8 8h238c5 0 8-4 8-8z" fill="#0ea5eb"/><path d="M350 70c155 0 280 125 280 280S505 630 350 630 70 505 70 350 195 70 350 70zm0 46c129 0 234 105 234 234S479 584 350 584 116 479 116 350s105-234 234-234z" fill="#2979ff"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 27 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="560" height="560" version="1.1" id="prefix__svg44" clip-rule="evenodd" fill-rule="evenodd" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision"><defs id="prefix__defs4"><style type="text/css" id="style2">.prefix__fil1{fill:#fefefe}.prefix__fil6{fill:#006498}.prefix__fil5{fill:#bdeaff}</style></defs><g id="prefix__g85" transform="translate(-70 -70)"><path class="prefix__fil1" d="M350 71c154 0 279 125 279 279S504 629 350 629 71 504 71 350 196 71 350 71z" id="prefix__path9" fill="#fefefe"/><path d="M475 236l118 151c3 116-149 252-292 198l-76-99 114-156s138-95 136-94z" id="prefix__path11" fill="#332c2b" fill-opacity=".149"/><path d="M231 211h208l38 24v246c0 5-3 8-8 8H231c-5 0-8-3-8-8V219c0-5 3-8 8-8z" id="prefix__path13" fill="#2bbcff"/><path d="M231 211h208l38 24v2l-37-23H231c-4 0-7 3-7 7v263c-1-1-1-2-1-3V219c0-5 3-8 8-8z" id="prefix__path15" fill="#53c6fc"/><path class="prefix__fil5" id="prefix__polygon17" fill="#bdeaff" d="M305 212h113v98H305z"/><path class="prefix__fil5" d="M255 363h189c3 0 5 2 5 4v116H250V367c0-2 2-4 5-4z" id="prefix__path19" fill="#bdeaff"/><path class="prefix__fil6" id="prefix__polygon21" fill="#006498" d="M250 470h199v13H250z"/><path class="prefix__fil6" d="M380 226h10c3 0 6 2 6 5v40c0 3-3 6-6 6h-10c-3 0-6-3-6-6v-40c0-3 3-5 6-5z" id="prefix__path23" fill="#006498"/><path class="prefix__fil1" d="M254 226c10 0 17 7 17 17 0 9-7 16-17 16-9 0-17-7-17-16 0-10 8-17 17-17z" id="prefix__path25" fill="#fefefe"/><path class="prefix__fil6" d="M267 448h165c2 0 3 1 3 3 0 1-1 3-3 3H267c-2 0-3-2-3-3 0-2 1-3 3-3z" id="prefix__path27" fill="#006498"/><path class="prefix__fil6" d="M267 415h165c2 0 3 1 3 3 0 1-1 2-3 2H267c-2 0-3-1-3-2 0-2 1-3 3-3z" id="prefix__path29" fill="#006498"/><path class="prefix__fil6" d="M267 381h165c2 0 3 2 3 3 0 2-1 3-3 3H267c-2 0-3-1-3-3 0-1 1-3 3-3z" id="prefix__path31" fill="#006498"/><path class="prefix__fil1" d="M236 472c3 0 5 2 5 5 0 2-2 4-5 4s-5-2-5-4c0-3 2-5 5-5z" id="prefix__path33" fill="#fefefe"/><path class="prefix__fil1" d="M463 472c3 0 5 2 5 5 0 2-2 4-5 4s-5-2-5-4c0-3 2-5 5-5z" id="prefix__path35" fill="#fefefe"/><path class="prefix__fil6" id="prefix__polygon37" fill="#006498" d="M305 212h-21v98h21z"/><path d="M477 479v2c0 5-3 8-8 8H231c-5 0-8-3-8-8v-2c0 4 3 8 8 8h238c5 0 8-4 8-8z" id="prefix__path39" fill="#0ea5eb"/><path d="M350 70c155 0 280 125 280 280S505 630 350 630 70 505 70 350 195 70 350 70zm0 46c129 0 234 105 234 234S479 584 350 584 116 479 116 350s105-234 234-234z" id="prefix__path41" fill="#2979ff"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/asdine/storm/v3"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/settings"
|
||||
"github.com/filebrowser/filebrowser/v2/storage"
|
||||
|
||||
28
common.mk
Normal file
@@ -0,0 +1,28 @@
|
||||
SHELL := /usr/bin/env bash
|
||||
DATE ?= $(shell date +%FT%T%z)
|
||||
BASE_PATH := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
VERSION ?= $(shell git describe --tags --always --match=v* 2> /dev/null || \
|
||||
cat $(CURDIR)/.version 2> /dev/null || echo v0)
|
||||
VERSION_HASH = $(shell git rev-parse HEAD)
|
||||
BRANCH = $(shell git rev-parse --abbrev-ref HEAD)
|
||||
|
||||
go = GOGC=off go
|
||||
MODULE = $(shell env GO111MODULE=on go list -m)
|
||||
|
||||
# printing
|
||||
# $Q (quiet) is used in the targets as a replacer for @.
|
||||
# This macro helps to print the command for debugging by setting V to 1. Example `make test-unit V=1`
|
||||
V = 0
|
||||
Q = $(if $(filter 1,$V),,@)
|
||||
# $M is a macro to print a colored ▶ character. Example `$(info $(M) running coverage tests…)` will print "▶ running coverage tests…"
|
||||
M = $(shell printf "\033[34;1m▶\033[0m")
|
||||
|
||||
GREEN := $(shell tput -Txterm setaf 2)
|
||||
YELLOW := $(shell tput -Txterm setaf 3)
|
||||
WHITE := $(shell tput -Txterm setaf 7)
|
||||
CYAN := $(shell tput -Txterm setaf 6)
|
||||
RESET := $(shell tput -Txterm sgr0)
|
||||
|
||||
define global_option
|
||||
printf " ${YELLOW}%-20s${GREEN}%s${RESET}\n" $(1) $(2)
|
||||
endef
|
||||
@@ -1,4 +1,5 @@
|
||||
//go:build !dev
|
||||
// +build !dev
|
||||
|
||||
package frontend
|
||||
|
||||
|
||||
15
frontend/assets_dev.go
Normal file
@@ -0,0 +1,15 @@
|
||||
//go:build dev
|
||||
// +build dev
|
||||
|
||||
package frontend
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
)
|
||||
|
||||
var assets fs.FS = os.DirFS("frontend")
|
||||
|
||||
func Assets() fs.FS {
|
||||
return assets
|
||||
}
|
||||
@@ -12,11 +12,7 @@
|
||||
|
||||
<link rel="icon" type="image/svg+xml" href="/img/icons/favicon.svg" />
|
||||
<link rel="shortcut icon" href="/img/icons/favicon.ico" />
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
href="/img/icons/apple-touch-icon.png"
|
||||
/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/img/icons/apple-touch-icon.png" />
|
||||
<meta name="apple-mobile-web-app-title" content="File Browser" />
|
||||
|
||||
<!-- Add to home screen for Android and modern mobile browsers -->
|
||||
|
||||
@@ -4,35 +4,37 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=24.0.0",
|
||||
"pnpm": ">=10.0.0"
|
||||
"node": ">=22.0.0",
|
||||
"pnpm": ">=9.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "pnpm run typecheck && vite build",
|
||||
"clean": "find ./dist -maxdepth 1 -mindepth 1 ! -name '.gitkeep' -exec rm -r {} +",
|
||||
"typecheck": "vue-tsc -p ./tsconfig.app.json --noEmit",
|
||||
"typecheck": "vue-tsc -p ./tsconfig.tsc.json --noEmit",
|
||||
"lint": "eslint src/",
|
||||
"lint:fix": "eslint --fix src/",
|
||||
"format": "prettier --write ."
|
||||
"format": "prettier --write .",
|
||||
"test": "playwright test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@chenfengyuan/vue-number-input": "^2.0.1",
|
||||
"@vueuse/core": "^14.0.0",
|
||||
"@vueuse/integrations": "^14.0.0",
|
||||
"@vueuse/core": "^12.5.0",
|
||||
"@vueuse/integrations": "^12.5.0",
|
||||
"ace-builds": "^1.43.2",
|
||||
"core-js": "^3.44.0",
|
||||
"dayjs": "^1.11.13",
|
||||
"dompurify": "^3.2.6",
|
||||
"epubjs": "^0.3.93",
|
||||
"filesize": "^11.0.13",
|
||||
"filesize": "^10.1.1",
|
||||
"js-base64": "^3.7.7",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"marked": "^17.0.0",
|
||||
"marked": "^15.0.6",
|
||||
"material-icons": "^1.13.14",
|
||||
"normalize.css": "^8.0.1",
|
||||
"pinia": "^3.0.4",
|
||||
"pretty-bytes": "^7.1.0",
|
||||
"pinia": "^2.3.1",
|
||||
"pretty-bytes": "^6.1.1",
|
||||
"qrcode.vue": "^3.6.0",
|
||||
"tus-js-client": "^4.3.1",
|
||||
"utif": "^3.1.0",
|
||||
@@ -48,28 +50,30 @@
|
||||
"vue-toastification": "^2.0.0-rc.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@intlify/unplugin-vue-i18n": "^11.0.1",
|
||||
"@tsconfig/node24": "^24.0.2",
|
||||
"@intlify/unplugin-vue-i18n": "^6.0.8",
|
||||
"@playwright/test": "^1.54.1",
|
||||
"@tsconfig/node22": "^22.0.2",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^24.10.1",
|
||||
"@types/node": "^22.10.10",
|
||||
"@typescript-eslint/eslint-plugin": "^8.37.0",
|
||||
"@vitejs/plugin-legacy": "^7.2.1",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"@vitejs/plugin-legacy": "^6.0.0",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"@vue/eslint-config-prettier": "^10.2.0",
|
||||
"@vue/eslint-config-typescript": "^14.6.0",
|
||||
"@vue/tsconfig": "^0.8.1",
|
||||
"@vue/tsconfig": "^0.7.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"concurrently": "^9.2.0",
|
||||
"eslint": "^9.31.0",
|
||||
"eslint-config-prettier": "^10.1.5",
|
||||
"eslint-plugin-prettier": "^5.5.1",
|
||||
"eslint-plugin-vue": "^10.5.1",
|
||||
"eslint-plugin-vue": "^9.24.0",
|
||||
"jsdom": "^26.1.0",
|
||||
"postcss": "^8.5.6",
|
||||
"prettier": "^3.6.2",
|
||||
"terser": "^5.43.1",
|
||||
"typescript": "^5.9.3",
|
||||
"vite": "^7.2.2",
|
||||
"vite-plugin-compression2": "^2.3.1",
|
||||
"vue-tsc": "^3.1.3"
|
||||
"vite": "^6.4.1",
|
||||
"vite-plugin-compression2": "^1.0.0",
|
||||
"vue-tsc": "^2.2.0"
|
||||
},
|
||||
"packageManager": "pnpm@10.22.0+sha512.bf049efe995b28f527fd2b41ae0474ce29186f7edcb3bf545087bd61fbbebb2bf75362d1307fda09c2d288e1e499787ac12d4fcb617a974718a6051f2eee741c"
|
||||
"packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0"
|
||||
}
|
||||
|
||||
80
frontend/playwright.config.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { defineConfig, devices } from "@playwright/test";
|
||||
|
||||
/**
|
||||
* Read environment variables from file.
|
||||
* https://github.com/motdotla/dotenv
|
||||
*/
|
||||
// require('dotenv').config();
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: "./tests",
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: "html",
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
baseURL: "http://127.0.0.1:5173",
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: "on-first-retry",
|
||||
|
||||
/* Set default locale to English (US) */
|
||||
locale: "en-US",
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
use: { ...devices["Desktop Chrome"] },
|
||||
},
|
||||
|
||||
{
|
||||
name: "firefox",
|
||||
use: { ...devices["Desktop Firefox"] },
|
||||
},
|
||||
|
||||
// {
|
||||
// name: "webkit",
|
||||
// use: { ...devices["Desktop Safari"] },
|
||||
// },
|
||||
|
||||
/* Test against mobile viewports. */
|
||||
// {
|
||||
// name: 'Mobile Chrome',
|
||||
// use: { ...devices['Pixel 5'] },
|
||||
// },
|
||||
// {
|
||||
// name: 'Mobile Safari',
|
||||
// use: { ...devices['iPhone 12'] },
|
||||
// },
|
||||
|
||||
/* Test against branded browsers. */
|
||||
// {
|
||||
// name: 'Microsoft Edge',
|
||||
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
|
||||
// },
|
||||
// {
|
||||
// name: 'Google Chrome',
|
||||
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
|
||||
// },
|
||||
],
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer: {
|
||||
command: "npm run dev",
|
||||
url: "http://127.0.0.1:5173",
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
});
|
||||
3715
frontend/pnpm-lock.yaml
generated
@@ -1 +1,147 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="560" height="560" version="1.1" id="prefix__svg44" clip-rule="evenodd" fill-rule="evenodd" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision"><defs id="prefix__defs4"><style type="text/css" id="style2">.prefix__fil1{fill:#fefefe}.prefix__fil6{fill:#006498}.prefix__fil5{fill:#bdeaff}</style></defs><g id="prefix__g85" transform="translate(-70 -70)"><path class="prefix__fil1" d="M350 71c154 0 279 125 279 279S504 629 350 629 71 504 71 350 196 71 350 71z" id="prefix__path9" fill="#fefefe"/><path d="M475 236l118 151c3 116-149 252-292 198l-76-99 114-156s138-95 136-94z" id="prefix__path11" fill="#332c2b" fill-opacity=".149"/><path d="M231 211h208l38 24v246c0 5-3 8-8 8H231c-5 0-8-3-8-8V219c0-5 3-8 8-8z" id="prefix__path13" fill="#2bbcff"/><path d="M231 211h208l38 24v2l-37-23H231c-4 0-7 3-7 7v263c-1-1-1-2-1-3V219c0-5 3-8 8-8z" id="prefix__path15" fill="#53c6fc"/><path class="prefix__fil5" id="prefix__polygon17" fill="#bdeaff" d="M305 212h113v98H305z"/><path class="prefix__fil5" d="M255 363h189c3 0 5 2 5 4v116H250V367c0-2 2-4 5-4z" id="prefix__path19" fill="#bdeaff"/><path class="prefix__fil6" id="prefix__polygon21" fill="#006498" d="M250 470h199v13H250z"/><path class="prefix__fil6" d="M380 226h10c3 0 6 2 6 5v40c0 3-3 6-6 6h-10c-3 0-6-3-6-6v-40c0-3 3-5 6-5z" id="prefix__path23" fill="#006498"/><path class="prefix__fil1" d="M254 226c10 0 17 7 17 17 0 9-7 16-17 16-9 0-17-7-17-16 0-10 8-17 17-17z" id="prefix__path25" fill="#fefefe"/><path class="prefix__fil6" d="M267 448h165c2 0 3 1 3 3 0 1-1 3-3 3H267c-2 0-3-2-3-3 0-2 1-3 3-3z" id="prefix__path27" fill="#006498"/><path class="prefix__fil6" d="M267 415h165c2 0 3 1 3 3 0 1-1 2-3 2H267c-2 0-3-1-3-2 0-2 1-3 3-3z" id="prefix__path29" fill="#006498"/><path class="prefix__fil6" d="M267 381h165c2 0 3 2 3 3 0 2-1 3-3 3H267c-2 0-3-1-3-3 0-1 1-3 3-3z" id="prefix__path31" fill="#006498"/><path class="prefix__fil1" d="M236 472c3 0 5 2 5 5 0 2-2 4-5 4s-5-2-5-4c0-3 2-5 5-5z" id="prefix__path33" fill="#fefefe"/><path class="prefix__fil1" d="M463 472c3 0 5 2 5 5 0 2-2 4-5 4s-5-2-5-4c0-3 2-5 5-5z" id="prefix__path35" fill="#fefefe"/><path class="prefix__fil6" id="prefix__polygon37" fill="#006498" d="M305 212h-21v98h21z"/><path d="M477 479v2c0 5-3 8-8 8H231c-5 0-8-3-8-8v-2c0 4 3 8 8 8h238c5 0 8-4 8-8z" id="prefix__path39" fill="#0ea5eb"/><path d="M350 70c155 0 280 125 280 280S505 630 350 630 70 505 70 350 195 70 350 70zm0 46c129 0 234 105 234 234S479 584 350 584 116 479 116 350s105-234 234-234z" id="prefix__path41" fill="#2979ff"/></g></svg>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xml:space="preserve"
|
||||
width="560"
|
||||
height="560"
|
||||
version="1.1"
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
|
||||
viewBox="0 0 560 560"
|
||||
id="svg44"
|
||||
sodipodi:docname="icon_raw.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
inkscape:export-filename="/home/umarcor/filebrowser/logo/icon_raw.svg.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"><metadata
|
||||
id="metadata48"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="711"
|
||||
id="namedview46"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.33714286"
|
||||
inkscape:cx="-172.33051"
|
||||
inkscape:cy="280"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="20"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg44" />
|
||||
<defs
|
||||
id="defs4">
|
||||
<style
|
||||
type="text/css"
|
||||
id="style2">
|
||||
<![CDATA[
|
||||
.fil1 {fill:#FEFEFE}
|
||||
.fil6 {fill:#006498}
|
||||
.fil7 {fill:#0EA5EB}
|
||||
.fil8 {fill:#2979FF}
|
||||
.fil3 {fill:#2BBCFF}
|
||||
.fil0 {fill:#455A64}
|
||||
.fil4 {fill:#53C6FC}
|
||||
.fil5 {fill:#BDEAFF}
|
||||
.fil2 {fill:#332C2B;fill-opacity:0.149020}
|
||||
]]>
|
||||
</style>
|
||||
</defs>
|
||||
<g
|
||||
id="g85"
|
||||
transform="translate(-70,-70)"><path
|
||||
class="fil1"
|
||||
d="M 350,71 C 504,71 629,196 629,350 629,504 504,629 350,629 196,629 71,504 71,350 71,196 196,71 350,71 Z"
|
||||
id="path9"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#fefefe" /><path
|
||||
class="fil2"
|
||||
d="M 475,236 593,387 C 596,503 444,639 301,585 L 225,486 339,330 c 0,0 138,-95 136,-94 z"
|
||||
id="path11"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#332c2b;fill-opacity:0.14902003" /><path
|
||||
class="fil3"
|
||||
d="m 231,211 h 208 l 38,24 v 246 c 0,5 -3,8 -8,8 H 231 c -5,0 -8,-3 -8,-8 V 219 c 0,-5 3,-8 8,-8 z"
|
||||
id="path13"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#2bbcff" /><path
|
||||
class="fil4"
|
||||
d="m 231,211 h 208 l 38,24 v 2 L 440,214 H 231 c -4,0 -7,3 -7,7 v 263 c -1,-1 -1,-2 -1,-3 V 219 c 0,-5 3,-8 8,-8 z"
|
||||
id="path15"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#53c6fc" /><polygon
|
||||
class="fil5"
|
||||
points="305,212 418,212 418,310 305,310 "
|
||||
id="polygon17"
|
||||
style="fill:#bdeaff" /><path
|
||||
class="fil5"
|
||||
d="m 255,363 h 189 c 3,0 5,2 5,4 V 483 H 250 V 367 c 0,-2 2,-4 5,-4 z"
|
||||
id="path19"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#bdeaff" /><polygon
|
||||
class="fil6"
|
||||
points="250,470 449,470 449,483 250,483 "
|
||||
id="polygon21"
|
||||
style="fill:#006498" /><path
|
||||
class="fil6"
|
||||
d="m 380,226 h 10 c 3,0 6,2 6,5 v 40 c 0,3 -3,6 -6,6 h -10 c -3,0 -6,-3 -6,-6 v -40 c 0,-3 3,-5 6,-5 z"
|
||||
id="path23"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#006498" /><path
|
||||
class="fil1"
|
||||
d="m 254,226 c 10,0 17,7 17,17 0,9 -7,16 -17,16 -9,0 -17,-7 -17,-16 0,-10 8,-17 17,-17 z"
|
||||
id="path25"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#fefefe" /><path
|
||||
class="fil6"
|
||||
d="m 267,448 h 165 c 2,0 3,1 3,3 v 0 c 0,1 -1,3 -3,3 H 267 c -2,0 -3,-2 -3,-3 v 0 c 0,-2 1,-3 3,-3 z"
|
||||
id="path27"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#006498" /><path
|
||||
class="fil6"
|
||||
d="m 267,415 h 165 c 2,0 3,1 3,3 v 0 c 0,1 -1,2 -3,2 H 267 c -2,0 -3,-1 -3,-2 v 0 c 0,-2 1,-3 3,-3 z"
|
||||
id="path29"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#006498" /><path
|
||||
class="fil6"
|
||||
d="m 267,381 h 165 c 2,0 3,2 3,3 v 0 c 0,2 -1,3 -3,3 H 267 c -2,0 -3,-1 -3,-3 v 0 c 0,-1 1,-3 3,-3 z"
|
||||
id="path31"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#006498" /><path
|
||||
class="fil1"
|
||||
d="m 236,472 c 3,0 5,2 5,5 0,2 -2,4 -5,4 -3,0 -5,-2 -5,-4 0,-3 2,-5 5,-5 z"
|
||||
id="path33"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#fefefe" /><path
|
||||
class="fil1"
|
||||
d="m 463,472 c 3,0 5,2 5,5 0,2 -2,4 -5,4 -3,0 -5,-2 -5,-4 0,-3 2,-5 5,-5 z"
|
||||
id="path35"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#fefefe" /><polygon
|
||||
class="fil6"
|
||||
points="305,212 284,212 284,310 305,310 "
|
||||
id="polygon37"
|
||||
style="fill:#006498" /><path
|
||||
class="fil7"
|
||||
d="m 477,479 v 2 c 0,5 -3,8 -8,8 H 231 c -5,0 -8,-3 -8,-8 v -2 c 0,4 3,8 8,8 h 238 c 5,0 8,-4 8,-8 z"
|
||||
id="path39"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#0ea5eb" /><path
|
||||
class="fil8"
|
||||
d="M 350,70 C 505,70 630,195 630,350 630,505 505,630 350,630 195,630 70,505 70,350 70,195 195,70 350,70 Z m 0,46 C 479,116 584,221 584,350 584,479 479,584 350,584 221,584 116,479 116,350 116,221 221,116 350,116 Z"
|
||||
id="path41"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#2979ff" /></g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 5.4 KiB |
@@ -18,17 +18,9 @@
|
||||
|
||||
<meta name="robots" content="noindex,nofollow" />
|
||||
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/svg+xml"
|
||||
href="[{[ .StaticURL ]}]/img/icons/favicon.svg"
|
||||
/>
|
||||
<link rel="icon" type="image/svg+xml" href="[{[ .StaticURL ]}]/img/icons/favicon.svg" />
|
||||
<link rel="shortcut icon" href="[{[ .StaticURL ]}]/img/icons/favicon.ico" />
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
href="[{[ .StaticURL ]}]/img/icons/apple-touch-icon.png"
|
||||
/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="[{[ .StaticURL ]}]/img/icons/apple-touch-icon.png" />
|
||||
<meta name="apple-mobile-web-app-title" content="File Browser" />
|
||||
|
||||
<!-- Add to home screen for Android and modern mobile browsers -->
|
||||
|
||||
@@ -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 {
|
||||
@@ -75,9 +75,8 @@
|
||||
local("Roboto"),
|
||||
local("Roboto-Regular"),
|
||||
url(../assets/fonts/roboto/normal-latin.woff2) format("woff2");
|
||||
unicode-range:
|
||||
U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F,
|
||||
U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
@@ -143,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 {
|
||||
@@ -155,9 +154,8 @@
|
||||
local("Roboto Medium"),
|
||||
local("Roboto-Medium"),
|
||||
url(../assets/fonts/roboto/medium-latin.woff2) format("woff2");
|
||||
unicode-range:
|
||||
U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F,
|
||||
U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
@@ -223,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 {
|
||||
@@ -235,9 +233,8 @@
|
||||
local("Roboto Bold"),
|
||||
local("Roboto-Bold"),
|
||||
url(../assets/fonts/roboto/bold-latin.woff2) format("woff2");
|
||||
unicode-range:
|
||||
U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F,
|
||||
U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"status": "failed",
|
||||
"failedTests": []
|
||||
}
|
||||
489
frontend/tests-examples/demo-todo-app.spec.ts
Normal file
@@ -0,0 +1,489 @@
|
||||
import { test, expect, type Page } from "@playwright/test";
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto("https://demo.playwright.dev/todomvc");
|
||||
});
|
||||
|
||||
const TODO_ITEMS = [
|
||||
"buy some cheese",
|
||||
"feed the cat",
|
||||
"book a doctors appointment",
|
||||
];
|
||||
|
||||
test.describe("New Todo", () => {
|
||||
test("should allow me to add todo items", async ({ page }) => {
|
||||
// create a new todo locator
|
||||
const newTodo = page.getByPlaceholder("What needs to be done?");
|
||||
|
||||
// Create 1st todo.
|
||||
await newTodo.fill(TODO_ITEMS[0]);
|
||||
await newTodo.press("Enter");
|
||||
|
||||
// Make sure the list only has one todo item.
|
||||
await expect(page.getByTestId("todo-title")).toHaveText([TODO_ITEMS[0]]);
|
||||
|
||||
// Create 2nd todo.
|
||||
await newTodo.fill(TODO_ITEMS[1]);
|
||||
await newTodo.press("Enter");
|
||||
|
||||
// Make sure the list now has two todo items.
|
||||
await expect(page.getByTestId("todo-title")).toHaveText([
|
||||
TODO_ITEMS[0],
|
||||
TODO_ITEMS[1],
|
||||
]);
|
||||
|
||||
await checkNumberOfTodosInLocalStorage(page, 2);
|
||||
});
|
||||
|
||||
test("should clear text input field when an item is added", async ({
|
||||
page,
|
||||
}) => {
|
||||
// create a new todo locator
|
||||
const newTodo = page.getByPlaceholder("What needs to be done?");
|
||||
|
||||
// Create one todo item.
|
||||
await newTodo.fill(TODO_ITEMS[0]);
|
||||
await newTodo.press("Enter");
|
||||
|
||||
// Check that input is empty.
|
||||
await expect(newTodo).toBeEmpty();
|
||||
await checkNumberOfTodosInLocalStorage(page, 1);
|
||||
});
|
||||
|
||||
test("should append new items to the bottom of the list", async ({
|
||||
page,
|
||||
}) => {
|
||||
// Create 3 items.
|
||||
await createDefaultTodos(page);
|
||||
|
||||
// create a todo count locator
|
||||
const todoCount = page.getByTestId("todo-count");
|
||||
|
||||
// Check test using different methods.
|
||||
await expect(page.getByText("3 items left")).toBeVisible();
|
||||
await expect(todoCount).toHaveText("3 items left");
|
||||
await expect(todoCount).toContainText("3");
|
||||
await expect(todoCount).toHaveText(/3/);
|
||||
|
||||
// Check all items in one call.
|
||||
await expect(page.getByTestId("todo-title")).toHaveText(TODO_ITEMS);
|
||||
await checkNumberOfTodosInLocalStorage(page, 3);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Mark all as completed", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await createDefaultTodos(page);
|
||||
await checkNumberOfTodosInLocalStorage(page, 3);
|
||||
});
|
||||
|
||||
test.afterEach(async ({ page }) => {
|
||||
await checkNumberOfTodosInLocalStorage(page, 3);
|
||||
});
|
||||
|
||||
test("should allow me to mark all items as completed", async ({ page }) => {
|
||||
// Complete all todos.
|
||||
await page.getByLabel("Mark all as complete").check();
|
||||
|
||||
// Ensure all todos have 'completed' class.
|
||||
await expect(page.getByTestId("todo-item")).toHaveClass([
|
||||
"completed",
|
||||
"completed",
|
||||
"completed",
|
||||
]);
|
||||
await checkNumberOfCompletedTodosInLocalStorage(page, 3);
|
||||
});
|
||||
|
||||
test("should allow me to clear the complete state of all items", async ({
|
||||
page,
|
||||
}) => {
|
||||
const toggleAll = page.getByLabel("Mark all as complete");
|
||||
// Check and then immediately uncheck.
|
||||
await toggleAll.check();
|
||||
await toggleAll.uncheck();
|
||||
|
||||
// Should be no completed classes.
|
||||
await expect(page.getByTestId("todo-item")).toHaveClass(["", "", ""]);
|
||||
});
|
||||
|
||||
test("complete all checkbox should update state when items are completed / cleared", async ({
|
||||
page,
|
||||
}) => {
|
||||
const toggleAll = page.getByLabel("Mark all as complete");
|
||||
await toggleAll.check();
|
||||
await expect(toggleAll).toBeChecked();
|
||||
await checkNumberOfCompletedTodosInLocalStorage(page, 3);
|
||||
|
||||
// Uncheck first todo.
|
||||
const firstTodo = page.getByTestId("todo-item").nth(0);
|
||||
await firstTodo.getByRole("checkbox").uncheck();
|
||||
|
||||
// Reuse toggleAll locator and make sure its not checked.
|
||||
await expect(toggleAll).not.toBeChecked();
|
||||
|
||||
await firstTodo.getByRole("checkbox").check();
|
||||
await checkNumberOfCompletedTodosInLocalStorage(page, 3);
|
||||
|
||||
// Assert the toggle all is checked again.
|
||||
await expect(toggleAll).toBeChecked();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Item", () => {
|
||||
test("should allow me to mark items as complete", async ({ page }) => {
|
||||
// create a new todo locator
|
||||
const newTodo = page.getByPlaceholder("What needs to be done?");
|
||||
|
||||
// Create two items.
|
||||
for (const item of TODO_ITEMS.slice(0, 2)) {
|
||||
await newTodo.fill(item);
|
||||
await newTodo.press("Enter");
|
||||
}
|
||||
|
||||
// Check first item.
|
||||
const firstTodo = page.getByTestId("todo-item").nth(0);
|
||||
await firstTodo.getByRole("checkbox").check();
|
||||
await expect(firstTodo).toHaveClass("completed");
|
||||
|
||||
// Check second item.
|
||||
const secondTodo = page.getByTestId("todo-item").nth(1);
|
||||
await expect(secondTodo).not.toHaveClass("completed");
|
||||
await secondTodo.getByRole("checkbox").check();
|
||||
|
||||
// Assert completed class.
|
||||
await expect(firstTodo).toHaveClass("completed");
|
||||
await expect(secondTodo).toHaveClass("completed");
|
||||
});
|
||||
|
||||
test("should allow me to un-mark items as complete", async ({ page }) => {
|
||||
// create a new todo locator
|
||||
const newTodo = page.getByPlaceholder("What needs to be done?");
|
||||
|
||||
// Create two items.
|
||||
for (const item of TODO_ITEMS.slice(0, 2)) {
|
||||
await newTodo.fill(item);
|
||||
await newTodo.press("Enter");
|
||||
}
|
||||
|
||||
const firstTodo = page.getByTestId("todo-item").nth(0);
|
||||
const secondTodo = page.getByTestId("todo-item").nth(1);
|
||||
const firstTodoCheckbox = firstTodo.getByRole("checkbox");
|
||||
|
||||
await firstTodoCheckbox.check();
|
||||
await expect(firstTodo).toHaveClass("completed");
|
||||
await expect(secondTodo).not.toHaveClass("completed");
|
||||
await checkNumberOfCompletedTodosInLocalStorage(page, 1);
|
||||
|
||||
await firstTodoCheckbox.uncheck();
|
||||
await expect(firstTodo).not.toHaveClass("completed");
|
||||
await expect(secondTodo).not.toHaveClass("completed");
|
||||
await checkNumberOfCompletedTodosInLocalStorage(page, 0);
|
||||
});
|
||||
|
||||
test("should allow me to edit an item", async ({ page }) => {
|
||||
await createDefaultTodos(page);
|
||||
|
||||
const todoItems = page.getByTestId("todo-item");
|
||||
const secondTodo = todoItems.nth(1);
|
||||
await secondTodo.dblclick();
|
||||
await expect(secondTodo.getByRole("textbox", { name: "Edit" })).toHaveValue(
|
||||
TODO_ITEMS[1]
|
||||
);
|
||||
await secondTodo
|
||||
.getByRole("textbox", { name: "Edit" })
|
||||
.fill("buy some sausages");
|
||||
await secondTodo.getByRole("textbox", { name: "Edit" }).press("Enter");
|
||||
|
||||
// Explicitly assert the new text value.
|
||||
await expect(todoItems).toHaveText([
|
||||
TODO_ITEMS[0],
|
||||
"buy some sausages",
|
||||
TODO_ITEMS[2],
|
||||
]);
|
||||
await checkTodosInLocalStorage(page, "buy some sausages");
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Editing", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await createDefaultTodos(page);
|
||||
await checkNumberOfTodosInLocalStorage(page, 3);
|
||||
});
|
||||
|
||||
test("should hide other controls when editing", async ({ page }) => {
|
||||
const todoItem = page.getByTestId("todo-item").nth(1);
|
||||
await todoItem.dblclick();
|
||||
await expect(todoItem.getByRole("checkbox")).not.toBeVisible();
|
||||
await expect(
|
||||
todoItem.locator("label", {
|
||||
hasText: TODO_ITEMS[1],
|
||||
})
|
||||
).not.toBeVisible();
|
||||
await checkNumberOfTodosInLocalStorage(page, 3);
|
||||
});
|
||||
|
||||
test("should save edits on blur", async ({ page }) => {
|
||||
const todoItems = page.getByTestId("todo-item");
|
||||
await todoItems.nth(1).dblclick();
|
||||
await todoItems
|
||||
.nth(1)
|
||||
.getByRole("textbox", { name: "Edit" })
|
||||
.fill("buy some sausages");
|
||||
await todoItems
|
||||
.nth(1)
|
||||
.getByRole("textbox", { name: "Edit" })
|
||||
.dispatchEvent("blur");
|
||||
|
||||
await expect(todoItems).toHaveText([
|
||||
TODO_ITEMS[0],
|
||||
"buy some sausages",
|
||||
TODO_ITEMS[2],
|
||||
]);
|
||||
await checkTodosInLocalStorage(page, "buy some sausages");
|
||||
});
|
||||
|
||||
test("should trim entered text", async ({ page }) => {
|
||||
const todoItems = page.getByTestId("todo-item");
|
||||
await todoItems.nth(1).dblclick();
|
||||
await todoItems
|
||||
.nth(1)
|
||||
.getByRole("textbox", { name: "Edit" })
|
||||
.fill(" buy some sausages ");
|
||||
await todoItems
|
||||
.nth(1)
|
||||
.getByRole("textbox", { name: "Edit" })
|
||||
.press("Enter");
|
||||
|
||||
await expect(todoItems).toHaveText([
|
||||
TODO_ITEMS[0],
|
||||
"buy some sausages",
|
||||
TODO_ITEMS[2],
|
||||
]);
|
||||
await checkTodosInLocalStorage(page, "buy some sausages");
|
||||
});
|
||||
|
||||
test("should remove the item if an empty text string was entered", async ({
|
||||
page,
|
||||
}) => {
|
||||
const todoItems = page.getByTestId("todo-item");
|
||||
await todoItems.nth(1).dblclick();
|
||||
await todoItems.nth(1).getByRole("textbox", { name: "Edit" }).fill("");
|
||||
await todoItems
|
||||
.nth(1)
|
||||
.getByRole("textbox", { name: "Edit" })
|
||||
.press("Enter");
|
||||
|
||||
await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]);
|
||||
});
|
||||
|
||||
test("should cancel edits on escape", async ({ page }) => {
|
||||
const todoItems = page.getByTestId("todo-item");
|
||||
await todoItems.nth(1).dblclick();
|
||||
await todoItems
|
||||
.nth(1)
|
||||
.getByRole("textbox", { name: "Edit" })
|
||||
.fill("buy some sausages");
|
||||
await todoItems
|
||||
.nth(1)
|
||||
.getByRole("textbox", { name: "Edit" })
|
||||
.press("Escape");
|
||||
await expect(todoItems).toHaveText(TODO_ITEMS);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Counter", () => {
|
||||
test("should display the current number of todo items", async ({ page }) => {
|
||||
// create a new todo locator
|
||||
const newTodo = page.getByPlaceholder("What needs to be done?");
|
||||
|
||||
// create a todo count locator
|
||||
const todoCount = page.getByTestId("todo-count");
|
||||
|
||||
await newTodo.fill(TODO_ITEMS[0]);
|
||||
await newTodo.press("Enter");
|
||||
|
||||
await expect(todoCount).toContainText("1");
|
||||
|
||||
await newTodo.fill(TODO_ITEMS[1]);
|
||||
await newTodo.press("Enter");
|
||||
await expect(todoCount).toContainText("2");
|
||||
|
||||
await checkNumberOfTodosInLocalStorage(page, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Clear completed button", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await createDefaultTodos(page);
|
||||
});
|
||||
|
||||
test("should display the correct text", async ({ page }) => {
|
||||
await page.locator(".todo-list li .toggle").first().check();
|
||||
await expect(
|
||||
page.getByRole("button", { name: "Clear completed" })
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("should remove completed items when clicked", async ({ page }) => {
|
||||
const todoItems = page.getByTestId("todo-item");
|
||||
await todoItems.nth(1).getByRole("checkbox").check();
|
||||
await page.getByRole("button", { name: "Clear completed" }).click();
|
||||
await expect(todoItems).toHaveCount(2);
|
||||
await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]);
|
||||
});
|
||||
|
||||
test("should be hidden when there are no items that are completed", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.locator(".todo-list li .toggle").first().check();
|
||||
await page.getByRole("button", { name: "Clear completed" }).click();
|
||||
await expect(
|
||||
page.getByRole("button", { name: "Clear completed" })
|
||||
).toBeHidden();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Persistence", () => {
|
||||
test("should persist its data", async ({ page }) => {
|
||||
// create a new todo locator
|
||||
const newTodo = page.getByPlaceholder("What needs to be done?");
|
||||
|
||||
for (const item of TODO_ITEMS.slice(0, 2)) {
|
||||
await newTodo.fill(item);
|
||||
await newTodo.press("Enter");
|
||||
}
|
||||
|
||||
const todoItems = page.getByTestId("todo-item");
|
||||
const firstTodoCheck = todoItems.nth(0).getByRole("checkbox");
|
||||
await firstTodoCheck.check();
|
||||
await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[1]]);
|
||||
await expect(firstTodoCheck).toBeChecked();
|
||||
await expect(todoItems).toHaveClass(["completed", ""]);
|
||||
|
||||
// Ensure there is 1 completed item.
|
||||
await checkNumberOfCompletedTodosInLocalStorage(page, 1);
|
||||
|
||||
// Now reload.
|
||||
await page.reload();
|
||||
await expect(todoItems).toHaveText([TODO_ITEMS[0], TODO_ITEMS[1]]);
|
||||
await expect(firstTodoCheck).toBeChecked();
|
||||
await expect(todoItems).toHaveClass(["completed", ""]);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Routing", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await createDefaultTodos(page);
|
||||
// make sure the app had a chance to save updated todos in storage
|
||||
// before navigating to a new view, otherwise the items can get lost :(
|
||||
// in some frameworks like Durandal
|
||||
await checkTodosInLocalStorage(page, TODO_ITEMS[0]);
|
||||
});
|
||||
|
||||
test("should allow me to display active items", async ({ page }) => {
|
||||
const todoItem = page.getByTestId("todo-item");
|
||||
await page.getByTestId("todo-item").nth(1).getByRole("checkbox").check();
|
||||
|
||||
await checkNumberOfCompletedTodosInLocalStorage(page, 1);
|
||||
await page.getByRole("link", { name: "Active" }).click();
|
||||
await expect(todoItem).toHaveCount(2);
|
||||
await expect(todoItem).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]);
|
||||
});
|
||||
|
||||
test("should respect the back button", async ({ page }) => {
|
||||
const todoItem = page.getByTestId("todo-item");
|
||||
await page.getByTestId("todo-item").nth(1).getByRole("checkbox").check();
|
||||
|
||||
await checkNumberOfCompletedTodosInLocalStorage(page, 1);
|
||||
|
||||
await test.step("Showing all items", async () => {
|
||||
await page.getByRole("link", { name: "All" }).click();
|
||||
await expect(todoItem).toHaveCount(3);
|
||||
});
|
||||
|
||||
await test.step("Showing active items", async () => {
|
||||
await page.getByRole("link", { name: "Active" }).click();
|
||||
});
|
||||
|
||||
await test.step("Showing completed items", async () => {
|
||||
await page.getByRole("link", { name: "Completed" }).click();
|
||||
});
|
||||
|
||||
await expect(todoItem).toHaveCount(1);
|
||||
await page.goBack();
|
||||
await expect(todoItem).toHaveCount(2);
|
||||
await page.goBack();
|
||||
await expect(todoItem).toHaveCount(3);
|
||||
});
|
||||
|
||||
test("should allow me to display completed items", async ({ page }) => {
|
||||
await page.getByTestId("todo-item").nth(1).getByRole("checkbox").check();
|
||||
await checkNumberOfCompletedTodosInLocalStorage(page, 1);
|
||||
await page.getByRole("link", { name: "Completed" }).click();
|
||||
await expect(page.getByTestId("todo-item")).toHaveCount(1);
|
||||
});
|
||||
|
||||
test("should allow me to display all items", async ({ page }) => {
|
||||
await page.getByTestId("todo-item").nth(1).getByRole("checkbox").check();
|
||||
await checkNumberOfCompletedTodosInLocalStorage(page, 1);
|
||||
await page.getByRole("link", { name: "Active" }).click();
|
||||
await page.getByRole("link", { name: "Completed" }).click();
|
||||
await page.getByRole("link", { name: "All" }).click();
|
||||
await expect(page.getByTestId("todo-item")).toHaveCount(3);
|
||||
});
|
||||
|
||||
test("should highlight the currently applied filter", async ({ page }) => {
|
||||
await expect(page.getByRole("link", { name: "All" })).toHaveClass(
|
||||
"selected"
|
||||
);
|
||||
|
||||
//create locators for active and completed links
|
||||
const activeLink = page.getByRole("link", { name: "Active" });
|
||||
const completedLink = page.getByRole("link", { name: "Completed" });
|
||||
await activeLink.click();
|
||||
|
||||
// Page change - active items.
|
||||
await expect(activeLink).toHaveClass("selected");
|
||||
await completedLink.click();
|
||||
|
||||
// Page change - completed items.
|
||||
await expect(completedLink).toHaveClass("selected");
|
||||
});
|
||||
});
|
||||
|
||||
async function createDefaultTodos(page: Page) {
|
||||
// create a new todo locator
|
||||
const newTodo = page.getByPlaceholder("What needs to be done?");
|
||||
|
||||
for (const item of TODO_ITEMS) {
|
||||
await newTodo.fill(item);
|
||||
await newTodo.press("Enter");
|
||||
}
|
||||
}
|
||||
|
||||
async function checkNumberOfTodosInLocalStorage(page: Page, expected: number) {
|
||||
return await page.waitForFunction((e) => {
|
||||
return JSON.parse(localStorage["react-todos"]).length === e;
|
||||
}, expected);
|
||||
}
|
||||
|
||||
async function checkNumberOfCompletedTodosInLocalStorage(
|
||||
page: Page,
|
||||
expected: number
|
||||
) {
|
||||
return await page.waitForFunction((e) => {
|
||||
return (
|
||||
JSON.parse(localStorage["react-todos"]).filter(
|
||||
(todo: any) => todo.completed
|
||||
).length === e
|
||||
);
|
||||
}, expected);
|
||||
}
|
||||
|
||||
async function checkTodosInLocalStorage(page: Page, title: string) {
|
||||
return await page.waitForFunction((t) => {
|
||||
return JSON.parse(localStorage["react-todos"])
|
||||
.map((todo: any) => todo.title)
|
||||
.includes(t);
|
||||
}, title);
|
||||
}
|
||||
32
frontend/tests/auth.spec.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { test, expect } from "./fixtures/auth";
|
||||
|
||||
test("redirect to login", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
await expect(page).toHaveURL(/\/login/);
|
||||
|
||||
await page.goto("/files/");
|
||||
await expect(page).toHaveURL(/\/login\?redirect=\/files\//);
|
||||
});
|
||||
|
||||
test("login and logout", async ({ authPage, page, context }) => {
|
||||
await authPage.goto();
|
||||
await expect(page).toHaveTitle(/Login - File Browser$/);
|
||||
|
||||
await authPage.loginAs("fake", "fake");
|
||||
await expect(authPage.wrongCredentials).toBeVisible();
|
||||
|
||||
await authPage.loginAs();
|
||||
await expect(authPage.wrongCredentials).toBeHidden();
|
||||
// await page.waitForURL("**/files/", { timeout: 5000 });
|
||||
await expect(page).toHaveTitle(/.*Files - File Browser$/);
|
||||
|
||||
let cookies = await context.cookies();
|
||||
expect(cookies.find((c) => c.name == "auth")?.value).toBeDefined();
|
||||
|
||||
await authPage.logout();
|
||||
// await page.waitForURL("**/login", { timeout: 5000 });
|
||||
await expect(page).toHaveTitle(/Login - File Browser$/);
|
||||
|
||||
cookies = await context.cookies();
|
||||
expect(cookies.find((c) => c.name == "auth")?.value).toBeUndefined();
|
||||
});
|
||||
40
frontend/tests/fixtures/auth.ts
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import {
|
||||
type Page,
|
||||
type Locator,
|
||||
test as base,
|
||||
expect,
|
||||
} from "@playwright/test";
|
||||
|
||||
export class AuthPage {
|
||||
public readonly wrongCredentials: Locator;
|
||||
|
||||
constructor(public readonly page: Page) {
|
||||
this.wrongCredentials = this.page.locator("div.wrong");
|
||||
}
|
||||
|
||||
async goto() {
|
||||
await this.page.goto("/login");
|
||||
}
|
||||
|
||||
async loginAs(username = "admin", password = "admin") {
|
||||
await this.page.getByPlaceholder("Username").fill(username);
|
||||
await this.page.getByPlaceholder("Password").fill(password);
|
||||
await this.page.getByRole("button", { name: "Login" }).click();
|
||||
}
|
||||
|
||||
async logout() {
|
||||
await this.page.getByRole("button", { name: "Logout" }).click();
|
||||
}
|
||||
}
|
||||
|
||||
const test = base.extend<{ authPage: AuthPage }>({
|
||||
authPage: async ({ page }, use) => {
|
||||
const authPage = new AuthPage(page);
|
||||
await authPage.goto();
|
||||
await authPage.loginAs();
|
||||
await use(authPage);
|
||||
// await authPage.logout();
|
||||
},
|
||||
});
|
||||
|
||||
export { test, expect };
|
||||
61
frontend/tests/fixtures/settings.ts
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
import {
|
||||
type Locator,
|
||||
type Page,
|
||||
test as base,
|
||||
expect,
|
||||
} from "@playwright/test";
|
||||
import { AuthPage } from "./auth";
|
||||
|
||||
type SettingsType = "profile" | "shares" | "global" | "users";
|
||||
|
||||
export class SettingsPage {
|
||||
public readonly hideDotfiles: Locator; // checkbox
|
||||
public readonly singleClick: Locator; // checkbox
|
||||
public readonly dateFormat: Locator; // checkbox
|
||||
private readonly languages: Locator; // selection
|
||||
private readonly submitProfile: Locator; // submit
|
||||
private readonly submitPassword: Locator; // submit
|
||||
|
||||
constructor(public readonly page: Page) {
|
||||
this.hideDotfiles = this.page.locator('input[name="hideDotfiles"]');
|
||||
this.singleClick = this.page.locator('input[name="singleClick"]');
|
||||
this.dateFormat = this.page.locator('input[name="dateFormat"]');
|
||||
this.languages = this.page.locator('select[name="selectLanguage"]');
|
||||
this.submitProfile = this.page.locator('input[name="submitProfile"]');
|
||||
this.submitPassword = this.page.locator('input[name="submitPassword"]');
|
||||
}
|
||||
|
||||
async goto(type: SettingsType = "profile") {
|
||||
await this.page.goto(`/settings/${type}`);
|
||||
}
|
||||
|
||||
async setLanguage(locale: string = "en") {
|
||||
await this.languages.selectOption(locale);
|
||||
}
|
||||
|
||||
async saveProfile() {
|
||||
await this.submitProfile.click();
|
||||
}
|
||||
|
||||
async savePassword() {
|
||||
await this.submitPassword.click();
|
||||
}
|
||||
}
|
||||
|
||||
const test = base.extend<{ settingsPage: SettingsPage }>({
|
||||
page: async ({ page }, use) => {
|
||||
// Sign in with our account.
|
||||
const authPage = new AuthPage(page);
|
||||
await authPage.goto();
|
||||
await authPage.loginAs();
|
||||
await expect(page).toHaveTitle(/.*Files - File Browser$/);
|
||||
// Use signed-in page in the test.
|
||||
await use(page);
|
||||
},
|
||||
settingsPage: async ({ page }, use) => {
|
||||
const settingsPage = new SettingsPage(page);
|
||||
await use(settingsPage);
|
||||
},
|
||||
});
|
||||
|
||||
export { test, expect };
|
||||
20
frontend/tests/fixtures/toast.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
//classes: Vue-Toastification__toast Vue-Toastification__toast--success bottom-center
|
||||
import { type Page, type Locator, expect } from "@playwright/test";
|
||||
|
||||
export class Toast {
|
||||
private readonly success: Locator;
|
||||
private readonly error: Locator;
|
||||
|
||||
constructor(public readonly page: Page) {
|
||||
this.success = this.page.locator("div.Vue-Toastification__toast--success");
|
||||
this.error = this.page.locator("div.Vue-Toastification__toast--error");
|
||||
}
|
||||
|
||||
async isSuccess() {
|
||||
await expect(this.success).toBeVisible();
|
||||
}
|
||||
|
||||
async isError() {
|
||||
await expect(this.error).toBeVisible();
|
||||
}
|
||||
}
|
||||
46
frontend/tests/settings.spec.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { test, expect } from "./fixtures/settings";
|
||||
import { Toast } from "./fixtures/toast";
|
||||
|
||||
// test.describe("profile settings", () => {
|
||||
test("settings button", async ({ page }) => {
|
||||
const button = page.getByLabel("Settings", { exact: true });
|
||||
await expect(button).toBeVisible();
|
||||
await button.click();
|
||||
await expect(page).toHaveTitle(/^Profile Settings/);
|
||||
await expect(
|
||||
page.getByRole("heading", { name: "Profile Settings" })
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("set locale", async ({ settingsPage, page }) => {
|
||||
const toast = new Toast(page);
|
||||
|
||||
await settingsPage.goto("profile");
|
||||
await expect(page).toHaveTitle(/^Profile Settings/);
|
||||
// await settingsPage.saveProfile();
|
||||
// await toast.isSuccess();
|
||||
// await expect(
|
||||
// page.getByText("Settings updated!", { exact: true })
|
||||
// ).toBeVisible();
|
||||
|
||||
await settingsPage.setLanguage("hu");
|
||||
await settingsPage.saveProfile();
|
||||
await toast.isSuccess();
|
||||
await expect(
|
||||
page.getByText("Beállítások frissítve!", { exact: true })
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("heading", { name: "Profilbeállítások" })
|
||||
).toBeVisible();
|
||||
|
||||
await settingsPage.setLanguage("en");
|
||||
await settingsPage.saveProfile();
|
||||
await toast.isSuccess();
|
||||
await expect(
|
||||
page.getByText("Settings updated!", { exact: true })
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("heading", { name: "Profile Settings" })
|
||||
).toBeVisible();
|
||||
});
|
||||
// });
|
||||
@@ -1,29 +1,13 @@
|
||||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
||||
"exclude": [
|
||||
"src/**/__tests__/*",
|
||||
// Excluding non-TS Vue files which use the old Options API.
|
||||
// This can be removed once those files are properly migrated to
|
||||
// the new Composition API with TS support.
|
||||
"src/components/Shell.vue",
|
||||
"src/components/prompts/Copy.vue",
|
||||
"src/components/prompts/Move.vue",
|
||||
"src/components/prompts/Delete.vue",
|
||||
"src/components/prompts/FileList.vue",
|
||||
"src/components/prompts/Rename.vue",
|
||||
"src/components/prompts/Share.vue"
|
||||
],
|
||||
"exclude": ["src/**/__tests__/*"],
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"types": ["vite/client", "@intlify/unplugin-vue-i18n/messages"],
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
},
|
||||
// Version 0.8.0 of @vue/tsconfig enabled this automatically.
|
||||
// Disabling for now since it's causing quite a lot of errors.
|
||||
// Should be revisited.
|
||||
"noUncheckedIndexedAccess": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
{
|
||||
"extends": "@tsconfig/node24/tsconfig.json",
|
||||
"extends": "@tsconfig/node22/tsconfig.json",
|
||||
"include": [
|
||||
"vite.config.*",
|
||||
"vitest.config.*",
|
||||
"cypress.config.*",
|
||||
"nightwatch.conf.*"
|
||||
"nightwatch.conf.*",
|
||||
"playwright.config.*"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
|
||||
14
frontend/tsconfig.tsc.json
Normal 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/Move.vue",
|
||||
"src/components/prompts/Delete.vue",
|
||||
"src/components/prompts/FileList.vue",
|
||||
"src/components/prompts/Rename.vue",
|
||||
"src/components/prompts/Share.vue"
|
||||
]
|
||||
}
|
||||
55
go.mod
@@ -1,35 +1,35 @@
|
||||
module github.com/filebrowser/filebrowser/v2
|
||||
|
||||
go 1.25
|
||||
go 1.24
|
||||
|
||||
require (
|
||||
github.com/asdine/storm/v3 v3.2.1
|
||||
github.com/asticode/go-astisub v0.38.0
|
||||
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/v5 v5.3.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/jellydator/ttlcache/v3 v3.4.0
|
||||
github.com/maruel/natural v1.2.1
|
||||
github.com/maruel/natural v1.1.1
|
||||
github.com/marusama/semaphore/v2 v2.5.0
|
||||
github.com/mholt/archives v0.1.5
|
||||
github.com/mholt/archives v0.1.3
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/pelletier/go-toml/v2 v2.2.4
|
||||
github.com/shirou/gopsutil/v4 v4.25.10
|
||||
github.com/spf13/afero v1.15.0
|
||||
github.com/spf13/cobra v1.10.1
|
||||
github.com/spf13/pflag v1.0.10
|
||||
github.com/spf13/viper v1.21.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/shirou/gopsutil/v3 v3.24.5
|
||||
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.4.3
|
||||
golang.org/x/crypto v0.44.0
|
||||
golang.org/x/image v0.33.0
|
||||
golang.org/x/text v0.31.0
|
||||
go.etcd.io/bbolt v1.4.2
|
||||
golang.org/x/crypto v0.40.0
|
||||
golang.org/x/image v0.29.0
|
||||
golang.org/x/text v0.27.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -44,7 +44,6 @@ require (
|
||||
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect
|
||||
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
|
||||
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 // indirect
|
||||
github.com/ebitengine/purego v0.9.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/go-errors/errors v1.5.1 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
@@ -57,22 +56,22 @@ require (
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/mikelolasagasti/xz v1.0.1 // indirect
|
||||
github.com/minio/minlz v1.0.1 // indirect
|
||||
github.com/nwaples/rardecode/v2 v2.2.0 // indirect
|
||||
github.com/nwaples/rardecode/v2 v2.1.1 // 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-20240221224432-82ca36839d55 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/sorairolake/lzip-go v0.3.8 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.9.0 // indirect
|
||||
github.com/sorairolake/lzip-go v0.3.7 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/cast v1.9.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/ulikunitz/xz v0.5.15 // indirect
|
||||
github.com/ulikunitz/xz v0.5.12 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||
golang.org/x/net v0.46.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/net v0.42.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
108
go.sum
@@ -31,8 +31,8 @@ github.com/asticode/go-astikit v0.20.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xbl
|
||||
github.com/asticode/go-astikit v0.30.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xblP7fCWbgwipF0=
|
||||
github.com/asticode/go-astikit v0.56.0 h1:DmD2p7YnvxiPdF0h+dRmos3bsejNEXbycENsY5JfBqw=
|
||||
github.com/asticode/go-astikit v0.56.0/go.mod h1:fV43j20UZYfXzP9oBn33udkvCvDvCDhzjVqoLFuuYZE=
|
||||
github.com/asticode/go-astisub v0.38.0 h1:Qh3IO8Cotn0wwok5maid7xqsIJTwn2DtABT1UajKJaI=
|
||||
github.com/asticode/go-astisub v0.38.0/go.mod h1:WTkuSzFB+Bp7wezuSf2Oxulj5A8zu2zLRVFf6bIFQK8=
|
||||
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=
|
||||
@@ -74,8 +74,6 @@ github.com/dsoprea/go-utility/v2 v2.0.0-20221003142440-7a1927d49d9d/go.mod h1:LV
|
||||
github.com/dsoprea/go-utility/v2 v2.0.0-20221003160719-7bc88537c05e/go.mod h1:VZ7cB0pTjm1ADBWhJUOHESu4ZYy9JN+ZPqjfiW09EPU=
|
||||
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 h1:DilThiXje0z+3UQ5YjYiSRRzVdtamFpvBQXKwMglWqw=
|
||||
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349/go.mod h1:4GC5sXji84i/p+irqghpPFZBF8tRN/Q7+700G0/DLe8=
|
||||
github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k=
|
||||
github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
@@ -97,8 +95,8 @@ 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.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||
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=
|
||||
@@ -115,8 +113,9 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
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 v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
|
||||
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
@@ -168,20 +167,20 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/maruel/natural v1.2.1 h1:G/y4pwtTA07lbQsMefvsmEO0VN0NfqpxprxXDM4R/4o=
|
||||
github.com/maruel/natural v1.2.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
|
||||
github.com/maruel/natural v1.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=
|
||||
github.com/marusama/semaphore/v2 v2.5.0/go.mod h1:z9nMiNUekt/LTpTUQdpp+4sJeYqUGpwMHfW0Z8V8fnQ=
|
||||
github.com/mholt/archives v0.1.5 h1:Fh2hl1j7VEhc6DZs2DLMgiBNChUux154a1G+2esNvzQ=
|
||||
github.com/mholt/archives v0.1.5/go.mod h1:3TPMmBLPsgszL+1As5zECTuKwKvIfj6YcwWPpeTAXF4=
|
||||
github.com/mholt/archives v0.1.3 h1:aEAaOtNra78G+TvV5ohmXrJOAzf++dIlYeDW3N9q458=
|
||||
github.com/mholt/archives v0.1.3/go.mod h1:LUCGp++/IbV/I0Xq4SzcIR6uwgeh2yjnQWamjRQfLTU=
|
||||
github.com/mikelolasagasti/xz v1.0.1 h1:Q2F2jX0RYJUG3+WsM+FJknv+6eVjsjXNDV0KJXZzkD0=
|
||||
github.com/mikelolasagasti/xz v1.0.1/go.mod h1:muAirjiOUxPRXwm9HdDtB3uoRPrGnL85XHtokL9Hcgc=
|
||||
github.com/minio/minlz v1.0.1 h1:OUZUzXcib8diiX+JYxyRLIdomyZYzHct6EShOKtQY2A=
|
||||
github.com/minio/minlz v1.0.1/go.mod h1:qT0aEB35q79LLornSzeDH75LBf3aH1MV+jB5w9Wasec=
|
||||
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/nwaples/rardecode/v2 v2.2.0 h1:4ufPGHiNe1rYJxYfehALLjup4Ls3ck42CWwjKiOqu0A=
|
||||
github.com/nwaples/rardecode/v2 v2.2.0/go.mod h1:7uz379lSxPe6j9nvzxUZ+n7mnJNgjsRNb6IbvGVHRmw=
|
||||
github.com/nwaples/rardecode/v2 v2.1.1 h1:OJaYalXdliBUXPmC8CZGQ7oZDxzX1/5mQmgn0/GASew=
|
||||
github.com/nwaples/rardecode/v2 v2.1.1/go.mod h1:7uz379lSxPe6j9nvzxUZ+n7mnJNgjsRNb6IbvGVHRmw=
|
||||
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.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
|
||||
@@ -194,29 +193,28 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
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/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA=
|
||||
github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM=
|
||||
github.com/sorairolake/lzip-go v0.3.8 h1:j5Q2313INdTA80ureWYRhX+1K78mUXfMoPZCw/ivWik=
|
||||
github.com/sorairolake/lzip-go v0.3.8/go.mod h1:JcBqGMV0frlxwrsE9sMWXDjqn3EeVf0/54YPsw66qkU=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
||||
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||
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/sorairolake/lzip-go v0.3.7 h1:vP2uiD/NoklLyzYMdgOWkZME0ulkSfVTTE4MNRKCwNs=
|
||||
github.com/sorairolake/lzip-go v0.3.7/go.mod h1:THOHr0FlNVCw2eOIEE9shFJAG1QxQg/pf2XUPAmNIqg=
|
||||
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.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/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@@ -227,15 +225,15 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
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.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY=
|
||||
github.com/ulikunitz/xz v0.5.15/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/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
@@ -244,16 +242,16 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
|
||||
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.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo=
|
||||
go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E=
|
||||
go.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I=
|
||||
go.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc=
|
||||
go4.org v0.0.0-20230225012048-214862532bf5/go.mod h1:F57wTi5Lrj6WLyswp5EYV1ncrEbFGHD4hhz6S1ZYeaU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@@ -262,8 +260,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU=
|
||||
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc=
|
||||
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -275,8 +273,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.33.0 h1:LXRZRnv1+zGd5XBUVRFmYEphyyKJjQjCRiOuAP3sZfQ=
|
||||
golang.org/x/image v0.33.0/go.mod h1:DD3OsTYT9chzuzTQt+zMcOlBHgfoKQb1gry8p76Y1sc=
|
||||
golang.org/x/image v0.29.0 h1:HcdsyR4Gsuys/Axh0rDEmlBmB68rW1U9BUdB3UVHsas=
|
||||
golang.org/x/image v0.29.0/go.mod h1:RVJROnf3SLK8d26OW91j4FrIHGbsJ8QnbEocVTOWQDA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -315,8 +313,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
|
||||
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -329,8 +327,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -356,8 +354,8 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
||||
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
@@ -368,8 +366,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
||||
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -434,6 +432,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
14
http/auth.go
@@ -9,8 +9,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/golang-jwt/jwt/v5/request"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/golang-jwt/jwt/v4/request"
|
||||
|
||||
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
"github.com/filebrowser/filebrowser/v2/users"
|
||||
@@ -69,19 +69,15 @@ func withUser(fn handleFunc) handleFunc {
|
||||
|
||||
var tk authToken
|
||||
token, err := request.ParseFromRequest(r, &extractor{}, keyFunc, request.WithClaims(&tk))
|
||||
|
||||
if err != nil || !token.Valid {
|
||||
return http.StatusUnauthorized, nil
|
||||
}
|
||||
|
||||
err = jwt.NewValidator(jwt.WithExpirationRequired()).Validate(tk)
|
||||
if err != nil {
|
||||
return http.StatusUnauthorized, nil
|
||||
}
|
||||
|
||||
expiresSoon := tk.ExpiresAt != nil && time.Until(tk.ExpiresAt.Time) < time.Hour
|
||||
expired := !tk.VerifyExpiresAt(time.Now().Add(time.Hour), true)
|
||||
updated := tk.IssuedAt != nil && tk.IssuedAt.Unix() < d.store.Users.LastUpdate(tk.User.ID)
|
||||
|
||||
if expiresSoon || updated {
|
||||
if expired || updated {
|
||||
w.Header().Add("X-Renew-Token", "true")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//go:build !dev
|
||||
// +build !dev
|
||||
|
||||
package http
|
||||
|
||||
|
||||
15
http/headers_dev.go
Normal file
@@ -0,0 +1,15 @@
|
||||
//go:build dev
|
||||
// +build dev
|
||||
|
||||
package http
|
||||
|
||||
// global headers to append to every response
|
||||
// cross-origin headers are necessary to be able to
|
||||
// access them from a different URL during development
|
||||
var globalHeaders = map[string]string{
|
||||
"Cache-Control": "no-cache, no-store, must-revalidate",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Headers": "*",
|
||||
"Access-Control-Allow-Methods": "*",
|
||||
"Access-Control-Allow-Credentials": "true",
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/shirou/gopsutil/v4/disk"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
"github.com/spf13/afero"
|
||||
|
||||
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:recommended",
|
||||
"group:allNonMajor",
|
||||
"group:allDigest",
|
||||
":disableDependencyDashboard",
|
||||
":semanticCommitTypeAll(chore)"
|
||||
],
|
||||
"postUpdateOptions": [
|
||||
"gomodUpdateImportPaths",
|
||||
"gomodTidy"
|
||||
]
|
||||
}
|
||||
14
scripts/bump_version.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if ! [ -x "$(command -v standard-version)" ]; then
|
||||
echo "standard-version is not installed. please run 'npm i -g standard-version'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
standard-version --dry-run --skip
|
||||
read -p "Continue (y/n)? " -n 1 -r
|
||||
echo ;
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
standard-version -s ;
|
||||
fi
|
||||
11
scripts/commitlint.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if ! [ -x "$(command -v commitlint)" ]; then
|
||||
echo "commitlint is not installed. please run 'npm i -g commitlint'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for commit_hash in $(git log --pretty=format:%H origin/master..HEAD); do
|
||||
commitlint -f ${commit_hash}~1 -t ${commit_hash}
|
||||
done
|
||||
8
settings.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"port": 80,
|
||||
"baseURL": "",
|
||||
"address": "",
|
||||
"log": "stdout",
|
||||
"database": "/database/filebrowser.db",
|
||||
"root": "/srv"
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
"github.com/asdine/storm/v3"
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/auth"
|
||||
"github.com/filebrowser/filebrowser/v2/settings"
|
||||
|
||||
37
tools.mk
Normal file
@@ -0,0 +1,37 @@
|
||||
include common.mk
|
||||
|
||||
# tools
|
||||
TOOLS_DIR := $(BASE_PATH)/tools
|
||||
TOOLS_GO_DEPS := $(TOOLS_DIR)/go.mod $(TOOLS_DIR)/go.sum
|
||||
TOOLS_BIN := $(TOOLS_DIR)/bin
|
||||
$(eval $(shell mkdir -p $(TOOLS_BIN)))
|
||||
PATH := $(TOOLS_BIN):$(PATH)
|
||||
export PATH
|
||||
|
||||
.PHONY: clean-tools
|
||||
clean-tools:
|
||||
$Q rm -rf $(TOOLS_BIN)
|
||||
|
||||
goimports=$(TOOLS_BIN)/goimports
|
||||
$(goimports): $(TOOLS_GO_DEPS)
|
||||
$Q cd $(TOOLS_DIR) && $(go) build -o $@ golang.org/x/tools/cmd/goimports
|
||||
|
||||
golangci-lint=$(TOOLS_BIN)/golangci-lint
|
||||
$(golangci-lint): $(TOOLS_GO_DEPS)
|
||||
$Q cd $(TOOLS_DIR) && $(go) build -o $@ github.com/golangci/golangci-lint/v2/cmd/golangci-lint
|
||||
|
||||
# js tools
|
||||
TOOLS_JS_DEPS=$(TOOLS_DIR)/node_modules/.modified
|
||||
$(TOOLS_JS_DEPS): $(TOOLS_DIR)/package.json $(TOOLS_DIR)/yarn.lock
|
||||
$Q cd ${TOOLS_DIR} && yarn install
|
||||
$Q touch -am $@
|
||||
|
||||
standard-version=$(TOOLS_BIN)/standard-version
|
||||
$(standard-version): $(TOOLS_JS_DEPS)
|
||||
$Q ln -sf $(TOOLS_DIR)/node_modules/.bin/standard-version $@
|
||||
$Q touch -am $@
|
||||
|
||||
commitlint=$(TOOLS_BIN)/commitlint
|
||||
$(commitlint): $(TOOLS_JS_DEPS)
|
||||
$Q ln -sf $(TOOLS_DIR)/node_modules/.bin/commitlint $@
|
||||
$Q touch -am $@
|
||||
207
tools/go.mod
Normal file
@@ -0,0 +1,207 @@
|
||||
module github.com/filebrowser/filebrowser/v2/tools
|
||||
|
||||
go 1.24
|
||||
|
||||
require (
|
||||
github.com/golangci/golangci-lint/v2 v2.1.6
|
||||
golang.org/x/tools v0.32.0
|
||||
)
|
||||
|
||||
require (
|
||||
4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
|
||||
4d63.com/gochecknoglobals v0.2.2 // indirect
|
||||
github.com/4meepo/tagalign v1.4.2 // indirect
|
||||
github.com/Abirdcfly/dupword v0.1.3 // indirect
|
||||
github.com/Antonboom/errname v1.1.0 // indirect
|
||||
github.com/Antonboom/nilnil v1.1.0 // indirect
|
||||
github.com/Antonboom/testifylint v1.6.1 // indirect
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
|
||||
github.com/GaijinEntertainment/go-exhaustruct/v3 v3.3.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.1 // indirect
|
||||
github.com/OpenPeeDeeP/depguard/v2 v2.2.1 // indirect
|
||||
github.com/alecthomas/chroma/v2 v2.17.2 // indirect
|
||||
github.com/alecthomas/go-check-sumtype v0.3.1 // indirect
|
||||
github.com/alexkohler/nakedret/v2 v2.0.6 // indirect
|
||||
github.com/alexkohler/prealloc v1.0.0 // indirect
|
||||
github.com/alingse/asasalint v0.0.11 // indirect
|
||||
github.com/alingse/nilnesserr v0.2.0 // indirect
|
||||
github.com/ashanbrown/forbidigo v1.6.0 // indirect
|
||||
github.com/ashanbrown/makezero v1.2.0 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bkielbasa/cyclop v1.2.3 // indirect
|
||||
github.com/blizzy78/varnamelen v0.8.0 // indirect
|
||||
github.com/bombsimon/wsl/v4 v4.7.0 // indirect
|
||||
github.com/breml/bidichk v0.3.3 // indirect
|
||||
github.com/breml/errchkjson v0.4.1 // indirect
|
||||
github.com/butuzov/ireturn v0.4.0 // indirect
|
||||
github.com/butuzov/mirror v1.3.0 // indirect
|
||||
github.com/catenacyber/perfsprint v0.9.1 // indirect
|
||||
github.com/ccojocar/zxcvbn-go v1.0.2 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/charithe/durationcheck v0.0.10 // indirect
|
||||
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
|
||||
github.com/charmbracelet/lipgloss v1.1.0 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.8.0 // indirect
|
||||
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
|
||||
github.com/charmbracelet/x/term v0.2.1 // indirect
|
||||
github.com/chavacava/garif v0.1.0 // indirect
|
||||
github.com/ckaznocha/intrange v0.3.1 // indirect
|
||||
github.com/curioswitch/go-reassign v0.3.0 // indirect
|
||||
github.com/daixiang0/gci v0.13.6 // indirect
|
||||
github.com/dave/dst v0.27.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/denis-tingaikin/go-header v0.5.0 // indirect
|
||||
github.com/dlclark/regexp2 v1.11.5 // indirect
|
||||
github.com/ettle/strcase v0.2.0 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/fatih/structtag v1.2.0 // indirect
|
||||
github.com/firefart/nonamedreturns v1.0.6 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||
github.com/fzipp/gocyclo v0.6.0 // indirect
|
||||
github.com/ghostiam/protogetter v0.3.15 // indirect
|
||||
github.com/go-critic/go-critic v0.13.0 // indirect
|
||||
github.com/go-toolsmith/astcast v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astcopy v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astequal v1.2.0 // indirect
|
||||
github.com/go-toolsmith/astfmt v1.1.0 // indirect
|
||||
github.com/go-toolsmith/astp v1.1.0 // indirect
|
||||
github.com/go-toolsmith/strparse v1.1.0 // indirect
|
||||
github.com/go-toolsmith/typep v1.1.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/gofrs/flock v0.12.1 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 // indirect
|
||||
github.com/golangci/go-printf-func-name v0.1.0 // indirect
|
||||
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect
|
||||
github.com/golangci/golines v0.0.0-20250217134842-442fd0091d95 // indirect
|
||||
github.com/golangci/misspell v0.6.0 // indirect
|
||||
github.com/golangci/plugin-module-register v0.1.1 // indirect
|
||||
github.com/golangci/revgrep v0.8.0 // indirect
|
||||
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/gordonklaus/ineffassign v0.1.0 // indirect
|
||||
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
|
||||
github.com/gostaticanalysis/comment v1.5.0 // indirect
|
||||
github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect
|
||||
github.com/gostaticanalysis/nilerr v0.1.1 // indirect
|
||||
github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
|
||||
github.com/hashicorp/go-version v1.7.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hexops/gotextdiff v1.0.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jgautheron/goconst v1.8.1 // indirect
|
||||
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
|
||||
github.com/jjti/go-spancheck v0.6.4 // indirect
|
||||
github.com/julz/importas v0.2.0 // indirect
|
||||
github.com/karamaru-alpha/copyloopvar v1.2.1 // indirect
|
||||
github.com/kisielk/errcheck v1.9.0 // indirect
|
||||
github.com/kkHAIKE/contextcheck v1.1.6 // indirect
|
||||
github.com/kulti/thelper v0.6.3 // indirect
|
||||
github.com/kunwardeep/paralleltest v1.0.14 // indirect
|
||||
github.com/lasiar/canonicalheader v1.1.2 // indirect
|
||||
github.com/ldez/exptostd v0.4.3 // indirect
|
||||
github.com/ldez/gomoddirectives v0.6.1 // indirect
|
||||
github.com/ldez/grignotin v0.9.0 // indirect
|
||||
github.com/ldez/tagliatelle v0.7.1 // indirect
|
||||
github.com/ldez/usetesting v0.4.3 // indirect
|
||||
github.com/leonklingele/grouper v1.1.2 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/macabu/inamedparam v0.2.0 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/manuelarte/funcorder v0.2.1 // indirect
|
||||
github.com/maratori/testableexamples v1.0.0 // indirect
|
||||
github.com/maratori/testpackage v1.1.1 // indirect
|
||||
github.com/matoous/godox v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/mgechev/revive v1.9.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/moricho/tparallel v0.3.2 // indirect
|
||||
github.com/muesli/termenv v0.16.0 // indirect
|
||||
github.com/nakabonne/nestif v0.3.1 // indirect
|
||||
github.com/nishanths/exhaustive v0.12.0 // indirect
|
||||
github.com/nishanths/predeclared v0.2.2 // indirect
|
||||
github.com/nunnatsa/ginkgolinter v0.19.1 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/polyfloyd/go-errorlint v1.8.0 // indirect
|
||||
github.com/prometheus/client_golang v1.12.1 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.32.1 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/quasilyte/go-ruleguard v0.4.4 // indirect
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect
|
||||
github.com/quasilyte/gogrep v0.5.0 // indirect
|
||||
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
|
||||
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
|
||||
github.com/raeperd/recvcheck v0.2.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||
github.com/ryancurrah/gomodguard v1.4.1 // indirect
|
||||
github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
|
||||
github.com/sanposhiho/wastedassign/v2 v2.1.0 // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 // indirect
|
||||
github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
|
||||
github.com/sashamelentyev/usestdlibvars v1.28.0 // indirect
|
||||
github.com/securego/gosec/v2 v2.22.3 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/sivchari/containedctx v1.0.3 // indirect
|
||||
github.com/sonatard/noctx v0.1.0 // indirect
|
||||
github.com/sourcegraph/go-diff v0.7.0 // indirect
|
||||
github.com/spf13/afero v1.14.0 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/cobra v1.9.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/spf13/viper v1.12.0 // indirect
|
||||
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
|
||||
github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/stretchr/testify v1.10.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.1 // indirect
|
||||
github.com/tdakkota/asciicheck v0.4.1 // indirect
|
||||
github.com/tetafro/godot v1.5.1 // indirect
|
||||
github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 // indirect
|
||||
github.com/timonwong/loggercheck v0.11.0 // indirect
|
||||
github.com/tomarrell/wrapcheck/v2 v2.11.0 // indirect
|
||||
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
|
||||
github.com/ultraware/funlen v0.2.0 // indirect
|
||||
github.com/ultraware/whitespace v0.2.0 // indirect
|
||||
github.com/uudashr/gocognit v1.2.0 // indirect
|
||||
github.com/uudashr/iface v1.3.1 // indirect
|
||||
github.com/xen0n/gosmopolitan v1.3.0 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
github.com/yagipy/maintidx v1.0.0 // indirect
|
||||
github.com/yeya24/promlinter v0.3.0 // indirect
|
||||
github.com/ykadowak/zerologlint v0.1.5 // indirect
|
||||
gitlab.com/bosi/decorder v0.4.2 // indirect
|
||||
go-simpler.org/musttag v0.13.1 // indirect
|
||||
go-simpler.org/sloglint v0.11.0 // indirect
|
||||
go.augendre.info/fatcontext v0.8.0 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/sync v0.13.0 // indirect
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
honnef.co/go/tools v0.6.1 // indirect
|
||||
mvdan.cc/gofumpt v0.8.0 // indirect
|
||||
mvdan.cc/unparam v0.0.0-20250301125049-0df0534333a4 // indirect
|
||||
)
|
||||
1003
tools/go.sum
Normal file
8
tools/package.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@commitlint/cli": "^15.0.0",
|
||||
"@commitlint/config-conventional": "^15.0.0",
|
||||
"standard-version": "^9.3.2"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||
}
|
||||
15
tools/tools.go
Normal file
@@ -0,0 +1,15 @@
|
||||
//go:build tools
|
||||
// +build tools
|
||||
|
||||
package tools
|
||||
|
||||
// Manage tool dependencies via go.mod.
|
||||
//
|
||||
// https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module
|
||||
// https://github.com/golang/go/issues/25922
|
||||
//
|
||||
// nolint
|
||||
import (
|
||||
_ "github.com/golangci/golangci-lint/v2/cmd/golangci-lint"
|
||||
_ "golang.org/x/tools/cmd/goimports"
|
||||
)
|
||||
1714
tools/yarn.lock
Normal file
@@ -2,12 +2,6 @@
|
||||
|
||||
Most of the configuration can be understood through the command line interface documentation. To access it, you need to install File Browser and run `filebrowser --help`. In this page, we cover some specific, more complex, topics.
|
||||
|
||||
## Flags as Environment Variables
|
||||
|
||||
In some situations, it is easier to use environment variables instead of flags. For example, if you're using our provided Docker image, it's easier for you to use environment variables to customize the settings instead of flags.
|
||||
|
||||
All flags should be available as environment variables prefixed with `FB_`. For example, the flag `--disable-thumbnails` is available as `FB_DISABLE_THUMBNAILS`.
|
||||
|
||||
## Custom Branding
|
||||
|
||||
You can customize File Browser to use your own branding. This includes the following:
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
</style>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/filebrowser/filebrowser/master/branding/banner.png" width="550"/>
|
||||
<img src="https://raw.githubusercontent.com/filebrowser/logo/master/banner.png" width="550"/>
|
||||
</p>
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> This project is on **maintenance-only** mode. For more information, read the information on [GitHub](https://github.com/filebrowser/filebrowser#project-status).
|
||||
> This project is currently on **maintenance-only** mode. For more information, read the information on [GitHub](https://github.com/filebrowser/filebrowser#project-status).
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ File Browser is a single binary and can be used as standalone executable. Howeve
|
||||
|
||||
## Binary
|
||||
|
||||
The quickest and easiest way to install File Browser is to use a package manager, or our download script, which automatically fetches the latest version of File Browser for your platform. Alternatively, you can manually download the binary from the [releases page](https://github.com/filebrowser/filebrowser/releases).
|
||||
The quickest and easiest way to install File Browser is to use a package manager, or our download script, which automatically fetches the latest version of File Browser for your platform.
|
||||
|
||||
=== "Brew"
|
||||
|
||||
|
||||