mirror of
https://github.com/photoprism/photoprism.git
synced 2026-01-23 02:24:24 +00:00
Merge remote-tracking branch 'origin/develop' into TestImprovements
This commit is contained in:
commit
6fd45a0940
787 changed files with 20740 additions and 15486 deletions
|
|
@ -59,7 +59,7 @@ compose.*.yaml
|
|||
__pycache__
|
||||
venv
|
||||
.venv
|
||||
.env
|
||||
.env*
|
||||
.tmp
|
||||
.nv
|
||||
.eslintcache
|
||||
|
|
|
|||
20
.editorconfig
Normal file
20
.editorconfig
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Top-most EditorConfig file, https://editorconfig.org
|
||||
root = true
|
||||
|
||||
# Use Unix-style newlines with a newline ending every file.
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = false
|
||||
|
||||
# Set rules by file type.
|
||||
[*.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{js,yaml,yml,md,txt}]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -27,7 +27,7 @@
|
|||
__pycache__
|
||||
venv
|
||||
.venv
|
||||
.env
|
||||
.env*
|
||||
.tmp
|
||||
.nv
|
||||
.eslintcache
|
||||
|
|
|
|||
|
|
@ -6,16 +6,9 @@ build/
|
|||
dist/
|
||||
bin/
|
||||
tests/upload-files/
|
||||
.tmp
|
||||
.gocache
|
||||
.var
|
||||
*.html
|
||||
*.md
|
||||
.*
|
||||
.idea
|
||||
.codex
|
||||
.local
|
||||
.config
|
||||
.github
|
||||
.tmp
|
||||
.local
|
||||
.cache
|
||||
.gocache
|
||||
.var
|
||||
|
|
|
|||
103
AGENTS.md
103
AGENTS.md
|
|
@ -1,11 +1,10 @@
|
|||
# PhotoPrism® Repository Guidelines
|
||||
# PhotoPrism® — Repository Guidelines
|
||||
|
||||
**Last Updated:** November 21, 2025
|
||||
**Last Updated:** December 8, 2025
|
||||
|
||||
## Purpose
|
||||
|
||||
This file tells automated coding agents (and humans) where to find the single sources of truth for building, testing, and contributing to PhotoPrism.
|
||||
Learn more: https://agents.md/
|
||||
This file tells automated coding agents (and humans) where to find the single sources of truth for building, testing, and contributing to this repository. Visit https://agents.md/ to learn more.
|
||||
|
||||
## Sources of Truth
|
||||
|
||||
|
|
@ -16,32 +15,44 @@ Learn more: https://agents.md/
|
|||
- Security: https://github.com/photoprism/photoprism/blob/develop/SECURITY.md
|
||||
- REST API: https://docs.photoprism.dev/ (Swagger), https://docs.photoprism.app/developer-guide/api/ (Docs)
|
||||
- Code Maps: [`CODEMAP.md`](CODEMAP.md) (Backend/Go), [`frontend/CODEMAP.md`](frontend/CODEMAP.md) (Frontend/JS)
|
||||
- Face Detection & Embeddings Notes: [`internal/ai/face/README.md`](internal/ai/face/README.md)
|
||||
- Vision Engine Guides: [`internal/ai/vision/openai/README.md`](internal/ai/vision/openai/README.md), [`internal/ai/vision/ollama/README.md`](internal/ai/vision/ollama/README.md)
|
||||
- Packages: `README.md` files under `internal/`, `pkg/`, and `frontend/src/`, e.g. [`internal/photoprism/README.md`](internal/photoprism/README.md), [`internal/photoprism/batch/README.md`](internal/photoprism/batch/README.md), [`internal/config/README.md`](internal/config/README.md), [`internal/server/README.md`](internal/server/README.md), [`internal/api/README.md`](internal/api/README.md), [`internal/thumb/README.md`](internal/thumb/README.md), [`internal/ffmpeg/README.md`](internal/ffmpeg/README.md), and [`frontend/src/common/README.md`](frontend/src/common/README.md).
|
||||
- Face Detection & Embeddings: [`internal/ai/face/README.md`](internal/ai/face/README.md)
|
||||
- Vision Config & Engines: [`internal/ai/vision/README.md`](internal/ai/vision/README.md), [`internal/ai/vision/openai/README.md`](internal/ai/vision/openai/README.md), [`internal/ai/vision/ollama/README.md`](internal/ai/vision/ollama/README.md)
|
||||
|
||||
> Quick Tip: to inspect GitHub issue details without leaving the terminal, run `curl -s https://api.github.com/repos/photoprism/photoprism/issues/<id>`.
|
||||
|
||||
### Specifications (Versioning & Usage)
|
||||
### Specifications, Versioning, & Writing Style
|
||||
|
||||
- In the main repo, `specs/` appears ignored because it is managed as a nested Git repository; change into `specs/` before staging or committing spec updates.
|
||||
- Availability: The `specs/` repository is private and is not guaranteed to be present in every clone or environment. Do not add `Makefile` targets in the main project that depend on `specs/` paths. When `specs/` is available, run its tools directly (e.g., `bash specs/scripts/lint-status.sh`).
|
||||
- If available, always use the latest spec version for a topic (highest `-vN`), as linked from `specs/README.md`.
|
||||
- Testing Guides: `specs/dev/backend-testing.md` (Backend/Go), `specs/dev/frontend-testing.md` (Frontend/JS)
|
||||
- Whenever the Change Management instructions for a document require it, publish changes as a new file with an incremented version suffix (e.g., `*-v3.md`) rather than overwriting the original file.
|
||||
- Older spec versions remain in the repo for historical reference but are not linked from the main TOC. Do not base new work on superseded files (e.g., `*-v1.md` when `*-v2.md` exists).
|
||||
- Auto-generated configuration and command references live under `specs/generated/`. Agents MUST NOT read, analyse, or modify anything in this directory; refer humans to `specs/generated/README.md` if regeneration is required.
|
||||
- Regenerate NOTICE files with `make notice` when dependencies change. Do not edit `NOTICE` or `frontend/NOTICE` manually.
|
||||
- In the main repo, `specs/` and other directories may appear to be ignored because they are nested Git repositories; if so, change directories before staging or committing updates.
|
||||
- Availability: The `specs/` repository is private and is not guaranteed to be present in every clone or environment. Do not add `Makefile` targets in the main project that depend on `specs/` paths. When `specs/` is available, you MAY run its tools manually (e.g., `bash specs/scripts/lint-status.sh`), but the main repo must remain buildable without `specs/`.
|
||||
- If available, always use the latest spec version for a topic (highest `-vN`), as linked from `specs/README.md`.
|
||||
- Testing Guides: `specs/dev/backend-testing.md` (Backend/Go), `specs/dev/frontend-testing.md` (Frontend/JS)
|
||||
- Whenever the Change Management instructions for a document require it, publish changes as a new file with an incremented version suffix (e.g., `*-v3.md`) rather than overwriting the original file.
|
||||
- Older spec versions remain in the repo for historical reference but are not linked from the main TOC. Do not base new work on superseded files (e.g., `*-v1.md` when `*-v2.md` exists).
|
||||
- Auto-generated configuration and command references live under `specs/generated/`. Agents MUST NOT read, analyse, or modify anything in this directory; refer humans to `specs/generated/README.md` if regeneration is required.
|
||||
- Regenerate `NOTICE` files with `make notice` when dependencies change (e.g., updates to `go.mod`, `go.sum`, `package-lock.json`, or other lockfiles). Do not edit `NOTICE` or `frontend/NOTICE` manually.
|
||||
- When writing CLI examples or scripts, place option flags before positional arguments unless the command requires a different order.
|
||||
|
||||
**Style note:** Document headings must use Title Case (capitalize words ≥4 letters in AP-style) across Markdown files to keep generated navigation and changelogs consistent.
|
||||
> Document headings must use **Title Case** (in APA or AP style) across Markdown files to keep generated navigation and changelogs consistent. Always spell the product name as `PhotoPrism`; this proper noun is an exception to generic naming rules.
|
||||
|
||||
**CLI note:** When writing CLI examples or scripts, place option flags before positional arguments unless the command requires a different order.
|
||||
## Safety & Data
|
||||
|
||||
- If `git status` shows unexpected changes, assume a human might be editing; if you think you caused them, ask for permission before using reset commands like `git checkout` or `git reset`.
|
||||
- Do not run `git config` (global or repo-level); changing Git configuration is prohibited for agents.
|
||||
- Do not run destructive commands against production data. Prefer ephemeral volumes and test fixtures for acceptance tests.
|
||||
- Never commit secrets, local configurations, or cache files. Use environment variables or a local `.env`.
|
||||
- Ensure `.env`, `.config`, `.local`, `.codex`, and `.gocache` are ignored in `.gitignore` and `.dockerignore`.
|
||||
- Prefer using existing caches, workers, and batching strategies referenced in code and `Makefile`.
|
||||
- Consider memory/CPU impact of changes; only suggest benchmarks or profiling when justified.
|
||||
|
||||
> If anything in this file conflicts with the `Makefile` or Sources of Truth, **ask** for clarification before proceeding.
|
||||
|
||||
## Project Structure & Languages
|
||||
|
||||
- Backend: Go (`internal/`, `pkg/`, `cmd/`) + MariaDB/SQLite
|
||||
- Package boundaries: Code in `pkg/*` MUST NOT import from `internal/*`.
|
||||
- If you need access to config/entity/DB, put new code in a package under `internal/` instead of `pkg/`.
|
||||
- GORM field naming: When adding struct fields that include uppercase abbreviations (e.g., `LabelNSFW`), set an explicit `gorm:"column:<name>"` tag so column names stay consistent (`label_nsfw` instead of `label_n_s_f_w`).
|
||||
- GORM field naming: When adding struct fields that include uppercase abbreviations (e.g., `LabelNSFW`, `UserID`, `URLHash`), set an explicit `gorm:"column:<name>"` tag so column names stay consistent (`label_nsfw`, `user_id`, `url_hash` instead of split-letter variants).
|
||||
- Frontend: Vue 3 + Vuetify 3 (`frontend/`)
|
||||
- Docker/compose for dev/CI; Traefik is used for local TLS (`*.localssl.dev`)
|
||||
|
||||
|
|
@ -64,16 +75,15 @@ Agents MAY run either:
|
|||
|
||||
Agents SHOULD detect the runtime and choose commands accordingly:
|
||||
|
||||
- **Inside container if** one of the following is true:
|
||||
- File exists: `/.dockerenv`
|
||||
- Project path equals (or is a direct child of): `/go/src/github.com/photoprism/photoprism`
|
||||
- **Inside container if** `/.dockerenv` exists (authoritative signal).
|
||||
- Path hint: when the project path is `/go/src/github.com/photoprism/photoprism` *and* `/.dockerenv` is absent, assume you are on the host with a bind mount; treat it as host mode and prefer host-side Docker commands.
|
||||
|
||||
#### Examples
|
||||
|
||||
Bash:
|
||||
|
||||
```bash
|
||||
if [ -f "/.dockerenv" ] || [ -d "/go/src/github.com/photoprism/photoprism/.git" ]; then
|
||||
if [ -f "/.dockerenv" ]; then
|
||||
echo "container"
|
||||
else
|
||||
echo "host"
|
||||
|
|
@ -85,8 +95,7 @@ Node.js:
|
|||
```js
|
||||
const fs = require("fs");
|
||||
const inContainer = fs.existsSync("/.dockerenv");
|
||||
const inDevPath = fs.existsSync("/go/src/github.com/photoprism/photoprism/.git");
|
||||
console.log(inContainer || inDevPath ? "container" : "host");
|
||||
console.log(inContainer ? "container" : "host");
|
||||
```
|
||||
|
||||
### Agent installation and invocation
|
||||
|
|
@ -132,10 +141,29 @@ console.log(inContainer || inDevPath ? "container" : "host");
|
|||
- Only if Traefik is running and the dev compose labels are active
|
||||
- Labels for `*.localssl.dev` are defined in the dev compose files, e.g. https://github.com/photoprism/photoprism/blob/develop/compose.yaml
|
||||
- Admin Login: Local compose files set `PHOTOPRISM_ADMIN_USER=admin` and `PHOTOPRISM_ADMIN_PASSWORD=photoprism`; if the credentials differ, inspect `compose.yaml` (or the active environment) for these variables before logging in.
|
||||
- Do not use the Docker CLI inside the container; starting/stopping services requires host Docker access.
|
||||
- Do not use the Docker CLI inside the container; starting/stopping services requires host Docker access. If you need to manage compose while inside the dev container, switch to host mode (or ask a human) instead of running `docker compose` there.
|
||||
|
||||
Note: Across our public documentation, official images, and in production, the command-line interface (CLI) name is `photoprism`. Other PhotoPrism binary names are only used in development builds for side-by-side comparisons of the Community Edition (CE) with PhotoPrism Plus (`photoprism-plus`) and PhotoPrism Pro (`photoprism-pro`).
|
||||
|
||||
### Operating Systems & Architectures
|
||||
|
||||
- Our guides and command examples generally assume the use of a Linux/Unix shell on a 64-bit AMD64 or ARM64 system.
|
||||
- For Windows-specifics, see the Developer Guide FAQ: https://docs.photoprism.app/developer-guide/faq/#can-your-development-environment-be-used-under-windows
|
||||
|
||||
## Code Style & Lint
|
||||
|
||||
- Go: run `make fmt-go swag-fmt` to reformat the backend code + Swagger annotations (see `Makefile` for additional targets)
|
||||
- Run `make lint-go` (golangci-lint) after Go changes; prefer `golangci-lint run ./internal/<pkg>/...` for focused edits.
|
||||
- Doc comments for packages and exported identifiers must be complete sentences that begin with the name of the thing being described and end with a period.
|
||||
- All newly added functions, including unexported helpers, must have a concise doc comment that explains their behavior.
|
||||
- For short examples inside comments, indent code rather than using backticks; godoc treats indented blocks as preformatted.
|
||||
- Branding: Always spell the product name as `PhotoPrism`; this proper noun is an exception to generic naming rules.
|
||||
- Every Go package must contain a `<package>.go` file in its root (for example, `internal/auth/jwt/jwt.go`) with the standard license header and a short package description comment explaining its purpose.
|
||||
- JS/Vue: use the lint/format scripts in `frontend/package.json` (ESLint + Prettier)
|
||||
- All added code and tests **must** be formatted according to our standards.
|
||||
|
||||
> Remember to update the `**Last Updated:**` line at the top whenever you edit these guidelines or other files containing a timestamp.
|
||||
|
||||
## Tests
|
||||
|
||||
- From within the Development Environment:
|
||||
|
|
@ -209,19 +237,6 @@ Note: Across our public documentation, official images, and in production, the c
|
|||
- `config.NewTestConfig("<pkg>")` defaults to SQLite with a per‑suite DSN like `.<pkg>.db`. Don’t assert an empty DSN for SQLite.
|
||||
- Clean up any per‑suite SQLite files in tests with `t.Cleanup(func(){ _ = os.Remove(dsn) })` if you capture the DSN.
|
||||
|
||||
## Code Style & Lint
|
||||
|
||||
- Go: run `make fmt-go swag-fmt` to reformat the backend code + Swagger annotations (see `Makefile` for additional targets)
|
||||
- Doc comments for packages and exported identifiers must be complete sentences that begin with the name of the thing being described and end with a period.
|
||||
- All newly added functions, including unexported helpers, must have a concise doc comment that explains their behavior.
|
||||
- For short examples inside comments, indent code rather than using backticks; godoc treats indented blocks as preformatted.
|
||||
- Branding: Always spell the product name as `PhotoPrism`; this proper noun is an exception to generic naming rules.
|
||||
- Every Go package must contain a `<package>.go` file in its root (for example, `internal/auth/jwt/jwt.go`) with the standard license header and a short package description comment explaining its purpose.
|
||||
- JS/Vue: use the lint/format scripts in `frontend/package.json` (ESLint + Prettier)
|
||||
- All added code and tests **must** be formatted according to our standards.
|
||||
|
||||
> Remember to update the `**Last Updated:**` line at the top whenever you edit these guidelines or other files containing a timestamp.
|
||||
|
||||
### Frontend Focus Management
|
||||
|
||||
- Dialogs must follow the shared focus pattern documented in `frontend/src/common/README.md`.
|
||||
|
|
@ -230,15 +245,6 @@ Note: Across our public documentation, official images, and in production, the c
|
|||
- Global shortcuts run through `onShortCut(ev)` in `common/view.js`; it only forwards Escape and `ctrl`/`meta` combinations, so do not rely on it for arbitrary keys.
|
||||
- When a dialog opens nested menus (for example, combobox suggestion lists), ensure they work with the global trap; see the README for troubleshooting tips.
|
||||
|
||||
## Safety & Data
|
||||
|
||||
- Never commit secrets, local configurations, or cache files. Use environment variables or a local `.env`.
|
||||
- Ensure `.env` and `.local` are ignored in `.gitignore` and `.dockerignore`.
|
||||
- Prefer using existing caches, workers, and batching strategies referenced in code and `Makefile`. Consider memory/CPU impact; suggest benchmarks or profiling only when justified.
|
||||
- Do not run destructive commands against production data. Prefer ephemeral volumes and test fixtures when running acceptance tests.
|
||||
|
||||
> If anything in this file conflicts with the `Makefile` or the Developer Guide, the `Makefile` and the documentation win. When unsure, **ask** for clarification before proceeding.
|
||||
|
||||
### Filesystem Permissions & io/fs Aliasing (Go)
|
||||
|
||||
- Always use our shared permission variables from `pkg/fs` when creating files/directories:
|
||||
|
|
@ -278,9 +284,6 @@ Note: Across our public documentation, official images, and in production, the c
|
|||
- `..` traversal skipped; `__MACOSX` skipped.
|
||||
- Per-file and total size limits enforced; directory entries created; nested paths extracted safely.
|
||||
|
||||
- Examples assume a Linux/Unix shell. For Windows specifics, see the Developer Guide FAQ:
|
||||
https://docs.photoprism.app/developer-guide/faq/#can-your-development-environment-be-used-under-windows
|
||||
|
||||
### HTTP Download — Security Checklist
|
||||
|
||||
- Use the shared safe HTTP helper instead of ad‑hoc `net/http` code:
|
||||
|
|
|
|||
10
CODEMAP.md
10
CODEMAP.md
|
|
@ -1,6 +1,6 @@
|
|||
PhotoPrism — Backend CODEMAP
|
||||
|
||||
**Last Updated:** November 21, 2025
|
||||
**Last Updated:** November 22, 2025
|
||||
|
||||
Purpose
|
||||
- Give agents and contributors a fast, reliable map of where things live and how they fit together, so you can add features, fix bugs, and write tests without spelunking.
|
||||
|
|
@ -40,8 +40,8 @@ High-Level Package Map (Go)
|
|||
- `internal/workers` — background schedulers (index, vision, sync, meta, backup)
|
||||
- `internal/auth` — ACL, sessions, OIDC
|
||||
- `internal/service` — cluster/portal, maps, hub, webdav
|
||||
- `internal/event` — logging, pub/sub, audit; canonical outcome tokens live in `pkg/log/status` (use helpers like `status.Error(err)` when the sanitized message should be the outcome)
|
||||
- `internal/ffmpeg`, `internal/thumb`, `internal/meta`, `internal/form`, `internal/mutex` — media, thumbs, metadata, forms, coordination
|
||||
- `internal/event` — logging, pub/sub, audit; canonical outcome tokens live in `pkg/log/status` (use helpers like `status.Error(err)` when the sanitized message should be the outcome). Docs: `internal/event/README.md`.
|
||||
- `internal/ffmpeg`, `internal/thumb`, `internal/meta`, `internal/form`, `internal/mutex` — media, thumbs, metadata, forms, coordination. Docs: `internal/ffmpeg/README.md`, `internal/meta/README.md`.
|
||||
- `pkg/*` — reusable utilities (must never import from `internal/*`), e.g. `pkg/clean`, `pkg/enum`, `pkg/fs`, `pkg/txt`, `pkg/http/header`
|
||||
|
||||
Templates & Static Assets
|
||||
|
|
@ -81,6 +81,10 @@ Configuration & Flags
|
|||
- ACL/mode aware: Values are filtered by user/session and may differ for public vs. authenticated users.
|
||||
- Don’t expose secrets: Treat it as client-visible; avoid sensitive data. To add fields, extend client values via `config.Register` rather than exposing Options directly.
|
||||
- Refresh cadence: The web UI (non‑mobile) also polls for updates every 10 minutes via `$config.update()` in `frontend/src/app.js`, complementing the websocket push.
|
||||
- OIDC Groups (Pro-Only)
|
||||
- Config options (tagged `pro`, flags hidden in CE): `oidc-group-claim` (default `groups`), `oidc-group` (required membership list), `oidc-group-role` (mapping `GROUP=ROLE`).
|
||||
- Parsing/helpers: `internal/auth/oidc/groups.go` normalizes IDs, detects Entra `_claim_names` overage, maps groups→roles, and enforces required membership in `internal/api/oidc_redirect.go`.
|
||||
- Overage: if `_claim_names.groups` is present and no groups are returned, login fails when required groups are configured; Graph fetch is not implemented yet.
|
||||
|
||||
Database & Migrations
|
||||
- Driver: GORM v1 (`github.com/jinzhu/gorm`). No `WithContext`. Use `db.Raw(stmt).Scan(&nop)` for raw SQL.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Ubuntu 25.10 (Questing Quokka)
|
||||
FROM photoprism/develop:251121-questing
|
||||
FROM photoprism/develop:251208-questing
|
||||
|
||||
# Harden npm usage by default (applies to npm ci / install in dev container)
|
||||
ENV NPM_CONFIG_IGNORE_SCRIPTS=true
|
||||
|
|
|
|||
27
Makefile
27
Makefile
|
|
@ -99,7 +99,7 @@ show-rev:
|
|||
show-build:
|
||||
@echo "$(BUILD_TAG)"
|
||||
test-all: test acceptance-run-chromium
|
||||
fmt: fmt-js fmt-go swag-fmt
|
||||
fmt: fmt-js fmt-go fmt-swag
|
||||
clean-local: clean-local-config clean-local-cache
|
||||
upgrade: dep-upgrade-js dep-upgrade
|
||||
devtools: install-go dep-npm
|
||||
|
|
@ -670,18 +670,18 @@ docker-preview-oracular:
|
|||
docker pull --platform=arm64 photoprism/develop:oracular
|
||||
docker pull --platform=arm64 photoprism/develop:oracular-slim
|
||||
scripts/docker/buildx-multi.sh photoprism linux/amd64,linux/arm64 preview-ce /oracular
|
||||
docker-preview-questing:
|
||||
docker pull --platform=amd64 photoprism/develop:questing
|
||||
docker pull --platform=amd64 photoprism/develop:questing-slim
|
||||
docker pull --platform=arm64 photoprism/develop:questing
|
||||
docker pull --platform=arm64 photoprism/develop:questing-slim
|
||||
scripts/docker/buildx-multi.sh photoprism linux/amd64,linux/arm64 preview-ce /questing "-t photoprism/photoprism:preview -t photoprism/photoprism:ubuntu"
|
||||
docker-preview-plucky:
|
||||
docker pull --platform=amd64 photoprism/develop:plucky
|
||||
docker pull --platform=amd64 photoprism/develop:plucky-slim
|
||||
docker pull --platform=arm64 photoprism/develop:plucky
|
||||
docker pull --platform=arm64 photoprism/develop:plucky-slim
|
||||
scripts/docker/buildx-multi.sh photoprism linux/amd64,linux/arm64 preview-ce /plucky
|
||||
docker-preview-questing:
|
||||
docker pull --platform=amd64 photoprism/develop:questing
|
||||
docker pull --platform=amd64 photoprism/develop:questing-slim
|
||||
docker pull --platform=arm64 photoprism/develop:questing
|
||||
docker pull --platform=arm64 photoprism/develop:questing-slim
|
||||
scripts/docker/buildx-multi.sh photoprism linux/amd64,linux/arm64 preview-ce /questing
|
||||
release: docker-release
|
||||
docker-release: docker-release-latest
|
||||
docker-release-all: docker-release-latest docker-release-other
|
||||
|
|
@ -752,18 +752,18 @@ docker-release-oracular:
|
|||
docker pull --platform=arm64 photoprism/develop:oracular
|
||||
docker pull --platform=arm64 photoprism/develop:oracular-slim
|
||||
scripts/docker/buildx-multi.sh photoprism linux/amd64,linux/arm64 ce /oracular
|
||||
docker-release-questing:
|
||||
docker pull --platform=amd64 photoprism/develop:questing
|
||||
docker pull --platform=amd64 photoprism/develop:questing-slim
|
||||
docker pull --platform=arm64 photoprism/develop:questing
|
||||
docker pull --platform=arm64 photoprism/develop:questing-slim
|
||||
scripts/docker/buildx-multi.sh photoprism linux/amd64,linux/arm64 ce /questing "-t photoprism/photoprism:latest -t photoprism/photoprism:ubuntu"
|
||||
docker-release-plucky:
|
||||
docker pull --platform=amd64 photoprism/develop:plucky
|
||||
docker pull --platform=amd64 photoprism/develop:plucky-slim
|
||||
docker pull --platform=arm64 photoprism/develop:plucky
|
||||
docker pull --platform=arm64 photoprism/develop:plucky-slim
|
||||
scripts/docker/buildx-multi.sh photoprism linux/amd64,linux/arm64 ce /plucky
|
||||
docker-release-questing:
|
||||
docker pull --platform=amd64 photoprism/develop:questing
|
||||
docker pull --platform=amd64 photoprism/develop:questing-slim
|
||||
docker pull --platform=arm64 photoprism/develop:questing
|
||||
docker pull --platform=arm64 photoprism/develop:questing-slim
|
||||
scripts/docker/buildx-multi.sh photoprism linux/amd64,linux/arm64 ce /questing
|
||||
start-traefik:
|
||||
$(DOCKER_COMPOSE) up -d --wait traefik
|
||||
stop-traefik:
|
||||
|
|
@ -949,6 +949,7 @@ fmt-go:
|
|||
go fmt ./pkg/... ./internal/... ./cmd/... ./.../internal/...
|
||||
gofmt -w -s pkg internal cmd
|
||||
goimports -w -local "github.com/photoprism" pkg internal cmd
|
||||
fmt-swag: swag-fmt
|
||||
tidy:
|
||||
go mod tidy
|
||||
users:
|
||||
|
|
|
|||
62
NOTICE
62
NOTICE
|
|
@ -9,7 +9,7 @@ The following 3rd-party software packages may be used by or distributed with
|
|||
PhotoPrism. Any information relevant to third-party vendors listed below are
|
||||
collected using common, reasonable means.
|
||||
|
||||
Date generated: 2025-11-12
|
||||
Date generated: 2025-12-10
|
||||
|
||||
================================================================================
|
||||
|
||||
|
|
@ -581,7 +581,7 @@ SOFTWARE.
|
|||
|
||||
Package: github.com/dsoprea/go-exif/v3
|
||||
Version: v3.0.1
|
||||
License: MIT (https://github.com/dsoprea/go-exif/blob/v3.0.1/v3/LICENSE)
|
||||
License: MIT (https://github.com/dsoprea/go-exif/blob/v3.0.1/LICENSE)
|
||||
|
||||
MIT LICENSE
|
||||
|
||||
|
|
@ -641,7 +641,7 @@ SOFTWARE.
|
|||
|
||||
Package: github.com/dsoprea/go-jpeg-image-structure/v2
|
||||
Version: v2.0.0-20221012074422-4f3f7e934102
|
||||
License: MIT (https://github.com/dsoprea/go-jpeg-image-structure/blob/4f3f7e934102/v2/LICENSE)
|
||||
License: MIT (https://github.com/dsoprea/go-jpeg-image-structure/blob/4f3f7e934102/LICENSE)
|
||||
|
||||
MIT LICENSE
|
||||
|
||||
|
|
@ -717,7 +717,7 @@ SOFTWARE.
|
|||
|
||||
Package: github.com/dsoprea/go-png-image-structure/v2
|
||||
Version: v2.0.0-20210512210324-29b889a6093d
|
||||
License: MIT (https://github.com/dsoprea/go-png-image-structure/blob/29b889a6093d/v2/LICENSE)
|
||||
License: MIT (https://github.com/dsoprea/go-png-image-structure/blob/29b889a6093d/LICENSE)
|
||||
|
||||
MIT LICENSE
|
||||
|
||||
|
|
@ -733,7 +733,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||
|
||||
Package: github.com/dsoprea/go-tiff-image-structure/v2
|
||||
Version: v2.0.0-20221003165014-8ecc4f52edca
|
||||
License: MIT (https://github.com/dsoprea/go-tiff-image-structure/blob/8ecc4f52edca/v2/LICENSE)
|
||||
License: MIT (https://github.com/dsoprea/go-tiff-image-structure/blob/8ecc4f52edca/LICENSE)
|
||||
|
||||
MIT License
|
||||
|
||||
|
|
@ -1206,8 +1206,8 @@ THE SOFTWARE.
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
Package: github.com/go-co-op/gocron/v2
|
||||
Version: v2.18.0
|
||||
License: MIT (https://github.com/go-co-op/gocron/blob/v2.18.0/LICENSE)
|
||||
Version: v2.18.2
|
||||
License: MIT (https://github.com/go-co-op/gocron/blob/v2.18.2/LICENSE)
|
||||
|
||||
MIT License
|
||||
|
||||
|
|
@ -2443,8 +2443,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
Package: github.com/golang/geo
|
||||
Version: v0.0.0-20251111181513-e7f3a1a58fb3
|
||||
License: Apache-2.0 (https://github.com/golang/geo/blob/e7f3a1a58fb3/LICENSE)
|
||||
Version: v0.0.0-20251209161508-25c597310d4b
|
||||
License: Apache-2.0 (https://github.com/golang/geo/blob/25c597310d4b/LICENSE)
|
||||
|
||||
|
||||
Apache License
|
||||
|
|
@ -5325,8 +5325,8 @@ License: Apache-2.0 (https://github.com/prometheus/client_model/blob/v0.6.2/LICE
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
Package: github.com/prometheus/common
|
||||
Version: v0.67.2
|
||||
License: Apache-2.0 (https://github.com/prometheus/common/blob/v0.67.2/LICENSE)
|
||||
Version: v0.67.4
|
||||
License: Apache-2.0 (https://github.com/prometheus/common/blob/v0.67.4/LICENSE)
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
|
|
@ -6376,8 +6376,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
Package: github.com/yalue/onnxruntime_go
|
||||
Version: v1.22.0
|
||||
License: MIT (https://github.com/yalue/onnxruntime_go/blob/v1.22.0/LICENSE)
|
||||
Version: v1.24.0
|
||||
License: MIT (https://github.com/yalue/onnxruntime_go/blob/v1.24.0/LICENSE)
|
||||
|
||||
Copyright (c) 2023 Nathan Otterness
|
||||
|
||||
|
|
@ -6610,8 +6610,8 @@ License: Apache-2.0 (https://github.com/zitadel/logging/blob/v0.6.2/LICENSE)
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
Package: github.com/zitadel/oidc/v3
|
||||
Version: v3.45.0
|
||||
License: Apache-2.0 (https://github.com/zitadel/oidc/blob/v3.45.0/LICENSE)
|
||||
Version: v3.45.1
|
||||
License: Apache-2.0 (https://github.com/zitadel/oidc/blob/v3.45.1/LICENSE)
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
|
|
@ -8188,8 +8188,8 @@ License: Apache-2.0 (https://github.com/go4org/go4/blob/214862532bf5/LICENSE)
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
Package: golang.org/x/crypto
|
||||
Version: v0.44.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/crypto/+/v0.44.0:LICENSE)
|
||||
Version: v0.46.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/crypto/+/v0.46.0:LICENSE)
|
||||
|
||||
Copyright 2009 The Go Authors.
|
||||
|
||||
|
|
@ -8222,8 +8222,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
Package: golang.org/x/image
|
||||
Version: v0.33.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/image/+/v0.33.0:LICENSE)
|
||||
Version: v0.34.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/image/+/v0.34.0:LICENSE)
|
||||
|
||||
Copyright 2009 The Go Authors.
|
||||
|
||||
|
|
@ -8256,8 +8256,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
Package: golang.org/x/mod/semver
|
||||
Version: v0.30.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/mod/+/v0.30.0:LICENSE)
|
||||
Version: v0.31.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/mod/+/v0.31.0:LICENSE)
|
||||
|
||||
Copyright 2009 The Go Authors.
|
||||
|
||||
|
|
@ -8290,8 +8290,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
Package: golang.org/x/net
|
||||
Version: v0.47.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/net/+/v0.47.0:LICENSE)
|
||||
Version: v0.48.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/net/+/v0.48.0:LICENSE)
|
||||
|
||||
Copyright 2009 The Go Authors.
|
||||
|
||||
|
|
@ -8324,8 +8324,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
Package: golang.org/x/oauth2
|
||||
Version: v0.32.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/oauth2/+/v0.32.0:LICENSE)
|
||||
Version: v0.33.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/oauth2/+/v0.33.0:LICENSE)
|
||||
|
||||
Copyright 2009 The Go Authors.
|
||||
|
||||
|
|
@ -8358,8 +8358,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
Package: golang.org/x/sync/errgroup
|
||||
Version: v0.18.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/sync/+/v0.18.0:LICENSE)
|
||||
Version: v0.19.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/sync/+/v0.19.0:LICENSE)
|
||||
|
||||
Copyright 2009 The Go Authors.
|
||||
|
||||
|
|
@ -8392,8 +8392,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
Package: golang.org/x/sys
|
||||
Version: v0.38.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/sys/+/v0.38.0:LICENSE)
|
||||
Version: v0.39.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/sys/+/v0.39.0:LICENSE)
|
||||
|
||||
Copyright 2009 The Go Authors.
|
||||
|
||||
|
|
@ -8426,8 +8426,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
--------------------------------------------------------------------------------
|
||||
|
||||
Package: golang.org/x/text
|
||||
Version: v0.31.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/text/+/v0.31.0:LICENSE)
|
||||
Version: v0.32.0
|
||||
License: BSD-3-Clause (https://cs.opensource.google/go/x/text/+/v0.32.0:LICENSE)
|
||||
|
||||
Copyright 2009 The Go Authors.
|
||||
|
||||
|
|
|
|||
122
assets/profiles/icc/NOTICE
Normal file
122
assets/profiles/icc/NOTICE
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
================================================================================
|
||||
================================================================================
|
||||
|
||||
Third-Party ICC Profiles for PhotoPrism
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The following 3rd-party ICC profiles may be used by or distributed with
|
||||
PhotoPrism. Any information relevant to third-party vendors listed below are
|
||||
collected using common, reasonable means.
|
||||
|
||||
Date generated: 2025-11-23
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Files: a98.icc (compatibleWithAdobeRGB1998.icc)
|
||||
Source: OpenICC "compatibleWithAdobeRGB1998.icc" via Debian icc-profiles-free
|
||||
URL: https://salsa.debian.org/debian/icc-profiles-free/-/blob/a7a3c11b8a6d3bc2937447183b87dc89de9d2388/icc-profiles-openicc/default_profiles/base/compatibleWithAdobeRGB1998.icc
|
||||
License: zlib/libpng
|
||||
Checksum (md5): 826a1e13374e3dc34f9872f31ec028c8
|
||||
|
||||
The zlib/libpng License
|
||||
|
||||
Copyright (c) Graeme Gill <graeme@argyllcms.com>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
The provided ICC Profiles in the package are called DATA in the following
|
||||
statement:
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
BECAUSE THE DATA IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE DATA, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE DATA "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE DATA IS WITH YOU. SHOULD THE
|
||||
DATA PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE DATA AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE DATA (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE DATA TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Files: adobecompat-v2.icc, adobecompat-v4.icc, applecompat-v2.icc, applecompat-v4.icc, cgats001compat-v2-micro.icc, colormatchcompat-v2.icc, colormatchcompat-v4.icc, dci-p3-v4.icc, displayp3-v2-magic.icc, displayp3-v2-micro.icc, displayp3-v4.icc, displayp3compat-v2-magic.icc, displayp3compat-v2-micro.icc, displayp3compat-v4.icc, prophoto-v2-magic.icc, prophoto-v2-micro.icc, prophoto-v4.icc, rec2020-g24-v4.icc, rec2020-v2-magic.icc, rec2020-v2-micro.icc, rec2020-v4.icc, rec2020compat-v2-magic.icc, rec2020compat-v2-micro.icc, rec2020compat-v4.icc, rec601ntsc-v2-magic.icc, rec601ntsc-v2-micro.icc, rec601ntsc-v4.icc, rec601pal-v2-magic.icc, rec601pal-v2-micro.icc, rec601pal-v4.icc, rec709-v2-magic.icc, rec709-v2-micro.icc, rec709-v4.icc, scrgb-v2.icc, sgrey-v2-magic.icc, sgrey-v2-micro.icc, sgrey-v2-nano.icc, sgrey-v4.icc, srgb-v2-magic.icc, srgb-v2-micro.icc, srgb-v2-nano.icc, srgb-v4.icc, widegamutcompat-v2.icc, widegamutcompat-v4.icc
|
||||
Source: Compact-ICC-Profiles via Debian icc-profiles-free
|
||||
URL: https://salsa.debian.org/debian/icc-profiles-free/-/tree/a7a3c11b8a6d3bc2937447183b87dc89de9d2388/Compact-ICC-Profiles/profiles
|
||||
License: CC0-1.0 (Public Domain Dedication)
|
||||
Checksums (md5):
|
||||
adobecompat-v2.icc 08220aa4b4e4259ec3c446a35197d89b
|
||||
adobecompat-v4.icc fbf912760a8d14e496ff389c29c3132d
|
||||
applecompat-v2.icc 21453c734d9364abceacc7ab837019ec
|
||||
applecompat-v4.icc fc399558e27a0d53748820cff2a98a2b
|
||||
cgats001compat-v2-micro.icc 56a85233ee08fa7527875be36cf426d6
|
||||
colormatchcompat-v2.icc 9f2a755b4b3069f46f4eaef11e24926d
|
||||
colormatchcompat-v4.icc 9e119efb0abaa31e955f8a30eeabc58c
|
||||
dci-p3-v4.icc bdedf9e7ad0b93ed8f85f8c3ebdc4223
|
||||
displayp3-v2-magic.icc 6748fcfd56d38770a02c023bbd6d0529
|
||||
displayp3-v2-micro.icc 2615293123ddc4366af3da39455c3d7a
|
||||
displayp3-v4.icc 32dc35d6a113b86cbc31bd1281e3baed
|
||||
displayp3compat-v2-magic.icc 05fb82a702e27438ecec47a2f120cdcd
|
||||
displayp3compat-v2-micro.icc 2ef6c295ac5d05760c1a4cf1668951a3
|
||||
displayp3compat-v4.icc c34c90451326b183916f05b3ae41d920
|
||||
prophoto-v2-magic.icc 15a31d407cf35662fbe4513f6204bfdf
|
||||
prophoto-v2-micro.icc 445c1a3f3f1a20aab68e76838d3ed334
|
||||
prophoto-v4.icc 8f4523255234753cd2d3111d8f09b184
|
||||
rec2020-g24-v4.icc 3c7afbfff612d10a10775c167d36b51e
|
||||
rec2020-v2-magic.icc 3b5846fb69faa53ebdfd29061f17b0e3
|
||||
rec2020-v2-micro.icc 13d1e96875c35f7d5ebaf0f6a3d16357
|
||||
rec2020-v4.icc 297c644758a979abe62349ca1ff416d5
|
||||
rec2020compat-v2-magic.icc 9aa85534e81c275bc0627badf157580a
|
||||
rec2020compat-v2-micro.icc fa39fc95daece7dcaff18e7265082368
|
||||
rec2020compat-v4.icc 66839229639bb55bc443b490fe302364
|
||||
rec601ntsc-v2-magic.icc 53ee12707ac87a8e3b3452af4a325e29
|
||||
rec601ntsc-v2-micro.icc af05afec2146917a67445ac6cb5ca61d
|
||||
rec601ntsc-v4.icc cc57dd6fa3d6f08e43e0f70b5376c00a
|
||||
rec601pal-v2-magic.icc f706fd528cedcd1c88dac50073112f94
|
||||
rec601pal-v2-micro.icc d193e01949eb5347b0d16d2b3ccdabcf
|
||||
rec601pal-v4.icc dd7cd61d6ee14a521c9fb5afa2803e8e
|
||||
rec709-v2-magic.icc 47f09046656a2f0d66117a9c1b15e137
|
||||
rec709-v2-micro.icc f91edc9f3ff1390c842bd9e8759688b0
|
||||
rec709-v4.icc 0339e2a70940aefd9237311889d065e6
|
||||
scrgb-v2.icc a841263101bdf48fb9b81486f5451f2d
|
||||
sgrey-v2-magic.icc ef6221686b517e4665480639202dacd5
|
||||
sgrey-v2-micro.icc ca08451dba57ca1e910330cda37515ad
|
||||
sgrey-v2-nano.icc 57d72e3f6437d65c618ebcdb1f6fa1bd
|
||||
sgrey-v4.icc b93b1e31e75243ea08fbdab9e82f7cbe
|
||||
srgb-v2-magic.icc 5967f401f9a54913a283942710cef93c
|
||||
srgb-v2-micro.icc e8de3a5b44d70610306b0a20225701d1
|
||||
srgb-v2-nano.icc e060a57b7a057f7f0bdb859b68db60e9
|
||||
srgb-v4.icc 3c6a277ddee033ad090ba22b8323dcaf
|
||||
widegamutcompat-v2.icc 63c0165987ee94c8c7f2c68749e0418d
|
||||
widegamutcompat-v4.icc 4ccb168ae2f7daa51d3cef7df6fa6f16
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
BIN
assets/profiles/icc/a98.icc
Normal file
BIN
assets/profiles/icc/a98.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/adobecompat-v2.icc
Normal file
BIN
assets/profiles/icc/adobecompat-v2.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/adobecompat-v4.icc
Normal file
BIN
assets/profiles/icc/adobecompat-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/applecompat-v2.icc
Normal file
BIN
assets/profiles/icc/applecompat-v2.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/applecompat-v4.icc
Normal file
BIN
assets/profiles/icc/applecompat-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/cgats001compat-v2-micro.icc
Normal file
BIN
assets/profiles/icc/cgats001compat-v2-micro.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/colormatchcompat-v2.icc
Normal file
BIN
assets/profiles/icc/colormatchcompat-v2.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/colormatchcompat-v4.icc
Normal file
BIN
assets/profiles/icc/colormatchcompat-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/dci-p3-v4.icc
Normal file
BIN
assets/profiles/icc/dci-p3-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/displayp3-v2-magic.icc
Normal file
BIN
assets/profiles/icc/displayp3-v2-magic.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/displayp3-v2-micro.icc
Normal file
BIN
assets/profiles/icc/displayp3-v2-micro.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/displayp3-v4.icc
Normal file
BIN
assets/profiles/icc/displayp3-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/displayp3compat-v2-magic.icc
Normal file
BIN
assets/profiles/icc/displayp3compat-v2-magic.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/displayp3compat-v2-micro.icc
Normal file
BIN
assets/profiles/icc/displayp3compat-v2-micro.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/displayp3compat-v4.icc
Normal file
BIN
assets/profiles/icc/displayp3compat-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/prophoto-v2-magic.icc
Normal file
BIN
assets/profiles/icc/prophoto-v2-magic.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/prophoto-v2-micro.icc
Normal file
BIN
assets/profiles/icc/prophoto-v2-micro.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/prophoto-v4.icc
Normal file
BIN
assets/profiles/icc/prophoto-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec2020-g24-v4.icc
Normal file
BIN
assets/profiles/icc/rec2020-g24-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec2020-v2-magic.icc
Normal file
BIN
assets/profiles/icc/rec2020-v2-magic.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec2020-v2-micro.icc
Normal file
BIN
assets/profiles/icc/rec2020-v2-micro.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec2020-v4.icc
Normal file
BIN
assets/profiles/icc/rec2020-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec2020compat-v2-magic.icc
Normal file
BIN
assets/profiles/icc/rec2020compat-v2-magic.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec2020compat-v2-micro.icc
Normal file
BIN
assets/profiles/icc/rec2020compat-v2-micro.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec2020compat-v4.icc
Normal file
BIN
assets/profiles/icc/rec2020compat-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec601ntsc-v2-magic.icc
Normal file
BIN
assets/profiles/icc/rec601ntsc-v2-magic.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec601ntsc-v2-micro.icc
Normal file
BIN
assets/profiles/icc/rec601ntsc-v2-micro.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec601ntsc-v4.icc
Normal file
BIN
assets/profiles/icc/rec601ntsc-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec601pal-v2-magic.icc
Normal file
BIN
assets/profiles/icc/rec601pal-v2-magic.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec601pal-v2-micro.icc
Normal file
BIN
assets/profiles/icc/rec601pal-v2-micro.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec601pal-v4.icc
Normal file
BIN
assets/profiles/icc/rec601pal-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec709-v2-magic.icc
Normal file
BIN
assets/profiles/icc/rec709-v2-magic.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec709-v2-micro.icc
Normal file
BIN
assets/profiles/icc/rec709-v2-micro.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/rec709-v4.icc
Normal file
BIN
assets/profiles/icc/rec709-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/scrgb-v2.icc
Normal file
BIN
assets/profiles/icc/scrgb-v2.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/sgrey-v2-magic.icc
Normal file
BIN
assets/profiles/icc/sgrey-v2-magic.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/sgrey-v2-micro.icc
Normal file
BIN
assets/profiles/icc/sgrey-v2-micro.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/sgrey-v2-nano.icc
Normal file
BIN
assets/profiles/icc/sgrey-v2-nano.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/sgrey-v4.icc
Normal file
BIN
assets/profiles/icc/sgrey-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/srgb-v2-magic.icc
Normal file
BIN
assets/profiles/icc/srgb-v2-magic.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/srgb-v2-micro.icc
Normal file
BIN
assets/profiles/icc/srgb-v2-micro.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/srgb-v2-nano.icc
Normal file
BIN
assets/profiles/icc/srgb-v2-nano.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/srgb-v4.icc
Normal file
BIN
assets/profiles/icc/srgb-v4.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/widegamutcompat-v2.icc
Normal file
BIN
assets/profiles/icc/widegamutcompat-v2.icc
Normal file
Binary file not shown.
BIN
assets/profiles/icc/widegamutcompat-v4.icc
Normal file
BIN
assets/profiles/icc/widegamutcompat-v4.icc
Normal file
Binary file not shown.
|
|
@ -121,7 +121,7 @@ services:
|
|||
PHOTOPRISM_THUMB_UNCACHED: "true" # enables on-demand thumbnail rendering (high memory and cpu usage)
|
||||
## Run/install on first startup (options: update tensorflow https intel gpu davfs yt-dlp):
|
||||
PHOTOPRISM_INIT: "https tensorflow-gpu"
|
||||
## Computer Vision API (https://docs.photoprism.app/getting-started/config-options/#computer-vision):
|
||||
## Computer Vision (https://docs.photoprism.app/getting-started/config-options/#computer-vision):
|
||||
PHOTOPRISM_VISION_API: "true" # server: enables service API endpoints under /api/v1/vision (requires access token)
|
||||
PHOTOPRISM_VISION_URI: "" # client: service URI, e.g. http://hostname/api/v1/vision (leave blank to disable)
|
||||
PHOTOPRISM_VISION_KEY: "" # client: service access token (for authentication)
|
||||
|
|
|
|||
|
|
@ -68,6 +68,12 @@ services:
|
|||
PHOTOPRISM_JPEG_SIZE: 7680 # size limit for converted image files in pixels (720-30000)
|
||||
## Run/install on first startup (options: update tensorflow https intel gpu davfs yt-dlp):
|
||||
PHOTOPRISM_INIT: "https"
|
||||
## Computer Vision (https://docs.photoprism.app/getting-started/config-options/#computer-vision):
|
||||
PHOTOPRISM_VISION_API: "true" # server: enables service API endpoints under /api/v1/vision (requires access token)
|
||||
PHOTOPRISM_VISION_URI: "" # client: service URI, e.g. http://hostname/api/v1/vision (leave blank to disable)
|
||||
PHOTOPRISM_VISION_KEY: "" # client: service access token (for authentication)
|
||||
OLLAMA_BASE_URL: "http://ollama:11434" # use "https://ollama.com" for Ollama Cloud
|
||||
OLLAMA_API_KEY: "" # API key required to access Ollama (optional)
|
||||
## External dependencies and tools:
|
||||
TF_CPP_MIN_LOG_LEVEL: 1
|
||||
GOCACHE: "/go/src/github.com/photoprism/photoprism/.local/gocache"
|
||||
|
|
@ -85,7 +91,7 @@ services:
|
|||
|
||||
## Dummy WebDAV Server
|
||||
dummy-webdav:
|
||||
image: photoprism/dummy-webdav:231015
|
||||
image: photoprism/dummy-webdav:251210
|
||||
environment:
|
||||
WEBDAV_USERNAME: admin
|
||||
WEBDAV_PASSWORD: photoprism
|
||||
|
|
|
|||
22
compose.yaml
22
compose.yaml
|
|
@ -131,10 +131,12 @@ services:
|
|||
# PHOTOPRISM_FFMPEG_BITRATE: "64" # video bitrate limit in Mbps (default: 60)
|
||||
## Run/install on first startup (options: update tensorflow https intel gpu davfs yt-dlp):
|
||||
PHOTOPRISM_INIT: "https"
|
||||
## Computer Vision API (https://docs.photoprism.app/getting-started/config-options/#computer-vision):
|
||||
## Computer Vision (https://docs.photoprism.app/getting-started/config-options/#computer-vision):
|
||||
PHOTOPRISM_VISION_API: "true" # server: enables service API endpoints under /api/v1/vision (requires access token)
|
||||
PHOTOPRISM_VISION_URI: "" # client: service URI, e.g. http://hostname/api/v1/vision (leave blank to disable)
|
||||
PHOTOPRISM_VISION_KEY: "" # client: service access token (for authentication)
|
||||
OLLAMA_BASE_URL: "http://ollama:11434" # use "https://ollama.com" for Ollama Cloud
|
||||
OLLAMA_API_KEY: "" # API key required to access Ollama (optional)
|
||||
## External dependencies and tools:
|
||||
TF_CPP_MIN_LOG_LEVEL: 1
|
||||
GOCACHE: "/go/src/github.com/photoprism/photoprism/.local/gocache"
|
||||
|
|
@ -154,7 +156,7 @@ services:
|
|||
## Release Notes: https://mariadb.com/kb/en/changes-improvements-in-mariadb-1011/
|
||||
mariadb:
|
||||
image: mariadb:11
|
||||
stop_grace_period: 15s
|
||||
stop_grace_period: 10s
|
||||
security_opt: # see https://github.com/MariaDB/mariadb-docker/issues/434#issuecomment-1136151239
|
||||
- seccomp:unconfined
|
||||
- apparmor:unconfined
|
||||
|
|
@ -181,7 +183,7 @@ services:
|
|||
qdrant:
|
||||
image: qdrant/qdrant:latest
|
||||
profiles: [ "all", "qdrant" ]
|
||||
stop_grace_period: 15s
|
||||
stop_grace_period: 10s
|
||||
links:
|
||||
- "traefik:localssl.dev"
|
||||
- "traefik:app.localssl.dev"
|
||||
|
|
@ -335,8 +337,8 @@ services:
|
|||
|
||||
## Dummy WebDAV Server
|
||||
dummy-webdav:
|
||||
image: photoprism/dummy-webdav:240627
|
||||
stop_grace_period: 30s
|
||||
image: photoprism/dummy-webdav:251210
|
||||
stop_grace_period: 10s
|
||||
environment:
|
||||
WEBDAV_USERNAME: admin
|
||||
WEBDAV_PASSWORD: photoprism
|
||||
|
|
@ -352,8 +354,8 @@ services:
|
|||
|
||||
## Dummy OIDC Identity Provider
|
||||
dummy-oidc:
|
||||
image: photoprism/dummy-oidc:240627
|
||||
stop_grace_period: 30s
|
||||
image: photoprism/dummy-oidc:251210
|
||||
stop_grace_period: 5s
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.services.dummy-oidc.loadbalancer.server.port=9998"
|
||||
|
|
@ -368,7 +370,7 @@ services:
|
|||
## Docs: https://glauth.github.io/docs/
|
||||
dummy-ldap:
|
||||
image: glauth/glauth-plugins:latest
|
||||
stop_grace_period: 15s
|
||||
stop_grace_period: 5s
|
||||
ports:
|
||||
- "127.0.0.1:389:389"
|
||||
labels:
|
||||
|
|
@ -388,7 +390,7 @@ services:
|
|||
## Login with "user / photoprism" and "admin / photoprism".
|
||||
keycloak:
|
||||
image: quay.io/keycloak/keycloak:25.0
|
||||
stop_grace_period: 20s
|
||||
stop_grace_period: 10s
|
||||
profiles: [ "all", "auth", "keycloak" ]
|
||||
command: "start-dev" # development mode, do not use this in production!
|
||||
links:
|
||||
|
|
@ -421,7 +423,7 @@ services:
|
|||
## ./photoprism client add --id=cs5cpu17n6gj2qo5 --secret=xcCbOrw6I0vcoXzhnOmXhjpVSyFq0l0e -s metrics -n Prometheus -e 60 -t 1
|
||||
prometheus:
|
||||
image: prom/prometheus:latest
|
||||
stop_grace_period: 15s
|
||||
stop_grace_period: 10s
|
||||
profiles: [ "all", "auth", "prometheus" ]
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@ FROM golang:1.22-alpine
|
|||
|
||||
RUN go install github.com/skibish/ddns@latest
|
||||
|
||||
CMD ["ddns", "-conf-file", "/config/ddns.yml"]
|
||||
CMD ["ddns", "-conf-file", "/config/ddns.yml"]
|
||||
|
|
|
|||
|
|
@ -79,4 +79,4 @@ WORKDIR /photoprism
|
|||
EXPOSE 2342 2442 2443
|
||||
|
||||
# Keep container running.
|
||||
CMD ["tail", "-f", "/dev/null"]
|
||||
CMD ["tail", "-f", "/dev/null"]
|
||||
|
|
|
|||
|
|
@ -99,4 +99,4 @@ WORKDIR /photoprism
|
|||
EXPOSE 2342 2443
|
||||
|
||||
# keep container running
|
||||
CMD ["tail", "-f", "/dev/null"]
|
||||
CMD ["tail", "-f", "/dev/null"]
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
|
|||
TF_CPP_MIN_LOG_LEVEL=4 \
|
||||
TF_ENABLE_ONEDNN_OPTS=1 \
|
||||
MALLOC_ARENA_MAX=2 \
|
||||
PROG="photoprism" \
|
||||
PROG="photoprism"
|
||||
S6_KEEP_ENV=0 \
|
||||
S6_VERBOSITY=0 \
|
||||
S6_LOGGING=0
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
|
|||
GOBIN="/usr/local/bin" \
|
||||
GO111MODULE="on" \
|
||||
CGO_CFLAGS="-g -O2 -Wno-return-local-addr" \
|
||||
PROG="photoprism" \
|
||||
PROG="photoprism"
|
||||
S6_KEEP_ENV=1 \
|
||||
S6_VERBOSITY=0 \
|
||||
S6_LOGGING=0
|
||||
|
|
|
|||
|
|
@ -1,26 +1,23 @@
|
|||
module caos-test-op
|
||||
|
||||
go 1.17
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
github.com/caos/oidc v0.15.10
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/zitadel/oidc v1.13.5
|
||||
gopkg.in/square/go-jose.v2 v2.6.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/caos/logging v0.3.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/gorilla/handlers v1.5.2 // indirect
|
||||
github.com/gorilla/schema v1.2.1 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/gorilla/schema v1.4.1 // indirect
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
github.com/rs/cors v1.11.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
golang.org/x/crypto v0.18.0 // indirect
|
||||
golang.org/x/net v0.20.0 // indirect
|
||||
golang.org/x/oauth2 v0.16.0 // indirect
|
||||
golang.org/x/sys v0.16.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/protobuf v1.32.0 // indirect
|
||||
github.com/stretchr/testify v1.11.1 // indirect
|
||||
github.com/zitadel/logging v0.6.2 // indirect
|
||||
golang.org/x/crypto v0.46.0 // indirect
|
||||
golang.org/x/oauth2 v0.34.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,476 +1,46 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/caos/logging v0.0.2 h1:ebg5C/HN0ludYR+WkvnFjwSExF4wvyiWPyWGcKMYsoo=
|
||||
github.com/caos/logging v0.0.2/go.mod h1:9LKiDE2ChuGv6CHYif/kiugrfEXu9AwDiFWSreX7Wp0=
|
||||
github.com/caos/logging v0.3.1 h1:892AMeHs09D0e3ZcGB+QDRsZ5+2xtPAsAhOy8eKfztc=
|
||||
github.com/caos/logging v0.3.1/go.mod h1:B8QNS0WDmR2Keac52Fw+XN4ZJkzLDGrcRIPB2Ux4uRo=
|
||||
github.com/caos/oidc v0.15.10 h1:dSzkIvsZR2PSZgvBFFkLJt8A/MujsyLac1yNvBShXuw=
|
||||
github.com/caos/oidc v0.15.10/go.mod h1:4l0PPwdc6BbrdCFhNrRTUddsG292uHGa7gE2DSEIqoU=
|
||||
github.com/caos/oidc v1.3.0 h1:6I4S5XPjFQZx/GZVZaRvemFWYTlO27UvZILrWYL+P60=
|
||||
github.com/caos/oidc v1.3.0/go.mod h1:/EWr+09pcXQbSpCgGna6D+d726NtFAR4KRdG9D0x3OE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
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/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
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/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github/v31 v31.0.0/go.mod h1:NQPZol8/1sMoWYGN2yaALIBytu17gAWfhbweiEed3pM=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
|
||||
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
|
||||
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
|
||||
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
|
||||
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/gorilla/schema v1.2.1 h1:tjDxcmdb+siIqkTNoV+qRH2mjYdr2hHe5MKXbp61ziM=
|
||||
github.com/gorilla/schema v1.2.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM=
|
||||
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E=
|
||||
github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM=
|
||||
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
||||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
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/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
|
||||
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
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.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
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-20201217014255-9d1352758620 h1:3wPMTskHO3+O6jqTEXyFcsnuxMQOqYSaHsDxcbUXpqA=
|
||||
golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
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=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
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/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=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
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=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
|
||||
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
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-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
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=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191206220618-eeba5f6aabab/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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/zitadel/logging v0.6.2 h1:MW2kDDR0ieQynPZ0KIZPrh9ote2WkxfBif5QoARDQcU=
|
||||
github.com/zitadel/logging v0.6.2/go.mod h1:z6VWLWUkJpnNVDSLzrPSQSQyttysKZ6bCRongw0ROK4=
|
||||
github.com/zitadel/oidc v1.13.5 h1:7jhh68NGZitLqwLiVU9Dtwa4IraJPFF1vS+4UupO93U=
|
||||
github.com/zitadel/oidc v1.13.5/go.mod h1:rHs1DhU3Sv3tnI6bQRVlFa3u0lCwtR7S21WHY+yXgPA=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
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/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
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/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
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/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
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-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
||||
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
|||
104
docker/dummy/oidc/app/mock/client.go
Normal file
104
docker/dummy/oidc/app/mock/client.go
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
package mock
|
||||
|
||||
// revive:disable
|
||||
// Dummy storage implementation for the test OIDC provider; lint strictness is relaxed intentionally.
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/oidc/pkg/oidc"
|
||||
"github.com/zitadel/oidc/pkg/op"
|
||||
)
|
||||
|
||||
// ConfClient represents a fixed client configuration used by the dummy provider.
|
||||
type ConfClient struct {
|
||||
applicationType op.ApplicationType
|
||||
authMethod oidc.AuthMethod
|
||||
responseTypes []oidc.ResponseType
|
||||
grantTypes []oidc.GrantType
|
||||
ID string
|
||||
accessTokenType op.AccessTokenType
|
||||
devMode bool
|
||||
}
|
||||
|
||||
func (c *ConfClient) GetID() string {
|
||||
return c.ID
|
||||
}
|
||||
|
||||
func (c *ConfClient) RedirectURIs() []string {
|
||||
return []string{
|
||||
"https://registered.com/callback",
|
||||
"http://localhost:9999/callback",
|
||||
"http://localhost:5556/auth/callback",
|
||||
"custom://callback",
|
||||
"https://localhost:8443/test/a/instructions-example/callback",
|
||||
"https://op.certification.openid.net:62064/authz_cb",
|
||||
"https://op.certification.openid.net:62064/authz_post",
|
||||
"http://localhost:2342/api/v1/oidc/redirect",
|
||||
"https://app.localssl.dev/api/v1/oidc/redirect",
|
||||
}
|
||||
}
|
||||
func (c *ConfClient) PostLogoutRedirectURIs() []string {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (c *ConfClient) LoginURL(id string) string {
|
||||
// return "authorize/callback?id=" + id
|
||||
return "login?id=" + id
|
||||
}
|
||||
|
||||
func (c *ConfClient) ApplicationType() op.ApplicationType {
|
||||
return c.applicationType
|
||||
}
|
||||
|
||||
func (c *ConfClient) AuthMethod() oidc.AuthMethod {
|
||||
return c.authMethod
|
||||
}
|
||||
|
||||
func (c *ConfClient) IDTokenLifetime() time.Duration {
|
||||
return 60 * time.Minute
|
||||
}
|
||||
|
||||
func (c *ConfClient) AccessTokenType() op.AccessTokenType {
|
||||
return c.accessTokenType
|
||||
}
|
||||
|
||||
func (c *ConfClient) ResponseTypes() []oidc.ResponseType {
|
||||
return c.responseTypes
|
||||
}
|
||||
|
||||
func (c *ConfClient) GrantTypes() []oidc.GrantType {
|
||||
return c.grantTypes
|
||||
}
|
||||
|
||||
func (c *ConfClient) DevMode() bool {
|
||||
return c.devMode
|
||||
}
|
||||
|
||||
func (c *ConfClient) AllowedScopes() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ConfClient) RestrictAdditionalIdTokenScopes() func(scopes []string) []string {
|
||||
return func(scopes []string) []string {
|
||||
return scopes
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ConfClient) RestrictAdditionalAccessTokenScopes() func(scopes []string) []string {
|
||||
return func(scopes []string) []string {
|
||||
return scopes
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ConfClient) IsScopeAllowed(scope string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *ConfClient) IDTokenUserinfoClaimsAssertion() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *ConfClient) ClockSkew() time.Duration {
|
||||
return 0
|
||||
}
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
// Package mock provides an in-memory OIDC storage used by the dummy provider in development.
|
||||
package mock
|
||||
|
||||
// revive:disable
|
||||
// Dummy storage implementation for the test OIDC provider; lint strictness is relaxed intentionally.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
|
|
@ -10,23 +14,36 @@ import (
|
|||
|
||||
"gopkg.in/square/go-jose.v2"
|
||||
|
||||
"github.com/caos/oidc/pkg/oidc"
|
||||
"github.com/caos/oidc/pkg/op"
|
||||
"github.com/zitadel/oidc/pkg/oidc"
|
||||
"github.com/zitadel/oidc/pkg/op"
|
||||
)
|
||||
|
||||
var (
|
||||
a = &AuthRequest{}
|
||||
t bool
|
||||
c string
|
||||
state string
|
||||
)
|
||||
|
||||
// AuthStorage keeps ephemeral keys and auth state for the dummy provider.
|
||||
type AuthStorage struct {
|
||||
key *rsa.PrivateKey
|
||||
kid string
|
||||
}
|
||||
|
||||
// NewAuthStorage constructs the dummy storage with a fresh RSA key.
|
||||
func NewAuthStorage() op.Storage {
|
||||
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
b := make([]byte, 16)
|
||||
rand.Read(b)
|
||||
|
||||
if _, err = rand.Read(b); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &AuthStorage{
|
||||
key: key,
|
||||
|
|
@ -34,9 +51,11 @@ func NewAuthStorage() op.Storage {
|
|||
}
|
||||
}
|
||||
|
||||
// AuthRequest is a lightweight auth request implementation for tests.
|
||||
type AuthRequest struct {
|
||||
ID string
|
||||
ResponseType oidc.ResponseType
|
||||
ResponseMode oidc.ResponseMode
|
||||
RedirectURI string
|
||||
Nonce string
|
||||
ClientID string
|
||||
|
|
@ -86,6 +105,13 @@ func (a *AuthRequest) GetResponseType() oidc.ResponseType {
|
|||
return a.ResponseType
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetResponseMode() oidc.ResponseMode {
|
||||
if a.ResponseMode != "" {
|
||||
return a.ResponseMode
|
||||
}
|
||||
return oidc.ResponseModeQuery
|
||||
}
|
||||
|
||||
func (a *AuthRequest) GetScopes() []string {
|
||||
return []string{
|
||||
"openid",
|
||||
|
|
@ -108,20 +134,13 @@ func (a *AuthRequest) Done() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
var (
|
||||
a = &AuthRequest{}
|
||||
t bool
|
||||
c string
|
||||
state string
|
||||
)
|
||||
|
||||
func (s *AuthStorage) Health(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateAuthRequest stores the incoming request in memory and returns a stub AuthRequest.
|
||||
func (s *AuthStorage) CreateAuthRequest(_ context.Context, authReq *oidc.AuthRequest, userId string) (op.AuthRequest, error) {
|
||||
fmt.Println("Userid: ", userId)
|
||||
fmt.Println("CreateAuthRequest ID: ", authReq.ID)
|
||||
fmt.Println("CreateAuthRequest CodeChallenge: ", authReq.CodeChallenge)
|
||||
fmt.Println("CreateAuthRequest CodeChallengeMethod: ", authReq.CodeChallengeMethod)
|
||||
fmt.Println("CreateAuthRequest State: ", authReq.State)
|
||||
|
|
@ -132,7 +151,14 @@ func (s *AuthStorage) CreateAuthRequest(_ context.Context, authReq *oidc.AuthReq
|
|||
fmt.Println("CreateAuthRequest Display: ", authReq.Display)
|
||||
fmt.Println("CreateAuthRequest LoginHint: ", authReq.LoginHint)
|
||||
fmt.Println("CreateAuthRequest IDTokenHint: ", authReq.IDTokenHint)
|
||||
a = &AuthRequest{ID: "authReqUserAgentId", ClientID: authReq.ClientID, ResponseType: authReq.ResponseType, Nonce: authReq.Nonce, RedirectURI: authReq.RedirectURI}
|
||||
a = &AuthRequest{
|
||||
ID: "authReqUserAgentId",
|
||||
ClientID: authReq.ClientID,
|
||||
ResponseType: authReq.ResponseType,
|
||||
ResponseMode: authReq.ResponseMode,
|
||||
Nonce: authReq.Nonce,
|
||||
RedirectURI: authReq.RedirectURI,
|
||||
}
|
||||
if authReq.CodeChallenge != "" {
|
||||
a.CodeChallenge = &oidc.CodeChallenge{
|
||||
Challenge: authReq.CodeChallenge,
|
||||
|
|
@ -143,12 +169,14 @@ func (s *AuthStorage) CreateAuthRequest(_ context.Context, authReq *oidc.AuthReq
|
|||
t = false
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (s *AuthStorage) AuthRequestByCode(_ context.Context, code string) (op.AuthRequest, error) {
|
||||
if code != c {
|
||||
return nil, errors.New("invalid code")
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (s *AuthStorage) SaveAuthCode(_ context.Context, id, code string) error {
|
||||
if a.ID != id {
|
||||
return errors.New("SaveAuthCode: not found")
|
||||
|
|
@ -156,10 +184,12 @@ func (s *AuthStorage) SaveAuthCode(_ context.Context, id, code string) error {
|
|||
c = code
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *AuthStorage) DeleteAuthRequest(context.Context, string) error {
|
||||
t = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *AuthStorage) AuthRequestByID(_ context.Context, id string) (op.AuthRequest, error) {
|
||||
fmt.Println("AuthRequestByID: ", id)
|
||||
if id != "authReqUserAgentId:usertoken" || t {
|
||||
|
|
@ -167,12 +197,15 @@ func (s *AuthStorage) AuthRequestByID(_ context.Context, id string) (op.AuthRequ
|
|||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (s *AuthStorage) CreateAccessToken(ctx context.Context, request op.TokenRequest) (string, time.Time, error) {
|
||||
return "loginId", time.Now().UTC().Add(5 * time.Minute), nil
|
||||
}
|
||||
|
||||
func (s *AuthStorage) CreateAccessAndRefreshTokens(ctx context.Context, request op.TokenRequest, currentRefreshToken string) (accessTokenID string, newRefreshToken string, expiration time.Time, err error) {
|
||||
return "loginId", "refreshToken", time.Now().UTC().Add(5 * time.Minute), nil
|
||||
}
|
||||
|
||||
func (s *AuthStorage) TokenRequestByRefreshToken(ctx context.Context, refreshToken string) (op.RefreshTokenRequest, error) {
|
||||
if refreshToken != c {
|
||||
return nil, errors.New("invalid token")
|
||||
|
|
@ -183,13 +216,21 @@ func (s *AuthStorage) TokenRequestByRefreshToken(ctx context.Context, refreshTok
|
|||
func (s *AuthStorage) TerminateSession(_ context.Context, userID, clientID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RevokeToken is a no-op for the dummy implementation.
|
||||
func (s *AuthStorage) RevokeToken(_ context.Context, tokenOrTokenID string, userID string, clientID string) *oidc.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *AuthStorage) GetSigningKey(_ context.Context, keyCh chan<- jose.SigningKey) {
|
||||
//keyCh <- jose.SigningKey{Algorithm: jose.RS256, Key: s.key}
|
||||
// keyCh <- jose.SigningKey{Algorithm: jose.RS256, Key: s.key}
|
||||
keyCh <- jose.SigningKey{Algorithm: jose.RS256, Key: &jose.JSONWebKey{Key: s.key, KeyID: s.kid}}
|
||||
}
|
||||
|
||||
func (s *AuthStorage) GetKey(_ context.Context) (*rsa.PrivateKey, error) {
|
||||
return s.key, nil
|
||||
}
|
||||
|
||||
func (s *AuthStorage) GetKeySet(_ context.Context) (*jose.JSONWebKeySet, error) {
|
||||
pubkey := s.key.Public()
|
||||
|
||||
|
|
@ -214,6 +255,7 @@ func (s *AuthStorage) GetKeySet(_ context.Context) (*jose.JSONWebKeySet, error)
|
|||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *AuthStorage) GetKeyByIDAndUserID(_ context.Context, _, _ string) (*jose.JSONWebKey, error) {
|
||||
pubkey := s.key.Public()
|
||||
|
||||
|
|
@ -229,6 +271,7 @@ func (s *AuthStorage) GetClientByClientID(_ context.Context, id string) (op.Clie
|
|||
if id == "none" {
|
||||
return nil, errors.New("GetClientByClientID: not found")
|
||||
}
|
||||
|
||||
var appType op.ApplicationType
|
||||
var authMethod oidc.AuthMethod
|
||||
var accessTokenType op.AccessTokenType
|
||||
|
|
@ -236,22 +279,25 @@ func (s *AuthStorage) GetClientByClientID(_ context.Context, id string) (op.Clie
|
|||
var grantTypes = []oidc.GrantType{
|
||||
oidc.GrantTypeCode,
|
||||
}
|
||||
if id == "web" {
|
||||
|
||||
switch id {
|
||||
case "web":
|
||||
appType = op.ApplicationTypeWeb
|
||||
authMethod = oidc.AuthMethodBasic
|
||||
accessTokenType = op.AccessTokenTypeBearer
|
||||
responseTypes = []oidc.ResponseType{oidc.ResponseTypeCode}
|
||||
} else if id == "native" {
|
||||
case "native":
|
||||
appType = op.ApplicationTypeNative
|
||||
authMethod = oidc.AuthMethodBasic
|
||||
accessTokenType = op.AccessTokenTypeBearer
|
||||
responseTypes = []oidc.ResponseType{oidc.ResponseTypeCode, oidc.ResponseTypeIDToken, oidc.ResponseTypeIDTokenOnly}
|
||||
} else {
|
||||
default:
|
||||
appType = op.ApplicationTypeUserAgent
|
||||
authMethod = oidc.AuthMethodNone
|
||||
accessTokenType = op.AccessTokenTypeJWT
|
||||
responseTypes = []oidc.ResponseType{oidc.ResponseTypeIDToken, oidc.ResponseTypeIDTokenOnly}
|
||||
}
|
||||
|
||||
return &ConfClient{ID: id, applicationType: appType, authMethod: authMethod, accessTokenType: accessTokenType, responseTypes: responseTypes, grantTypes: grantTypes, devMode: true}, nil
|
||||
}
|
||||
|
||||
|
|
@ -262,9 +308,10 @@ func (s *AuthStorage) AuthorizeClientIDSecret(_ context.Context, id string, _ st
|
|||
func (s *AuthStorage) SetUserinfoFromToken(ctx context.Context, userinfo oidc.UserInfoSetter, _, _, _ string) error {
|
||||
return s.SetUserinfoFromScopes(ctx, userinfo, "", "", []string{})
|
||||
}
|
||||
|
||||
func (s *AuthStorage) SetUserinfoFromScopes(ctx context.Context, userinfo oidc.UserInfoSetter, _, _ string, _ []string) error {
|
||||
userinfo.SetSubject(a.GetSubject())
|
||||
//userinfo.SetAddress(oidc.NewUserInfoAddress("Test 789\nPostfach 2", "", "", "", "", ""))
|
||||
// userinfo.SetAddress(oidc.NewUserInfoAddress("Test 789\nPostfach 2", "", "", "", "", ""))
|
||||
userinfo.SetEmail("test@example.com", true)
|
||||
userinfo.SetPhone("0791234567", true)
|
||||
userinfo.SetName("Test")
|
||||
|
|
@ -273,6 +320,7 @@ func (s *AuthStorage) SetUserinfoFromScopes(ctx context.Context, userinfo oidc.U
|
|||
userinfo.SetPreferredUsername("prefname")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *AuthStorage) GetPrivateClaimsFromScopes(_ context.Context, _, _ string, _ []string) (map[string]interface{}, error) {
|
||||
return map[string]interface{}{"private_claim": "test"}, nil
|
||||
}
|
||||
|
|
@ -281,98 +329,12 @@ func (s *AuthStorage) SetIntrospectionFromToken(ctx context.Context, introspect
|
|||
if err := s.SetUserinfoFromScopes(ctx, introspect, "", "", []string{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
introspect.SetClientID(a.ClientID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *AuthStorage) ValidateJWTProfileScopes(ctx context.Context, userID string, scope []string) ([]string, error) {
|
||||
return scope, nil
|
||||
}
|
||||
|
||||
type ConfClient struct {
|
||||
applicationType op.ApplicationType
|
||||
authMethod oidc.AuthMethod
|
||||
responseTypes []oidc.ResponseType
|
||||
grantTypes []oidc.GrantType
|
||||
ID string
|
||||
accessTokenType op.AccessTokenType
|
||||
devMode bool
|
||||
}
|
||||
|
||||
func (c *ConfClient) GetID() string {
|
||||
return c.ID
|
||||
}
|
||||
func (c *ConfClient) RedirectURIs() []string {
|
||||
return []string{
|
||||
"https://registered.com/callback",
|
||||
"http://localhost:9999/callback",
|
||||
"http://localhost:5556/auth/callback",
|
||||
"custom://callback",
|
||||
"https://localhost:8443/test/a/instructions-example/callback",
|
||||
"https://op.certification.openid.net:62064/authz_cb",
|
||||
"https://op.certification.openid.net:62064/authz_post",
|
||||
"http://localhost:2342/api/v1/oidc/redirect",
|
||||
"https://app.localssl.dev/api/v1/oidc/redirect",
|
||||
}
|
||||
}
|
||||
func (c *ConfClient) PostLogoutRedirectURIs() []string {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (c *ConfClient) LoginURL(id string) string {
|
||||
//return "authorize/callback?id=" + id
|
||||
return "login?id=" + id
|
||||
}
|
||||
|
||||
func (c *ConfClient) ApplicationType() op.ApplicationType {
|
||||
return c.applicationType
|
||||
}
|
||||
|
||||
func (c *ConfClient) AuthMethod() oidc.AuthMethod {
|
||||
return c.authMethod
|
||||
}
|
||||
|
||||
func (c *ConfClient) IDTokenLifetime() time.Duration {
|
||||
return 60 * time.Minute
|
||||
}
|
||||
func (c *ConfClient) AccessTokenType() op.AccessTokenType {
|
||||
return c.accessTokenType
|
||||
}
|
||||
func (c *ConfClient) ResponseTypes() []oidc.ResponseType {
|
||||
return c.responseTypes
|
||||
}
|
||||
func (c *ConfClient) GrantTypes() []oidc.GrantType {
|
||||
return c.grantTypes
|
||||
}
|
||||
|
||||
func (c *ConfClient) DevMode() bool {
|
||||
return c.devMode
|
||||
}
|
||||
|
||||
func (c *ConfClient) AllowedScopes() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ConfClient) RestrictAdditionalIdTokenScopes() func(scopes []string) []string {
|
||||
return func(scopes []string) []string {
|
||||
return scopes
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ConfClient) RestrictAdditionalAccessTokenScopes() func(scopes []string) []string {
|
||||
return func(scopes []string) []string {
|
||||
return scopes
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ConfClient) IsScopeAllowed(scope string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *ConfClient) IDTokenUserinfoClaimsAssertion() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *ConfClient) ClockSkew() time.Duration {
|
||||
return 0
|
||||
}
|
||||
|
|
|
|||
27
docker/dummy/oidc/app/mock/storage_test.go
Normal file
27
docker/dummy/oidc/app/mock/storage_test.go
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package mock
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/zitadel/oidc/pkg/oidc"
|
||||
)
|
||||
|
||||
func TestAuthRequestResponseModeDefault(t *testing.T) {
|
||||
req := &AuthRequest{}
|
||||
if got := req.GetResponseMode(); got != oidc.ResponseModeQuery {
|
||||
t.Fatalf("expected default response mode %q, got %q", oidc.ResponseModeQuery, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRevokeTokenNoError(t *testing.T) {
|
||||
s := &AuthStorage{}
|
||||
if err := s.RevokeToken(
|
||||
context.TODO(),
|
||||
"token",
|
||||
"user",
|
||||
"client",
|
||||
); err != nil {
|
||||
t.Fatalf("expected nil error from RevokeToken, got %v", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +1,33 @@
|
|||
// Command dummy-oidc starts a minimal OIDC provider used by docker-compose for local development.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/zitadel/oidc/pkg/op"
|
||||
|
||||
"caos-test-op/mock"
|
||||
"github.com/caos/oidc/pkg/op"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
b := make([]byte, 32)
|
||||
rand.Read(b)
|
||||
_, _ = rand.Read(b)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
log.Printf("failed to seed crypto key: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
port := "9998"
|
||||
config := &op.Config{
|
||||
|
|
@ -29,26 +39,39 @@ func main() {
|
|||
|
||||
handler, err := op.NewOpenIDProvider(ctx, config, storage)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Printf("failed to create OIDC provider: %v", err)
|
||||
return
|
||||
}
|
||||
router := handler.HttpHandler().(*mux.Router)
|
||||
router.Methods("GET").Path("/login").HandlerFunc(HandleLogin)
|
||||
server := &http.Server{
|
||||
Addr: ":" + port,
|
||||
Handler: router,
|
||||
Addr: ":" + port,
|
||||
Handler: router,
|
||||
ReadHeaderTimeout: 5 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
IdleTimeout: 30 * time.Second,
|
||||
}
|
||||
err = server.ListenAndServe()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
_ = server.Shutdown(context.Background())
|
||||
}()
|
||||
|
||||
if err = server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
log.Printf("OIDC server stopped with error: %v", err)
|
||||
}
|
||||
<-ctx.Done()
|
||||
}
|
||||
|
||||
func HandleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
// HandleLogin mocks a login page and immediately redirects with a user token.
|
||||
if err := r.ParseForm(); err != nil {
|
||||
http.Error(w, "invalid login request", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
requestId := r.Form.Get("id")
|
||||
// simulate user login and retrieve a token that indicates a successfully logged-in user
|
||||
usertoken := requestId + ":usertoken"
|
||||
userToken := requestId + ":usertoken"
|
||||
|
||||
http.Redirect(w, r, "/authorize/callback?id="+usertoken, http.StatusFound)
|
||||
http.Redirect(w, r, "/authorize/callback?id="+userToken, http.StatusFound)
|
||||
}
|
||||
|
|
|
|||
36
docker/dummy/oidc/app/server_test.go
Normal file
36
docker/dummy/oidc/app/server_test.go
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHandleLoginRedirects(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodGet, "/login?id=abc123", nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
HandleLogin(w, req)
|
||||
|
||||
resp := w.Result()
|
||||
if resp.StatusCode != http.StatusFound {
|
||||
t.Fatalf("expected status %d, got %d", http.StatusFound, resp.StatusCode)
|
||||
}
|
||||
location := resp.Header.Get("Location")
|
||||
if location != "/authorize/callback?id=abc123:usertoken" {
|
||||
t.Fatalf("unexpected redirect location: %s", location)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleLoginBadRequest(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodPost, "/login", strings.NewReader("%zz"))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
HandleLogin(w, req)
|
||||
|
||||
if w.Result().StatusCode != http.StatusBadRequest {
|
||||
t.Fatalf("expected bad request, got %d", w.Result().StatusCode)
|
||||
}
|
||||
}
|
||||
|
|
@ -16,4 +16,4 @@ EXPOSE 80
|
|||
COPY /docker/dummy/webdav/config.yml /webdav/config.yml
|
||||
COPY /docker/dummy/webdav/files /webdav/files
|
||||
|
||||
CMD webdav -c /webdav/config.yml
|
||||
CMD ["webdav", "-c", "/webdav/config.yml"]
|
||||
|
|
|
|||
|
|
@ -23,4 +23,4 @@ VOLUME "/go"
|
|||
EXPOSE 8888
|
||||
|
||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
||||
CMD ["/goproxy", "-listen", "0.0.0.0:8888"]
|
||||
CMD ["/goproxy", "-listen", "0.0.0.0:8888"]
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ ENV PHOTOPRISM_ARCH=$TARGETARCH \
|
|||
TF_VERSION=1.15.2 \
|
||||
TF_CPP_MIN_LOG_LEVEL=4 \
|
||||
MALLOC_ARENA_MAX=2 \
|
||||
PROG="photoprism" \
|
||||
PROG="photoprism"
|
||||
PHOTOPRISM_ASSETS_PATH="/opt/photoprism/assets" \
|
||||
PHOTOPRISM_IMPORT_PATH="/photoprism/import" \
|
||||
PHOTOPRISM_ORIGINALS_PATH="/photoprism/originals" \
|
||||
|
|
|
|||
|
|
@ -3,16 +3,9 @@ node_modules/
|
|||
tests/screenshots/
|
||||
tests/acceptance/screenshots/
|
||||
tests/upload-files/
|
||||
*.html
|
||||
*.md
|
||||
.*
|
||||
.idea
|
||||
.codex
|
||||
.local
|
||||
.config
|
||||
.github
|
||||
.tmp
|
||||
.local
|
||||
.cache
|
||||
.gocache
|
||||
.var
|
||||
*.html
|
||||
*.md
|
||||
.*
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"printWidth": 120,
|
||||
"printWidth": 160,
|
||||
"semi": true,
|
||||
"singleQuote": false,
|
||||
"trailingComma": "es5",
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ export default defineConfig([
|
|||
"prettier/prettier": [
|
||||
"warn",
|
||||
{
|
||||
printWidth: 120,
|
||||
printWidth: 160,
|
||||
semi: true,
|
||||
singleQuote: false,
|
||||
bracketSpacing: true,
|
||||
|
|
|
|||
1020
frontend/package-lock.json
generated
1020
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -27,7 +27,7 @@
|
|||
"security:scan": "npm run -s security:scan-installs && npm run -s security:scan-xss",
|
||||
"security:scan-installs": "sh -lc 'set -e; MATCHES=\"$(rg -n --hidden --glob !**/.git/** -S \"npm (ci|install|update)\" ./Makefile ./package.json 2>/dev/null || true)\"; if [ -z \"$MATCHES\" ]; then echo \"No npm install/update/ci commands found in frontend/\"; exit 0; fi; VIOLATIONS=\"$(printf %s \"$MATCHES\" | rg -v -e \"ignore-scripts\" -e \"install .* -g npm\" -e \"update .* -g npm\" -e \":[0-9]+:\\s*#\" -e \"install-npm\" || true)\"; if [ -n \"$VIOLATIONS\" ]; then echo \"ERROR: npm install/update/ci without --ignore-scripts (exceptions excluded)\"; printf %s\\n \"$VIOLATIONS\"; exit 1; fi; echo \"OK: All frontend installs/updates use --ignore-scripts or are allowed exceptions.\"'",
|
||||
"security:scan-xss": "sh -lc 'set -e; if rg -n --glob \"src/**\" -S \"v-html=\\\"\" src >/dev/null; then echo \"ERROR: v-html usage detected; prefer v-sanitize or $util.sanitizeHtml()\"; rg -n --glob \"src/**\" -S \"v-html=\\\"\" src; exit 1; else echo \"OK: No v-html usage detected.\"; fi'",
|
||||
"watch": "webpack --watch"
|
||||
"watch": "cross-env BUILD_ENV=development NODE_ENV=production webpack --watch"
|
||||
},
|
||||
"browserslist": [
|
||||
">0.25% and last 2 years"
|
||||
|
|
@ -39,26 +39,26 @@
|
|||
"@babel/preset-env": "^7.28.5",
|
||||
"@babel/register": "^7.28.3",
|
||||
"@babel/runtime": "^7.28.4",
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/eslintrc": "^3.3.3",
|
||||
"@eslint/js": "^9.33.0",
|
||||
"@mdi/font": "^7.4.47",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@vitejs/plugin-react": "^5.1.1",
|
||||
"@vitejs/plugin-react": "^5.1.2",
|
||||
"@vitejs/plugin-vue": "^6.0.2",
|
||||
"@vitest/browser": "^3.2.4",
|
||||
"@vitest/coverage-v8": "^3.2.4",
|
||||
"@vitest/ui": "^3.2.4",
|
||||
"@vue/compiler-sfc": "^3.5.18",
|
||||
"@vue/language-server": "^3.1.4",
|
||||
"@vue/language-server": "^3.1.8",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"@vvo/tzdb": "^6.196.0",
|
||||
"@vvo/tzdb": "^6.198.0",
|
||||
"axios": "^1.13.2",
|
||||
"axios-mock-adapter": "^2.1.0",
|
||||
"babel-loader": "^10.0.0",
|
||||
"babel-plugin-istanbul": "^7.0.1",
|
||||
"babel-plugin-polyfill-corejs3": "^0.13.0",
|
||||
"browserslist": "^4.28.0",
|
||||
"browserslist": "^4.28.1",
|
||||
"cheerio": "1.0.0-rc.12",
|
||||
"core-js": "^3.47.0",
|
||||
"cross-env": "^7.0.3",
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^5.5.4",
|
||||
"eslint-plugin-vue": "^10.5.1",
|
||||
"eslint-plugin-vue": "^10.6.2",
|
||||
"eslint-plugin-vuetify": "^2.5.3",
|
||||
"eslint-webpack-plugin": "^5.0.2",
|
||||
"eventsource-polyfill": "^0.9.6",
|
||||
|
|
@ -84,26 +84,26 @@
|
|||
"i": "^0.3.7",
|
||||
"jsdom": "^26.1.0",
|
||||
"luxon": "^3.7.2",
|
||||
"maplibre-gl": "^5.13.0",
|
||||
"maplibre-gl": "^5.14.0",
|
||||
"memoize-one": "^6.0.0",
|
||||
"mini-css-extract-plugin": "^2.9.4",
|
||||
"minimist": "^1.2.8",
|
||||
"node-storage-shim": "^2.0.1",
|
||||
"passive-events-support": "^1.1.0",
|
||||
"photoswipe": "^5.4.4",
|
||||
"playwright": "^1.56.1",
|
||||
"playwright": "^1.57.0",
|
||||
"postcss": "^8.5.6",
|
||||
"postcss-import": "^16.1.1",
|
||||
"postcss-loader": "^8.2.0",
|
||||
"postcss-preset-env": "^10.4.0",
|
||||
"postcss-preset-env": "^10.5.0",
|
||||
"postcss-reporter": "^7.1.0",
|
||||
"postcss-url": "^10.1.3",
|
||||
"prettier": "^3.6.2",
|
||||
"prettier": "^3.7.4",
|
||||
"pubsub-js": "^1.9.5",
|
||||
"regenerator-runtime": "^0.14.1",
|
||||
"resolve-url-loader": "^5.0.0",
|
||||
"sanitize-html": "^2.17.0",
|
||||
"sass": "^1.94.2",
|
||||
"sass": "^1.95.1",
|
||||
"sass-loader": "^16.0.6",
|
||||
"sockette": "^2.0.6",
|
||||
"style-loader": "^4.0.0",
|
||||
|
|
@ -122,7 +122,7 @@
|
|||
"vue-sanitize-directive": "^0.2.1",
|
||||
"vue-style-loader": "^4.1.3",
|
||||
"vue3-gettext": "^2.4.0",
|
||||
"vuetify": "^3.10.11",
|
||||
"vuetify": "^3.11.3",
|
||||
"webpack": "^5.103.0",
|
||||
"webpack-bundle-analyzer": "^4.10.2",
|
||||
"webpack-cli": "^6.0.1",
|
||||
|
|
|
|||
|
|
@ -12,9 +12,7 @@ export function processAlbumSelection(selectedAlbums, availableAlbums) {
|
|||
selectedAlbums.forEach((item) => {
|
||||
// If it's a string, try to match it with existing albums
|
||||
if (typeof item === "string" && item.trim().length > 0) {
|
||||
const matchedAlbum = availableAlbums.find(
|
||||
(album) => album.Title && album.Title.toLowerCase() === item.trim().toLowerCase()
|
||||
);
|
||||
const matchedAlbum = availableAlbums.find((album) => album.Title && album.Title.toLowerCase() === item.trim().toLowerCase());
|
||||
|
||||
if (matchedAlbum && !seenUids.has(matchedAlbum.UID)) {
|
||||
// Replace string with actual album object
|
||||
|
|
|
|||
|
|
@ -125,13 +125,12 @@ export class Clipboard {
|
|||
|
||||
const id = model.getId();
|
||||
|
||||
this.addId(id);
|
||||
return this.addId(id);
|
||||
}
|
||||
|
||||
addId(id) {
|
||||
this.updateDom(id, true);
|
||||
|
||||
if (this.hasId(id)) {
|
||||
this.lastId = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -145,6 +144,7 @@ export class Clipboard {
|
|||
this.lastId = id;
|
||||
|
||||
this.saveToStorage();
|
||||
this.updateDom(id, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -170,12 +170,19 @@ export class Clipboard {
|
|||
rangeEnd = newEnd;
|
||||
}
|
||||
|
||||
let added = 0;
|
||||
|
||||
for (let i = rangeStart; i <= rangeEnd; i++) {
|
||||
this.add(models[i], false);
|
||||
this.updateDom(models[i].getId(), true);
|
||||
const result = this.add(models[i]);
|
||||
|
||||
if (!result) {
|
||||
break;
|
||||
}
|
||||
|
||||
added++;
|
||||
}
|
||||
|
||||
return rangeEnd - rangeStart + 1;
|
||||
return added;
|
||||
}
|
||||
|
||||
has(model) {
|
||||
|
|
|
|||
|
|
@ -241,12 +241,7 @@ export default class Config {
|
|||
.filter((m) => m.UID === values.UID)
|
||||
.forEach((m) => {
|
||||
for (let key in values) {
|
||||
if (
|
||||
key !== "UID" &&
|
||||
values.hasOwnProperty(key) &&
|
||||
values[key] != null &&
|
||||
typeof values[key] !== "object"
|
||||
) {
|
||||
if (key !== "UID" && values.hasOwnProperty(key) && values[key] != null && typeof values[key] !== "object") {
|
||||
m[key] = values[key];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,11 +102,7 @@ export class Form {
|
|||
|
||||
// getOptions resolves the options array for select-style fields.
|
||||
getOptions(fieldName) {
|
||||
if (
|
||||
this.definition &&
|
||||
this.definition.hasOwnProperty(fieldName) &&
|
||||
this.definition[fieldName].hasOwnProperty("options")
|
||||
) {
|
||||
if (this.definition && this.definition.hasOwnProperty(fieldName) && this.definition[fieldName].hasOwnProperty("options")) {
|
||||
return this.definition[fieldName].options;
|
||||
}
|
||||
|
||||
|
|
@ -209,9 +205,7 @@ export class rules {
|
|||
return false;
|
||||
}
|
||||
|
||||
return /^[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]+@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/.test(
|
||||
v
|
||||
);
|
||||
return /^[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]+@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/.test(v);
|
||||
}
|
||||
|
||||
// isUrl validates strings by length and URL parsing.
|
||||
|
|
@ -260,10 +254,7 @@ export class rules {
|
|||
// email returns Vuetify rule callbacks for email validation.
|
||||
static email(required) {
|
||||
if (required) {
|
||||
return [
|
||||
(v) => !!v || $gettext("This field is required"),
|
||||
(v) => !v || this.isEmail(v) || $gettext("Invalid address"),
|
||||
];
|
||||
return [(v) => !!v || $gettext("This field is required"), (v) => !v || this.isEmail(v) || $gettext("Invalid address")];
|
||||
} else {
|
||||
return [(v) => !v || this.isEmail(v) || $gettext("Invalid address")];
|
||||
}
|
||||
|
|
@ -352,20 +343,14 @@ export class rules {
|
|||
(v) => this.maxLen(v, 2) || $gettext("Invalid country"),
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
(v) => this.minLen(v, 2) || $gettext("Invalid country"),
|
||||
(v) => this.maxLen(v, 2) || $gettext("Invalid country"),
|
||||
];
|
||||
return [(v) => this.minLen(v, 2) || $gettext("Invalid country"), (v) => this.maxLen(v, 2) || $gettext("Invalid country")];
|
||||
}
|
||||
}
|
||||
|
||||
// day validates day-of-month values between 1 and 31.
|
||||
static day(required) {
|
||||
if (required) {
|
||||
return [
|
||||
(v) => !!v || Number(v) < -1 || $gettext("This field is required"),
|
||||
(v) => this.isNumberRange(v, 1, 31) || $gettext("Invalid"),
|
||||
];
|
||||
return [(v) => !!v || Number(v) < -1 || $gettext("This field is required"), (v) => this.isNumberRange(v, 1, 31) || $gettext("Invalid")];
|
||||
} else {
|
||||
return [(v) => this.isNumberRange(v, 1, 31) || $gettext("Invalid")];
|
||||
}
|
||||
|
|
@ -374,10 +359,7 @@ export class rules {
|
|||
// month validates month values between 1 and 12.
|
||||
static month(required) {
|
||||
if (required) {
|
||||
return [
|
||||
(v) => !!v || Number(v) < -1 || $gettext("This field is required"),
|
||||
(v) => this.isNumberRange(v, 1, 12) || $gettext("Invalid"),
|
||||
];
|
||||
return [(v) => !!v || Number(v) < -1 || $gettext("This field is required"), (v) => this.isNumberRange(v, 1, 12) || $gettext("Invalid")];
|
||||
} else {
|
||||
return [(v) => this.isNumberRange(v, 1, 12) || $gettext("Invalid")];
|
||||
}
|
||||
|
|
@ -394,10 +376,7 @@ export class rules {
|
|||
}
|
||||
|
||||
if (required) {
|
||||
return [
|
||||
(v) => !!v || Number(v) < -1 || $gettext("This field is required"),
|
||||
(v) => this.isNumberRange(v, min, max) || $gettext("Invalid"),
|
||||
];
|
||||
return [(v) => !!v || Number(v) < -1 || $gettext("This field is required"), (v) => this.isNumberRange(v, min, max) || $gettext("Invalid")];
|
||||
} else {
|
||||
return [(v) => this.isNumberRange(v, min, max) || $gettext("Invalid")];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,10 +75,7 @@ export class Input {
|
|||
return InputInvalid;
|
||||
}
|
||||
|
||||
if (
|
||||
Math.abs(this.touches[0].screenX - ev.changedTouches[0].screenX) > 4 ||
|
||||
Math.abs(this.touches[0].screenY - ev.changedTouches[0].screenY) > 4
|
||||
) {
|
||||
if (Math.abs(this.touches[0].screenX - ev.changedTouches[0].screenX) > 4 || Math.abs(this.touches[0].screenY - ev.changedTouches[0].screenY) > 4) {
|
||||
return InputInvalid;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,13 +15,7 @@ const langFallbackDecorate = function (style, cfg) {
|
|||
for (let i = layers.length - 1; i >= 0; i--) {
|
||||
let layer = layers[i];
|
||||
if (
|
||||
!(
|
||||
lf[0] === "in" &&
|
||||
lfProp === "layout.text-field" &&
|
||||
layer.layout &&
|
||||
layer.layout["text-field"] &&
|
||||
lfValues.indexOf(layer.layout["text-field"]) >= 0
|
||||
)
|
||||
!(lf[0] === "in" && lfProp === "layout.text-field" && layer.layout && layer.layout["text-field"] && lfValues.indexOf(layer.layout["text-field"]) >= 0)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -95,27 +89,7 @@ maplibregl.Map.prototype.setLanguage = function (language, noAlt) {
|
|||
return;
|
||||
}
|
||||
|
||||
let isNonlatin =
|
||||
[
|
||||
"ar",
|
||||
"hy",
|
||||
"be",
|
||||
"bg",
|
||||
"zh",
|
||||
"ka",
|
||||
"el",
|
||||
"he",
|
||||
"ja",
|
||||
"ja_kana",
|
||||
"kn",
|
||||
"kk",
|
||||
"ko",
|
||||
"mk",
|
||||
"ru",
|
||||
"sr",
|
||||
"th",
|
||||
"uk",
|
||||
].indexOf(language) >= 0;
|
||||
let isNonlatin = ["ar", "hy", "be", "bg", "zh", "ka", "el", "he", "ja", "ja_kana", "kn", "kk", "ko", "mk", "ru", "sr", "th", "uk"].indexOf(language) >= 0;
|
||||
|
||||
let style = JSON.parse(JSON.stringify(this.styleUndecorated));
|
||||
let langCfg = {
|
||||
|
|
@ -131,15 +105,12 @@ maplibregl.Map.prototype.setLanguage = function (language, noAlt) {
|
|||
],
|
||||
"decorators": [
|
||||
{
|
||||
"layout.text-field": isNonlatin
|
||||
? "{name:nonlatin}" + (noAlt ? "" : "\n{name:latin}")
|
||||
: "{name:latin}" + (noAlt ? "" : "\n{name:nonlatin}"),
|
||||
"layout.text-field": isNonlatin ? "{name:nonlatin}" + (noAlt ? "" : "\n{name:latin}") : "{name:latin}" + (noAlt ? "" : "\n{name:nonlatin}"),
|
||||
"filter-all-part": ["!has", "name:" + language],
|
||||
},
|
||||
{
|
||||
"layer-name-postfix": language,
|
||||
"layout.text-field":
|
||||
"{name:" + language + "}" + (noAlt ? "" : "\n{name:" + (isNonlatin ? "latin" : "nonlatin") + "}"),
|
||||
"layout.text-field": "{name:" + language + "}" + (noAlt ? "" : "\n{name:" + (isNonlatin ? "latin" : "nonlatin") + "}"),
|
||||
"filter-all-part": ["has", "name:" + language],
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -89,10 +89,7 @@ export default class Session {
|
|||
}
|
||||
|
||||
// Restore authentication from session storage.
|
||||
if (
|
||||
this.applyAuthToken(this.storage.getItem(this.storageKey + ".token")) &&
|
||||
this.applyId(this.storage.getItem(this.storageKey + ".id"))
|
||||
) {
|
||||
if (this.applyAuthToken(this.storage.getItem(this.storageKey + ".token")) && this.applyId(this.storage.getItem(this.storageKey + ".id"))) {
|
||||
const dataJson = this.storage.getItem(this.storageKey + ".data");
|
||||
if (dataJson && dataJson !== "undefined") {
|
||||
this.data = JSON.parse(dataJson);
|
||||
|
|
|
|||
|
|
@ -353,12 +353,7 @@ export default class $util {
|
|||
}
|
||||
|
||||
// Escape HTML control characters.
|
||||
text = text
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
text = text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
||||
|
||||
// Make URLs clickable.
|
||||
text = text.replace(linkRegex, linkFunc);
|
||||
|
|
|
|||
|
|
@ -521,10 +521,7 @@ export class View {
|
|||
const scope = this.scopes.map((s) => `${s?.$options?.name} #${s?.$?.uid.toString()}`).join(" › ");
|
||||
// To make them easy to recognize, the collapsed view logs are displayed
|
||||
// in the browser console with bold white text on a purple background.
|
||||
console.groupCollapsed(
|
||||
`%c${scope}`,
|
||||
"background: #502A85; color: white; padding: 3px 5px; border-radius: 8px; font-weight: bold;"
|
||||
);
|
||||
console.groupCollapsed(`%c${scope}`, "background: #502A85; color: white; padding: 3px 5px; border-radius: 8px; font-weight: bold;");
|
||||
console.log("data:", toRaw(c?.$data));
|
||||
}
|
||||
|
||||
|
|
@ -744,11 +741,7 @@ export class View {
|
|||
|
||||
ev.preventDefault();
|
||||
|
||||
const target =
|
||||
(fallback && fallback.isConnected && root.contains(fallback) && fallback) ||
|
||||
resolveFocusTarget(root) ||
|
||||
findFocusElement(component) ||
|
||||
root;
|
||||
const target = (fallback && fallback.isConnected && root.contains(fallback) && fallback) || resolveFocusTarget(root) || findFocusElement(component) || root;
|
||||
|
||||
if (!target) {
|
||||
return;
|
||||
|
|
@ -1019,10 +1012,7 @@ export class View {
|
|||
|
||||
const current = typeof this.navigation.currentPosition === "number" ? this.navigation.currentPosition : nextPos;
|
||||
|
||||
if (
|
||||
this.navigation.direction !== NavigationDirection.Back &&
|
||||
this.navigation.direction !== NavigationDirection.Forward
|
||||
) {
|
||||
if (this.navigation.direction !== NavigationDirection.Back && this.navigation.direction !== NavigationDirection.Forward) {
|
||||
if (nextPos < current) {
|
||||
this.navigation.direction = NavigationDirection.Back;
|
||||
} else if (nextPos > current) {
|
||||
|
|
|
|||
|
|
@ -6,26 +6,14 @@
|
|||
</strong>
|
||||
<span :title="version" class="body-link text-selectable">
|
||||
<span class="cursor-copy" @click.stop.prevent="$util.copyText(about, version)">Build</span>
|
||||
<a
|
||||
href="https://docs.photoprism.app/release-notes/"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="body-link text-truncate"
|
||||
>{{ build }}</a
|
||||
>
|
||||
<a href="https://docs.photoprism.app/release-notes/" target="_blank" rel="noopener" class="body-link text-truncate">{{ build }}</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="hidden-xs text-sm-end">
|
||||
<a
|
||||
href="https://raw.githubusercontent.com/photoprism/photoprism/develop/NOTICE"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="text-link"
|
||||
<a href="https://raw.githubusercontent.com/photoprism/photoprism/develop/NOTICE" target="_blank" rel="noopener" class="text-link"
|
||||
>3rd-party software packages</a
|
||||
>
|
||||
<a href="https://www.photoprism.app/about/team/" target="_blank" rel="noopener" class="body-link"
|
||||
>© 2018-2025 PhotoPrism UG</a
|
||||
>
|
||||
<a href="https://www.photoprism.app/about/team/" target="_blank" rel="noopener" class="body-link">© 2018-2025 PhotoPrism UG</a>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,20 +1,8 @@
|
|||
<template>
|
||||
<div class="p-action-menu">
|
||||
<v-menu
|
||||
:model-value="visible"
|
||||
:open-on-hover="openOnHover"
|
||||
class="action-menu action-menu--default"
|
||||
@update:model-value="onMenu"
|
||||
>
|
||||
<v-menu :model-value="visible" :open-on-hover="openOnHover" class="action-menu action-menu--default" @update:model-value="onMenu">
|
||||
<template #activator="{ props }">
|
||||
<v-btn
|
||||
v-bind="props"
|
||||
density="comfortable"
|
||||
:icon="buttonIcon"
|
||||
:tabindex="tabindex"
|
||||
class="action-menu__btn"
|
||||
:class="buttonClass"
|
||||
></v-btn>
|
||||
<v-btn v-bind="props" density="comfortable" :icon="buttonIcon" :tabindex="tabindex" class="action-menu__btn" :class="buttonClass"></v-btn>
|
||||
</template>
|
||||
|
||||
<v-list slim nav density="compact" bg-color="navigation" class="action-menu__list" :class="listClass">
|
||||
|
|
|
|||
|
|
@ -13,15 +13,7 @@
|
|||
offset="12"
|
||||
>
|
||||
<template #activator="{ props }">
|
||||
<v-btn
|
||||
v-bind="props"
|
||||
icon
|
||||
size="52"
|
||||
color="highlight"
|
||||
variant="elevated"
|
||||
density="comfortable"
|
||||
class="action-menu opacity-95 ma-5"
|
||||
>
|
||||
<v-btn v-bind="props" icon size="52" color="highlight" variant="elevated" density="comfortable" class="action-menu opacity-95 ma-5">
|
||||
<span class="count-clipboard">{{ selection.length }}</span>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
|
@ -81,26 +73,11 @@
|
|||
class="action-delete"
|
||||
@click.stop="dialog.delete = true"
|
||||
></v-btn>
|
||||
<v-btn
|
||||
key="action-close"
|
||||
icon="mdi-close"
|
||||
color="grey-darken-2"
|
||||
density="comfortable"
|
||||
class="action-clear"
|
||||
@click.stop="clearClipboard()"
|
||||
></v-btn>
|
||||
<v-btn key="action-close" icon="mdi-close" color="grey-darken-2" density="comfortable" class="action-clear" @click.stop="clearClipboard()"></v-btn>
|
||||
</v-speed-dial>
|
||||
</div>
|
||||
<p-photo-album-dialog
|
||||
:visible="dialog.album"
|
||||
@close="dialog.album = false"
|
||||
@confirm="cloneAlbums"
|
||||
></p-photo-album-dialog>
|
||||
<p-album-delete-dialog
|
||||
:visible="dialog.delete"
|
||||
@close="dialog.delete = false"
|
||||
@confirm="batchDelete"
|
||||
></p-album-delete-dialog>
|
||||
<p-photo-album-dialog :visible="dialog.album" @close="dialog.album = false" @confirm="cloneAlbums"></p-photo-album-dialog>
|
||||
<p-album-delete-dialog :visible="dialog.delete" @close="dialog.delete = false" @confirm="batchDelete"></p-album-delete-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
|
@ -143,8 +120,7 @@ export default {
|
|||
|
||||
return {
|
||||
canDelete: this.$config.allow("albums", "delete"),
|
||||
canDownload:
|
||||
this.$config.allow("albums", "download") && features.download && !settings?.albums?.download?.disabled,
|
||||
canDownload: this.$config.allow("albums", "download") && features.download && !settings?.albums?.download?.disabled,
|
||||
canShare: this.$config.allow("albums", "share") && features.share,
|
||||
canManage: this.$config.allow("albums", "manage"),
|
||||
deletable: ["album", "moment", "state"],
|
||||
|
|
|
|||
|
|
@ -10,13 +10,7 @@
|
|||
@after-enter="afterEnter"
|
||||
@after-leave="afterLeave"
|
||||
>
|
||||
<v-form
|
||||
ref="form"
|
||||
validate-on="invalid-input"
|
||||
class="form-album-edit"
|
||||
accept-charset="UTF-8"
|
||||
@submit.prevent="confirm"
|
||||
>
|
||||
<v-form ref="form" validate-on="invalid-input" class="form-album-edit" accept-charset="UTF-8" @submit.prevent="confirm">
|
||||
<v-card>
|
||||
<v-card-title class="d-flex justify-start align-center ga-3">
|
||||
<v-icon size="28" color="primary">mdi-bookmark</v-icon>
|
||||
|
|
@ -40,13 +34,7 @@
|
|||
></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12">
|
||||
<v-text-field
|
||||
v-model="model.Location"
|
||||
hide-details
|
||||
:label="$gettext('Location')"
|
||||
:disabled="disabled"
|
||||
class="input-location"
|
||||
></v-text-field>
|
||||
<v-text-field v-model="model.Location" hide-details :label="$gettext('Location')" :disabled="disabled" class="input-location"></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12">
|
||||
<v-textarea
|
||||
|
|
@ -85,22 +73,10 @@
|
|||
></v-select>
|
||||
</v-col>
|
||||
<v-col sm="3">
|
||||
<v-checkbox
|
||||
v-model="model.Favorite"
|
||||
:disabled="disabled"
|
||||
:label="$gettext('Favorite')"
|
||||
density="comfortable"
|
||||
hide-details
|
||||
></v-checkbox>
|
||||
<v-checkbox v-model="model.Favorite" :disabled="disabled" :label="$gettext('Favorite')" density="comfortable" hide-details></v-checkbox>
|
||||
</v-col>
|
||||
<v-col v-if="experimental && featPrivate" sm="3">
|
||||
<v-checkbox
|
||||
v-model="model.Private"
|
||||
:disabled="disabled"
|
||||
:label="$gettext('Private')"
|
||||
density="comfortable"
|
||||
hide-details
|
||||
></v-checkbox>
|
||||
<v-checkbox v-model="model.Private" :disabled="disabled" :label="$gettext('Private')" density="comfortable" hide-details></v-checkbox>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
|
|
|
|||
|
|
@ -7,12 +7,7 @@
|
|||
accept-charset="UTF-8"
|
||||
@submit.prevent="updateQuery()"
|
||||
>
|
||||
<v-toolbar
|
||||
flat
|
||||
:density="$vuetify.display.smAndDown ? 'compact' : 'default'"
|
||||
class="page-toolbar"
|
||||
color="secondary"
|
||||
>
|
||||
<v-toolbar flat :density="$vuetify.display.smAndDown ? 'compact' : 'default'" class="page-toolbar" color="secondary">
|
||||
<v-toolbar-title :title="album.Title" class="page__title">
|
||||
<router-link :to="{ name: collectionRoute }" class="hidden-xs">
|
||||
{{ T(collectionTitle) }}
|
||||
|
|
@ -36,13 +31,7 @@
|
|||
class="ms-1"
|
||||
>
|
||||
<v-btn value="cards" icon="mdi-view-column" class="ps-1 action-view-cards" @click="setView('cards')"></v-btn>
|
||||
<v-btn
|
||||
v-if="listView"
|
||||
value="list"
|
||||
icon="mdi-view-list"
|
||||
class="action-view-list"
|
||||
@click="setView('list')"
|
||||
></v-btn>
|
||||
<v-btn v-if="listView" value="list" icon="mdi-view-list" class="action-view-list" @click="setView('list')"></v-btn>
|
||||
<v-btn value="mosaic" icon="mdi-view-comfy" class="pe-1 action-view-mosaic" @click="setView('mosaic')"></v-btn>
|
||||
</v-btn-toggle>
|
||||
|
||||
|
|
@ -53,12 +42,7 @@
|
|||
{{ album.Description }}
|
||||
</div>
|
||||
|
||||
<p-share-dialog
|
||||
:visible="dialog.share"
|
||||
:model="album"
|
||||
@upload="webdavUpload"
|
||||
@close="dialog.share = false"
|
||||
></p-share-dialog>
|
||||
<p-share-dialog :visible="dialog.share" :model="album" @upload="webdavUpload" @close="dialog.share = false"></p-share-dialog>
|
||||
<p-service-upload
|
||||
:visible="dialog.upload"
|
||||
:items="{ albums: album.getId() }"
|
||||
|
|
@ -124,8 +108,7 @@ export default {
|
|||
return {
|
||||
expanded: false,
|
||||
canUpload: this.$config.allow("files", "upload") && features.upload,
|
||||
canDownload:
|
||||
this.$config.allow("albums", "download") && features.download && !settings?.albums?.download?.disabled,
|
||||
canDownload: this.$config.allow("albums", "download") && features.download && !settings?.albums?.download?.disabled,
|
||||
canShare: this.$config.allow("albums", "share") && features.share,
|
||||
canManage: this.$config.allow("albums", "manage"),
|
||||
canDelete: this.$config.allow("albums", "delete"),
|
||||
|
|
|
|||
|
|
@ -15,9 +15,7 @@
|
|||
<h6 class="text-h6">{{ $gettext(`Support Our Mission`) }}</h6>
|
||||
</v-card-title>
|
||||
<v-card-text class="text-subtitle-2">{{
|
||||
$gettext(
|
||||
`Your continued support helps us provide regular updates and remain independent, so we can fulfill our mission and protect your privacy.`
|
||||
)
|
||||
$gettext(`Your continued support helps us provide regular updates and remain independent, so we can fulfill our mission and protect your privacy.`)
|
||||
}}</v-card-text>
|
||||
<v-card-text class="text-body-2">{{
|
||||
$gettext(
|
||||
|
|
|
|||
|
|
@ -156,7 +156,6 @@ export default {
|
|||
color: "on-surface",
|
||||
bgColor: "secondary",
|
||||
baseColor: "secondary",
|
||||
sliderColor: "surface-variant",
|
||||
},
|
||||
VTable: {
|
||||
density: "comfortable",
|
||||
|
|
|
|||
|
|
@ -8,17 +8,8 @@
|
|||
:tab="edit.tab"
|
||||
@close="closeEditDialog"
|
||||
></p-photo-edit-dialog>
|
||||
<p-photo-batch-edit
|
||||
:visible="batchEdit.visible"
|
||||
:selection="batchEdit.selection"
|
||||
@close="closeBatchEdit"
|
||||
></p-photo-batch-edit>
|
||||
<p-upload-dialog
|
||||
:visible="upload.visible"
|
||||
:data="upload.data"
|
||||
@close="closeUploadDialog"
|
||||
@confirm="closeUploadDialog"
|
||||
></p-upload-dialog>
|
||||
<p-photo-batch-edit :visible="batchEdit.visible" :selection="batchEdit.selection" @close="closeBatchEdit"></p-photo-batch-edit>
|
||||
<p-upload-dialog :visible="upload.visible" :data="upload.data" @close="closeUploadDialog" @confirm="closeUploadDialog"></p-upload-dialog>
|
||||
<p-update :visible="update.visible" @close="closeUpdateDialog"></p-update>
|
||||
<p-lightbox @enter="onLightboxEnter" @leave="onLightboxLeave"></p-lightbox>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,15 +13,7 @@
|
|||
offset="12"
|
||||
>
|
||||
<template #activator="{ props }">
|
||||
<v-btn
|
||||
v-bind="props"
|
||||
icon
|
||||
size="52"
|
||||
color="highlight"
|
||||
variant="elevated"
|
||||
density="comfortable"
|
||||
class="action-menu opacity-95 ma-5"
|
||||
>
|
||||
<v-btn v-bind="props" icon size="52" color="highlight" variant="elevated" density="comfortable" class="action-menu opacity-95 ma-5">
|
||||
<span class="count-clipboard">{{ selection.length }}</span>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
|
@ -61,11 +53,7 @@
|
|||
></v-btn>
|
||||
</v-speed-dial>
|
||||
</div>
|
||||
<p-photo-album-dialog
|
||||
:visible="dialog.album"
|
||||
@close="dialog.album = false"
|
||||
@confirm="addToAlbum"
|
||||
></p-photo-album-dialog>
|
||||
<p-photo-album-dialog :visible="dialog.album" @close="dialog.album = false" @confirm="addToAlbum"></p-photo-album-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,5 @@
|
|||
<template>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
enable-background="new 0 0 24 24"
|
||||
height="24px"
|
||||
viewBox="0 0 24 24"
|
||||
width="24px"
|
||||
fill="currentColor"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
|
||||
<rect fill="none" height="24" width="24" />
|
||||
<path
|
||||
d="M9.68,13.69L12,11.93l2.31,1.76l-0.88-2.85L15.75,9h-2.84L12,6.19L11.09,9H8.25l2.31,1.84L9.68,13.69z M20,10 c0-4.42-3.58-8-8-8s-8,3.58-8,8c0,2.03,0.76,3.87,2,5.28V23l6-2l6,2v-7.72C19.24,13.87,20,12.03,20,10z M12,4c3.31,0,6,2.69,6,6 s-2.69,6-6,6s-6-2.69-6-6S8.69,4,12,4z"
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
hide-no-data
|
||||
return-object
|
||||
class="chip-selector__input"
|
||||
@click:control="focusInput"
|
||||
@keydown.enter.prevent="onEnter"
|
||||
@blur="addNewItem"
|
||||
@update:model-value="onComboboxChange"
|
||||
|
|
@ -220,17 +221,13 @@ export default {
|
|||
updateItemAction(itemToUpdate, action) {
|
||||
// Special case: remove new items completely
|
||||
if (itemToUpdate.isNew && action === "remove") {
|
||||
const updatedItems = this.items.filter(
|
||||
(item) => (item.value || item.title) !== (itemToUpdate.value || itemToUpdate.title)
|
||||
);
|
||||
const updatedItems = this.items.filter((item) => (item.value || item.title) !== (itemToUpdate.value || itemToUpdate.title));
|
||||
this.$emit("update:items", updatedItems);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update action for existing item
|
||||
const updatedItems = this.items.map((item) =>
|
||||
(item.value || item.title) === (itemToUpdate.value || itemToUpdate.title) ? { ...item, action } : item
|
||||
);
|
||||
const updatedItems = this.items.map((item) => ((item.value || item.title) === (itemToUpdate.value || itemToUpdate.title) ? { ...item, action } : item));
|
||||
|
||||
this.$emit("update:items", updatedItems);
|
||||
},
|
||||
|
|
@ -238,19 +235,8 @@ export default {
|
|||
onComboboxChange(value) {
|
||||
if (value && typeof value === "object" && value.title) {
|
||||
this.newItemTitle = value;
|
||||
this.temporarilyCloseMenu();
|
||||
this.addNewItem();
|
||||
this.menuOpen = false;
|
||||
// Immediately clear the input, remove focus and restore placeholder
|
||||
this.$nextTick(() => {
|
||||
this.newItemTitle = "";
|
||||
if (this.$refs.inputField) {
|
||||
this.$refs.inputField.blur();
|
||||
// Force the combobox to reset completely
|
||||
setTimeout(() => {
|
||||
this.newItemTitle = null;
|
||||
}, 10);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.newItemTitle = value;
|
||||
}
|
||||
|
|
@ -283,15 +269,12 @@ export default {
|
|||
}
|
||||
|
||||
const normalizedTitle = this.normalizeTitle(title);
|
||||
const existingItem = this.items.find(
|
||||
(item) => (item.value && value && item.value === value) || this.normalizeTitle(item.title) === normalizedTitle
|
||||
);
|
||||
const existingItem = this.items.find((item) => (item.value && value && item.value === value) || this.normalizeTitle(item.title) === normalizedTitle);
|
||||
|
||||
if (existingItem) {
|
||||
let changed = false;
|
||||
const updatedItems = this.items.map((item) => {
|
||||
const isSame =
|
||||
(item.value && value && item.value === value) || this.normalizeTitle(item.title) === normalizedTitle;
|
||||
const isSame = (item.value && value && item.value === value) || this.normalizeTitle(item.title) === normalizedTitle;
|
||||
if (!isSame) {
|
||||
return item;
|
||||
}
|
||||
|
|
@ -341,24 +324,13 @@ export default {
|
|||
};
|
||||
|
||||
this.$emit("update:items", [...this.items, newItem]);
|
||||
this.newItemTitle = null;
|
||||
this.menuOpen = false;
|
||||
|
||||
// Refocus input field
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.inputField) {
|
||||
this.$refs.inputField.focus();
|
||||
}
|
||||
});
|
||||
this.temporarilyCloseMenu();
|
||||
this.clearAndOptionallyRefocus(true);
|
||||
},
|
||||
|
||||
onEnter() {
|
||||
this.suppressMenuOpen = true;
|
||||
this.menuOpen = false;
|
||||
this.temporarilyCloseMenu();
|
||||
this.addNewItem();
|
||||
window.setTimeout(() => {
|
||||
this.suppressMenuOpen = false;
|
||||
}, 250);
|
||||
},
|
||||
|
||||
onMenuUpdate(val) {
|
||||
|
|
@ -368,20 +340,42 @@ export default {
|
|||
}
|
||||
this.menuOpen = val;
|
||||
},
|
||||
resetInputField() {
|
||||
|
||||
focusInput() {
|
||||
if (this.$refs.inputField && typeof this.$refs.inputField.focus === "function") {
|
||||
this.$refs.inputField.focus();
|
||||
}
|
||||
},
|
||||
|
||||
temporarilyCloseMenu() {
|
||||
this.menuOpen = false;
|
||||
this.suppressMenuOpen = true;
|
||||
window.setTimeout(() => {
|
||||
this.suppressMenuOpen = false;
|
||||
}, 200);
|
||||
},
|
||||
|
||||
clearAndOptionallyRefocus(shouldRefocus = false) {
|
||||
this.$nextTick(() => {
|
||||
this.newItemTitle = "";
|
||||
if (this.$refs.inputField) {
|
||||
this.$refs.inputField.blur();
|
||||
setTimeout(() => {
|
||||
this.newItemTitle = null;
|
||||
if (shouldRefocus) {
|
||||
this.focusInput();
|
||||
}
|
||||
}, 10);
|
||||
} else {
|
||||
this.newItemTitle = null;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
resetInputField() {
|
||||
this.temporarilyCloseMenu();
|
||||
this.clearAndOptionallyRefocus(false);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -13,15 +13,7 @@
|
|||
offset="12"
|
||||
>
|
||||
<template #activator="{ props }">
|
||||
<v-btn
|
||||
v-bind="props"
|
||||
icon
|
||||
size="52"
|
||||
color="highlight"
|
||||
variant="elevated"
|
||||
density="comfortable"
|
||||
class="action-menu opacity-95 ma-5"
|
||||
>
|
||||
<v-btn v-bind="props" icon size="52" color="highlight" variant="elevated" density="comfortable" class="action-menu opacity-95 ma-5">
|
||||
<span class="count-clipboard">{{ selection.length }}</span>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
|
@ -47,26 +39,11 @@
|
|||
class="action-delete"
|
||||
@click.stop="dialog.delete = true"
|
||||
></v-btn>
|
||||
<v-btn
|
||||
key="action-close"
|
||||
icon="mdi-close"
|
||||
color="grey-darken-2"
|
||||
density="comfortable"
|
||||
class="action-clear"
|
||||
@click.stop="clearClipboard()"
|
||||
></v-btn>
|
||||
<v-btn key="action-close" icon="mdi-close" color="grey-darken-2" density="comfortable" class="action-clear" @click.stop="clearClipboard()"></v-btn>
|
||||
</v-speed-dial>
|
||||
</div>
|
||||
<p-photo-album-dialog
|
||||
:visible="dialog.album"
|
||||
@close="dialog.album = false"
|
||||
@confirm="addToAlbum"
|
||||
></p-photo-album-dialog>
|
||||
<p-label-delete-dialog
|
||||
:visible="dialog.delete"
|
||||
@close="dialog.delete = false"
|
||||
@confirm="batchDelete"
|
||||
></p-label-delete-dialog>
|
||||
<p-photo-album-dialog :visible="dialog.album" @close="dialog.album = false" @confirm="addToAlbum"></p-photo-album-dialog>
|
||||
<p-label-delete-dialog :visible="dialog.delete" @close="dialog.delete = false" @confirm="batchDelete"></p-label-delete-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -11,14 +11,7 @@
|
|||
@after-enter="afterEnter"
|
||||
@after-leave="afterLeave"
|
||||
>
|
||||
<v-form
|
||||
ref="form"
|
||||
validate-on="invalid-input"
|
||||
class="form-label-edit"
|
||||
accept-charset="UTF-8"
|
||||
tabindex="-1"
|
||||
@submit.prevent="confirm"
|
||||
>
|
||||
<v-form ref="form" validate-on="invalid-input" class="form-label-edit" accept-charset="UTF-8" tabindex="-1" @submit.prevent="confirm">
|
||||
<v-card>
|
||||
<v-card-title class="d-flex justify-start align-center ga-3">
|
||||
<v-icon size="28" color="primary">mdi-label</v-icon>
|
||||
|
|
@ -38,14 +31,7 @@
|
|||
></v-text-field>
|
||||
</v-col>
|
||||
<v-col sm="4">
|
||||
<v-checkbox
|
||||
v-model="model.Favorite"
|
||||
:disabled="disabled"
|
||||
:label="$gettext('Favorite')"
|
||||
density="comfortable"
|
||||
hide-details
|
||||
>
|
||||
</v-checkbox>
|
||||
<v-checkbox v-model="model.Favorite" :disabled="disabled" :label="$gettext('Favorite')" density="comfortable" hide-details> </v-checkbox>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue