Compare commits

...
Author SHA1 Message Date
Dominik Schmidt 29f704a5cc chore(deps): bump libre-graph-api-go to latest main
GetUserPhoto now returns io.Reader; drop the obsolete Close().
2026-08-13 02:22:24 +02:00
Viktor Scharf 76ff13b47e api-test: replace sleeps with WaitHelper poll for async state (#3239)
* api-test: replace sleeps with WaitHelper poll for async state

* php-style
2026-08-05 09:23:57 +02:00
Andre Duffeck 799f98339e Merge pull request #3235 from pbleser-oc/feat/3182-posixfs-scan-add-subtree
feat(posixfs): #3182 add basepath option in the "posixfs scan" command
2026-08-04 09:15:22 +02:00
OpenCloud Devopsandv.scharf d695d283f6 🎉 Release 7.4.0 (#3143)
* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

---------

Co-authored-by: v.scharf <v.scharf@opencloud.eu>
2026-08-03 20:42:51 +02:00
Viktor Scharf 553c85b7ff set introduction version 7.4.0 (#3234) 2026-08-03 20:07:23 +02:00
Pascal Bleser 6663fbeeed feat(posixfs): #3182 add basepath option in the "posixfs scan" command
* add support for specifying a set of resources when running the
   posixfs scan command scanning, or a singular file to scan, as opposed

 * refactors the resource walking function implemented in
   https://github.com/opencloud-eu/opencloud/pull/3220 in order to
   reuse it for the posixfs scan command

 * implements https://github.com/opencloud-eu/opencloud/issues/3182

 * add --halt-on-error flag

 * collect errors and fail command when more than one error occured
2026-08-03 20:04:39 +02:00
Viktor Scharf 19e44f9b64 [full-ci] chore: bump web to v7.3.0 (#3223)
* chore: bump web to v7.3.0

* Update WEB_COMMITID in .woodpecker.env
2026-08-03 19:58:05 +02:00
Andre Duffeck c93f50dc37 Merge pull request #3233 from aduffeck/extend-posixfs-consistency-check
Do not check ignored paths
2026-08-03 17:50:35 +02:00
Viktor Scharf bb4cd1ebf5 chore: reva bump -2.48.0 (#3230) 2026-08-03 17:43:51 +02:00
dependabot[bot] e12966a4fd build(deps): bump github.com/open-policy-agent/opa from 1.18.2 to 1.19.0
Bumps [github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa) from 1.18.2 to 1.19.0.
- [Release notes](https://github.com/open-policy-agent/opa/releases)
- [Changelog](https://github.com/open-policy-agent/opa/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-policy-agent/opa/compare/v1.18.2...v1.19.0)

---
updated-dependencies:
- dependency-name: github.com/open-policy-agent/opa
  dependency-version: 1.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 17:00:51 +02:00
André Duffeck b350b355c0 Do not check ignored paths 2026-08-03 16:29:30 +02:00
dependabot[bot] 9df3881128 build(deps): bump google.golang.org/grpc from 1.82.0 to 1.83.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.82.0 to 1.83.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.82.0...v1.83.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.83.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 16:15:46 +02:00
Andre Duffeck 557adfc327 Merge pull request #3220 from aduffeck/extend-posixfs-consistency-check
Extend posixfs consistency check
2026-08-03 14:04:10 +02:00
André Duffeck 97ad525d5b Infer the indexes path from the config instead of calculating it 2026-08-03 13:24:23 +02:00
Ralf Haferkamp 0fd02c5ecf chore(idp): bump dependencies 2026-08-03 13:20:03 +02:00
Viktor Scharf 27a77567dd chore(skills): add skill for bumping reva (#3224)
* chore(skills): add skill for bumping reva

* chore(skills): derive OpenCloud version from open release PR

* chore: exclude .agents from codacy analysis
2026-08-03 13:18:43 +02:00
dependabot[bot] 57a615d6ce build(deps): bump github.com/nats-io/nats-server/v2
Bumps [github.com/nats-io/nats-server/v2](https://github.com/nats-io/nats-server) from 2.14.3 to 2.14.4.
- [Release notes](https://github.com/nats-io/nats-server/releases)
- [Changelog](https://github.com/nats-io/nats-server/blob/main/RELEASES.md)
- [Commits](https://github.com/nats-io/nats-server/compare/v2.14.3...v2.14.4)

---
updated-dependencies:
- dependency-name: github.com/nats-io/nats-server/v2
  dependency-version: 2.14.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 13:17:14 +02:00
André Duffeck deb3247b99 Move consistency check logic into a checker struct
This makes it possible to get rid of the globals without passing
multiple state vars around.
2026-08-03 12:17:19 +02:00
dependabot[bot] b9adb507f8 build(deps): bump github.com/go-ldap/ldap/v3 from 3.4.13 to 3.4.14
Bumps [github.com/go-ldap/ldap/v3](https://github.com/go-ldap/ldap) from 3.4.13 to 3.4.14.
- [Release notes](https://github.com/go-ldap/ldap/releases)
- [Commits](https://github.com/go-ldap/ldap/compare/v3.4.13...v3.4.14)

---
updated-dependencies:
- dependency-name: github.com/go-ldap/ldap/v3
  dependency-version: 3.4.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 12:16:16 +02:00
André Duffeck c6fba8543f Improve wording 2026-08-03 11:55:14 +02:00
dependabot[bot] 7c2cb14a80 build(deps): bump github.com/prometheus/client_golang
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.23.2 to 1.24.1.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/v1.24.1/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.23.2...v1.24.1)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-version: 1.24.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 11:04:15 +02:00
André Duffeck b125f0681f Fix typos 2026-08-03 11:03:45 +02:00
André Duffeck 20d16c5275 Allow for providing multiple paths to check 2026-08-03 10:58:53 +02:00
dependabot[bot] 639e3657cd build(deps): bump github.com/gabriel-vasile/mimetype
Bumps [github.com/gabriel-vasile/mimetype](https://github.com/gabriel-vasile/mimetype) from 1.4.13 to 1.4.15.
- [Release notes](https://github.com/gabriel-vasile/mimetype/releases)
- [Commits](https://github.com/gabriel-vasile/mimetype/compare/v1.4.13...v1.4.15)

---
updated-dependencies:
- dependency-name: github.com/gabriel-vasile/mimetype
  dependency-version: 1.4.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 10:44:05 +02:00
André Duffeck 559b10e90a Check if the given path is part of the storage 2026-08-03 09:49:10 +02:00
dependabot[bot] e63f1d542a build(deps): bump golang.org/x/net from 0.56.0 to 0.57.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.56.0 to 0.57.0.
- [Commits](https://github.com/golang/net/compare/v0.56.0...v0.57.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.57.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 09:26:21 +02:00
dependabot[bot] 51089765d0 build(deps): bump github.com/beevik/etree from 1.6.0 to 1.7.0
Bumps [github.com/beevik/etree](https://github.com/beevik/etree) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/beevik/etree/releases)
- [Changelog](https://github.com/beevik/etree/blob/main/RELEASE_NOTES.md)
- [Commits](https://github.com/beevik/etree/compare/v1.6.0...v1.7.0)

---
updated-dependencies:
- dependency-name: github.com/beevik/etree
  dependency-version: 1.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 09:25:47 +02:00
André Duffeck 54cced7c56 Streamline logging in the commands 2026-08-03 08:58:19 +02:00
André Duffeck 3d546693c6 Allow for checking specific spaces and files as well 2026-08-03 08:55:49 +02:00
André Duffeck 40ced9997e Also check blobsize and checksums (when --fix-checkums is set) 2026-08-03 08:55:10 +02:00
André Duffeck 3bd188122e Simplify output, remove spinner lib 2026-08-03 08:55:10 +02:00
opencloudeu 9b5849f470 [tx] updated from transifex 2026-07-31 23:16:44 +00:00
Andre Duffeck 942cca8eef Merge pull request #3191 from pbleser-oc/feat/#3182-posixfs-scan-subtree
feat(posixfs): #3182 add basepath option in the "posixfs scan" command
2026-07-31 16:39:48 +02:00
Dominik Schmidt a9f39b85d5 Merge pull request #3140 from opencloud-eu/fix/service-startup-logging
fix(runtime): log service startup errors instead of printing them beside the log
2026-07-31 16:37:19 +02:00
Andre Duffeck 15fc44be94 Merge pull request #3213 from aduffeck/improve-reindex-command
Improve reindex command
2026-07-31 16:34:54 +02:00
André Duffeck 2eb1fe069c Add a --concurrency flag to the index command
It controls the number of spaces that are indexed in parallel. The max
concurrency configured in the server is still considered.
2026-07-31 16:07:18 +02:00
André Duffeck a82b6223aa Remove the SilenceUsage flag again
It will be obsolete once #3140 has been merged
2026-07-31 15:55:36 +02:00
Pascal Bleser 433dea41e8 feat(posixfs): #3182 add basepath option in the "posixfs scan" command
* add support for specifying a basepath using -p when running the
   posixfs scan command, to indicate a directory under which to start
   scanning, or a singular file to scan, as opposed to scanning from the
   storage root directory as is the default behaviour

 * implements https://github.com/opencloud-eu/opencloud/issues/3182
2026-07-31 15:06:50 +02:00
André Duffeck e26a009fc1 Improve "opencloud search index" command
The command no longer times out after 10 minutes when the processing
hasn't been finished yet. Instead it shows progress and logs successful
and failed spaces. The process can also be aborted using ctrl+c.

Example output:

```
$ bin/opencloud search index --all-spaces --insecure --force-rescan
[1/602] indexed space a9033d65-6c13-4556-b923-f321ab33a9ca$eb6a8a0e-2e62-4b40-bce9-360063236676!eb6a8a0e-2e62-4b40-bce9-360063236676 in 5.501190908s
[2/602] indexed space a9033d65-6c13-4556-b923-f321ab33a9ca$34b7c565-da3b-4f53-8559-825e87db4011!34b7c565-da3b-4f53-8559-825e87db4011 in 5.935075697s
[3/602] indexed space a9033d65-6c13-4556-b923-f321ab33a9ca$e08c6026-24f6-4a9e-a805-ed335b34b8da!e08c6026-24f6-4a9e-a805-ed335b34b8da in 6.016350958s
^Caborted, indexing has been stopped
```

Fixes #2592
2026-07-31 14:50:09 +02:00
André Duffeck 49a81c9c1f Cleanup .bingo 2026-07-31 14:50:09 +02:00
Andre Duffeck 7e8179a704 Merge pull request #3207 from aduffeck/concurrent-reindex
Reindex spaces concurrently
2026-07-31 14:49:58 +02:00
André Duffeck d50d8d8900 Rename max concurrency option 2026-07-31 12:04:44 +02:00
André Duffeck 243514ec17 Do not abort reindexing all spaces if one of the spaces fails 2026-07-30 15:34:57 +02:00
André Duffeck be75d8fe95 Reindex spaces concurrently
This speeds up reindexing all spaces which happend sequentially space
after space until now. The level of concurrency can be configured using
the SEARCH_REINDEX_CONCURRENCY env var (3 by default).
2026-07-30 15:25:13 +02:00
Dominik Schmidt bb8cefa33b Merge pull request #3189 from opencloud-eu/feat/announcement-banner
feat: add announcement banner
2026-07-30 10:44:17 +02:00
Viktor Scharf 0a44bbae9e api-test: mark group last-manager removal scenario as flaky (#3194) 2026-07-30 09:50:05 +05:45
opencloudeu fb387a16b6 [tx] updated from transifex 2026-07-29 23:16:50 +00:00
Ralf Haferkamp e358cb6e6e fix(posixfs scan): Setup logger for scan command
Setup a logger for the FS. The nats kv clients for the caches need one
to be able to log NAT connection issues.

Fixes: #3184
2026-07-29 14:29:19 +02:00
Dominik Schmidt 341ebdf6cc refactor: mark the announcement config as output-only (yaml:"-")
The announcement is runtime-managed and injected into config.json; it is not a
static yaml config option. Exclude it from yaml (yaml:"-") so it is not
presented as a configurable knob, keeping the json tag only for the config.json
output.
2026-07-29 12:03:57 +02:00
Dominik Schmidt 6d2d6c38ec fix: fail fast when the announcement store is unreachable
Replace reva's cache.NewNatsKeyValue (which retries with backoff and can hang
the web service startup) with a direct nats.Connect + jetstream setup like the
graph service, so an unreachable or misconfigured store surfaces as a clear
startup error instead of a hang.
2026-07-29 11:53:58 +02:00
Dominik Schmidt d27b7ef40a refactor: drop static config for the announcement, runtime store only
A statically configured announcement is not supported: it cannot be removed via
the runtime API and disappears from the running session once the admin settings
load (they read the store, not config.json). Make the store the single source
of truth, config.json always reflects it and a statically configured
options.announcement is ignored.
2026-07-29 11:52:09 +02:00
Dominik Schmidt 27bdda265f refactor: back the announcement store with plain NATS JetStream
Replace the go-micro store with a NATS JetStream key-value bucket, created via
reva's cache.NewNatsKeyValue, so the web service no longer depends on go-micro
stores. The store methods now take a context, threaded through the config.json
render path and the management handlers. Tests use a mockery mock of
jetstream.KeyValue.
2026-07-29 10:22:43 +02:00
Dominik Schmidt 7d59a83c18 feat: log announcement handler errors with the request id
Add a logger to the announcement service and log server-side errors before
returning a 5xx, tagged with the request id so they correlate with the
request log line from the logging middleware.
2026-07-29 10:08:47 +02:00
Dominik Schmidt 9d472290f2 fix: return 413 when the announcement body exceeds the size cap
Distinguish the http.MaxBytesReader limit from a malformed body: an
oversized payload now returns 413 Request Entity Too Large instead of a
generic 400.
2026-07-29 08:46:46 +02:00
Dominik Schmidt e29d961be3 refactor: rename Announcement.Write to Announcement.ReadWrite
The permission gates reading the full announcement state (including
disabled ones) as well as writing it, so name it ReadWrite to match the
other management permissions (Accounts.ReadWrite, Settings.ReadWrite, ...)
and use the READWRITE operation.
2026-07-29 08:40:29 +02:00
Dominik Schmidt 809d32c4d8 fix: keep a static announcement as fallback when the store is empty
Make the store authoritative only once it manages an announcement: an
enabled record is exposed, a disabled record clears any static config, and
an empty store falls back to a statically configured
web.config.options.announcement. This matches the review request and stops
a static announcement from being silently dropped.
2026-07-29 08:29:58 +02:00
Dominik Schmidt 046f46ce8d fix: make the runtime store authoritative for the announcement
Always reflect the stored announcement in config.json: expose it while live
and clear it otherwise. A disabled announcement now clears the config output
instead of falling back to a statically configured one, which removes the
precedence ambiguity raised in review.
2026-07-29 08:18:56 +02:00
Dominik Schmidt 51dd107767 feat: add announcement banner 2026-07-29 00:39:59 +02:00
Viktor Scharf d9e406ca99 rerun flaky tests (#3183) 2026-07-28 13:44:28 +02:00
Viktor Scharf a2bdbc8b56 api-test: fix removeAccessToDrive.feature:145 (#3179)
* api-test: fix removeAccessToDrive.feature:145

* fix after review
2026-07-28 13:19:26 +02:00
Viktor Scharf 743899055a delete qa report (#3178) 2026-07-28 09:29:44 +02:00
opencloudeu f6ffd125c9 [tx] updated from transifex 2026-07-27 23:16:42 +00:00
Viktor Scharf f3693ef112 api-test: cover additional unified roles in acceptance tests (#3169) 2026-07-27 09:12:38 +02:00
opencloudeu a87163fb14 [tx] updated from transifex 2026-07-25 23:16:48 +00:00
Thomas Schweiger 2649fa0aab Merge pull request #3155 from opencloud-eu/clean-up-auth-app-docu
maint: clean-up auth-app documentation
2026-07-24 21:31:41 +02:00
opencloudeu 12cec14b56 [tx] updated from transifex 2026-07-22 23:16:36 +00:00
Viktor Scharf 44ae3a8ab5 ci: sync tests/README.md to docs (#3164) 2026-07-22 14:27:50 +02:00
Viktor Scharf a3a271aad5 test(apiAuthApp): fix flaky token pattern (#3163) 2026-07-22 17:39:01 +05:45
Florian Schadeandv.scharf 9041ee8df9 feat: add space viewer with versions role (#2961)
* feat: add space viewer with versions role

* fix after review

---------

Co-authored-by: v.scharf <v.scharf@opencloud.eu>
2026-07-22 07:05:51 +02:00
opencloudeu 052636ff0f [tx] updated from transifex 2026-07-21 23:16:43 +00:00
Ralf Haferkamp c8805265e2 chore: don't log non-error message at error level
When walking the tree for creating the search index, ignore "not found"
errors. Search indexing happens asynchronously so the underlying space,
file or folder might just not exist anymore when the indexing starts.
2026-07-21 11:40:44 +02:00
Thomas Schweiger a28ddc8285 maint: clean-up auth-app documentation 2026-07-20 10:37:57 +02:00
opencloudeu 0245a2197b [tx] updated from transifex 2026-07-19 23:16:36 +00:00
Michael Stingl bf3b5c5e1f test(apiArchiver): the single-resource archive is named after the resource (#3080)
An archive download of a single folder was always named "download.zip" until the
handler resolved the resource name for the Content-Disposition header
(https://github.com/opencloud-eu/reva/pull/661). Add a scenario asserting the
archive of a folder carries a Content-Disposition filename of the folder,
reusing the archiver download step and the header-regex assertion.

Verified red->green on posix and decomposed: red on an opencloud built on a reva
with the change reverted (the archive is "download.zip"), green on the shipped
reva.
2026-07-17 16:37:36 +02:00
Michael Stinglandv.scharf 76ffc82bba test(coreApiWebdavUploadTUS): assert etag and permissions on the finalizing TUS chunk (#3078)
* test(coreApiWebdavUploadTUS): assert etag and permissions on the finalizing TUS chunk

The chunked TUS finalize returns OC-ETag, ETag and OC-Perm since
https://github.com/opencloud-eu/reva/pull/718, so a client no longer
needs a follow-up PROPFIND for the new etag and permissions. Add a
scenario asserting these headers on the finalizing chunk, reusing
existing step definitions (the etag is a dynamic quoted hash, hence the
header-regex assertion).

Verified locally red->green: red on stock (headers absent), green on an
opencloud built on a reva carrying that change, on posix and decomposed.

https://github.com/opencloud-eu/opencloud/issues/2409

* test(coreApiWebdavUploadTUS): assert exact OC-Perm and tighten etag regex

---------

Co-authored-by: v.scharf <v.scharf@opencloud.eu>
2026-07-17 14:40:37 +02:00
Michael Stingl 3893be6ed1 test(coreApiWebdavOperations): download a file with a literal "%" via its oc:downloadURL (#3079)
A file whose name contains a literal "%" 404s on download because the
server-built oc:downloadURL did not percent-encode the path (#2852, fixed in
reva by https://github.com/opencloud-eu/reva/pull/653). Add a scenario mirroring
the web client download flow: read the oc:downloadURL from PROPFIND and GET it
as-is (the signature in the URL authenticates it), asserting 200 and the content.

The new step "user X downloads the P file via its oc:downloadURL" lives in
WebDavPropertiesContext; a regex annotation avoids the ":" in oc:downloadURL
colliding with the turnip :placeholder syntax.

Verified red->green on posix and decomposed: red on an opencloud built on a reva
with the fix reverted (the download 404s), green on the shipped reva.

https://github.com/opencloud-eu/opencloud/issues/2852
2026-07-17 14:20:00 +02:00
Viktor Scharf a82aeef2eb add header to release pr. remove 📦️ Dependencies from release description (#3144) 2026-07-17 08:07:28 +02:00
Viktor Scharf e13b86950a fix(ci): replace deprecated runs_on. Removed skipCheckStep() (#3145)
* fix(ci): replace deprecated runs_on

* drop skipCheckStep()

* fix
2026-07-17 08:06:35 +02:00
Alex 2f9d9c582c add version to apps config (#3139) 2026-07-16 11:28:45 +02:00
Jannik Stehle d731cb4c0f Merge pull request #3137 from opencloud-eu/refactor/remove-color-palette-from-theme
refactor(web): remove colorPalette from theme
2026-07-16 06:29:50 +02:00
Dominik Schmidt fec92d2f22 fix(runtime): keep the usage block for flag errors only 2026-07-15 19:01:03 +02:00
Dominik Schmidt 00dd4f1b7f fix(runtime): log service startup errors instead of printing them beside the log 2026-07-15 18:32:04 +02:00
Jannik Stehle e7f850c2aa refactor(web): remove colorPalette from theme
With the recently added new file type icons in Web, the colorPalette
option in the theme.json becomes obsolete. Hence remove it.

Also see https://github.com/opencloud-eu/web/pull/2892
2026-07-15 08:56:37 +02:00
OpenCloud Devopsandv.scharf 85e63ca252 🎉 Release 7.3.0 (#2890)
* 🎉 Release 6.2.1

* 🎉 Release 6.2.1

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 7.0.0

* add release 7.2.0 to changelog

* add release 7.3.0 to changelog

---------

Co-authored-by: v.scharf <v.scharf@opencloud.eu>
2026-07-14 18:52:14 +02:00
Viktor Scharf 5accb6056b set 7.3.0 version placeholder (#3132) 2026-07-14 18:12:24 +02:00
Elias Schneider 4734c57f2b fix(proxy): honor access token cache ttl 2026-07-14 17:49:40 +02:00
dependabot[bot] fcde95750b build(deps): bump golang.org/x/image from 0.43.0 to 0.44.0
Bumps [golang.org/x/image](https://github.com/golang/image) from 0.43.0 to 0.44.0.
- [Commits](https://github.com/golang/image/compare/v0.43.0...v0.44.0)

---
updated-dependencies:
- dependency-name: golang.org/x/image
  dependency-version: 0.44.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-14 16:38:06 +02:00
dependabot[bot] eab58b8190 build(deps): bump golang.org/x/text from 0.39.0 to 0.40.0
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.39.0 to 0.40.0.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.39.0...v0.40.0)

---
updated-dependencies:
- dependency-name: golang.org/x/text
  dependency-version: 0.40.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-14 16:37:38 +02:00
Jörn Friedrich Dreyer 48e40a385c update collaboration readme
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
2026-07-14 16:29:57 +02:00
Viktor Scharf 4d511a3a42 [full-ci] chore: reva bump -2.47.0 (#3127) 2026-07-14 13:15:54 +02:00
Viktor Scharf a53eb44083 steps refactoring (#3100) 2026-07-14 09:32:35 +02:00
Benedikt Kulmann ea1a1dd5e2 Merge pull request #3121 from opencloud-eu/chore/bump-web-v7.2.0
[full-ci] chore: bump web to v7.2.0
2026-07-13 12:30:10 +02:00
v.scharf ff5bcdee3f add rclone to web-config 2026-07-13 11:56:15 +02:00
v.scharf 559706696a adjust e2e tests in CI 2026-07-13 11:19:51 +02:00
Benedikt Kulmann 02aea2e65e chore: bump web to v7.2.0 2026-07-13 10:29:16 +02:00
Ralf Haferkamp 8c3ef60da1 chore(idp): bump form-data and xmldom
To address issues raised in the security dashboard. Also ran `pnpm
dedupe` for cleanup
2026-07-10 14:46:32 +02:00
dependabot[bot] b5b6a4ee26 build(deps): bump golang.org/x/term from 0.44.0 to 0.45.0
Bumps [golang.org/x/term](https://github.com/golang/term) from 0.44.0 to 0.45.0.
- [Commits](https://github.com/golang/term/compare/v0.44.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/term
  dependency-version: 0.45.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-10 13:11:45 +02:00
dependabot[bot] e992f952d3 build(deps): bump github.com/coreos/go-oidc/v3 from 3.19.0 to 3.20.0
Bumps [github.com/coreos/go-oidc/v3](https://github.com/coreos/go-oidc) from 3.19.0 to 3.20.0.
- [Release notes](https://github.com/coreos/go-oidc/releases)
- [Commits](https://github.com/coreos/go-oidc/compare/v3.19.0...v3.20.0)

---
updated-dependencies:
- dependency-name: github.com/coreos/go-oidc/v3
  dependency-version: 3.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-10 13:11:02 +02:00
Jörn Friedrich Dreyer e5105ab33f Merge pull request #3097 from opencloud-eu/update-idp-i18n
chore(idp): update i18n, document workflow
2026-07-10 08:38:34 +02:00
opencloudeu 44c51e88ca [tx] updated from transifex 2026-07-09 23:16:27 +00:00
Jörn Friedrich Dreyer bb028a569f chore(idp): update i18n, document workflow
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
2026-07-09 14:48:34 +02:00
796 changed files with 54581 additions and 22138 deletions

No files matched your search

+153
View File
@@ -0,0 +1,153 @@
---
name: bumping-reva
description: Use when the user asks to bump, update, or upgrade the OpenCloud reva dependency to a specific version (e.g. "reva bump to 2.48.0", "bump reva to v2.48.0"). Covers editing go.mod, re-vendoring, bumping the OpenCloud LatestTag, the single commit, and opening the PR against main.
---
# Bumping Reva
## Overview
Bumping reva updates the pinned [opencloud-eu/reva](https://github.com/opencloud-eu/reva) dependency (`github.com/opencloud-eu/reva/v2`) to a tagged release, re-vendors the module graph, and bumps the OpenCloud dev version. It touches `go.mod`, `go.sum`, `vendor/**` and `pkg/version/version.go`, lands as one commit, and ships as a PR whose body is the reva changelog for that version.
Template PR: https://github.com/opencloud-eu/opencloud/pull/3127
## Prerequisites
- **The reva release must already be tagged.** A reva release is cut by merging its release PR (title `🎉 Release X.Y.Z`, branch `next-release/main`). The **user merges that PR themselves** — this skill starts *after* the tag `vX.Y.Z` exists. Verify the tag before doing anything (step 1); if it's missing, stop and ask the user to merge the reva release PR first.
- **`gh` (GitHub CLI), authenticated** — tag lookup and PR creation go through `gh api` / `gh pr`. Verify with `gh auth status`; if it fails, ask the user to run `gh auth login` (suggest `! gh auth login` so it runs in-session).
- `gh` needs the system keyring, so run all `gh` commands with the sandbox disabled.
- **Go toolchain + network** — `go get` / `go mod tidy` / `go mod vendor` hit the Go module proxy. Run them with the sandbox disabled (network access).
- `git` and `base64` (decoding the changelog) — standard on macOS/Linux.
## Inputs
- `REVA_VERSION` — the new reva tag, always normalized to a leading `v` (e.g. `v2.48.0`). If the user didn't give it, ask (or take the latest reva release tag).
- `OC_VERSION` — the OpenCloud target for `LatestTag`, **without** the `+dev` suffix (e.g. `7.4.0`). **Do not ask or guess** — derive it from the open OpenCloud release PR (step 3). It can be a new major (e.g. `8.0.0`) when release-please picked up a breaking change.
## What changes
| File | What |
| ------------------------ | ------------------------------------------------------------------- |
| `go.mod` | `github.com/opencloud-eu/reva/v2``REVA_VERSION` (+ indirect deps pulled by `go mod tidy`) |
| `go.sum` | updated by `go get` / `go mod tidy` |
| `vendor/**` | re-vendored by `go mod vendor` (incl. `vendor/modules.txt`) |
| `pkg/version/version.go` | `LatestTag = "<OC_VERSION>+dev"` |
## Procedure
### 1. Verify the reva tag exists
```bash
gh api repos/opencloud-eu/reva/commits/$REVA_VERSION --jq '.sha'
```
- Success (a sha) → the release is tagged, continue.
- `422`/`404` → the tag does not exist yet. The reva release PR (`🎉 Release X.Y.Z`) is probably not merged. **Stop** and tell the user to merge it first. Helpful checks:
```bash
gh api repos/opencloud-eu/reva/releases/latest --jq '.tag_name' # current latest tag
gh pr list --repo opencloud-eu/reva --search '🎉 Release in:title' --state open --json number,title
```
### 2. Bump the dependency and re-vendor
```bash
go get github.com/opencloud-eu/reva/v2@$REVA_VERSION
go mod tidy
go mod vendor
```
(Sandbox disabled — these need network.) Notes:
- Right after a fresh tag the module proxy can lag; if `go get` reports the version as unknown, retry, or use `GOPROXY=direct go get github.com/opencloud-eu/reva/v2@$REVA_VERSION`.
- `go mod tidy` will also bump indirect dependencies that reva pulled in — that is expected (the template PR did the same).
### 3. Bump the OpenCloud dev version
`OC_VERSION` is the version of the **open OpenCloud release PR** — the release-please PR from branch `next-release/main`, titled `🎉 Release X.Y.Z` (e.g. #3143). Derive it, don't ask:
```bash
gh pr list --repo opencloud-eu/opencloud --head next-release/main --state open \
--json title --jq '.[0].title' | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1
```
This is the next release target and tracks breaking changes — it may be a new major (e.g. `8.0.0`), not just a minor bump. If no such PR is open, stop and ask the user.
Edit `pkg/version/version.go`:
```go
LatestTag = "<OC_VERSION>+dev" // e.g. "7.4.0+dev"
```
### 4. Fetch the reva changelog for the PR body
```bash
gh api "repos/opencloud-eu/reva/contents/CHANGELOG.md?ref=$REVA_VERSION" --jq '.content' | base64 -d
```
Take **only the section for this version** and trim it exactly like the web bump: start at the first content heading (`### 🐛 Bug Fixes` / `### 📈 Enhancement` / `### 💥 Breaking changes`), drop the `# Changelog` title, the `## [x.y.z] - date` header and the `### ❤️ Thanks to all contributors!` block, and stop before the next `## [...]` version header.
Then **prepend two summary bullets** so the final PR body is:
```
- bump opencloud version to <OC_VERSION>
- reva bump <REVA_VERSION without the leading v>
### 🐛 Bug Fixes
...trimmed reva changelog...
```
Write this to a file for `--body-file` (e.g. in the scratchpad).
### 5. Confirm before committing
The `vendor/` diff is huge — do **not** dump it. Show the user:
```bash
git diff go.mod pkg/version/version.go # the meaningful edits
git diff --stat | tail -1 # vendor churn summary
```
Confirm the reva line in `go.mod` is exactly `github.com/opencloud-eu/reva/v2 REVA_VERSION`, show the target branch (`main`), and the PR body. **Do not commit until the user approves.**
### 6. Commit, push, open PR
- Create a branch (do not commit on `main`), e.g. `reva-bump-2.48.0`.
- Stage everything the bump touched: `git add go.mod go.sum vendor pkg/version/version.go`.
- One commit, conventional-commits format, **empty body**:
```
chore: reva bump -2.48.0
```
- PR base: **`main`** (reva bumps always target main).
- PR title: `[full-ci] chore: reva bump -2.48.0` (the commit message prefixed with `[full-ci] `).
- PR body: the file from step 4.
- Add the label `Type:Maintenance`.
```bash
gh pr create --base main \
--title "[full-ci] chore: reva bump -$REVA_VERSION_NO_V" \
--label "Type:Maintenance" \
--body-file <body-file>
```
(`gh` commands need the sandbox disabled — they require the system keyring.)
## Quick reference
```bash
REVA_VERSION=v2.48.0
gh api repos/opencloud-eu/reva/commits/$REVA_VERSION --jq '.sha' # verify tag exists
OC_VERSION=$(gh pr list --repo opencloud-eu/opencloud --head next-release/main --state open \
--json title --jq '.[0].title' | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) # from open release PR
go get github.com/opencloud-eu/reva/v2@$REVA_VERSION && go mod tidy && go mod vendor # bump + re-vendor
# edit pkg/version/version.go -> LatestTag = "$OC_VERSION+dev"
gh api "repos/opencloud-eu/reva/contents/CHANGELOG.md?ref=$REVA_VERSION" --jq '.content' | base64 -d # changelog
```
## Common mistakes
- Running the bump before the reva release PR is merged — the tag won't exist and `go get` will fail. Verify the tag first (step 1).
- Forgetting to re-run `go mod vendor` after `go mod tidy`, leaving `vendor/` out of sync with `go.mod`.
- Asking for or hardcoding `OC_VERSION` — always derive it from the open `next-release/main` release PR (step 3); it can even be a new major after a breaking change.
- Reading the changelog from reva `main` instead of the tag (`?ref=$REVA_VERSION`). Always pin to the tag.
- Missing the `[full-ci] ` prefix in the PR title, the `Type:Maintenance` label, or the two summary bullets at the top of the body.
- Dumping the full `vendor/` diff at the confirmation step instead of `go.mod` + `version.go` + a `--stat` summary.
- Committing before the user confirms the diff.
+2
View File
@@ -1,6 +1,7 @@
---
exclude_paths:
- '.github/**'
- '.agents/**'
- 'CHANGELOG.md'
- '**/CHANGELOG.md'
- 'changelog/**'
@@ -15,6 +16,7 @@ exclude_paths:
- 'idp/src/**'
- 'devtools/**'
- 'deployments/**'
- "release-config.ts"
- 'tests/acceptance/expected-failures-*.md'
- 'tests/acceptance/bootstrap/**'
- 'tests/acceptance/TestHelpers/**'
+2 -2
View File
@@ -40,8 +40,8 @@ vendor-php
suite-logs
tests/acceptance/filesForUpload/filesWithVirus/
# QA activity reports
tests/qa-activity-report/reports/
# Generated docs page (published to the server-testing-docs branch by CI)
tests/.docs-dist/
# drone CI is in .drone.star, do not let someone accidentally commit a local .drone.yml
.drone.yml
+5
View File
@@ -0,0 +1,5 @@
{
"recommendations": [
"alexkrechik.cucumberautocomplete"
]
}
+16
View File
@@ -0,0 +1,16 @@
{
"cucumberautocomplete.steps": [
"tests/acceptance/bootstrap/*.php"
],
"cucumberautocomplete.syncfeatures": "tests/acceptance/features/**/*.feature",
"cucumberautocomplete.strictGherkinCompletion": false,
"cucumberautocomplete.strictGherkinValidation": false,
"cucumberautocomplete.customParameters": [
{ "parameter": ":string", "value": "\"([^\"]*)\"" },
{ "parameter": "'/\\^(.*)\\$/'", "value": "'^$1$$'", "isRegex": true, "flags": "g" },
{ "parameter": "\\$\\w+", "value": "(.*)", "isRegex": true, "flags": "g" },
{ "parameter": "(?<!\\?):[a-zA-Z_][a-zA-Z0-9_]*", "value": "\"([^\"]*)\"", "isRegex": true, "flags": "g" }
],
"cucumberautocomplete.gherkinDefinitionPart": "(Given|When|Then|But)\\(",
"cucumberautocomplete.pureTextSteps": false
}
+1 -1
View File
@@ -1,3 +1,3 @@
# The test runner source for UI tests
WEB_COMMITID=47a1cfb1dbda4479b88e831d089bfa54b1f4bb8d
WEB_COMMITID=52b3c79f772feae23b7e77058c89c4151087502e
WEB_BRANCH=main
+217 -129
View File
@@ -375,30 +375,31 @@ config = {
"1": {
"skip": False,
"suites": [
"journeys",
"smoke",
"journeys/",
"smoke/",
],
},
"2": {
"skip": False,
"suites": [
"admin-settings",
"spaces",
"admin-settings/",
"spaces/",
"rclone-crypt/",
],
},
"3": {
"skip": False,
"suites": [
"shares",
"search",
"shares/",
"search/",
],
"tikaNeeded": True,
},
"4": {
"skip": False,
"suites": [
"user-settings",
#"fileaction",
"user-settings/",
"fileaction/",
"embed",
],
},
@@ -407,12 +408,12 @@ config = {
"testSuites": {
"skip": False,
"suites": [
"smoke",
"shares",
"search",
"journeys",
#"file-action",
"spaces",
"smoke/",
"shares/",
"search/",
"journeys/",
"file-action/",
"spaces/",
],
"tikaNeeded": True,
},
@@ -489,13 +490,14 @@ def prefixStepCommands(pipeline, commands = [], skip_steps = []):
if "commands" in step.keys() and step["name"] not in skip_steps:
step["commands"] = commands + step["commands"]
def pipelineDependsOn(pipeline, dependant_pipelines):
def pipelineDependsOn(pipeline, dependant_pipelines, optional = False):
if type(pipeline) == "list":
pipeline = pipeline[0]
depends = getPipelineNames(dependant_pipelines, optional = optional)
if "depends_on" in pipeline.keys():
pipeline["depends_on"] = pipeline["depends_on"] + getPipelineNames(dependant_pipelines)
pipeline["depends_on"] = pipeline["depends_on"] + depends
else:
pipeline["depends_on"] = getPipelineNames(dependant_pipelines)
pipeline["depends_on"] = depends
return pipeline
def pipelinesDependsOn(pipelines, dependant_pipelines):
@@ -505,18 +507,13 @@ def pipelinesDependsOn(pipelines, dependant_pipelines):
return pipes
def getPipelineNames(pipelines = []):
"""getPipelineNames returns names of pipelines as a string array
Args:
pipelines: array of woodpecker pipelines
Returns:
names of the given pipelines as string array
"""
def getPipelineNames(pipelines = [], optional = False):
names = []
for pipeline in pipelines:
names.append(pipeline["name"])
if optional:
names.append({"name": pipeline["name"], "optional": True})
else:
names.append(pipeline["name"])
return names
def main(ctx):
@@ -569,6 +566,7 @@ def main(ctx):
pipelineDependsOn(
purgeBuildArtifactCache(ctx),
testPipelines(ctx),
optional = True,
),
)
@@ -576,6 +574,7 @@ def main(ctx):
pipelineDependsOn(
purgeBrowserCache(ctx),
testPipelines(ctx),
optional = True,
),
)
@@ -583,6 +582,7 @@ def main(ctx):
pipelineDependsOn(
purgeTracingCache(ctx),
testPipelines(ctx),
optional = True,
),
)
@@ -590,6 +590,7 @@ def main(ctx):
pipelineDependsOn(
purgeOpencloudWebBuildCache(ctx),
testPipelines(ctx),
optional = True,
),
)
@@ -597,6 +598,7 @@ def main(ctx):
pipelineDependsOn(
purgeGoBinCache(ctx),
testPipelines(ctx),
optional = True,
),
)
@@ -604,10 +606,11 @@ def main(ctx):
pipelineDependsOn(
purgePipelineInfoCache(),
testPipelines(ctx),
optional = True,
),
)
pipelines = test_pipelines + build_release_pipelines + genDocsPr(ctx) + notifyMatrixCheckSteps(ctx, getPipelineNames(testPipelines(ctx)))
pipelines = test_pipelines + build_release_pipelines + genDocsPr(ctx) + serverTestingDocs(ctx) + notifyMatrixCheckSteps(ctx, getPipelineNames(testPipelines(ctx), optional = True))
pipelineSanityChecks(pipelines)
return savePipelineNumber(ctx) + pipelines
@@ -648,7 +651,6 @@ def evaluateWorkflowStep():
}]
def cachePipeline(ctx, name, steps):
steps = skipCheckStep(ctx, "base") + steps
pipeline = {
"name": "cache-%s" % name,
"steps": steps,
@@ -658,13 +660,14 @@ def cachePipeline(ctx, name, steps):
"branch": ["main", "stable-*"],
},
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "base"),
},
},
],
}
prefixStepCommands(pipeline, [
". ./.woodpecker.env",
'[ "$SKIP_WORKFLOW" = "true" ] && exit 0',
])
return pipeline
def buildWebCache(ctx):
@@ -713,8 +716,7 @@ def testPipelines(ctx):
def getGoBinForTesting(ctx):
pipeline = {
"name": "get-go-bin-cache",
"steps": skipCheckStep(ctx, "base") +
checkGoBinCache() +
"steps": checkGoBinCache() +
cacheGoBin(),
"when": [
event["tag"],
@@ -723,14 +725,15 @@ def getGoBinForTesting(ctx):
"event": ["push", "manual"],
"branch": ["main", "stable-*"],
},
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "unit-tests"),
},
},
],
"workspace": workspace,
}
prefixStepCommands(pipeline, [
". ./.woodpecker.env",
'[ "$SKIP_WORKFLOW" = "true" ] && exit 0',
])
return [pipeline]
def checkGoBinCache():
@@ -803,7 +806,6 @@ def restoreGoBinCache():
]
def testOpencloud(ctx):
#steps = skipCheckStep(ctx, "unit-tests") + evaluateWorkflowStep() + restoreGoBinCache() + makeGoGenerate("") + [
steps = evaluateWorkflowStep() + restoreGoBinCache() + makeGoGenerate("") + [
{
"name": "golangci-lint",
@@ -873,7 +875,12 @@ def testOpencloud(ctx):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "unit-tests"),
},
},
],
"depends_on": getPipelineNames(getGoBinForTesting(ctx)),
"workspace": workspace,
@@ -887,7 +894,7 @@ def testOpencloud(ctx):
return [pipeline]
def scanOpencloud(ctx):
steps = skipCheckStep(ctx, "base") + restoreGoBinCache() + makeGoGenerate("") + [
steps = restoreGoBinCache() + makeGoGenerate("") + [
{
"name": "govulncheck",
"image": OC_CI_GOLANG,
@@ -898,22 +905,22 @@ def scanOpencloud(ctx):
},
]
pipeline = {
return {
"name": "go-vulnerability-scanning",
"steps": steps,
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
"depends_on": getPipelineNames(getGoBinForTesting(ctx)),
"workspace": workspace,
}
prefixStepCommands(pipeline, [
". ./.woodpecker.env",
'[ "$SKIP_WORKFLOW" = "true" ] && exit 0',
])
return [pipeline]
def buildOpencloudBinaryForTesting(ctx):
pipeline = {
@@ -970,7 +977,12 @@ def checkTestSuitesInExpectedFailures(ctx):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}]
@@ -990,7 +1002,12 @@ def checkGherkinLint(ctx):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "lint"),
},
},
],
}]
@@ -1054,7 +1071,12 @@ def codestyle(ctx):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "lint"),
},
},
],
}
@@ -1065,8 +1087,7 @@ def codestyle(ctx):
def cs3ApiTests(ctx, storage):
pipeline = {
"name": "test-cs3-API-%s" % storage,
"steps": skipCheckStep(ctx, "acceptance-tests") +
evaluateWorkflowStep() +
"steps": evaluateWorkflowStep() +
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
opencloudServer(storage, deploy_type = "cs3api_validator") +
[
@@ -1085,7 +1106,12 @@ def cs3ApiTests(ctx, storage):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}
prefixStepCommands(pipeline, [
@@ -1169,8 +1195,7 @@ def wopiValidatorTests(ctx, storage, wopiServerType):
pipeline = {
"name": "test-wopi-validator-%s-%s" % (wopiServerType, storage),
"services": fakeOffice(),
"steps": skipCheckStep(ctx, "acceptance-tests") +
evaluateWorkflowStep() +
"steps": evaluateWorkflowStep() +
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
waitForServices("fake-office", ["fakeoffice:8080"]) +
opencloudServer(storage, deploy_type = "wopi_validator", extra_server_environment = extra_server_environment) +
@@ -1201,7 +1226,12 @@ def wopiValidatorTests(ctx, storage, wopiServerType):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}
prefixStepCommands(pipeline, [
@@ -1320,7 +1350,7 @@ def localApiTestPipeline(ctx):
pipeline = {
"name": pipeline_name,
"steps": skipCheckStep(ctx, "acceptance-tests") + evaluateWorkflowStep() + restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
"steps": evaluateWorkflowStep() + restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
(tikaService() if params["tikaNeeded"] else []) +
(waitForWebOffices(["https://collabora:9980", "https://onlyoffice", "http://fakeoffice:8080"]) if params["collaborationServiceNeeded"] else []) +
(waitForClamavService() if params["antivirusNeeded"] else []) +
@@ -1346,7 +1376,12 @@ def localApiTestPipeline(ctx):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}
prefixStepCommands(pipeline, [
@@ -1441,8 +1476,7 @@ def coreApiTestPipeline(ctx):
pipeline = {
"name": pipeline_name,
"steps": skipCheckStep(ctx, "acceptance-tests") +
evaluateWorkflowStep() +
"steps": evaluateWorkflowStep() +
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
opencloudServer(
storage,
@@ -1461,7 +1495,12 @@ def coreApiTestPipeline(ctx):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}
prefixStepCommands(pipeline, [
@@ -1520,7 +1559,12 @@ def e2eTestPipeline(ctx):
e2e_trigger = [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "e2e-tests"),
},
},
{
"event": "tag",
"ref": "refs/tags/**",
@@ -1546,15 +1590,16 @@ def e2eTestPipeline(ctx):
if "[decomposed]" in ctx.build.title.lower():
params["storages"] = ["decomposed"]
e2e_args = "--suites %s" % ",".join(params["suites"]) if params["suites"] else ""
e2e_args = " ".join(params["suites"]) if params["suites"] else ""
if "with-tracing" in ctx.build.title.lower():
params["reportTracing"] = True
for storage in params["storages"]:
for watch_fs_enabled in params["enableWatchFs"]:
pipeline_name = "test-e2e-%s-%s%s" % (name, storage, "-watchfs" if watch_fs_enabled else "")
steps = \
skipCheckStep(ctx, "e2e-tests") + \
evaluateWorkflowStep() + \
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBin"]) + \
restoreWebCache() + \
@@ -1572,24 +1617,23 @@ def e2eTestPipeline(ctx):
"image": OC_CI_NODEJS,
"environment": {
"OC_BASE_URL": OC_DOMAIN,
"HEADLESS": True,
"RETRY": "1",
"WEB_UI_CONFIG_FILE": "%s/%s" % (dirs["base"], dirs["opencloudConfig"]),
"LOCAL_UPLOAD_DIR": "/uploads",
"PLAYWRIGHT_BROWSERS_PATH": "%s/%s" % (dirs["base"], ".playwright"),
"BROWSER": "chromium",
"REPORT_TRACING": params["reportTracing"],
"SLOW_MO": "300",
},
"commands": [
"cd %s/tests/e2e" % dirs["web"],
"bash run-e2e.sh %s" % e2e_args,
"pnpm playwright install chromium",
"pnpm bddgen",
"pnpm playwright test %s --project=chromium" % e2e_args,
],
}] + \
uploadTracingResult(ctx)
uploadTestArtifacts(pipeline_name)
pipeline = {
"name": "test-e2e-%s-%s%s" % (name, storage, "-watchfs" if watch_fs_enabled else ""),
"name": pipeline_name,
"steps": steps,
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx) + buildWebCache(ctx)),
"when": e2e_trigger,
@@ -1608,7 +1652,6 @@ def multiServiceE2ePipeline(ctx):
defaults = {
"skip": False,
"suites": [],
"xsuites": [],
"tikaNeeded": False,
"reportTracing": False,
"enableWatchFs": [False],
@@ -1618,7 +1661,12 @@ def multiServiceE2ePipeline(ctx):
e2e_trigger = [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "e2e-tests"),
},
},
]
if "skip-e2e" in ctx.build.title.lower():
@@ -1692,13 +1740,7 @@ def multiServiceE2ePipeline(ctx):
if "[decomposed]" in ctx.build.title.lower():
params["storages"] = ["decomposed"]
e2e_args = ""
if params["suites"]:
e2e_args = "--suites %s" % ",".join(params["suites"])
# suites to skip
if params["xsuites"]:
e2e_args += " --xsuites %s" % ",".join(params["xsuites"])
e2e_args = " ".join(params["suites"]) if params["suites"] else ""
if "with-tracing" in ctx.build.title.lower():
params["reportTracing"] = True
@@ -1708,8 +1750,9 @@ def multiServiceE2ePipeline(ctx):
if watch_fs_enabled:
extra_server_environment["STORAGE_USERS_POSIX_WATCH_FS"] = True
pipeline_name = "test-e2e-multi-service%s" % ("-watchfs" if watch_fs_enabled else "")
steps = \
skipCheckStep(ctx, "e2e-tests") + \
evaluateWorkflowStep() + \
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBin"]) + \
restoreWebCache() + \
@@ -1723,21 +1766,20 @@ def multiServiceE2ePipeline(ctx):
"image": OC_CI_NODEJS,
"environment": {
"OC_BASE_URL": OC_DOMAIN,
"HEADLESS": True,
"RETRY": "1",
"REPORT_TRACING": params["reportTracing"],
"PLAYWRIGHT_BROWSERS_PATH": "%s/%s" % (dirs["base"], ".playwright"),
"BROWSER": "chromium",
},
"commands": [
"cd %s/tests/e2e" % dirs["web"],
"bash run-e2e.sh %s" % e2e_args,
"pnpm playwright install chromium",
"pnpm bddgen",
"pnpm playwright test %s --project=chromium" % e2e_args,
],
}] + \
uploadTracingResult(ctx)
uploadTestArtifacts(pipeline_name)
pipeline = {
"name": "test-e2e-multi-service%s" % ("-watchfs" if watch_fs_enabled else ""),
"name": pipeline_name,
"steps": steps,
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx) + buildWebCache(ctx)),
"when": e2e_trigger,
@@ -1749,24 +1791,20 @@ def multiServiceE2ePipeline(ctx):
pipelines.append(pipeline)
return pipelines
def uploadTracingResult(ctx):
status = ["failure"]
if "with-tracing" in ctx.build.title.lower():
status = ["failure", "success"]
def uploadTestArtifacts(pipeline_name):
return [{
"name": "upload-tracing-result",
"name": "upload-test-artifacts",
"image": MINIO_MC,
"environment": MINIO_MC_ENV,
"commands": [
"microdnf install -y zip",
"mc alias set s3 $MC_HOST $AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEY",
"mc cp -a %s/reports/e2e/playwright/tracing/* s3/$PUBLIC_BUCKET/web/tracing/$CI_REPO_NAME/$CI_PIPELINE_NUMBER/" % dirs["web"],
"cd %s/reports/e2e/playwright/tracing/" % dirs["web"],
'echo "To see the trace, please open the following link in the console"',
'for f in *.zip; do echo "npx playwright show-trace $MC_HOST/$PUBLIC_BUCKET/web/tracing/$CI_REPO_NAME/$CI_PIPELINE_NUMBER/$f \n"; done',
"cd %s/tests/e2e/playwright-report && zip -r /tmp/playwright-report.zip ." % dirs["web"],
"mc cp /tmp/playwright-report.zip s3/$PUBLIC_BUCKET/web/artifacts/$CI_REPO_NAME/$CI_PIPELINE_NUMBER/%s/playwright-report.zip" % pipeline_name,
'printf "=== HTML Report ===\ncurl -O $MC_HOST/$PUBLIC_BUCKET/web/artifacts/$CI_REPO_NAME/$CI_PIPELINE_NUMBER/%s/playwright-report.zip && npx playwright show-report playwright-report.zip\n"' % pipeline_name,
],
"when": {
"status": status,
"status": ["failure", "success"],
},
}]
@@ -2305,11 +2343,56 @@ def genDocsPr(ctx):
],
}]
def serverTestingDocs(ctx):
return [{
"name": "server-testing-docs",
"steps": [
{
"name": "build",
"image": OC_CI_NODEJS,
"commands": [
"node tests/scripts/generate-docs.mjs",
# add dummy woodpecker config to disable CI on push to the docs branch
"printf 'def main(ctx):\n return [{\n \"name\":\"dummy-pipeline\",\n" +
" \"steps\":[{\"name\":\"dummy-step\",\"image\":\"alpine:latest\"}],\n" +
" \"when\":[{\"branch\":[\"main\"]}],\n }]\n' > tests/.docs-dist/.woodpecker.star",
],
},
{
"name": "publish",
"image": "plugins/gh-pages:1",
"settings": {
"username": {
"from_secret": "github_username",
},
"password": {
"from_secret": "github_token",
},
"pages_directory": "tests/.docs-dist/",
"copy_contents": True,
"target_branch": "server-testing-docs",
"delete": True,
},
"when": [
{
"event": ["push"],
"branch": "${CI_REPO_DEFAULT_BRANCH}",
},
],
},
],
"when": [
{
"event": ["push", "pull_request"],
"path": "tests/README.md",
},
],
}]
def notifyMatrixCheckSteps(ctx, depends_on):
result = [{
"name": "all-checks-finished",
"skip_clone": True,
"runs_on": ["success", "failure"],
"depends_on": depends_on,
"steps": [
{
@@ -2348,9 +2431,9 @@ def notifyMatrixCheckSteps(ctx, depends_on):
},
],
"when": [
event["cron"],
event["base"],
event["pull_request"],
dict(event["cron"], status = ["success", "failure"]),
dict(event["base"], status = ["success", "failure"]),
dict(event["pull_request"], status = ["success", "failure"]),
],
}]
@@ -2573,14 +2656,18 @@ def skipIfUnchanged(ctx, type):
return []
base = [
".agents/**",
".claude/**",
".github/**",
".vscode/**",
"docs/**",
"deployments/**",
".codacy.yml",
"CHANGELOG.md",
"CONTRIBUTING.md",
"LICENSE",
"README.md",
"release-config.ts",
]
unit = [
"**/*_test.go",
@@ -2680,7 +2767,12 @@ def checkStarlark(ctx):
"when": [
event["cron"],
event["base"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "base"),
},
},
],
}]
@@ -2720,11 +2812,10 @@ def purgeCache(name, flush_path, flush_age):
"name": name,
"skip_clone": True,
"when": [
event["cron"],
event["base"],
event["pull_request"],
dict(event["cron"], status = ["success", "failure"]),
dict(event["base"], status = ["success", "failure"]),
dict(event["pull_request"], status = ["success", "failure"]),
],
"runs_on": ["success", "failure"],
"steps": [
{
"name": "purge",
@@ -2807,8 +2898,9 @@ def pipelineSanityChecks(pipelines):
for pipeline in pipelines:
if "depends_on" in pipeline.keys():
for depends in pipeline["depends_on"]:
if not depends in possible_depends:
print("Error: depends_on %s for pipeline %s is not defined" % (depends, pipeline["name"]))
depends_name = depends["name"] if type(depends) == "dict" else depends
if not depends_name in possible_depends:
print("Error: depends_on %s for pipeline %s is not defined" % (depends_name, pipeline["name"]))
# check for non declared volumes
# for pipeline in pipelines:
@@ -2854,8 +2946,7 @@ def litmus(ctx, storage):
pipeline = {
"name": "test-litmus",
"steps": skipCheckStep(ctx, "litmus") +
evaluateWorkflowStep() +
"steps": evaluateWorkflowStep() +
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
opencloudServer(storage) +
setupForLitmus() +
@@ -2930,7 +3021,12 @@ def litmus(ctx, storage):
"when": [
event["cron"],
event["base"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "litmus"),
},
},
],
}
@@ -3034,7 +3130,12 @@ def cacheBrowsers(ctx):
e2e_trigger = [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "e2e-tests"),
},
},
{
"event": "tag",
"ref": "refs/tags/**",
@@ -3431,16 +3532,3 @@ def waitForWebOffices(services = []):
"commands": commands,
},
]
def skipCheckStep(ctx, type):
if ("full-ci" in ctx.build.title.lower() or ctx.build.event == "tag" or ctx.build.event == "cron"):
return []
return [{
"name": "skip-check",
"image": OC_CI_NODEJS_ALPINE,
"commands": [
"npm install minimatch",
"node tests/config/woodpecker/skip_if_unchanged.js %s" % type,
],
}]
+127
View File
@@ -1,5 +1,132 @@
# Changelog
## [7.4.0](https://github.com/opencloud-eu/opencloud/releases/tag/v7.4.0) - 2026-08-03
### ❤️ Thanks to all contributors! ❤️
@AlexAndBear, @JammingBen, @aduffeck, @dschmidt, @fschade, @michaelstingl, @pbleser-oc, @rhafer, @schweigisito, @v-scharf
### 📈 Enhancement
- Do not check ignored paths [[#3233](https://github.com/opencloud-eu/opencloud/pull/3233)]
- Extend posixfs consistency check [[#3220](https://github.com/opencloud-eu/opencloud/pull/3220)]
- Improve reindex command [[#3213](https://github.com/opencloud-eu/opencloud/pull/3213)]
- Reindex spaces concurrently [[#3207](https://github.com/opencloud-eu/opencloud/pull/3207)]
- feat: add announcement banner [[#3189](https://github.com/opencloud-eu/opencloud/pull/3189)]
- feat: add space viewer with versions role [[#2961](https://github.com/opencloud-eu/opencloud/pull/2961)]
### 🐛 Bug Fixes
- fix(runtime): log service startup errors instead of printing them beside the log [[#3140](https://github.com/opencloud-eu/opencloud/pull/3140)]
- fix(posixfs scan): Setup logger for scan command [[#3185](https://github.com/opencloud-eu/opencloud/pull/3185)]
### ✅ Tests
- api-test: mark group last-manager removal scenario as flaky [[#3194](https://github.com/opencloud-eu/opencloud/pull/3194)]
- rerun flaky tests [[#3183](https://github.com/opencloud-eu/opencloud/pull/3183)]
- api-test: fix removeAccessToDrive.feature:145 [[#3179](https://github.com/opencloud-eu/opencloud/pull/3179)]
- api-test: cover additional unified roles in acceptance tests [[#3169](https://github.com/opencloud-eu/opencloud/pull/3169)]
- test(apiAuthApp): fix flaky token pattern [[#3163](https://github.com/opencloud-eu/opencloud/pull/3163)]
- test(apiArchiver): the single-resource archive is named after the resource [[#3080](https://github.com/opencloud-eu/opencloud/pull/3080)]
- test(coreApiWebdavUploadTUS): assert etag and permissions on the finalizing TUS chunk [[#3078](https://github.com/opencloud-eu/opencloud/pull/3078)]
- test(coreApiWebdavOperations): download a file with a literal "%" via its oc:downloadURL [[#3079](https://github.com/opencloud-eu/opencloud/pull/3079)]
### 📚 Documentation
- maint: clean-up auth-app documentation [[#3155](https://github.com/opencloud-eu/opencloud/pull/3155)]
- ci: sync tests/README.md to docs [[#3164](https://github.com/opencloud-eu/opencloud/pull/3164)]
### 📦️ Dependencies
- [full-ci] chore: bump web to v7.3.0 [[#3223](https://github.com/opencloud-eu/opencloud/pull/3223)]
- build(deps): bump github.com/open-policy-agent/opa from 1.18.2 to 1.19.0 [[#3231](https://github.com/opencloud-eu/opencloud/pull/3231)]
- build(deps): bump google.golang.org/grpc from 1.82.0 to 1.83.0 [[#3232](https://github.com/opencloud-eu/opencloud/pull/3232)]
- chore(idp): bump dependencies [[#3226](https://github.com/opencloud-eu/opencloud/pull/3226)]
- build(deps): bump github.com/nats-io/nats-server/v2 from 2.14.3 to 2.14.4 [[#3221](https://github.com/opencloud-eu/opencloud/pull/3221)]
- build(deps): bump github.com/go-ldap/ldap/v3 from 3.4.13 to 3.4.14 [[#3222](https://github.com/opencloud-eu/opencloud/pull/3222)]
- build(deps): bump github.com/prometheus/client_golang from 1.23.2 to 1.24.1 [[#3218](https://github.com/opencloud-eu/opencloud/pull/3218)]
- build(deps): bump github.com/gabriel-vasile/mimetype from 1.4.13 to 1.4.15 [[#3217](https://github.com/opencloud-eu/opencloud/pull/3217)]
- build(deps): bump golang.org/x/net from 0.56.0 to 0.57.0 [[#3136](https://github.com/opencloud-eu/opencloud/pull/3136)]
- build(deps): bump github.com/beevik/etree from 1.6.0 to 1.7.0 [[#3134](https://github.com/opencloud-eu/opencloud/pull/3134)]
## [7.3.0](https://github.com/opencloud-eu/opencloud/releases/tag/v7.3.0) - 2026-07-14
### 🐛 Bug Fixes
- fix(proxy): honor access token cache ttl [[#3056](https://github.com/opencloud-eu/opencloud/pull/3056)]
- chore(idp): update axios [[#3094](https://github.com/opencloud-eu/opencloud/pull/3094)]
- fix: make the collaboration service events optional [[#3001](https://github.com/opencloud-eu/opencloud/pull/3001)]
- Revert "fix: disallow thumbnails for tiff and jpeg2000 images" [[#2973](https://github.com/opencloud-eu/opencloud/pull/2973)]
- bump reva [[#2950](https://github.com/opencloud-eu/opencloud/pull/2950)]
- change error level for trashing items interaction with search [[#2951](https://github.com/opencloud-eu/opencloud/pull/2951)]
- fix: Send SSE events for SpaceEnabled/Disabled to affected users [[#2871](https://github.com/opencloud-eu/opencloud/pull/2871)]
### 📚 Documentation
- update collaboration readme [[#3076](https://github.com/opencloud-eu/opencloud/pull/3076)]
- fix: fix typo in proxy service documentation [[#3089](https://github.com/opencloud-eu/opencloud/pull/3089)]
- roling release template [[#2972](https://github.com/opencloud-eu/opencloud/pull/2972)]
- enhance: fix typos in webfinger service description [[#2958](https://github.com/opencloud-eu/opencloud/pull/2958)]
### ✅ Tests
- [full-ci] gherkin steps refactoring. cleaning code [[#3100](https://github.com/opencloud-eu/opencloud/pull/3100)]
- [decomposed] more cli command tests [[#3087](https://github.com/opencloud-eu/opencloud/pull/3087)]
- test(apiSpaces): a space admin can delete a space with no manager [[#3040](https://github.com/opencloud-eu/opencloud/pull/3040)]
- Update tests for opencloud-eu/reva#655 [[#2889](https://github.com/opencloud-eu/opencloud/pull/2889)]
- api-test: deleting space [[#2970](https://github.com/opencloud-eu/opencloud/pull/2970)]
### 📈 Enhancement
- feat: add disableSponsorLink web config option [[#3093](https://github.com/opencloud-eu/opencloud/pull/3093)]
- feat(graph): add MS Graph colon-syntax path lookup middleware [[#2688](https://github.com/opencloud-eu/opencloud/pull/2688)]
- feat: adjust theme chrome colors and logos [[#2599](https://github.com/opencloud-eu/opencloud/pull/2599)]
- add tls support for all nats connections [[#2063](https://github.com/opencloud-eu/opencloud/pull/2063)]
- feat: add more roles [[#2928](https://github.com/opencloud-eu/opencloud/pull/2928)]
- next to main [[#2924](https://github.com/opencloud-eu/opencloud/pull/2924)]
- feat: add core apps env variable to override the default core apps [[#2930](https://github.com/opencloud-eu/opencloud/pull/2930)]
### 📦️ Dependencies
- build(deps): bump golang.org/x/image from 0.43.0 to 0.44.0 [[#3112](https://github.com/opencloud-eu/opencloud/pull/3112)]
- build(deps): bump golang.org/x/text from 0.39.0 to 0.40.0 [[#3101](https://github.com/opencloud-eu/opencloud/pull/3101)]
- [full-ci] chore: bump web to v7.2.0 [[#3121](https://github.com/opencloud-eu/opencloud/pull/3121)]
- build(deps): bump golang.org/x/term from 0.44.0 to 0.45.0 [[#3103](https://github.com/opencloud-eu/opencloud/pull/3103)]
- build(deps): bump github.com/coreos/go-oidc/v3 from 3.19.0 to 3.20.0 [[#3102](https://github.com/opencloud-eu/opencloud/pull/3102)]
- build(deps): bump golang.org/x/text from 0.38.0 to 0.39.0 [[#3085](https://github.com/opencloud-eu/opencloud/pull/3085)]
- build(deps): bump github.com/go-chi/chi/v5 from 5.3.0 to 5.3.1 [[#3073](https://github.com/opencloud-eu/opencloud/pull/3073)]
- build(deps): bump github.com/nats-io/nats-server/v2 from 2.14.2 to 2.14.3 [[#3063](https://github.com/opencloud-eu/opencloud/pull/3063)]
- build(deps): bump github.com/gookit/config/v2 from 2.2.8 to 2.2.9 [[#3075](https://github.com/opencloud-eu/opencloud/pull/3075)]
- build(deps): bump github.com/open-policy-agent/opa from 1.18.1 to 1.18.2 [[#3061](https://github.com/opencloud-eu/opencloud/pull/3061)]
- build(deps): bump github.com/kovidgoyal/imaging from 1.8.21 to 1.8.22 [[#3060](https://github.com/opencloud-eu/opencloud/pull/3060)]
- build(deps): bump github.com/libregraph/lico from 0.66.0 to 0.67.0 [[#3028](https://github.com/opencloud-eu/opencloud/pull/3028)]
- chore: bump web to v7.2.0-beta.3 [[#2953](https://github.com/opencloud-eu/opencloud/pull/2953)]
- chore: bump reva to latest main [[#2943](https://github.com/opencloud-eu/opencloud/pull/2943)]
## [7.2.0](https://github.com/opencloud-eu/opencloud/releases/tag/v7.2.0) - 2026-06-24
### ❤️ Thanks to all contributors! ❤️
@Heiko-Pohl, @JammingBen, @ScharfViktor, @aduffeck, @butonic, @dragonchaser, @kulmann, @rhafer
### 🐛 Bug Fixes
- [stable-7.2] Backport fixes from main [[#2999](https://github.com/opencloud-eu/opencloud/pull/2999)]
- fix(idp): aarch64 build [[#2906](https://github.com/opencloud-eu/opencloud/pull/2906)]
- use ldap instead of ldaps internally [[#2880](https://github.com/opencloud-eu/opencloud/pull/2880)]
### 📚 Documentation
- Rename role_name from "guest" to "user-light" [[#2912](https://github.com/opencloud-eu/opencloud/pull/2912)]
### 📦️ Dependencies
- [full-ci] chore: bump web to v7.1.2 [[#3012](https://github.com/opencloud-eu/opencloud/pull/3012)]
- [full-ci] chore: bump web to v7.1.1 [[#2998](https://github.com/opencloud-eu/opencloud/pull/2998)]
- bump reva to latest main [[#2922](https://github.com/opencloud-eu/opencloud/pull/2922)]
- build(deps-dev): bump webpack-manifest-plugin from 5.0.0 to 6.0.1 in /services/idp [[#2884](https://github.com/opencloud-eu/opencloud/pull/2884)]
- build(deps): bump axios from 1.16.0 to 1.16.1 in /services/idp [[#2883](https://github.com/opencloud-eu/opencloud/pull/2883)]
## [7.1.0](https://github.com/opencloud-eu/opencloud/releases/tag/v7.1.0) - 2026-06-02
### ❤️ Thanks to all contributors! ❤️
+5 -7
View File
@@ -107,6 +107,7 @@ help:
@echo -e "${GREEN}Tools for linting gherkin feature files:\n${RESET}"
@echo -e "\tmake test-gherkin-lint\t\t${BLUE}run lint checks on Gherkin feature files${RESET}"
@echo -e "\tmake test-gherkin-lint-fix\t${BLUE}apply lint fixes to gherkin feature files${RESET}"
@echo -e "\tmake find-unused-steps\t\t${BLUE}list Behat step definitions unused by any .feature file${RESET}"
@echo
.PHONY: clean-tests
@@ -228,6 +229,10 @@ test-gherkin-lint:
test-gherkin-lint-fix:
gherlint --fix tests/acceptance/features -c tests/acceptance/config/.gherlintrc.json
.PHONY: find-unused-steps
find-unused-steps: vendor-bin/behat/vendor
tests/acceptance/scripts/find-unused-steps.sh
.PHONY: bingo-update
bingo-update: $(BINGO)
$(BINGO) get -l -v -t 20
@@ -341,10 +346,3 @@ vendor-bin/php_codesniffer/vendor: vendor/bamarni/composer-bin-plugin vendor-bin
vendor-bin/php_codesniffer/composer.lock: vendor-bin/php_codesniffer/composer.json
@echo php_codesniffer composer.lock is not up to date.
.PHONY: generate-qa-activity-report
generate-qa-activity-report: node_modules
@if [ -z "${MONTH}" ] || [ -z "${YEAR}" ]; then \
echo "Please set the MONTH and YEAR environment variables. Usage: make generate-qa-activity-report MONTH=<month> YEAR=<year>"; \
exit 1; \
fi
go run tests/qa-activity-report/generate-qa-activity-report.go --month ${MONTH} --year ${YEAR}
+46 -49
View File
@@ -10,20 +10,20 @@ require (
github.com/MicahParks/keyfunc/v2 v2.1.0
github.com/Nerzal/gocloak/v13 v13.9.0
github.com/bbalet/stopwords v1.0.0
github.com/beevik/etree v1.6.0
github.com/beevik/etree v1.7.0
github.com/blevesearch/bleve/v2 v2.6.0
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/coreos/go-oidc/v3 v3.19.0
github.com/coreos/go-oidc/v3 v3.20.0
github.com/cs3org/go-cs3apis v0.0.0-20260424072047-8d9ef7076ae9
github.com/davidbyttow/govips/v2 v2.18.0
github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
github.com/gabriel-vasile/mimetype v1.4.13
github.com/gabriel-vasile/mimetype v1.4.15
github.com/ggwhite/go-masker v1.1.0
github.com/go-chi/chi/v5 v5.3.1
github.com/go-chi/render v1.0.3
github.com/go-jose/go-jose/v3 v3.0.5
github.com/go-ldap/ldap/v3 v3.4.13
github.com/go-ldap/ldap/v3 v3.4.14
github.com/go-ldap/ldif v0.0.0-20200320164324-fd88d9b715b3
github.com/go-micro/plugins/v4/client/grpc v1.2.1
github.com/go-micro/plugins/v4/logger/zerolog v1.2.0
@@ -55,26 +55,27 @@ require (
github.com/libregraph/lico v0.67.0
github.com/mna/pigeon v1.3.0
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/nats-io/nats-server/v2 v2.14.3
github.com/nats-io/nats-server/v2 v2.14.4
github.com/nats-io/nats.go v1.52.0
github.com/olekukonko/tablewriter v1.1.4
github.com/onsi/ginkgo v1.16.5
github.com/onsi/ginkgo/v2 v2.32.0
github.com/onsi/gomega v1.42.1
github.com/open-policy-agent/opa v1.18.2
github.com/open-policy-agent/opa v1.19.0
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d
github.com/opencloud-eu/reva/v2 v2.46.4-0.20260625152426-8cff2a7032ec
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260811135939-91387d92a263
github.com/opencloud-eu/reva/v2 v2.48.0
github.com/opensearch-project/opensearch-go/v4 v4.6.0
github.com/orcaman/concurrent-map v1.0.0
github.com/pkg/errors v0.9.1
github.com/pkg/xattr v0.4.12
github.com/prometheus/client_golang v1.23.2
github.com/prometheus/client_golang v1.24.1
github.com/r3labs/sse/v2 v2.10.0
github.com/riandyrn/otelchi v0.12.3
github.com/rogpeppe/go-internal v1.15.0
github.com/rs/cors v1.11.1
github.com/rs/zerolog v1.35.1
github.com/shamaton/msgpack/v2 v2.4.1
github.com/sirupsen/logrus v1.9.4
github.com/spf13/afero v1.15.0
github.com/spf13/cobra v1.10.2
@@ -84,7 +85,6 @@ require (
github.com/test-go/testify v1.1.4
github.com/testcontainers/testcontainers-go v0.43.0
github.com/testcontainers/testcontainers-go/modules/opensearch v0.43.0
github.com/theckman/yacspin v0.13.12
github.com/thejerf/suture/v4 v4.0.6
github.com/tidwall/gjson v1.19.0
github.com/tidwall/sjson v1.2.5
@@ -102,16 +102,16 @@ require (
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.44.0
go.opentelemetry.io/otel/sdk v1.44.0
go.opentelemetry.io/otel/trace v1.44.0
golang.org/x/crypto v0.53.0
golang.org/x/crypto v0.54.0
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f
golang.org/x/image v0.43.0
golang.org/x/net v0.56.0
golang.org/x/image v0.44.0
golang.org/x/net v0.57.0
golang.org/x/oauth2 v0.36.0
golang.org/x/sync v0.21.0
golang.org/x/term v0.44.0
golang.org/x/text v0.39.0
golang.org/x/sync v0.22.0
golang.org/x/term v0.45.0
golang.org/x/text v0.40.0
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa
google.golang.org/grpc v1.82.0
google.golang.org/grpc v1.83.0
google.golang.org/protobuf v1.36.11
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
@@ -126,7 +126,7 @@ require (
github.com/Azure/go-ntlmssp v0.1.1 // indirect
github.com/BurntSushi/toml v1.6.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/Masterminds/semver/v3 v3.5.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProtonMail/go-crypto v1.1.6 // indirect
@@ -135,7 +135,7 @@ require (
github.com/ajg/form v1.5.1 // indirect
github.com/alexedwards/argon2id v1.0.0 // indirect
github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 // indirect
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op // indirect
github.com/antithesishq/antithesis-sdk-go v0.7.2 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
@@ -166,8 +166,8 @@ require (
github.com/ceph/go-ceph v0.40.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cevaris/ordered_map v0.0.0-20190319150403-3adeae072e73 // indirect
github.com/clipperhouse/displaywidth v0.10.0 // indirect
github.com/clipperhouse/uax29/v2 v2.6.0 // indirect
github.com/clipperhouse/displaywidth v0.11.0 // indirect
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
github.com/cloudflare/circl v1.6.3 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
@@ -189,7 +189,7 @@ require (
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/dlclark/regexp2 v1.12.0 // indirect
github.com/docker/go-connections v0.6.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
@@ -198,20 +198,19 @@ require (
github.com/emirpasic/gods v1.18.1 // indirect
github.com/emvi/iso-639-1 v1.1.1 // indirect
github.com/evanphx/json-patch/v5 v5.5.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fatih/color v1.19.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.10.1 // indirect
github.com/gdexlab/go-render v1.0.1 // indirect
github.com/go-acme/lego/v4 v4.4.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.8 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.9.0 // indirect
github.com/go-git/go-git/v5 v5.19.1 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/logr v1.4.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-micro/plugins/v4/events/natsjs v1.2.2 // indirect
github.com/go-micro/plugins/v4/store/nats-js v1.2.1 // indirect
@@ -256,7 +255,7 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/juliangruber/go-intersect v1.1.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.18.6 // indirect
github.com/klauspost/compress v1.19.1 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/klauspost/crc32 v1.3.0 // indirect
github.com/kovidgoyal/go-parallel v1.1.1 // indirect
@@ -275,10 +274,10 @@ require (
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.10 // indirect
github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.19 // indirect
github.com/mattn/go-sqlite3 v1.14.42 // indirect
github.com/mattn/go-colorable v0.1.15 // indirect
github.com/mattn/go-isatty v0.0.22 // indirect
github.com/mattn/go-runewidth v0.0.24 // indirect
github.com/mattn/go-sqlite3 v1.14.49 // indirect
github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b // indirect
github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 // indirect
github.com/miekg/dns v1.1.68 // indirect
@@ -286,7 +285,7 @@ require (
github.com/minio/crc64nvme v1.1.1 // indirect
github.com/minio/highwayhash v1.0.4 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/minio-go/v7 v7.1.0 // indirect
github.com/minio/minio-go/v7 v7.2.1 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
@@ -317,17 +316,17 @@ require (
github.com/pablodz/inotifywaitgo v0.0.12 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pelletier/go-toml/v2 v2.3.1 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
github.com/pierrec/lz4/v4 v4.1.15 // indirect
github.com/pierrec/lz4/v4 v4.1.26 // indirect
github.com/pjbgf/sha1cd v0.6.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/pquerna/cachecontrol v0.2.0 // indirect
github.com/prometheus/alertmanager v0.31.1 // indirect
github.com/prometheus/alertmanager v0.33.1 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.1 // indirect
github.com/prometheus/common v0.70.1 // indirect
github.com/prometheus/procfs v0.21.1 // indirect
github.com/prometheus/statsd_exporter v0.22.8 // indirect
github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect
github.com/rs/xid v1.6.0 // indirect
@@ -339,16 +338,13 @@ require (
github.com/samber/slog-common v0.21.0 // indirect
github.com/samber/slog-zerolog/v2 v2.9.2 // indirect
github.com/segmentio/asm v1.2.1 // indirect
github.com/segmentio/kafka-go v0.4.50 // indirect
github.com/segmentio/kafka-go v0.4.51 // indirect
github.com/segmentio/ksuid v1.0.4 // indirect
github.com/sercand/kuberesolver/v5 v5.1.1 // indirect
github.com/sergi/go-diff v1.4.0 // indirect
github.com/sethvargo/go-diceware v0.5.0 // indirect
github.com/sethvargo/go-password v0.3.1 // indirect
github.com/shamaton/msgpack/v2 v2.4.1 // indirect
github.com/sethvargo/go-diceware v0.6.0 // indirect
github.com/sethvargo/go-password v0.4.0 // indirect
github.com/shirou/gopsutil/v4 v4.26.5 // indirect
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
github.com/spacewander/go-suffix-tree v0.0.0-20191010040751-0865e368c784 // indirect
@@ -366,7 +362,7 @@ require (
github.com/trustelem/zxcvbn v1.0.1 // indirect
github.com/urfave/cli/v2 v2.27.7 // indirect
github.com/valyala/fastjson v1.6.10 // indirect
github.com/vektah/gqlparser/v2 v2.5.34 // indirect
github.com/vektah/gqlparser/v2 v2.5.36 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/wk8/go-ordered-map v1.0.0 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
@@ -376,9 +372,9 @@ require (
github.com/yashtewari/glob-intersection v0.2.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
github.com/zeebo/xxh3 v1.1.0 // indirect
go.etcd.io/etcd/api/v3 v3.6.11 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.6.11 // indirect
go.etcd.io/etcd/client/v3 v3.6.11 // indirect
go.etcd.io/etcd/api/v3 v3.6.13 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.6.13 // indirect
go.etcd.io/etcd/client/v3 v3.6.13 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 // indirect
@@ -389,12 +385,13 @@ require (
go.yaml.in/yaml/v2 v2.4.4 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/mod v0.37.0 // indirect
golang.org/x/sys v0.46.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/time v0.15.0 // indirect
golang.org/x/tools v0.47.0 // indirect
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260729162451-8efbd57d26e0 // indirect
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
gopkg.in/ini.v1 v1.67.3 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
+96 -102
View File
@@ -76,8 +76,8 @@ github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJ
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE=
github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/MicahParks/keyfunc/v2 v2.1.0 h1:6ZXKb9Rp6qp1bDbJefnG7cTH8yMN1IC/4nf+GVjO99k=
@@ -115,8 +115,8 @@ github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 h1:I9YN9WMo3SUh7p/
github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964/go.mod h1:eFiR01PwTcpbzXtdMces7zxg6utvFM5puiWHpWB8D/k=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
github.com/antithesishq/antithesis-sdk-go v0.7.2 h1:oEEedg1Xgi8drRjqB0f9tfjhLoInE0IYZfZ6zAhQUbY=
github.com/antithesishq/antithesis-sdk-go v0.7.2/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
@@ -132,8 +132,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:W
github.com/aws/aws-sdk-go v1.37.27/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/bbalet/stopwords v1.0.0 h1:0TnGycCtY0zZi4ltKoOGRFIlZHv0WqpoIGUsObjztfo=
github.com/bbalet/stopwords v1.0.0/go.mod h1:sAWrQoDMfqARGIn4s6dp7OW7ISrshUD8IP2q3KoqPjc=
github.com/beevik/etree v1.6.0 h1:u8Kwy8pp9D9XeITj2Z0XtA5qqZEmtJtuXZRQi+j03eE=
github.com/beevik/etree v1.6.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc=
github.com/beevik/etree v1.7.0 h1:xjBk9O4p4x7D1YajePjfLzdaFC4/uYUENA7P0pv6gXA=
github.com/beevik/etree v1.7.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -195,8 +195,6 @@ github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
github.com/butonic/go-micro/v4 v4.11.1-0.20241115112658-b5d4de5ed9b3 h1:h8Z0hBv5tg/uZMKu8V47+DKWYVQg0lYP8lXDQq7uRpE=
github.com/butonic/go-micro/v4 v4.11.1-0.20241115112658-b5d4de5ed9b3/go.mod h1:eE/tD53n3KbVrzrWxKLxdkGw45Fg1qaNLWjpJMvIUF4=
github.com/bytecodealliance/wasmtime-go/v44 v44.0.0 h1:WRZXnLPIer/TWs5aYPaMlmVcOlzmR6Ur6wjLRIQOhTQ=
github.com/bytecodealliance/wasmtime-go/v44 v44.0.0/go.mod h1:GP93piU+39CoFVCQ5xfHrPOUtL0APlMnkbblJ2d3YY0=
github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
@@ -220,10 +218,10 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
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/clipperhouse/displaywidth v0.10.0 h1:GhBG8WuerxjFQQYeuZAeVTuyxuX+UraiZGD4HJQ3Y8g=
github.com/clipperhouse/displaywidth v0.10.0/go.mod h1:XqJajYsaiEwkxOj4bowCTMcT1SgvHo9flfF3jQasdbs=
github.com/clipperhouse/uax29/v2 v2.6.0 h1:z0cDbUV+aPASdFb2/ndFnS9ts/WNXgTNNGFoKXuhpos=
github.com/clipperhouse/uax29/v2 v2.6.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8=
github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0=
github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk=
github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304=
@@ -238,8 +236,8 @@ github.com/containerd/platforms v1.0.0-rc.2 h1:0SPgaNZPVWGEi4grZdV8VRYQn78y+nm6a
github.com/containerd/platforms v1.0.0-rc.2/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-oidc/v3 v3.19.0 h1:F/xyOi3x1UnG1U27YVnM1N6bHiL1K2upi6U/0qr8r+I=
github.com/coreos/go-oidc/v3 v3.19.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4=
github.com/coreos/go-oidc/v3 v3.20.0 h1:EtE0WIBHk03N+DqGkY4+UONzzZHk7amKt6IyNd7OsZE=
github.com/coreos/go-oidc/v3 v3.20.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
@@ -281,8 +279,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1/go.mod h1:ZXNYxsqcloTdSy/rNShjY
github.com/deepmap/oapi-codegen v1.3.11/go.mod h1:suMvK7+rKlx3+tpa8ByptmvoXbAV70wERKTOGH3hLp0=
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
github.com/dgraph-io/badger/v4 v4.9.2 h1:Wb5qw8gElqwV1a8msHTeQKova9b1V10heFKMIiPd80E=
github.com/dgraph-io/badger/v4 v4.9.2/go.mod h1:nJjaJTUOSsQEBhsq209FmwCvMJzEA3e74RjZw6V2pQI=
github.com/dgraph-io/badger/v4 v4.9.4 h1:bcw+waCpzRZ2nmcSPbnPvDVhiEsn98TKmvnAhK7r7LM=
github.com/dgraph-io/badger/v4 v4.9.4/go.mod h1:nJjaJTUOSsQEBhsq209FmwCvMJzEA3e74RjZw6V2pQI=
github.com/dgraph-io/ristretto v0.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE=
github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU=
github.com/dgraph-io/ristretto/v2 v2.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM=
@@ -300,8 +298,8 @@ github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8/go.mod h1:apkPC/CR3s48
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8=
github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/dnsimple/dnsimple-go v0.63.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg=
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
@@ -334,8 +332,8 @@ github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl
github.com/exoscale/egoscale v0.46.0/go.mod h1:mpEXBpROAa/2i5GC0r33rfxG+TxSEka11g1PIXt9+zc=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
@@ -350,8 +348,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho=
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gabriel-vasile/mimetype v1.4.15 h1:05iP/CYtZ/w455R/KZM6rZ5ieAdh99UPtd+d3YzLmaI=
github.com/gabriel-vasile/mimetype v1.4.15/go.mod h1:azpTcoLcDZRNgFou5j+APrqQx9HqVPWa6ijYQIIVswQ=
github.com/gdexlab/go-render v1.0.1 h1:rxqB3vo5s4n1kF0ySmoNeSPRYkEsyHgln4jFIQY7v0U=
github.com/gdexlab/go-render v1.0.1/go.mod h1:wRi5nW2qfjiGj4mPukH4UV0IknS1cHD4VgFTmJX5JzM=
github.com/getkin/kin-openapi v0.13.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw=
@@ -370,8 +368,8 @@ github.com/go-acme/lego/v4 v4.4.0 h1:uHhU5LpOYQOdp3aDU+XY2bajseu8fuExphTL1Ss6/Fc
github.com/go-acme/lego/v4 v4.4.0/go.mod h1:l3+tFUFZb590dWcqhWZegynUthtaHJbG2fevUpoOOE0=
github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-asn1-ber/asn1-ber v1.4.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo=
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-asn1-ber/asn1-ber v1.5.8 h1:H9AZkK22UOmfX8J84ubyaZxKJZ3FMHVwn8swoMML7iQ=
github.com/go-asn1-ber/asn1-ber v1.5.8/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-chi/chi/v5 v5.3.1 h1:3j4HZLGZQ3JpMCrPJF/Jl3mYJfWLKBfNJ6quurUGCf8=
github.com/go-chi/chi/v5 v5.3.1/go.mod h1:R+tYY2hNuVUUjxoPtqUdgBqevM9s9njzkTLutVsOCto=
@@ -390,8 +388,6 @@ github.com/go-git/go-git/v5 v5.19.1/go.mod h1:Pb1v0c7/g8aGQJwx9Us09W85yGoyvSwuhE
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/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
github.com/go-jose/go-jose/v3 v3.0.5 h1:BLLJWbC4nMZOfuPVxoZIxeYsn6Nl2r1fITaJ78UQlVQ=
github.com/go-jose/go-jose/v3 v3.0.5/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
@@ -404,8 +400,8 @@ github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-ldap/ldap/v3 v3.1.7/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q=
github.com/go-ldap/ldap/v3 v3.4.13 h1:+x1nG9h+MZN7h/lUi5Q3UZ0fJ1GyDQYbPvbuH38baDQ=
github.com/go-ldap/ldap/v3 v3.4.13/go.mod h1:LxsGZV6vbaK0sIvYfsv47rfh4ca0JXokCoKjZxsszv0=
github.com/go-ldap/ldap/v3 v3.4.14 h1:D6PYdEgsaVzsXyr6w/yDC06Ria4uUhWm+Rb+er8lfAs=
github.com/go-ldap/ldap/v3 v3.4.14/go.mod h1:S4eJUMUNjDkE0ZJtIZdybwyb03sGGLW6gxXT1Hs8VKA=
github.com/go-ldap/ldif v0.0.0-20200320164324-fd88d9b715b3 h1:sfz1YppV05y4sYaW7kXZtrocU/+vimnIWt4cxAYh7+o=
github.com/go-ldap/ldif v0.0.0-20200320164324-fd88d9b715b3/go.mod h1:ZXFhGda43Z2TVbfGZefXyMJzsDHhCh0go3bZUcwTx7o=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
@@ -414,8 +410,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8=
github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-micro/plugins/v4/client/grpc v1.2.1 h1:7xAwZRCO6mdUtBHsYIQs1/eCTdhCrnjF70GB+AVd6L0=
@@ -717,8 +713,8 @@ github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao=
github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk=
github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
@@ -803,23 +799,23 @@ github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY=
github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-sqlite3 v1.14.42 h1:MigqEP4ZmHw3aIdIT7T+9TLa90Z6smwcthx+Azv4Cgo=
github.com/mattn/go-sqlite3 v1.14.42/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ=
github.com/mattn/go-runewidth v0.0.24 h1:cpokDiIn0MGnhdHwuWnJBITySJ20QyNGnY2kR/ay2DU=
github.com/mattn/go-runewidth v0.0.24/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-sqlite3 v1.14.49 h1:B8jBHC3xhxZgxztrgruTuLucebnULQnx4W7cF7SAE9w=
github.com/mattn/go-sqlite3 v1.14.49/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -841,8 +837,8 @@ github.com/minio/highwayhash v1.0.4 h1:asJizugGgchQod2ja9NJlGOWq4s7KsAWr5XUc9Clg
github.com/minio/highwayhash v1.0.4/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.1.0 h1:QEt5IStDpxgGjEdtOgpiZ5QhmSl3ax7qy61vi2SwHO8=
github.com/minio/minio-go/v7 v7.1.0/go.mod h1:Dm7WS1AgLmBa0NcQD6SeJnJf+K/EUW3GR7Ks6olB3OA=
github.com/minio/minio-go/v7 v7.2.1 h1:PfBfwvKB/MmqyN8Vb1G9voWisaM9OrLv+WwOvMwS9Dw=
github.com/minio/minio-go/v7 v7.2.1/go.mod h1:EU9hENAStx/xXduNdrGO5e4X5vk19NtgB+RIPjZO8o0=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
@@ -896,8 +892,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8=
github.com/nats-io/jwt/v2 v2.8.2 h1:XXRgB60MSTnqsRwejQurVDs/hcv2dkt+86GjI+I/bMc=
github.com/nats-io/jwt/v2 v2.8.2/go.mod h1:Ag/56sq9OblL4JgdYufDd16Egb17Kr/8WwwuO/forVc=
github.com/nats-io/nats-server/v2 v2.14.3 h1:+xjydPt7rkit67G+04TN0mcO2n+8nveZE7tK/PPV53A=
github.com/nats-io/nats-server/v2 v2.14.3/go.mod h1:5IlCtBzfwyzQzPMjmoJ9W2/LKmnJRtNyuOs/OT+NHDY=
github.com/nats-io/nats-server/v2 v2.14.4 h1:efgjZ8cdExAKRuqSg8UPJFprb+l7NlBtSDPhDlw3rO4=
github.com/nats-io/nats-server/v2 v2.14.4/go.mod h1:BltdpOYestjbtQSnVO2zGHdg5SGBZjt+GYTgB9LZq/I=
github.com/nats-io/nats.go v1.52.0 h1:n3avV4VBsCgsdwh71TppsTwtv+QdPs7ntSKM8qJLGsc=
github.com/nats-io/nats.go v1.52.0/go.mod h1:26HypzazeOkyO3/mqd1zZd53STJN0EjCYF9Uy2ZOBno=
github.com/nats-io/nkeys v0.4.16 h1:rd5oAuLOb8mnAycB0xleuEBNS1pVVnN0fv/FF34Eypg=
@@ -938,16 +934,16 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I=
github.com/onsi/gomega v1.42.1/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg=
github.com/open-policy-agent/opa v1.18.2 h1:VBiLJpioTuk7XTW1JoQi4ILo+FVxD2/8uD8iP9/OcxY=
github.com/open-policy-agent/opa v1.18.2/go.mod h1:9GY+hER4ZEXtxPlMjftVbqJJY9xLtCD3Q0oufRCfAKo=
github.com/open-policy-agent/opa v1.19.0 h1:+j2OCsjMezZEML2T1lI9giJdGJS/PL1XFKgkHPGIhpo=
github.com/open-policy-agent/opa v1.19.0/go.mod h1:pb6Y6klyf7X7X8uXNDflruA9dQC2gMqWROXI5w/kvv0=
github.com/opencloud-eu/go-micro-plugins/v4/store/nats-js-kv v0.0.0-20250512152754-23325793059a h1:Sakl76blJAaM6NxylVkgSzktjo2dS504iDotEFJsh3M=
github.com/opencloud-eu/go-micro-plugins/v4/store/nats-js-kv v0.0.0-20250512152754-23325793059a/go.mod h1:pjcozWijkNPbEtX5SIQaxEW/h8VAVZYTLx+70bmB3LY=
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 h1:W1ms+lP5lUUIzjRGDg93WrQfZJZCaV1ZP3KeyXi8bzY=
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89/go.mod h1:vigJkNss1N2QEceCuNw/ullDehncuJNFB6mEnzfq9UI=
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d h1:JcqGDiyrcaQwVyV861TUyQgO7uEmsjkhfm7aQd84dOw=
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d/go.mod h1:pzatilMEHZFT3qV7C/X3MqOa3NlRQuYhlRhZTL+hN6Q=
github.com/opencloud-eu/reva/v2 v2.46.4-0.20260625152426-8cff2a7032ec h1:kL9P87cVpe8GKvo5vzLpJstpiVXFvkZn2+Dco53nfuM=
github.com/opencloud-eu/reva/v2 v2.46.4-0.20260625152426-8cff2a7032ec/go.mod h1:l4CG5u8tdWZj6IyavXO9xDdnNTV85oaFudGwEDPvsnk=
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260811135939-91387d92a263 h1:nLueJ4Vr2/to0KRpOex1HAU3wBejVePc+P/QjRlQpUc=
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260811135939-91387d92a263/go.mod h1:lTM8JeGblNpoMySTW7Lui2+c5TTLI95mwxtdUIHHrhU=
github.com/opencloud-eu/reva/v2 v2.48.0 h1:G/4Jbv0DWWOfA5u5DtV0CB75pi9Wwtj7JkJQOEBvErs=
github.com/opencloud-eu/reva/v2 v2.48.0/go.mod h1:ZCo/xQM6if+upZa7rJCmdifZ/Y5XHLCrscHytC39yI4=
github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 h1:l2oB/RctH+t8r7QBj5p8thfEHCM/jF35aAY3WQ3hADI=
github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
@@ -975,15 +971,15 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2D
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pelletier/go-toml/v2 v2.3.1 h1:MYEvvGnQjeNkRF1qUuGolNtNExTDwct51yp7olPtrEc=
github.com/pelletier/go-toml/v2 v2.3.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY=
github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4=
github.com/pierrec/xxHash v0.1.5 h1:n/jBpwTHiER4xYvK3/CdPVnLDPchj8eTJFFLUb4QHBo=
github.com/pierrec/xxHash v0.1.5/go.mod h1:w2waW5Zoa/Wc4Yqe0wgrIYAGKqRMf7czn2HNKXmuL+I=
github.com/pjbgf/sha1cd v0.6.0 h1:3WJ8Wz8gvDz29quX1OcEmkAlUg9diU4GxJHqs0/XiwU=
@@ -1005,8 +1001,8 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:Om
github.com/pquerna/cachecontrol v0.2.0 h1:vBXSNuE5MYP9IJ5kjsdo8uq+w41jSPgvba2DEnkRx9k=
github.com/pquerna/cachecontrol v0.2.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/prometheus/alertmanager v0.31.1 h1:eAmIC42lzbWslHkMt693T36qdxfyZULswiHr681YS3Q=
github.com/prometheus/alertmanager v0.31.1/go.mod h1:zWPQwhbLt2ybee8rL921UONeQ59Oncash+m/hGP17tU=
github.com/prometheus/alertmanager v0.33.1 h1:PJHGvTdb8Q0ZEpJnWff120WxB2kxIScLa707AaIudTo=
github.com/prometheus/alertmanager v0.33.1/go.mod h1:V06Uc8EZ5X5wLOJRGhtXx+EE2LgrinFIADbKWMVm1RY=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
@@ -1018,8 +1014,8 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_golang v1.24.1 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU=
github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE=
github.com/prometheus/client_model v0.0.0-20170216185247-6f3806018612/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@@ -1039,8 +1035,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/common v0.70.1 h1:1HvjP4D5oL3t8RsPlwxA9onvvStjtIHYE5XuuwOi/PY=
github.com/prometheus/common v0.70.1/go.mod h1:VdFUQDMZK3VLkurFUVhia6uys/0suUp86TJz5qbJRhc=
github.com/prometheus/procfs v0.0.0-20170703101242-e645f4e5aaa8/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
@@ -1051,8 +1047,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI=
github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY=
github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI=
github.com/prometheus/statsd_exporter v0.22.8 h1:Qo2D9ZzaQG+id9i5NYNGmbf1aa/KxKbB9aKfMS+Yib0=
github.com/prometheus/statsd_exporter v0.22.8/go.mod h1:/DzwbTEaFTE0Ojz5PqcSk6+PFHOPWGxdXVr6yC8eFOM=
@@ -1096,29 +1092,25 @@ github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210127161313-bd30bebeac4f/
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0=
github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/segmentio/kafka-go v0.4.50 h1:mcyC3tT5WeyWzrFbd6O374t+hmcu1NKt2Pu1L3QaXmc=
github.com/segmentio/kafka-go v0.4.50/go.mod h1:Y1gn60kzLEEaW28YshXyk2+VCUKbJ3Qr6DrnT3i4+9E=
github.com/segmentio/kafka-go v0.4.51 h1:JgDPPG75tC1rWIS2Me6MwcvXJ6f49UQ4HjAOef71Hno=
github.com/segmentio/kafka-go v0.4.51/go.mod h1:Y1gn60kzLEEaW28YshXyk2+VCUKbJ3Qr6DrnT3i4+9E=
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
github.com/sercand/kuberesolver/v5 v5.1.1 h1:CYH+d67G0sGBj7q5wLK61yzqJJ8gLLC8aeprPTHb6yY=
github.com/sercand/kuberesolver/v5 v5.1.1/go.mod h1:Fs1KbKhVRnB2aDWN12NjKCB+RgYMWZJ294T3BtmVCpQ=
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/sethvargo/go-diceware v0.5.0 h1:exrQ7GpaBo00GqRVM1N8ChXSsi3oS7tjQiIehsD+yR0=
github.com/sethvargo/go-diceware v0.5.0/go.mod h1:Lg1SyPS7yQO6BBgTN5r4f2MUDkqGfLWsOjHPY0kA8iw=
github.com/sethvargo/go-password v0.3.1 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU=
github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs=
github.com/sethvargo/go-diceware v0.6.0 h1:B3nhMhbBP7KwtTQ7hHRIOmv5FqeD8bJs77RFrV24iWk=
github.com/sethvargo/go-diceware v0.6.0/go.mod h1:lHmdB0xuWaJ06KCraW6bztRT+71Dp+lsXQvborhhsBc=
github.com/sethvargo/go-password v0.4.0 h1:eSidVKQw5C7CmTDAtH3RipBTSjdU1ZRxQaynD2GWLVU=
github.com/sethvargo/go-password v0.4.0/go.mod h1:PO3nYHwUpcHPR0F9woy7a4abZPvzRuqJr0GaeIYTm3k=
github.com/shamaton/msgpack/v2 v2.4.1 h1:JtJ141QoQ3NqgPDsjq2v9VXlaON8SiQOwEaoNLEK/MQ=
github.com/shamaton/msgpack/v2 v2.4.1/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil/v4 v4.26.5 h1:RPcBXkpz7kOj9PqGFQOlBPZHsyaPvPVQc098y9RmCNM=
github.com/shirou/gopsutil/v4 v4.26.5/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ=
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 h1:OfRzdxCzDhp+rsKWXuOO2I/quKMJ/+TQwVbIP/gltZg=
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92/go.mod h1:7/OT02F6S6I7v6WXb+IjhMuZEYfH/RJ5RwEWnEo5BMg=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
@@ -1167,6 +1159,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4=
github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@@ -1179,6 +1172,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
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/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
@@ -1193,10 +1187,10 @@ github.com/testcontainers/testcontainers-go v0.43.0 h1:oEQx5MW2DGd9z3AeEQfB2lPM0
github.com/testcontainers/testcontainers-go v0.43.0/go.mod h1:+VxkT2NQnKOZPKi6praMuMKYHYyOGXr0XSBSlSMCzFo=
github.com/testcontainers/testcontainers-go/modules/opensearch v0.43.0 h1:a1ipjF7d/VxPX1dgVPIk4F+t6YkgMbE2OtBuRQCHJt8=
github.com/testcontainers/testcontainers-go/modules/opensearch v0.43.0/go.mod h1:OWSeUDiGMUy30iMsAltIJIo9uh/CleLv6KyxjYOsgR8=
github.com/tetratelabs/wazero v1.12.0 h1:DuWcpNu/FzgEXgGBDp8J1Spc+CWOvvtvVyjKlaZopYU=
github.com/tetratelabs/wazero v1.12.0/go.mod h1:LvKtzl2RqO4gyF27BiXU+nKAjcV8f38U+kP/q2vgxh0=
github.com/thanhpk/randstr v1.0.6 h1:psAOktJFD4vV9NEVb3qkhRSMvYh4ORRaj1+w/hn4B+o=
github.com/thanhpk/randstr v1.0.6/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZuEQk3r0U=
github.com/theckman/yacspin v0.13.12 h1:CdZ57+n0U6JMuh2xqjnjRq5Haj6v1ner2djtLQRzJr4=
github.com/theckman/yacspin v0.13.12/go.mod h1:Rd2+oG2LmQi5f3zC3yeZAOl245z8QOvrH4OPOJNZxLg=
github.com/thejerf/suture/v4 v4.0.6 h1:QsuCEsCqb03xF9tPAsWAj8QOAJBgQI1c0VqJNaingg8=
github.com/thejerf/suture/v4 v4.0.6/go.mod h1:gu9Y4dXNUWFrByqRt30Rm9/UZ0wzRSt9AJS6xu/ZGxU=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
@@ -1233,8 +1227,8 @@ github.com/valyala/fastjson v1.6.10 h1:/yjJg8jaVQdYR3arGxPE2X5z89xrlhS0eGXdv+ADT
github.com/valyala/fastjson v1.6.10/go.mod h1:e6FubmQouUNP73jtMLmcbxS6ydWIpOfhz34TSfO3JaE=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/vektah/gqlparser/v2 v2.5.34 h1:MEea5P0qhdcqfBL45ghKE+qr9laidVHTMHjav5h7ckk=
github.com/vektah/gqlparser/v2 v2.5.34/go.mod h1:mFdHLGCio7OGX1fby9ZjTW6FN+qxgmbnBcRIeeScE5s=
github.com/vektah/gqlparser/v2 v2.5.36 h1:CN9mKVHgMkc+XftdOWIhb4HEL8wKSYkFAqhf8booa7s=
github.com/vektah/gqlparser/v2 v2.5.36/go.mod h1:cAJ9qwVgPaUkWv6Gn8vn0mqOE0Ui5Pn56wNy5396XWo=
github.com/vinyldns/go-vinyldns v0.0.0-20200917153823-148a5f6b8f14/go.mod h1:RWc47jtnVuQv6+lY3c768WtXCas/Xi+U5UFc5xULmYg=
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
@@ -1280,12 +1274,12 @@ github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.5.0 h1:S7GAl7Fxv12yohbwFfIbQCGDWbQbtDGPET4P/bD4lxU=
go.etcd.io/bbolt v1.5.0/go.mod h1:mkltfYE5aUHQxUct9N9V+Kp7aSjFqjgrhcXIS70Lrdk=
go.etcd.io/etcd/api/v3 v3.6.11 h1:XFGTgrJ8nak3kB4NgMG8t7NT+lEeuuvKQAqUHKVgkWQ=
go.etcd.io/etcd/api/v3 v3.6.11/go.mod h1:HYfTh0jyh+uFgp6gMbxJteIDYY97yMuYz85Rnw6Gy9o=
go.etcd.io/etcd/client/pkg/v3 v3.6.11 h1:e41mp315Yn3QMGPmEzCyLsMINgJXTY/dX8kM++1csxU=
go.etcd.io/etcd/client/pkg/v3 v3.6.11/go.mod h1:DysuMe/inqRyC/1tjRR6hReH/VV9Lufs27YKSKBWWJg=
go.etcd.io/etcd/client/v3 v3.6.11 h1:LAByD96VmmeuairkvdAcE0RZnrmGz/q3ceeWePo9bwc=
go.etcd.io/etcd/client/v3 v3.6.11/go.mod h1:vOTDMCo+fGPEClJqcFEFSqZ+8e7WKV7AyqJjX//HR2w=
go.etcd.io/etcd/api/v3 v3.6.13 h1:AvHPZv15LYEe7tZDyFglv7xnbiuF6GMZpZqKpIzXTt0=
go.etcd.io/etcd/api/v3 v3.6.13/go.mod h1:X9+3gaKwzjlOxzo6TZ2u3b7HcHBcAL+Ph7EBPjI/VWk=
go.etcd.io/etcd/client/pkg/v3 v3.6.13 h1:7QeMOisYByx8dBA7/CKcwCaPWfjb5C0xpmrIov/8WyY=
go.etcd.io/etcd/client/pkg/v3 v3.6.13/go.mod h1:Dn2zUBOCu/6xYcd6iAjB7LgoY16OTQjDZfWHLwvuQj4=
go.etcd.io/etcd/client/v3 v3.6.13 h1:0E+9ZYGpMsi9KlOJVoCdONh9PUDawKDTy5mSNY8wOEI=
go.etcd.io/etcd/client/v3 v3.6.13/go.mod h1:rtVI3vwobljb8xlTGcp1Yhz7hBIuBWULXwB848kqJGw=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@@ -1360,8 +1354,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
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=
@@ -1376,8 +1370,8 @@ golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJk
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.43.0 h1:FLxcP4ec2350nTfOC8ysKtqYSIFbk/QGjw1ZHNP4tsY=
golang.org/x/image v0.43.0/go.mod h1:rrpelvGFt+kLPAjPM4HeWPgrl0FtafueU//e5N0qk/Q=
golang.org/x/image v0.44.0 h1:+tDekMZED9+LrtB3G5xzRggpVh9CARjZqROla3R3R+I=
golang.org/x/image v0.44.0/go.mod h1:V8K3KE9KKKE+pLpQDOeN18w9oacNSvy1tDOirTu4xtY=
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=
@@ -1451,8 +1445,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
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=
@@ -1476,8 +1470,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1558,8 +1552,8 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
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=
@@ -1568,8 +1562,8 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
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=
@@ -1582,8 +1576,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus=
golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
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=
@@ -1646,8 +1640,6 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q=
golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA=
golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk=
golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg=
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=
@@ -1711,8 +1703,8 @@ google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgn
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I=
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8=
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260729162451-8efbd57d26e0 h1:mJiOtnGp0k/BcSgdu03G2NwnscCfCH+h2QKUBZr18KI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260729162451-8efbd57d26e0/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -1728,8 +1720,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
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/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.82.0 h1:vguDnZUPjE26w09A63VoxZPnvPjB5Riyc0mkXPFmAIU=
google.golang.org/grpc v1.82.0/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
google.golang.org/grpc v1.83.0 h1:JeNZEKJFbQxArAMl+hiytHauacDNqJUllNfmIMmpqnQ=
google.golang.org/grpc v1.83.0/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ=
google.golang.org/grpc/examples v0.0.0-20211102180624-670c133e568e h1:m7aQHHqd0q89mRwhwS9Bx2rjyl/hsFAeta+uGrHsQaU=
google.golang.org/grpc/examples v0.0.0-20211102180624-670c133e568e/go.mod h1:gID3PKrg7pWKntu9Ss6zTLJ0ttC0X9IHgREOCZwbCVU=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -1764,6 +1756,8 @@ gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.3 h1:iM9Lhz5MRSGhHVGGwCuzG9KO8PoirCXj/m/qTmOJJQw=
gopkg.in/ini.v1 v1.67.3/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss=
gopkg.in/ns1/ns1-go.v2 v2.4.4/go.mod h1:GMnKY+ZuoJ+lVLL+78uSTjwTz2jMazq6AfGKQOYhsPk=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+273 -446
View File
@@ -1,17 +1,16 @@
package command
import (
"bufio"
"fmt"
"os"
"path/filepath"
"strings"
"time"
"github.com/opencloud-eu/opencloud/opencloud/pkg/register"
"github.com/opencloud-eu/opencloud/pkg/config"
"github.com/opencloud-eu/opencloud/pkg/config/configlog"
"github.com/opencloud-eu/opencloud/pkg/config/parser"
"github.com/opencloud-eu/opencloud/pkg/x/path/filepathx"
storageUsersParser "github.com/opencloud-eu/opencloud/services/storage-users/pkg/config/parser"
"github.com/opencloud-eu/opencloud/services/storage-users/pkg/event"
"github.com/opencloud-eu/opencloud/services/storage-users/pkg/revaconfig"
@@ -19,27 +18,10 @@ import (
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/ignore"
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/options"
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/registry"
"github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/prefixes"
"github.com/pkg/xattr"
"github.com/rs/zerolog"
"github.com/spf13/cobra"
"github.com/theckman/yacspin"
"github.com/vmihailenco/msgpack/v5"
)
// Define the names of the extended attributes we are working with.
const (
parentIDAttrName = "user.oc.parentid"
idAttrName = "user.oc.id"
nameAttrName = "user.oc.name"
spaceIDAttrName = "user.oc.space.id"
ownerIDAttrName = "user.oc.owner.id"
)
var (
spinner *yacspin.Spinner
restartRequired = false
ignorer *ignore.Ignorer
)
type IDCacher interface {
@@ -73,11 +55,23 @@ func init() {
// scanCmd performs a posixfs id cache warmup scan
func scanCmd(ocCfg *config.Config) *cobra.Command {
cmd := &cobra.Command{
Use: "scan",
scanCmd := &cobra.Command{
Use: "scan [path ...]",
Short: "Perform a filesystem scan and update the ID and filemetadata cache",
PreRunE: func(cmd *cobra.Command, args []string) error {
Long: `Perform a filesystem scan and update the ID and filemetadata cache.
You can specify one or more paths to limit the scope of the scan.
If no path is provided, the whole storage is checked, starting at the storage root directory.
The provided arguments determines the scope of the check:
- a storage root: the whole storage (all personal and project spaces) is scanned
- a space root: only that space is scanned
- a file or directory: only that single resource is scanned (and its children, if it is a directory)
Any specified file or directory must be underneath the storage root directory and if that is not the case,
the command is aborted with an error before performing any scanning.`,
Args: cobra.ArbitraryArgs,
PreRunE: func(cmd *cobra.Command, args []string) error {
if err := parser.ParseConfig(ocCfg, true); err != nil {
return configlog.ReturnError(err)
}
@@ -94,448 +88,281 @@ func scanCmd(ocCfg *config.Config) *cobra.Command {
os.Exit(1)
}
// We want to initialize the driver but disable scanfs on boot, so we can trigger it manually afterwards
drivers := revaconfig.StorageProviderDrivers(cfg)
drivers["posix"] = revaconfig.Posix(cfg, false, false)
var fsStream events.Stream
var err error
fsStream, err = event.NewStream(cfg)
haltOnError, err := cmd.Flags().GetBool("halt-on-error")
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create event stream for posix driver: %v\n", err)
os.Exit(1)
}
f, ok := registry.NewFuncs["posix"]
if !ok {
fmt.Fprintf(os.Stderr, "posix driver not found in registry\n")
os.Exit(1)
}
fs, err := f(drivers["posix"].(map[string]any), fsStream, nil)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to initialize filesystem driver '%s': %v\n", cfg.Driver, err)
return err
}
cacher, ok := fs.(IDCacher)
if !ok {
fmt.Fprintf(os.Stderr, "The posix driver does not expose WarmupIDCache.\n")
os.Exit(1)
storageRoot := cfg.Drivers.Posix.Root
paths := []string{storageRoot}
if len(args) > 0 {
paths = []string{}
for _, v := range args {
path := v
if !filepath.IsAbs(path) {
if v, err := filepath.Abs(path); err != nil {
fmt.Fprintf(os.Stderr, "Failed to make the specified path %q absolute: %v\n", v, err)
os.Exit(1)
} else {
path = v
}
}
// not ensuring whether the path is under the storage root here, will be done when iterating over them
path = filepath.Clean(path)
paths = append(paths, path)
}
}
fmt.Println("Starting posixfs scan...")
err = cacher.WarmupIDCache(cfg.Drivers.Posix.Root, true, false)
if err != nil {
fmt.Fprintf(os.Stderr, "Scan failed: %v\n", err)
return err
var scan func(path string) error = nil
{
// We want to initialize the driver but disable scanfs on boot, so we can trigger it manually afterwards
drivers := revaconfig.StorageProviderDrivers(cfg)
drivers["posix"] = revaconfig.Posix(cfg, false, false)
var fsStream events.Stream
var err error
fsStream, err = event.NewStream(cfg)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create event stream for posix driver: %v\n", err)
os.Exit(1)
}
log := logger("posixfs")
f, ok := registry.NewFuncs["posix"]
if !ok {
fmt.Fprintf(os.Stderr, "posix driver not found in registry\n")
os.Exit(1)
}
fs, err := f(drivers["posix"].(map[string]any), fsStream, &log)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to initialize filesystem driver '%s': %v\n", cfg.Driver, err)
return err
}
cacher, ok := fs.(IDCacher)
if !ok {
fmt.Fprintf(os.Stderr, "The posix driver does not expose WarmupIDCache.\n")
os.Exit(1)
}
scan = func(path string) error {
err := cacher.WarmupIDCache(path, true, false)
if err != nil {
logFailure("Error scanning path '%s': %v", path, err)
}
return err
}
}
fmt.Println("Scan completed successfully.")
return nil
errors := processPosixFsResources(paths, !haltOnError,
func(path string) error {
fmt.Println("Scanning personal spaces...")
return scan(path)
},
func(path string) error {
fmt.Println("Scanning project spaces...")
return scan(path)
},
func(path string) error {
fmt.Printf("Scanning space '%s'...\n", path)
return scan(path)
},
func(path string) error {
fmt.Printf("Scanning '%s'...\n", path)
return scan(path)
},
)
if len(errors) == 0 {
fmt.Println("Scan completed successfully.")
return nil
} else {
plural := "s"
if len(errors) == 1 {
plural = ""
}
verb := "completed"
if haltOnError {
verb = "aborted"
}
return fmt.Errorf("scan %s with %d error%s", verb, len(errors), plural)
}
},
}
return cmd
scanCmd.Flags().BoolP("halt-on-error", "E", false, "Halt at once when an error occurs when processing one of the paths (default behaviour is to keep going and attempt to process all paths).")
return scanCmd
}
// consistencyCmd returns a command to check the consistency of the posixfs storage.
func consistencyCmd(cfg *config.Config) *cobra.Command {
func consistencyCmd(ocCfg *config.Config) *cobra.Command {
consCmd := &cobra.Command{
Use: "consistency",
Short: "check the consistency of the posixfs storage",
Use: "consistency [path ...]",
Short: "Check the consistency of the posixfs storage",
Long: `Check the consistency of the posixfs storage.
You can specify one or more paths to limit the scope of the check.
If no path is provided, the whole storage is checked.
The provided arguments determines the scope of the check:
- a storage root: the whole storage (all personal and project spaces) is checked
- a space root: only that space is checked
- a file or directory: only that single entity is checked (and its children, if it is a directory)`,
Args: cobra.ArbitraryArgs,
PreRunE: func(cmd *cobra.Command, args []string) error {
if err := parser.ParseConfig(ocCfg, true); err != nil {
return configlog.ReturnError(err)
}
// Parse storage users config
ocCfg.StorageUsers.Commons = ocCfg.Commons
return configlog.ReturnFatal(storageUsersParser.ParseConfig(ocCfg.StorageUsers))
},
RunE: func(cmd *cobra.Command, args []string) error {
return checkPosixfsConsistency(cmd, cfg)
cfg := ocCfg.StorageUsers
if len(args) == 0 {
args = []string{cfg.Drivers.Posix.Root}
}
log := logger("posixfs")
recalculateChecksums, err := cmd.Flags().GetBool("fix-checksums")
if err != nil {
return err
}
drivers := revaconfig.StorageProviderDrivers(cfg)
drivers["posix"] = revaconfig.Posix(cfg, false, false)
opts, err := options.New(drivers["posix"].(map[string]any))
if err != nil {
return err
}
ignorer := ignore.NewIgnorer(opts, &log)
checker := &consistencyChecker{
cfg: cfg,
ignorer: ignorer,
recalculateChecksums: recalculateChecksums,
}
return checker.Check(args)
},
}
consCmd.Flags().StringP("root", "r", "", "Path to the root directory of the posixfs storage")
_ = consCmd.MarkFlagRequired("root")
consCmd.Flags().Bool("fix-checksums", false, "Recalculate and fix the file checksums. This reads every file and can be slow on large storages.")
return consCmd
}
// checkPosixfsConsistency checks the consistency of the posixfs storage.
func checkPosixfsConsistency(cmd *cobra.Command, cfg *config.Config) error {
rootPath, _ := cmd.Flags().GetString("root")
indexesPath := filepath.Join(rootPath, "indexes")
opt, _ := options.New(map[string]interface{}{
"root": rootPath,
})
log := zerolog.Nop()
ignorer = ignore.NewIgnorer(opt, &log)
_, err := os.Stat(indexesPath)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("consistency check failed: '%s' is not a posixfs root", rootPath)
}
return fmt.Errorf("error accessing '%s': %w", indexesPath, err)
}
spinnerCfg := yacspin.Config{
Frequency: 100 * time.Millisecond,
CharSet: yacspin.CharSets[11],
StopCharacter: "✓",
StopColors: []string{"fgGreen"},
StopFailCharacter: "✗",
StopFailColors: []string{"fgRed"},
}
spinner, err = yacspin.New(spinnerCfg)
err = spinner.Start()
if err != nil {
return fmt.Errorf("error creating spinner: %w", err)
}
checkSpaces(filepath.Join(rootPath, "users"))
spinner.Suffix(" Personal spaces check ")
spinner.StopMessage("completed\n")
spinner.Stop()
checkSpaces(filepath.Join(rootPath, "projects"))
spinner.Suffix(" Project spaces check ")
spinner.StopMessage("completed")
spinner.Stop()
if restartRequired {
fmt.Println("\n\n ⚠️ Please restart your openCloud instance to apply changes.")
}
return nil
}
func checkSpaces(basePath string) {
dirEntries, err := os.ReadDir(basePath)
if err != nil {
spinner.Message(fmt.Sprintf("Error reading spaces directory '%s'\n", basePath))
spinner.StopFail()
return
}
for _, entry := range dirEntries {
if entry.IsDir() {
fullPath := filepath.Join(basePath, entry.Name())
checkSpace(fullPath)
}
}
}
func checkSpace(spacePath string) {
spinner.Message("")
spinner.Suffix(fmt.Sprintf(" Checking space '%s'", spacePath))
info, err := os.Stat(spacePath)
if err != nil {
logFailure("Error accessing path '%s': %v", spacePath, err)
return
}
if !info.IsDir() {
logFailure("Error: The provided path '%s' is not a directory\n", spacePath)
return
}
spaceID, err := xattr.Get(spacePath, spaceIDAttrName)
if err != nil || len(spaceID) == 0 {
logFailure("Error: The directory '%s' does not seem to be a space root, it's missing the '%s' attribute\n", spacePath, spaceIDAttrName)
return
}
checkSpaceID(spacePath)
checkNodeIDs(spacePath)
}
func checkSpaceID(spacePath string) {
spinner.Message(" - checking space ID uniqueness")
entries, uniqueIDs, oldestEntry, err := gatherAttributes(spacePath)
if err != nil {
logFailure("Failed to gather attributes: %v", err)
return
}
if len(entries) == 0 {
return
}
if len(uniqueIDs) > 1 {
spinner.Pause()
fmt.Println("\n ⚠ Multiple space IDs found:")
for id := range uniqueIDs {
fmt.Printf(" - %s\n", id)
}
fmt.Printf("\n ⏳ Oldest entry is '%s' (modified on %s).\n",
filepath.Base(oldestEntry.Path), oldestEntry.ModTime.Format(time.RFC1123))
targetID := oldestEntry.ParentID
fmt.Printf(" ✅ Proposed target Parent ID: %s\n", targetID)
fmt.Printf("\n Do you want to unify all parent IDs to '%s'? This will modify %d entries, the directory, and the user index. (y/N): ", targetID, len(entries))
reader := bufio.NewReader(os.Stdin)
input, _ := reader.ReadString('\n')
input = strings.TrimSpace(strings.ToLower(input))
if input != "y" {
spinner.Unpause()
logFailure("Operation cancelled by user.")
return
}
restartRequired = true
obsoleteIDs := []string{}
for id := range uniqueIDs {
if id != targetID {
obsoleteIDs = append(obsoleteIDs, id)
}
}
fixSpaceID(spacePath, obsoleteIDs, targetID, entries)
spinner.Unpause()
}
}
func walkNodes(dir string, parentID string) int {
fixes := 0
entries, err := os.ReadDir(dir)
if err != nil {
logFailure("Error reading directory '%s': %v", dir, err)
return 0
}
for _, entry := range entries {
fullPath := filepath.Join(dir, entry.Name())
if ignorer.IsIgnored(fullPath) {
continue
}
// Check if the parent ID attribute matches the expected parent ID, if not, fix it.
actualParentID, err := xattr.Get(fullPath, parentIDAttrName)
if err != nil || string(actualParentID) != parentID {
err = xattr.Set(fullPath, parentIDAttrName, []byte(parentID))
if err != nil {
logFailure("Failed to fix parent ID for '%s': %v", fullPath, err)
} else {
spinner.Pause()
fmt.Printf(" + Fixed parent ID for '%s'", fullPath)
spinner.Unpause()
fixes++
restartRequired = true
}
}
// Check that the name attribute matches the actual name of the file/directory, if not, fix it.
nameAttr, err := xattr.Get(fullPath, nameAttrName)
if err != nil || string(nameAttr) != entry.Name() {
err = xattr.Set(fullPath, nameAttrName, []byte(entry.Name()))
if err != nil {
logFailure("Failed to fix name attribute for '%s': %v", fullPath, err)
} else {
spinner.Pause()
fmt.Printf(" + Fixed name attribute for '%s'", fullPath)
spinner.Unpause()
fixes++
restartRequired = true
}
}
if entry.IsDir() {
nodeID, err := xattr.Get(fullPath, idAttrName)
if err != nil || len(nodeID) == 0 {
logFailure("Directory '%s' missing '%s', skipping its children", fullPath, idAttrName)
continue
}
walkNodes(fullPath, string(nodeID))
}
}
return fixes
}
func checkNodeIDs(spacePath string) {
spinner.Message(" - checking nodes")
rootID, err := xattr.Get(spacePath, idAttrName)
if err != nil || len(rootID) == 0 {
logFailure("Space root '%s' missing '%s' attribute", spacePath, idAttrName)
return
}
fixes := walkNodes(spacePath, string(rootID))
if fixes > 0 {
spinner.Pause()
fmt.Printf("\n ✓ Fixed %d incorrect node attributes in %s\n", fixes, filepath.Base(spacePath))
spinner.Unpause()
}
}
func fixSpaceID(spacePath string, obsoleteIDs []string, targetID string, entries []EntryInfo) {
// Set all parentid attributes to the proper space ID
err := setAllParentIDAttributes(entries, targetID)
if err != nil {
logFailure("an error occurred during file attribute update: %v", err)
return
}
// Update space ID itself
fmt.Printf(" Updating directory '%s' with attribute '%s' -> %s\n", filepath.Base(spacePath), idAttrName, targetID)
err = xattr.Set(spacePath, idAttrName, []byte(targetID))
if err != nil {
logFailure("Failed to set attribute on directory '%s': %v", spacePath, err)
return
}
err = xattr.Set(spacePath, spaceIDAttrName, []byte(targetID))
if err != nil {
logFailure("Failed to set attribute on directory '%s': %v", spacePath, err)
return
}
// update the index
err = updateOwnerIndexFile(spacePath, obsoleteIDs)
if err != nil {
logFailure("Could not update the owner index file: %v", err)
}
}
func gatherAttributes(path string) ([]EntryInfo, map[string]struct{}, EntryInfo, error) {
dirEntries, err := os.ReadDir(path)
if err != nil {
return nil, nil, EntryInfo{}, fmt.Errorf("failed to read directory: %w", err)
}
var allEntries []EntryInfo
uniqueIDs := make(map[string]struct{})
var oldestEntry EntryInfo
oldestTime := time.Now().Add(100 * 365 * 24 * time.Hour) // Set to a future date to find the oldest entry
for _, entry := range dirEntries {
fullPath := filepath.Join(path, entry.Name())
if ignorer.IsIgnored(fullPath) {
continue
}
info, err := os.Stat(fullPath)
if err != nil {
fmt.Printf(" - Warning: could not stat %s: %v\n", entry.Name(), err)
continue
}
parentID, err := xattr.Get(fullPath, parentIDAttrName)
if err != nil {
continue // Skip if attribute doesn't exist or can't be read
}
entryInfo := EntryInfo{
Path: fullPath,
ModTime: info.ModTime(),
ParentID: string(parentID),
}
allEntries = append(allEntries, entryInfo)
uniqueIDs[string(parentID)] = struct{}{}
if entryInfo.ModTime.Before(oldestTime) {
oldestTime = entryInfo.ModTime
oldestEntry = entryInfo
}
}
return allEntries, uniqueIDs, oldestEntry, nil
}
func setAllParentIDAttributes(entries []EntryInfo, targetID string) error {
fmt.Printf(" Setting all parent IDs to '%s':\n", targetID)
for _, entry := range entries {
if entry.ParentID == targetID {
fmt.Printf(" - Skipping '%s' (already has target ID).\n", filepath.Base(entry.Path))
continue
}
fmt.Printf(" - Removing all attributes from '%s'. It will be re-assimilated\n", filepath.Base(entry.Path))
filepath.WalkDir(entry.Path, func(path string, d os.DirEntry, err error) error {
if err != nil {
return fmt.Errorf("error walking path '%s': %w", path, err)
}
// Remove all attributes from the file.
if err := removeAttributes(path); err != nil {
fmt.Printf("failed to remove attributes from '%s': %v", path, err)
}
return nil
})
}
return nil
}
// updateOwnerIndexFile handles the logic of reading, modifying, and writing the MessagePack index file.
func updateOwnerIndexFile(basePath string, obsoleteIDs []string) error {
fmt.Printf(" Rewriting index file '%s'\n", basePath)
ownerID, err := xattr.Get(basePath, ownerIDAttrName)
if err != nil {
return fmt.Errorf("could not get owner ID from oldest entry '%s' to find index: %w", basePath, err)
}
indexPath := filepath.Join(basePath, "../../indexes/by-user-id", string(ownerID)+".mpk")
indexPath = filepath.Clean(indexPath)
// Read the MessagePack file
fileData, err := os.ReadFile(indexPath)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("index file does not exist, skipping update")
}
return fmt.Errorf("could not read index file: %w", err)
}
var indexMap map[string]string
if err := msgpack.Unmarshal(fileData, &indexMap); err != nil {
return fmt.Errorf("failed to parse MessagePack index file (is it corrupt?): %w", err)
}
// Remove obsolete IDs from the map
itemsRemoved := 0
for _, id := range obsoleteIDs {
if _, exists := indexMap[id]; exists {
fmt.Printf(" - Removing obsolete ID '%s' from index.\n", id)
delete(indexMap, id)
itemsRemoved++
} else {
fmt.Printf(" - Obsolete ID '%s' not found in index\n", id)
}
}
if itemsRemoved == 0 {
return nil
}
// Write the data back to the file
updatedData, err := msgpack.Marshal(&indexMap)
if err != nil {
return fmt.Errorf("failed to marshal updated index map: %w", err)
}
if err := os.WriteFile(indexPath, updatedData, 0644); err != nil {
return fmt.Errorf("failed to write updated index file: %w", err)
}
fmt.Printf(" ✓ Successfully removed %d item(s) and saved index file.\n", itemsRemoved)
return nil
}
func removeAttributes(path string) error {
attrNames, err := xattr.List(path)
if err != nil {
return fmt.Errorf("failed to list attributes for '%s': %w", path, err)
}
for _, attrName := range attrNames {
if err := xattr.Remove(path, attrName); err != nil {
return fmt.Errorf("failed to remove attribute '%s' from '%s': %w", attrName, path, err)
}
}
return nil
}
func logFailure(message string, args ...any) {
spinner.StopFailMessage(fmt.Sprintf("\n"+message, args...))
spinner.StopFail()
spinner.Start()
fmt.Fprintf(os.Stderr, message+"\n", args...)
}
// findStorageRoot walks up the directory tree starting at path until it finds a
// directory that contains an "indexes" subdirectory which marks the root of a
// posixfs storage. A user directory inside a space might also be named "indexes",
// so to disambiguate we require that the "indexes" directory is an internal
// directory: the storage's own indexes directory is skipped during assimilation
// and therefore never receives a node ID attribute, whereas a regular user
// directory would have one.
func findStorageRoot(path string) (string, error) {
current := path
for {
indexesPath := filepath.Join(current, "indexes")
if info, err := os.Stat(indexesPath); err == nil && info.IsDir() {
if id, err := xattr.Get(indexesPath, prefixes.IDAttr); err != nil || len(id) == 0 {
return current, nil
}
}
parent := filepath.Dir(current)
if parent == current {
return "", fmt.Errorf("'%s' does not appear to be inside a posixfs storage (no 'indexes' directory found)", path)
}
current = parent
}
}
// isSpaceRoot reports whether the given path is a space root, which is
// identified by the presence of the space ID attribute.
func isSpaceRoot(path string) bool {
spaceID, err := xattr.Get(path, prefixes.SpaceIDAttr)
return err == nil && len(spaceID) > 0
}
// iterates over a list of paths and processes them all, using the appropriate function
// depending on the type of resource
//
// note that whenever an error occurs, it collects that error and continues processing
// subsequent paths, and then returns a slice of errors at the end (or an empty slice
// if no errors occured)
func processPosixFsResources(paths []string,
keepGoing bool,
personalSpaceDir func(string) error,
projectSpaceDir func(string) error,
spaceRoot func(string) error,
entity func(string) error,
) []error {
// no need to guard this with a mutex for now, since the implementation is not parallelized
errors := []error{}
for _, path := range paths {
rootPath, err := findStorageRoot(path)
if err != nil {
errors = append(errors, err)
logFailure("error: %s", err)
if keepGoing {
continue
} else {
return errors
}
}
path = filepath.Clean(path)
if _, err := os.Stat(path); err != nil {
errors = append(errors, err)
logFailure("error accessing '%s': %w", path, err)
if keepGoing {
continue
} else {
return errors
}
}
contained, _ := filepathx.IsSameOrContainedBy(rootPath, path)
switch {
case path == rootPath:
if err := personalSpaceDir(filepath.Join(path, "users")); err != nil {
errors = append(errors, err)
if !keepGoing {
return errors
}
}
if err := projectSpaceDir(filepath.Join(path, "projects")); err != nil {
errors = append(errors, err)
if !keepGoing {
return errors
}
}
case isSpaceRoot(path):
if err := spaceRoot(path); err != nil {
errors = append(errors, err)
if !keepGoing {
return errors
}
}
case contained:
if err := entity(path); err != nil {
errors = append(errors, err)
if !keepGoing {
return errors
}
}
default:
err := fmt.Errorf("error: the provided path '%s' is neither a space root nor contained by the storage root '%s'", path, rootPath)
errors = append(errors, err)
logFailure(err.Error())
if !keepGoing {
return errors
}
}
}
return errors
}
@@ -0,0 +1,489 @@
// Copyright 2026 OpenCloud GmbH <mail@opencloud.eu>
// SPDX-License-Identifier: Apache-2.0
package command
import (
"bufio"
"bytes"
"context"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"time"
storageUsersConfig "github.com/opencloud-eu/opencloud/services/storage-users/pkg/config"
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/ignore"
"github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/prefixes"
"github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node"
"github.com/pkg/xattr"
"github.com/shamaton/msgpack/v2"
)
type consistencyChecker struct {
cfg *storageUsersConfig.Config
ignorer *ignore.Ignorer
recalculateChecksums bool
restartRequired bool
}
// checkPosixfsConsistency checks the consistency of the posixfs storage. The
// given path determines the scope of the check: the whole storage, a single
// space or a single entity within a space.
func (c *consistencyChecker) Check(paths []string) error {
_ = processPosixFsResources(paths, true,
func(path string) error {
fmt.Println("Checking personal spaces...")
c.checkSpaces(path)
return nil
},
func(path string) error {
fmt.Println("Checking project spaces...")
c.checkSpaces(path)
return nil
},
func(path string) error {
fmt.Printf("Checking space '%s'...\n", path)
c.checkSpace(path)
return nil
},
func(path string) error {
if c.ignorer.IsIgnored(path) {
return nil
}
fmt.Printf("Checking '%s'...\n", path)
c.checkEntity(path)
return nil
},
)
if c.restartRequired {
fmt.Println("\n\n ⚠️ Please restart your openCloud instance to apply changes.")
}
return nil
}
func (c *consistencyChecker) checkSpaces(basePath string) {
dirEntries, err := os.ReadDir(basePath)
if err != nil {
logFailure("Error reading spaces directory '%s': %v", basePath, err)
return
}
for _, entry := range dirEntries {
if entry.IsDir() {
fullPath := filepath.Join(basePath, entry.Name())
c.checkSpace(fullPath)
}
}
}
func (c *consistencyChecker) checkSpace(spacePath string) {
info, err := os.Stat(spacePath)
if err != nil {
logFailure("Error accessing path '%s': %v", spacePath, err)
return
}
if !info.IsDir() {
logFailure("Error: The provided path '%s' is not a directory\n", spacePath)
return
}
spaceID, err := xattr.Get(spacePath, prefixes.SpaceIDAttr)
if err != nil || len(spaceID) == 0 {
logFailure("Error: The directory '%s' does not seem to be a space root, it's missing the '%s' attribute\n", spacePath, prefixes.SpaceIDAttr)
return
}
c.checkSpaceID(spacePath)
c.checkNodes(spacePath)
}
func (c *consistencyChecker) checkSpaceID(spacePath string) {
entries, uniqueIDs, oldestEntry, err := c.gatherAttributes(spacePath)
if err != nil {
logFailure("Failed to gather attributes: %v", err)
return
}
if len(entries) == 0 {
return
}
if len(uniqueIDs) > 1 {
fmt.Println("\n ⚠ Multiple space IDs found:")
for id := range uniqueIDs {
fmt.Printf(" - %s\n", id)
}
fmt.Printf("\n ⏳ Oldest entry is '%s' (modified on %s).\n",
filepath.Base(oldestEntry.Path), oldestEntry.ModTime.Format(time.RFC1123))
targetID := oldestEntry.ParentID
fmt.Printf(" ✅ Proposed target Parent ID: %s\n", targetID)
fmt.Printf("\n Do you want to unify all parent IDs to '%s'? This will modify %d entries, the directory, and the user index. (y/N): ", targetID, len(entries))
reader := bufio.NewReader(os.Stdin)
input, _ := reader.ReadString('\n')
input = strings.TrimSpace(strings.ToLower(input))
if input != "y" {
logFailure("Operation cancelled by user.")
return
}
c.restartRequired = true
obsoleteIDs := []string{}
for id := range uniqueIDs {
if id != targetID {
obsoleteIDs = append(obsoleteIDs, id)
}
}
c.fixSpaceID(spacePath, obsoleteIDs, targetID, entries)
}
}
func (c *consistencyChecker) walkNodes(dir string, parentID string) int {
fixes := 0
entries, err := os.ReadDir(dir)
if err != nil {
logFailure("Error reading directory '%s': %v", dir, err)
return 0
}
for _, entry := range entries {
fullPath := filepath.Join(dir, entry.Name())
if c.ignorer.IsIgnored(fullPath) {
continue
}
fixes += c.checkNodeAttributes(fullPath, entry.Name(), parentID, entry.IsDir())
if entry.IsDir() {
nodeID, err := xattr.Get(fullPath, prefixes.IDAttr)
if err != nil || len(nodeID) == 0 {
logFailure("Directory '%s' missing '%s', skipping its children", fullPath, prefixes.IDAttr)
continue
}
fixes += c.walkNodes(fullPath, string(nodeID))
}
}
return fixes
}
// checkNodeAttributes checks and fixes the parent ID and name attributes of a
// single node. For files it additionally checks the blobsize and, when
// requested, the checksums. It returns the number of fixes applied.
func (c *consistencyChecker) checkNodeAttributes(path, name, parentID string, isDir bool) int {
fixes := 0
// Check if the parent ID attribute matches the expected parent ID, if not, fix it.
actualParentID, err := xattr.Get(path, prefixes.ParentidAttr)
if err != nil || string(actualParentID) != parentID {
if err := xattr.Set(path, prefixes.ParentidAttr, []byte(parentID)); err != nil {
logFailure("Failed to fix parent ID for '%s': %v", path, err)
} else {
fmt.Printf(" + Fixed parent ID for '%s'\n", path)
fixes++
c.restartRequired = true
}
}
// Check that the name attribute matches the actual name of the file/directory, if not, fix it.
nameAttr, err := xattr.Get(path, prefixes.NameAttr)
if err != nil || string(nameAttr) != name {
if err := xattr.Set(path, prefixes.NameAttr, []byte(name)); err != nil {
logFailure("Failed to fix name attribute for '%s': %v", path, err)
} else {
fmt.Printf(" + Fixed name attribute for '%s'\n", path)
fixes++
c.restartRequired = true
}
}
if !isDir {
fixes += c.checkBlobsize(path)
if c.recalculateChecksums {
fixes += c.fixChecksums(path)
}
}
return fixes
}
// checkEntity checks a single file or directory within a space, including its own
// parent ID, name and (for files) blobsize/checksums. If the entity is a directory
// its children are checked recursively.
func (c *consistencyChecker) checkEntity(path string) {
info, err := os.Stat(path)
if err != nil {
logFailure("Error accessing path '%s': %v", path, err)
return
}
// The expected parent ID is the ID attribute of the containing directory.
parentDir := filepath.Dir(path)
parentID, err := xattr.Get(parentDir, prefixes.IDAttr)
if err != nil || len(parentID) == 0 {
logFailure("Parent directory '%s' is missing the '%s' attribute", parentDir, prefixes.IDAttr)
return
}
fixes := c.checkNodeAttributes(path, info.Name(), string(parentID), info.IsDir())
if info.IsDir() {
nodeID, err := xattr.Get(path, prefixes.IDAttr)
if err != nil || len(nodeID) == 0 {
logFailure("Directory '%s' missing '%s' attribute", path, prefixes.IDAttr)
} else {
fixes += c.walkNodes(path, string(nodeID))
}
}
if fixes > 0 {
fmt.Printf(" ✓ Fixed %d incorrect node attributes for %s\n", fixes, filepath.Base(path))
}
}
// checkBlobsize verifies that the stored blobsize attribute matches the actual
// file size and fixes it if it doesn't. It returns the number of fixes applied.
func (c *consistencyChecker) checkBlobsize(path string) int {
info, err := os.Stat(path)
if err != nil {
logFailure("Error accessing file '%s': %v", path, err)
return 0
}
expectedSize := strconv.FormatInt(info.Size(), 10)
blobsize, err := xattr.Get(path, prefixes.BlobsizeAttr)
if err == nil && string(blobsize) == expectedSize {
return 0
}
if err := xattr.Set(path, prefixes.BlobsizeAttr, []byte(expectedSize)); err != nil {
logFailure("Failed to fix blobsize for '%s': %v", path, err)
return 0
}
fmt.Printf(" + Fixed blobsize for '%s'\n", path)
c.restartRequired = true
return 1
}
// fixChecksums recalculates the sha1, md5 and adler32 checksums of the file and
// updates the stored attributes if they differ. It returns the number of fixes applied.
func (c *consistencyChecker) fixChecksums(path string) int {
sha1h, md5h, adler32h, err := node.CalculateChecksums(context.Background(), path)
if err != nil {
logFailure("Failed to calculate checksums for '%s': %v", path, err)
return 0
}
checksums := map[string][]byte{
prefixes.ChecksumPrefix + "sha1": sha1h.Sum(nil),
prefixes.ChecksumPrefix + "md5": md5h.Sum(nil),
prefixes.ChecksumPrefix + "adler32": adler32h.Sum(nil),
}
fixes := 0
for attrName, sum := range checksums {
current, err := xattr.Get(path, attrName)
if err == nil && bytes.Equal(current, sum) {
continue
}
if err := xattr.Set(path, attrName, sum); err != nil {
logFailure("Failed to fix checksum '%s' for '%s': %v", attrName, path, err)
continue
}
fmt.Printf(" + Fixed checksum '%s' for '%s'\n", attrName, path)
c.restartRequired = true
fixes++
}
return fixes
}
func (c *consistencyChecker) checkNodes(spacePath string) {
rootID, err := xattr.Get(spacePath, prefixes.IDAttr)
if err != nil || len(rootID) == 0 {
logFailure("Space root '%s' missing '%s' attribute", spacePath, prefixes.IDAttr)
return
}
fixes := c.walkNodes(spacePath, string(rootID))
if fixes > 0 {
fmt.Printf(" ✓ Fixed %d incorrect node attributes in %s\n", fixes, filepath.Base(spacePath))
}
}
// fixSpaceID updates the parentid attributes of all entries in a space to a new target ID,
// updates the space's own ID attributes, and removes obsolete IDs from the user index file.
func (c *consistencyChecker) fixSpaceID(spacePath string, obsoleteIDs []string, targetID string, entries []EntryInfo) {
// Set all parentid attributes to the proper space ID
err := setAllParentIDAttributes(entries, targetID)
if err != nil {
logFailure("an error occurred during file attribute update: %v", err)
return
}
// Update space ID itself
fmt.Printf(" Updating directory '%s' with attribute '%s' -> %s\n", filepath.Base(spacePath), prefixes.IDAttr, targetID)
err = xattr.Set(spacePath, prefixes.IDAttr, []byte(targetID))
if err != nil {
logFailure("Failed to set attribute on directory '%s': %v", spacePath, err)
return
}
err = xattr.Set(spacePath, prefixes.SpaceIDAttr, []byte(targetID))
if err != nil {
logFailure("Failed to set attribute on directory '%s': %v", spacePath, err)
return
}
// update the index
err = c.updateOwnerIndexFile(spacePath, obsoleteIDs)
if err != nil {
logFailure("Could not update the owner index file: %v", err)
}
}
func (c *consistencyChecker) gatherAttributes(path string) ([]EntryInfo, map[string]struct{}, EntryInfo, error) {
dirEntries, err := os.ReadDir(path)
if err != nil {
return nil, nil, EntryInfo{}, fmt.Errorf("failed to read directory: %w", err)
}
var allEntries []EntryInfo
uniqueIDs := make(map[string]struct{})
var oldestEntry EntryInfo
oldestTime := time.Now().Add(100 * 365 * 24 * time.Hour) // Set to a future date to find the oldest entry
for _, entry := range dirEntries {
fullPath := filepath.Join(path, entry.Name())
if c.ignorer.IsIgnored(fullPath) {
continue
}
info, err := os.Stat(fullPath)
if err != nil {
fmt.Printf(" - Warning: could not stat %s: %v\n", entry.Name(), err)
continue
}
parentID, err := xattr.Get(fullPath, prefixes.ParentidAttr)
if err != nil {
continue // Skip if attribute doesn't exist or can't be read
}
entryInfo := EntryInfo{
Path: fullPath,
ModTime: info.ModTime(),
ParentID: string(parentID),
}
allEntries = append(allEntries, entryInfo)
uniqueIDs[string(parentID)] = struct{}{}
if entryInfo.ModTime.Before(oldestTime) {
oldestTime = entryInfo.ModTime
oldestEntry = entryInfo
}
}
return allEntries, uniqueIDs, oldestEntry, nil
}
func setAllParentIDAttributes(entries []EntryInfo, targetID string) error {
fmt.Printf(" Setting all parent IDs to '%s':\n", targetID)
for _, entry := range entries {
if entry.ParentID == targetID {
fmt.Printf(" - Skipping '%s' (already has target ID).\n", filepath.Base(entry.Path))
continue
}
fmt.Printf(" - Removing all attributes from '%s'. It will be re-assimilated\n", filepath.Base(entry.Path))
filepath.WalkDir(entry.Path, func(path string, d os.DirEntry, err error) error {
if err != nil {
return fmt.Errorf("error walking path '%s': %w", path, err)
}
// Remove all attributes from the file.
if err := removeAttributes(path); err != nil {
fmt.Printf("failed to remove attributes from '%s': %v", path, err)
}
return nil
})
}
return nil
}
// updateOwnerIndexFile handles the logic of reading, modifying, and writing the MessagePack index file.
func (c *consistencyChecker) updateOwnerIndexFile(basePath string, obsoleteIDs []string) error {
fmt.Printf(" Rewriting index file '%s'\n", basePath)
ownerID, err := xattr.Get(basePath, prefixes.OwnerIDAttr)
if err != nil {
return fmt.Errorf("could not get owner ID from oldest entry '%s' to find index: %w", basePath, err)
}
indexPath := filepath.Join(c.cfg.Drivers.Posix.Root, "indexes", "by-user-id", string(ownerID)+".mpk")
indexPath = filepath.Clean(indexPath)
// Read the MessagePack file
fileData, err := os.ReadFile(indexPath)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("index file does not exist, skipping update")
}
return fmt.Errorf("could not read index file: %w", err)
}
var indexMap map[string]string
if err := msgpack.Unmarshal(fileData, &indexMap); err != nil {
return fmt.Errorf("failed to parse MessagePack index file (is it corrupt?): %w", err)
}
// Remove obsolete IDs from the map
itemsRemoved := 0
for _, id := range obsoleteIDs {
if _, exists := indexMap[id]; exists {
fmt.Printf(" - Removing obsolete ID '%s' from index.\n", id)
delete(indexMap, id)
itemsRemoved++
} else {
fmt.Printf(" - Obsolete ID '%s' not found in index\n", id)
}
}
if itemsRemoved == 0 {
return nil
}
// Write the data back to the file
updatedData, err := msgpack.Marshal(&indexMap)
if err != nil {
return fmt.Errorf("failed to marshal updated index map: %w", err)
}
if err := os.WriteFile(indexPath, updatedData, 0644); err != nil {
return fmt.Errorf("failed to write updated index file: %w", err)
}
fmt.Printf(" ✓ Successfully removed %d item(s) and saved index file.\n", itemsRemoved)
return nil
}
func removeAttributes(path string) error {
attrNames, err := xattr.List(path)
if err != nil {
return fmt.Errorf("failed to list attributes for '%s': %w", path, err)
}
for _, attrName := range attrNames {
if err := xattr.Remove(path, attrName); err != nil {
return fmt.Errorf("failed to remove attribute '%s' from '%s': %w", attrName, path, err)
}
}
return nil
}
+12 -2
View File
@@ -6,11 +6,13 @@ import (
"os/signal"
"syscall"
"github.com/rs/zerolog"
"github.com/spf13/cobra"
"github.com/opencloud-eu/opencloud/opencloud/pkg/register"
"github.com/opencloud-eu/opencloud/pkg/clihelper"
"github.com/opencloud-eu/opencloud/pkg/config"
"github.com/spf13/cobra"
oclog "github.com/opencloud-eu/opencloud/pkg/log"
)
// Execute is the entry point for the opencloud command.
@@ -38,3 +40,11 @@ func Execute() error {
ctx, _ := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
return app.ExecuteContext(ctx)
}
func logger(name string) zerolog.Logger {
return oclog.NewLogger(
oclog.Name(name),
oclog.Level("info"),
oclog.Pretty(true),
oclog.Color(true)).Logger
}
+2 -12
View File
@@ -9,7 +9,6 @@ import (
"github.com/opencloud-eu/opencloud/pkg/config"
"github.com/opencloud-eu/opencloud/pkg/config/configlog"
"github.com/opencloud-eu/opencloud/pkg/config/parser"
oclog "github.com/opencloud-eu/opencloud/pkg/log"
mregistry "github.com/opencloud-eu/opencloud/pkg/registry"
sharing "github.com/opencloud-eu/opencloud/services/sharing/pkg/config"
sharingparser "github.com/opencloud-eu/opencloud/services/sharing/pkg/config/parser"
@@ -85,7 +84,7 @@ func cleanup(_ *cobra.Command, cfg *config.Config) error {
return configlog.ReturnError(errors.New("cleanup is only implemented for the jsoncs3 share manager"))
}
l := logger()
l := logger("migrate")
zerolog.SetGlobalLevel(zerolog.InfoLevel)
@@ -94,7 +93,7 @@ func cleanup(_ *cobra.Command, cfg *config.Config) error {
if !ok {
return configlog.ReturnError(errors.New("Unknown share manager type '" + driver + "'"))
}
mgr, err := f(rcfg[driver].(map[string]any), l)
mgr, err := f(rcfg[driver].(map[string]any), &l)
if err != nil {
return configlog.ReturnError(err)
}
@@ -167,12 +166,3 @@ func revaShareConfig(cfg *sharing.Config) map[string]any {
},
}
}
func logger() *zerolog.Logger {
log := oclog.NewLogger(
oclog.Name("migrate"),
oclog.Level("info"),
oclog.Pretty(true),
oclog.Color(true)).Logger
return &log
}
+10 -3
View File
@@ -389,9 +389,16 @@ func Start(ctx context.Context, o ...Option) error {
if ev.Restarting {
l = s.Log.Error()
}
l.Str("event", e.String()).Str("service", ev.ServiceName).Str("supervisor", ev.SupervisorName).
Bool("restarting", ev.Restarting).Float64("failures", ev.CurrentFailures).Float64("threshold", ev.FailureThreshold).
Interface("error", ev.Err).Msg("service terminated")
l = l.Str("event", e.String()).Str("service", ev.ServiceName).Str("supervisor", ev.SupervisorName).
Bool("restarting", ev.Restarting).Float64("failures", ev.CurrentFailures).Float64("threshold", ev.FailureThreshold)
// ev.Err is an interface{}: marshaling an error yields {} because
// its fields are unexported, so the message has to go through Err
if err, ok := ev.Err.(error); ok {
l = l.Err(err)
} else {
l = l.Interface("error", ev.Err)
}
l.Msg("service terminated")
case suture.EventBackoff:
s.Log.Warn().Str("event", e.String()).Str("supervisor", ev.SupervisorName).Msg("service backoff")
case suture.EventResume:
+1
View File
@@ -86,5 +86,6 @@
<property name="lineLimit" value="120" />
<property name="absoluteLineLimit" value="120" />
</properties>
<exclude-pattern>*/tests/acceptance/bootstrap/*</exclude-pattern>
</rule>
</ruleset>
+12
View File
@@ -14,5 +14,17 @@ func DefaultApp(app *cobra.Command) *cobra.Command {
// version info
app.Version = fmt.Sprintf("%s (%s <%s>) (%s)", version.String, "OpenCloud GmbH", "support@opencloud.eu", version.Compiled())
// cobra would print the error on top of what main() already prints
app.SilenceErrors = true
// keep the usage block for flag parse errors, drop it once RunE runs.
// Traversing runs the hook even below a subcommand that brings its own,
// e.g. every service below ServiceCommand.
cobra.EnableTraverseRunHooks = true
app.PersistentPreRunE = func(cmd *cobra.Command, _ []string) error {
cmd.SilenceUsage = true
return nil
}
return app
}
+3 -3
View File
@@ -56,9 +56,9 @@ type Cache struct {
DisablePersistence bool `yaml:"disable_persistence" env:"OC_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"1.0.0"`
AuthUsername string `yaml:"auth_username" env:"OC_CACHE_AUTH_USERNAME" desc:"The username to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
AuthPassword string `yaml:"auth_password" env:"OC_CACHE_AUTH_PASSWORD" desc:"The password to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided OC_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided OC_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
// Commons holds configuration that are common to all extensions. Each extension can then decide whether
+1 -1
View File
@@ -34,7 +34,7 @@ var (
// LatestTag is the latest released version plus the dev meta version.
// Will be overwritten by the release pipeline
// Needs a manual change for every tagged release
LatestTag = "7.1.0+dev"
LatestTag = "7.4.0+dev"
// Date indicates the build date.
// This has been removed, it looks like you can only replace static strings with recent go versions
+26
View File
@@ -1,7 +1,9 @@
package filepathx
import (
"fmt"
"path/filepath"
"strings"
)
// JailJoin joins any number of path elements into a single path,
@@ -10,3 +12,27 @@ import (
func JailJoin(jail string, elem ...string) string {
return filepath.Join(jail, filepath.Join(append([]string{"/"}, elem...)...))
}
// Determines whether the file or directory 'child' is same as or underneath the directory 'parent'.
//
// Note that 'parent' is expected to be a directory.
func IsSameOrContainedBy(parent string, child string) (bool, error) {
absParent, err := filepath.Abs(parent)
if err != nil {
return false, fmt.Errorf("failed to make parent directory absolute: %q: %w", parent, err)
}
absChild, err := filepath.Abs(child)
if err != nil {
return false, fmt.Errorf("failed to make child file/directory absolute: %q: %w", child, err)
}
rel, err := filepath.Rel(absParent, absChild)
if err != nil {
return false, fmt.Errorf("failed to determine the relative path between the parent directory %q and the child file/directory: %q: %w", absParent, absChild, err)
}
if rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) {
return false, nil
}
return true, nil
}
+23
View File
@@ -1,9 +1,12 @@
package filepathx_test
import (
"fmt"
"strings"
"testing"
"github.com/opencloud-eu/opencloud/pkg/x/path/filepathx"
"github.com/stretchr/testify/require"
)
func TestJailJoin(t *testing.T) {
@@ -61,3 +64,23 @@ func TestJailJoin(t *testing.T) {
})
}
}
func TestIsSameOrContainedBy(t *testing.T) {
for _, tt := range []struct {
parent string
child string
expected bool
}{
{"foo", "foo", true},
{"/foo", "/foo", true},
{"foo", "foo/bar", true},
{"foo", "bar", false},
} {
t.Run(fmt.Sprintf("%s: %s vs %s", t.Name(), strings.ReplaceAll(tt.parent, "/", "."), strings.ReplaceAll(tt.child, "/", ".")), func(t *testing.T) {
require := require.New(t)
b, err := filepathx.IsSameOrContainedBy(tt.parent, tt.child)
require.NoError(err)
require.Equal(tt.expected, b)
})
}
}
@@ -627,13 +627,13 @@ type Bundle struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id"
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // @gotags: yaml:"name"
Type Bundle_Type `protobuf:"varint,3,opt,name=type,proto3,enum=opencloud.messages.settings.v0.Bundle_Type" json:"type,omitempty"` // @gotags: yaml:"type"
Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty"` // @gotags: yaml:"extension"
DisplayName string `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // @gotags: yaml:"display_name"
Settings []*Setting `protobuf:"bytes,6,rep,name=settings,proto3" json:"settings,omitempty"` // @gotags: yaml:"settings"
Resource *Resource `protobuf:"bytes,7,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource"
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id"
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` // @gotags: yaml:"name"
Type Bundle_Type `protobuf:"varint,3,opt,name=type,proto3,enum=opencloud.messages.settings.v0.Bundle_Type" json:"type,omitempty" yaml:"type"` // @gotags: yaml:"type"
Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty" yaml:"extension"` // @gotags: yaml:"extension"
DisplayName string `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty" yaml:"display_name"` // @gotags: yaml:"display_name"
Settings []*Setting `protobuf:"bytes,6,rep,name=settings,proto3" json:"settings,omitempty" yaml:"settings"` // @gotags: yaml:"settings"
Resource *Resource `protobuf:"bytes,7,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource"
}
func (x *Bundle) Reset() {
@@ -722,10 +722,10 @@ type Setting struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id"
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // @gotags: yaml:"name"
DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // @gotags: yaml:"display_name"
Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` // @gotags: yaml:"description"
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id"
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` // @gotags: yaml:"name"
DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty" yaml:"display_name"` // @gotags: yaml:"display_name"
Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` // @gotags: yaml:"description"
// Types that are assignable to Value:
//
// *Setting_IntValue
@@ -736,7 +736,7 @@ type Setting struct {
// *Setting_PermissionValue
// *Setting_MultiChoiceCollectionValue
Value isSetting_Value `protobuf_oneof:"value"`
Resource *Resource `protobuf:"bytes,11,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource"
Resource *Resource `protobuf:"bytes,11,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource"
}
func (x *Setting) Reset() {
@@ -867,31 +867,31 @@ type isSetting_Value interface {
}
type Setting_IntValue struct {
IntValue *Int `protobuf:"bytes,5,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value"
IntValue *Int `protobuf:"bytes,5,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value"
}
type Setting_StringValue struct {
StringValue *String `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value"
StringValue *String `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value"
}
type Setting_BoolValue struct {
BoolValue *Bool `protobuf:"bytes,7,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value"
BoolValue *Bool `protobuf:"bytes,7,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value"
}
type Setting_SingleChoiceValue struct {
SingleChoiceValue *SingleChoiceList `protobuf:"bytes,8,opt,name=single_choice_value,json=singleChoiceValue,proto3,oneof"` // @gotags: yaml:"single_choice_value"
SingleChoiceValue *SingleChoiceList `protobuf:"bytes,8,opt,name=single_choice_value,json=singleChoiceValue,proto3,oneof" yaml:"single_choice_value"` // @gotags: yaml:"single_choice_value"
}
type Setting_MultiChoiceValue struct {
MultiChoiceValue *MultiChoiceList `protobuf:"bytes,9,opt,name=multi_choice_value,json=multiChoiceValue,proto3,oneof"` // @gotags: yaml:"multi_choice_value"
MultiChoiceValue *MultiChoiceList `protobuf:"bytes,9,opt,name=multi_choice_value,json=multiChoiceValue,proto3,oneof" yaml:"multi_choice_value"` // @gotags: yaml:"multi_choice_value"
}
type Setting_PermissionValue struct {
PermissionValue *Permission `protobuf:"bytes,10,opt,name=permission_value,json=permissionValue,proto3,oneof"` // @gotags: yaml:"permission_value"
PermissionValue *Permission `protobuf:"bytes,10,opt,name=permission_value,json=permissionValue,proto3,oneof" yaml:"permission_value"` // @gotags: yaml:"permission_value"
}
type Setting_MultiChoiceCollectionValue struct {
MultiChoiceCollectionValue *MultiChoiceCollection `protobuf:"bytes,12,opt,name=multi_choice_collection_value,json=multiChoiceCollectionValue,proto3,oneof"` // @gotags: yaml:"multi_choice_collection_value"
MultiChoiceCollectionValue *MultiChoiceCollection `protobuf:"bytes,12,opt,name=multi_choice_collection_value,json=multiChoiceCollectionValue,proto3,oneof" yaml:"multi_choice_collection_value"` // @gotags: yaml:"multi_choice_collection_value"
}
func (*Setting_IntValue) isSetting_Value() {}
@@ -913,11 +913,11 @@ type Int struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Default int64 `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default"
Min int64 `protobuf:"varint,2,opt,name=min,proto3" json:"min,omitempty"` // @gotags: yaml:"min"
Max int64 `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty"` // @gotags: yaml:"max"
Step int64 `protobuf:"varint,4,opt,name=step,proto3" json:"step,omitempty"` // @gotags: yaml:"step"
Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty"` // @gotags: yaml:"placeholder"
Default int64 `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default"
Min int64 `protobuf:"varint,2,opt,name=min,proto3" json:"min,omitempty" yaml:"min"` // @gotags: yaml:"min"
Max int64 `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty" yaml:"max"` // @gotags: yaml:"max"
Step int64 `protobuf:"varint,4,opt,name=step,proto3" json:"step,omitempty" yaml:"step"` // @gotags: yaml:"step"
Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty" yaml:"placeholder"` // @gotags: yaml:"placeholder"
}
func (x *Int) Reset() {
@@ -992,11 +992,11 @@ type String struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Default string `protobuf:"bytes,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default"
Required bool `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty"` // @gotags: yaml:"required"
MinLength int32 `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty"` // @gotags: yaml:"min_length"
MaxLength int32 `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty"` // @gotags: yaml:"max_length"
Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty"` // @gotags: yaml:"placeholder"
Default string `protobuf:"bytes,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default"
Required bool `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty" yaml:"required"` // @gotags: yaml:"required"
MinLength int32 `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty" yaml:"min_length"` // @gotags: yaml:"min_length"
MaxLength int32 `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty" yaml:"max_length"` // @gotags: yaml:"max_length"
Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty" yaml:"placeholder"` // @gotags: yaml:"placeholder"
}
func (x *String) Reset() {
@@ -1071,8 +1071,8 @@ type Bool struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Default bool `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default"
Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` // @gotags: yaml:"label"
Default bool `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default"
Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty" yaml:"label"` // @gotags: yaml:"label"
}
func (x *Bool) Reset() {
@@ -1126,7 +1126,7 @@ type SingleChoiceList struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options"
Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options"
}
func (x *SingleChoiceList) Reset() {
@@ -1173,7 +1173,7 @@ type MultiChoiceList struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options"
Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options"
}
func (x *MultiChoiceList) Reset() {
@@ -1220,9 +1220,9 @@ type ListOption struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Value *ListOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` // @gotags: yaml:"value"
Default bool `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default"
DisplayValue string `protobuf:"bytes,3,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty"` // @gotags: yaml:"display_value"
Value *ListOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty" yaml:"value"` // @gotags: yaml:"value"
Default bool `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default"
DisplayValue string `protobuf:"bytes,3,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty" yaml:"display_value"` // @gotags: yaml:"display_value"
}
func (x *ListOption) Reset() {
@@ -1283,7 +1283,7 @@ type MultiChoiceCollection struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Options []*MultiChoiceCollectionOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options"
Options []*MultiChoiceCollectionOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options"
}
func (x *MultiChoiceCollection) Reset() {
@@ -1330,10 +1330,10 @@ type MultiChoiceCollectionOption struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Value *MultiChoiceCollectionOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` // @gotags: yaml:"value"
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` // @gotags: yaml:"key"
Attribute string `protobuf:"bytes,3,opt,name=attribute,proto3" json:"attribute,omitempty"` // @gotags: yaml:"attribute"
DisplayValue string `protobuf:"bytes,4,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty"` // @gotags: yaml:"display_value"
Value *MultiChoiceCollectionOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty" yaml:"value"` // @gotags: yaml:"value"
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty" yaml:"key"` // @gotags: yaml:"key"
Attribute string `protobuf:"bytes,3,opt,name=attribute,proto3" json:"attribute,omitempty" yaml:"attribute"` // @gotags: yaml:"attribute"
DisplayValue string `protobuf:"bytes,4,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty" yaml:"display_value"` // @gotags: yaml:"display_value"
}
func (x *MultiChoiceCollectionOption) Reset() {
@@ -1474,15 +1474,15 @@ type isMultiChoiceCollectionOptionValue_Option interface {
}
type MultiChoiceCollectionOptionValue_IntValue struct {
IntValue *Int `protobuf:"bytes,1,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value"
IntValue *Int `protobuf:"bytes,1,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value"
}
type MultiChoiceCollectionOptionValue_StringValue struct {
StringValue *String `protobuf:"bytes,2,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value"
StringValue *String `protobuf:"bytes,2,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value"
}
type MultiChoiceCollectionOptionValue_BoolValue struct {
BoolValue *Bool `protobuf:"bytes,3,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value"
BoolValue *Bool `protobuf:"bytes,3,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value"
}
func (*MultiChoiceCollectionOptionValue_IntValue) isMultiChoiceCollectionOptionValue_Option() {}
@@ -1496,8 +1496,8 @@ type Permission struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Operation Permission_Operation `protobuf:"varint,1,opt,name=operation,proto3,enum=opencloud.messages.settings.v0.Permission_Operation" json:"operation,omitempty"` // @gotags: yaml:"operation"
Constraint Permission_Constraint `protobuf:"varint,2,opt,name=constraint,proto3,enum=opencloud.messages.settings.v0.Permission_Constraint" json:"constraint,omitempty"` // @gotags: yaml:"constraint"
Operation Permission_Operation `protobuf:"varint,1,opt,name=operation,proto3,enum=opencloud.messages.settings.v0.Permission_Operation" json:"operation,omitempty" yaml:"operation"` // @gotags: yaml:"operation"
Constraint Permission_Constraint `protobuf:"varint,2,opt,name=constraint,proto3,enum=opencloud.messages.settings.v0.Permission_Constraint" json:"constraint,omitempty" yaml:"constraint"` // @gotags: yaml:"constraint"
}
func (x *Permission) Reset() {
@@ -1552,12 +1552,12 @@ type Value struct {
unknownFields protoimpl.UnknownFields
// id is the id of the Value. It is generated on saving it.
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id"
BundleId string `protobuf:"bytes,2,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty"` // @gotags: yaml:"bundle_id"
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id"
BundleId string `protobuf:"bytes,2,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty" yaml:"bundle_id"` // @gotags: yaml:"bundle_id"
// setting_id is the id of the setting from within its bundle.
SettingId string `protobuf:"bytes,3,opt,name=setting_id,json=settingId,proto3" json:"setting_id,omitempty"` // @gotags: yaml:"setting_id"
AccountUuid string `protobuf:"bytes,4,opt,name=account_uuid,json=accountUuid,proto3" json:"account_uuid,omitempty"` // @gotags: yaml:"account_uuid"
Resource *Resource `protobuf:"bytes,5,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource"
SettingId string `protobuf:"bytes,3,opt,name=setting_id,json=settingId,proto3" json:"setting_id,omitempty" yaml:"setting_id"` // @gotags: yaml:"setting_id"
AccountUuid string `protobuf:"bytes,4,opt,name=account_uuid,json=accountUuid,proto3" json:"account_uuid,omitempty" yaml:"account_uuid"` // @gotags: yaml:"account_uuid"
Resource *Resource `protobuf:"bytes,5,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource"
// Types that are assignable to Value:
//
// *Value_BoolValue
@@ -1682,23 +1682,23 @@ type isValue_Value interface {
}
type Value_BoolValue struct {
BoolValue bool `protobuf:"varint,6,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value"
BoolValue bool `protobuf:"varint,6,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value"
}
type Value_IntValue struct {
IntValue int64 `protobuf:"varint,7,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value"
IntValue int64 `protobuf:"varint,7,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value"
}
type Value_StringValue struct {
StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value"
StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value"
}
type Value_ListValue struct {
ListValue *ListValue `protobuf:"bytes,9,opt,name=list_value,json=listValue,proto3,oneof"` // @gotags: yaml:"list_value"
ListValue *ListValue `protobuf:"bytes,9,opt,name=list_value,json=listValue,proto3,oneof" yaml:"list_value"` // @gotags: yaml:"list_value"
}
type Value_CollectionValue struct {
CollectionValue *CollectionValue `protobuf:"bytes,10,opt,name=collection_value,json=collectionValue,proto3,oneof"` // @gotags: yaml:"collection_value"
CollectionValue *CollectionValue `protobuf:"bytes,10,opt,name=collection_value,json=collectionValue,proto3,oneof" yaml:"collection_value"` // @gotags: yaml:"collection_value"
}
func (*Value_BoolValue) isValue_Value() {}
@@ -1716,7 +1716,7 @@ type ListValue struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Values []*ListOptionValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` // @gotags: yaml:"values"
Values []*ListOptionValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" yaml:"values"` // @gotags: yaml:"values"
}
func (x *ListValue) Reset() {
@@ -1836,15 +1836,15 @@ type isListOptionValue_Option interface {
}
type ListOptionValue_StringValue struct {
StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value"
StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value"
}
type ListOptionValue_IntValue struct {
IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value"
IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value"
}
type ListOptionValue_BoolValue struct {
BoolValue bool `protobuf:"varint,3,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value"
BoolValue bool `protobuf:"varint,3,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value"
}
func (*ListOptionValue_StringValue) isListOptionValue_Option() {}
@@ -1858,7 +1858,7 @@ type CollectionValue struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Values []*CollectionOption `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` // @gotags: yaml:"values"
Values []*CollectionOption `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" yaml:"values"` // @gotags: yaml:"values"
}
func (x *CollectionValue) Reset() {
@@ -1906,7 +1906,7 @@ type CollectionOption struct {
unknownFields protoimpl.UnknownFields
// required
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // @gotags: yaml:"key"
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty" yaml:"key"` // @gotags: yaml:"key"
// Types that are assignable to Option:
//
// *CollectionOption_IntValue
@@ -1987,15 +1987,15 @@ type isCollectionOption_Option interface {
}
type CollectionOption_IntValue struct {
IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value"
IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value"
}
type CollectionOption_StringValue struct {
StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value"
StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value"
}
type CollectionOption_BoolValue struct {
BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value"
BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value"
}
func (*CollectionOption_IntValue) isCollectionOption_Option() {}
@@ -40,7 +40,7 @@ func (_m *SearchProviderService) EXPECT() *SearchProviderService_Expecter {
}
// IndexSpace provides a mock function for the type SearchProviderService
func (_mock *SearchProviderService) IndexSpace(ctx context.Context, in *v0.IndexSpaceRequest, opts ...client.CallOption) (*v0.IndexSpaceResponse, error) {
func (_mock *SearchProviderService) IndexSpace(ctx context.Context, in *v0.IndexSpaceRequest, opts ...client.CallOption) (v0.SearchProvider_IndexSpaceService, error) {
var tmpRet mock.Arguments
if len(opts) > 0 {
tmpRet = _mock.Called(ctx, in, opts)
@@ -53,16 +53,16 @@ func (_mock *SearchProviderService) IndexSpace(ctx context.Context, in *v0.Index
panic("no return value specified for IndexSpace")
}
var r0 *v0.IndexSpaceResponse
var r0 v0.SearchProvider_IndexSpaceService
var r1 error
if returnFunc, ok := ret.Get(0).(func(context.Context, *v0.IndexSpaceRequest, ...client.CallOption) (*v0.IndexSpaceResponse, error)); ok {
if returnFunc, ok := ret.Get(0).(func(context.Context, *v0.IndexSpaceRequest, ...client.CallOption) (v0.SearchProvider_IndexSpaceService, error)); ok {
return returnFunc(ctx, in, opts...)
}
if returnFunc, ok := ret.Get(0).(func(context.Context, *v0.IndexSpaceRequest, ...client.CallOption) *v0.IndexSpaceResponse); ok {
if returnFunc, ok := ret.Get(0).(func(context.Context, *v0.IndexSpaceRequest, ...client.CallOption) v0.SearchProvider_IndexSpaceService); ok {
r0 = returnFunc(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v0.IndexSpaceResponse)
r0 = ret.Get(0).(v0.SearchProvider_IndexSpaceService)
}
}
if returnFunc, ok := ret.Get(1).(func(context.Context, *v0.IndexSpaceRequest, ...client.CallOption) error); ok {
@@ -112,12 +112,12 @@ func (_c *SearchProviderService_IndexSpace_Call) Run(run func(ctx context.Contex
return _c
}
func (_c *SearchProviderService_IndexSpace_Call) Return(indexSpaceResponse *v0.IndexSpaceResponse, err error) *SearchProviderService_IndexSpace_Call {
_c.Call.Return(indexSpaceResponse, err)
func (_c *SearchProviderService_IndexSpace_Call) Return(searchProvider_IndexSpaceService v0.SearchProvider_IndexSpaceService, err error) *SearchProviderService_IndexSpace_Call {
_c.Call.Return(searchProvider_IndexSpaceService, err)
return _c
}
func (_c *SearchProviderService_IndexSpace_Call) RunAndReturn(run func(ctx context.Context, in *v0.IndexSpaceRequest, opts ...client.CallOption) (*v0.IndexSpaceResponse, error)) *SearchProviderService_IndexSpace_Call {
func (_c *SearchProviderService_IndexSpace_Call) RunAndReturn(run func(ctx context.Context, in *v0.IndexSpaceRequest, opts ...client.CallOption) (v0.SearchProvider_IndexSpaceService, error)) *SearchProviderService_IndexSpace_Call {
_c.Call.Return(run)
return _c
}
@@ -12,6 +12,7 @@ import (
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
durationpb "google.golang.org/protobuf/types/known/durationpb"
_ "google.golang.org/protobuf/types/known/fieldmaskpb"
reflect "reflect"
sync "sync"
@@ -310,6 +311,7 @@ type IndexSpaceRequest struct {
SpaceId string `protobuf:"bytes,1,opt,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"`
UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
ForceReindex bool `protobuf:"varint,3,opt,name=force_reindex,json=forceReindex,proto3" json:"force_reindex,omitempty"`
Concurrency int32 `protobuf:"varint,4,opt,name=concurrency,proto3" json:"concurrency,omitempty"`
}
func (x *IndexSpaceRequest) Reset() {
@@ -365,10 +367,28 @@ func (x *IndexSpaceRequest) GetForceReindex() bool {
return false
}
func (x *IndexSpaceRequest) GetConcurrency() int32 {
if x != nil {
return x.Concurrency
}
return 0
}
type IndexSpaceResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The id of the space that has just been indexed.
SpaceId string `protobuf:"bytes,1,opt,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"`
// The duration it took to index this space.
SpaceDuration *durationpb.Duration `protobuf:"bytes,2,opt,name=space_duration,json=spaceDuration,proto3" json:"space_duration,omitempty"`
// The number of spaces that have been indexed so far.
IndexedSpaces int64 `protobuf:"varint,3,opt,name=indexed_spaces,json=indexedSpaces,proto3" json:"indexed_spaces,omitempty"`
// The total number of spaces that are being indexed.
TotalSpaces int64 `protobuf:"varint,4,opt,name=total_spaces,json=totalSpaces,proto3" json:"total_spaces,omitempty"`
// Contains an error message in case indexing this particular space failed.
Error string `protobuf:"bytes,5,opt,name=error,proto3" json:"error,omitempty"`
}
func (x *IndexSpaceResponse) Reset() {
@@ -403,6 +423,41 @@ func (*IndexSpaceResponse) Descriptor() ([]byte, []int) {
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{5}
}
func (x *IndexSpaceResponse) GetSpaceId() string {
if x != nil {
return x.SpaceId
}
return ""
}
func (x *IndexSpaceResponse) GetSpaceDuration() *durationpb.Duration {
if x != nil {
return x.SpaceDuration
}
return nil
}
func (x *IndexSpaceResponse) GetIndexedSpaces() int64 {
if x != nil {
return x.IndexedSpaces
}
return 0
}
func (x *IndexSpaceResponse) GetTotalSpaces() int64 {
if x != nil {
return x.TotalSpaces
}
return 0
}
func (x *IndexSpaceResponse) GetError() string {
if x != nil {
return x.Error
}
return ""
}
var File_opencloud_services_search_v0_search_proto protoreflect.FileDescriptor
var file_opencloud_services_search_v0_search_proto_rawDesc = []byte{
@@ -422,6 +477,8 @@ var file_opencloud_services_search_v0_search_proto_rawDesc = []byte{
0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xae, 0x01, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f,
0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x01,
@@ -465,68 +522,83 @@ var file_opencloud_services_search_v0_search_proto_rawDesc = []byte{
0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f,
0x74, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
0x05, 0x52, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22,
0x6c, 0x0a, 0x11, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12,
0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x6f, 0x72, 0x63,
0x65, 0x5f, 0x72, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
0x0c, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x14, 0x0a,
0x12, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x32, 0xb1, 0x02, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72,
0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x85, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63,
0x68, 0x12, 0x2b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30,
0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c,
0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65,
0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x1a, 0x3a, 0x01, 0x2a, 0x22, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30,
0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x96,
0x01, 0x0a, 0x0a, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2f, 0x2e,
0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e, 0x64,
0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30,
0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e,
0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x61, 0x70,
0x69, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x69, 0x6e, 0x64, 0x65,
0x78, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x32, 0xa7, 0x01, 0x0a, 0x0d, 0x49, 0x6e, 0x64, 0x65,
0x78, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x95, 0x01, 0x0a, 0x06, 0x53, 0x65,
0x61, 0x72, 0x63, 0x68, 0x12, 0x30, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
0x94, 0x01, 0x0a, 0x11, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64,
0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x6f, 0x72,
0x63, 0x65, 0x5f, 0x72, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
0x52, 0x0c, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x26,
0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20,
0x01, 0x28, 0x05, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x01, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75,
0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0xd1, 0x01, 0x0a, 0x12, 0x49, 0x6e, 0x64, 0x65, 0x78,
0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a,
0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x73, 0x70, 0x61, 0x63,
0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x73, 0x70, 0x61,
0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e,
0x64, 0x65, 0x78, 0x65, 0x64, 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01,
0x28, 0x03, 0x52, 0x0d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x53, 0x70, 0x61, 0x63, 0x65,
0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65,
0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x70,
0x61, 0x63, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20,
0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x32, 0xb3, 0x02, 0x0a, 0x0e, 0x53,
0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x85, 0x01,
0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x2b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63,
0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65,
0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75,
0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63,
0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x3a, 0x01, 0x2a, 0x22, 0x15,
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x73,
0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x98, 0x01, 0x0a, 0x0a, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53,
0x70, 0x61, 0x63, 0x65, 0x12, 0x2f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68,
0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f,
0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72,
0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x49, 0x6e, 0x64, 0x65,
0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x65,
0x61, 0x72, 0x63, 0x68, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63,
0x68, 0x42, 0xf2, 0x02, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70,
0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e,
0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x73,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x76, 0x30,
0x92, 0x41, 0xa2, 0x02, 0x12, 0xb7, 0x01, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6c, 0x6f,
0x75, 0x64, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, 0x51, 0x0a, 0x0e, 0x4f, 0x70, 0x65,
0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x47, 0x6d, 0x62, 0x48, 0x12, 0x29, 0x68, 0x74, 0x74,
0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65,
0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x1a, 0x14, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x40,
0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x65, 0x75, 0x2a, 0x49, 0x0a, 0x0a,
0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x32, 0x2e, 0x30, 0x12, 0x3b, 0x68, 0x74, 0x74, 0x70,
0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f,
0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e,
0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f,
0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x2a, 0x02,
0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f,
0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x72, 0x3e, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f,
0x70, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x12, 0x2a, 0x68, 0x74, 0x74, 0x70,
0x73, 0x3a, 0x2f, 0x2f, 0x64, 0x6f, 0x63, 0x73, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f,
0x75, 0x64, 0x2e, 0x65, 0x75, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x73,
0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75,
0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63,
0x68, 0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a,
0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x65, 0x61, 0x72,
0x63, 0x68, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x30, 0x01,
0x32, 0xa7, 0x01, 0x0a, 0x0d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
0x65, 0x72, 0x12, 0x95, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x30, 0x2e,
0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61,
0x72, 0x63, 0x68, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x31, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53,
0x65, 0x61, 0x72, 0x63, 0x68, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f,
0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x69, 0x6e,
0x64, 0x65, 0x78, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x42, 0xf2, 0x02, 0x5a, 0x4a, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c,
0x6f, 0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x6f, 0x70,
0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f,
0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x76, 0x30, 0x92, 0x41, 0xa2, 0x02, 0x12, 0xb7, 0x01,
0x0a, 0x10, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x73, 0x65, 0x61, 0x72,
0x63, 0x68, 0x22, 0x51, 0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20,
0x47, 0x6d, 0x62, 0x48, 0x12, 0x29, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f,
0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x1a,
0x14, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f,
0x75, 0x64, 0x2e, 0x65, 0x75, 0x2a, 0x49, 0x0a, 0x0a, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2d,
0x32, 0x2e, 0x30, 0x12, 0x3b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75,
0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x62,
0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45,
0x32, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x2a, 0x02, 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70,
0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61,
0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x72,
0x3e, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e,
0x75, 0x61, 0x6c, 0x12, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x64, 0x6f, 0x63,
0x73, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x65, 0x75, 0x2f, 0x73,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -551,23 +623,25 @@ var file_opencloud_services_search_v0_search_proto_goTypes = []interface{}{
(*IndexSpaceResponse)(nil), // 5: opencloud.services.search.v0.IndexSpaceResponse
(*v0.Reference)(nil), // 6: opencloud.messages.search.v0.Reference
(*v0.Match)(nil), // 7: opencloud.messages.search.v0.Match
(*durationpb.Duration)(nil), // 8: google.protobuf.Duration
}
var file_opencloud_services_search_v0_search_proto_depIdxs = []int32{
6, // 0: opencloud.services.search.v0.SearchRequest.ref:type_name -> opencloud.messages.search.v0.Reference
7, // 1: opencloud.services.search.v0.SearchResponse.matches:type_name -> opencloud.messages.search.v0.Match
6, // 2: opencloud.services.search.v0.SearchIndexRequest.ref:type_name -> opencloud.messages.search.v0.Reference
7, // 3: opencloud.services.search.v0.SearchIndexResponse.matches:type_name -> opencloud.messages.search.v0.Match
0, // 4: opencloud.services.search.v0.SearchProvider.Search:input_type -> opencloud.services.search.v0.SearchRequest
4, // 5: opencloud.services.search.v0.SearchProvider.IndexSpace:input_type -> opencloud.services.search.v0.IndexSpaceRequest
2, // 6: opencloud.services.search.v0.IndexProvider.Search:input_type -> opencloud.services.search.v0.SearchIndexRequest
1, // 7: opencloud.services.search.v0.SearchProvider.Search:output_type -> opencloud.services.search.v0.SearchResponse
5, // 8: opencloud.services.search.v0.SearchProvider.IndexSpace:output_type -> opencloud.services.search.v0.IndexSpaceResponse
3, // 9: opencloud.services.search.v0.IndexProvider.Search:output_type -> opencloud.services.search.v0.SearchIndexResponse
7, // [7:10] is the sub-list for method output_type
4, // [4:7] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
8, // 4: opencloud.services.search.v0.IndexSpaceResponse.space_duration:type_name -> google.protobuf.Duration
0, // 5: opencloud.services.search.v0.SearchProvider.Search:input_type -> opencloud.services.search.v0.SearchRequest
4, // 6: opencloud.services.search.v0.SearchProvider.IndexSpace:input_type -> opencloud.services.search.v0.IndexSpaceRequest
2, // 7: opencloud.services.search.v0.IndexProvider.Search:input_type -> opencloud.services.search.v0.SearchIndexRequest
1, // 8: opencloud.services.search.v0.SearchProvider.Search:output_type -> opencloud.services.search.v0.SearchResponse
5, // 9: opencloud.services.search.v0.SearchProvider.IndexSpace:output_type -> opencloud.services.search.v0.IndexSpaceResponse
3, // 10: opencloud.services.search.v0.IndexProvider.Search:output_type -> opencloud.services.search.v0.SearchIndexResponse
8, // [8:11] is the sub-list for method output_type
5, // [5:8] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
}
func init() { file_opencloud_services_search_v0_search_proto_init() }
@@ -9,6 +9,7 @@ import (
_ "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/messages/search/v0"
_ "google.golang.org/genproto/googleapis/api/annotations"
proto "google.golang.org/protobuf/proto"
_ "google.golang.org/protobuf/types/known/durationpb"
_ "google.golang.org/protobuf/types/known/fieldmaskpb"
math "math"
)
@@ -45,6 +46,7 @@ func NewSearchProviderEndpoints() []*api.Endpoint {
Name: "SearchProvider.IndexSpace",
Path: []string{"/api/v0/search/index-space"},
Method: []string{"POST"},
Stream: true,
Handler: "rpc",
},
}
@@ -54,7 +56,9 @@ func NewSearchProviderEndpoints() []*api.Endpoint {
type SearchProviderService interface {
Search(ctx context.Context, in *SearchRequest, opts ...client.CallOption) (*SearchResponse, error)
IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...client.CallOption) (*IndexSpaceResponse, error)
// IndexSpace (re)indexes one or all spaces. The response is streamed, sending
// progress information after each space has been indexed.
IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...client.CallOption) (SearchProvider_IndexSpaceService, error)
}
type searchProviderService struct {
@@ -79,27 +83,73 @@ func (c *searchProviderService) Search(ctx context.Context, in *SearchRequest, o
return out, nil
}
func (c *searchProviderService) IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...client.CallOption) (*IndexSpaceResponse, error) {
req := c.c.NewRequest(c.name, "SearchProvider.IndexSpace", in)
out := new(IndexSpaceResponse)
err := c.c.Call(ctx, req, out, opts...)
func (c *searchProviderService) IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...client.CallOption) (SearchProvider_IndexSpaceService, error) {
req := c.c.NewRequest(c.name, "SearchProvider.IndexSpace", &IndexSpaceRequest{})
stream, err := c.c.Stream(ctx, req, opts...)
if err != nil {
return nil, err
}
return out, nil
if err := stream.Send(in); err != nil {
return nil, err
}
return &searchProviderServiceIndexSpace{stream}, nil
}
type SearchProvider_IndexSpaceService interface {
Context() context.Context
SendMsg(interface{}) error
RecvMsg(interface{}) error
CloseSend() error
Close() error
Recv() (*IndexSpaceResponse, error)
}
type searchProviderServiceIndexSpace struct {
stream client.Stream
}
func (x *searchProviderServiceIndexSpace) CloseSend() error {
return x.stream.CloseSend()
}
func (x *searchProviderServiceIndexSpace) Close() error {
return x.stream.Close()
}
func (x *searchProviderServiceIndexSpace) Context() context.Context {
return x.stream.Context()
}
func (x *searchProviderServiceIndexSpace) SendMsg(m interface{}) error {
return x.stream.Send(m)
}
func (x *searchProviderServiceIndexSpace) RecvMsg(m interface{}) error {
return x.stream.Recv(m)
}
func (x *searchProviderServiceIndexSpace) Recv() (*IndexSpaceResponse, error) {
m := new(IndexSpaceResponse)
err := x.stream.Recv(m)
if err != nil {
return nil, err
}
return m, nil
}
// Server API for SearchProvider service
type SearchProviderHandler interface {
Search(context.Context, *SearchRequest, *SearchResponse) error
IndexSpace(context.Context, *IndexSpaceRequest, *IndexSpaceResponse) error
// IndexSpace (re)indexes one or all spaces. The response is streamed, sending
// progress information after each space has been indexed.
IndexSpace(context.Context, *IndexSpaceRequest, SearchProvider_IndexSpaceStream) error
}
func RegisterSearchProviderHandler(s server.Server, hdlr SearchProviderHandler, opts ...server.HandlerOption) error {
type searchProvider interface {
Search(ctx context.Context, in *SearchRequest, out *SearchResponse) error
IndexSpace(ctx context.Context, in *IndexSpaceRequest, out *IndexSpaceResponse) error
IndexSpace(ctx context.Context, stream server.Stream) error
}
type SearchProvider struct {
searchProvider
@@ -115,6 +165,7 @@ func RegisterSearchProviderHandler(s server.Server, hdlr SearchProviderHandler,
Name: "SearchProvider.IndexSpace",
Path: []string{"/api/v0/search/index-space"},
Method: []string{"POST"},
Stream: true,
Handler: "rpc",
}))
return s.Handle(s.NewHandler(&SearchProvider{h}, opts...))
@@ -128,8 +179,44 @@ func (h *searchProviderHandler) Search(ctx context.Context, in *SearchRequest, o
return h.SearchProviderHandler.Search(ctx, in, out)
}
func (h *searchProviderHandler) IndexSpace(ctx context.Context, in *IndexSpaceRequest, out *IndexSpaceResponse) error {
return h.SearchProviderHandler.IndexSpace(ctx, in, out)
func (h *searchProviderHandler) IndexSpace(ctx context.Context, stream server.Stream) error {
m := new(IndexSpaceRequest)
if err := stream.Recv(m); err != nil {
return err
}
return h.SearchProviderHandler.IndexSpace(ctx, m, &searchProviderIndexSpaceStream{stream})
}
type SearchProvider_IndexSpaceStream interface {
Context() context.Context
SendMsg(interface{}) error
RecvMsg(interface{}) error
Close() error
Send(*IndexSpaceResponse) error
}
type searchProviderIndexSpaceStream struct {
stream server.Stream
}
func (x *searchProviderIndexSpaceStream) Close() error {
return x.stream.Close()
}
func (x *searchProviderIndexSpaceStream) Context() context.Context {
return x.stream.Context()
}
func (x *searchProviderIndexSpaceStream) SendMsg(m interface{}) error {
return x.stream.Send(m)
}
func (x *searchProviderIndexSpaceStream) RecvMsg(m interface{}) error {
return x.stream.Recv(m)
}
func (x *searchProviderIndexSpaceStream) Send(m *IndexSpaceResponse) error {
return x.stream.Send(m)
}
// Api Endpoints for IndexProvider service
@@ -1,346 +0,0 @@
// Code generated by protoc-gen-microweb. DO NOT EDIT.
// source: v0.proto
package v0
import (
"bytes"
"encoding/json"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/go-chi/render"
"github.com/golang/protobuf/jsonpb"
merrors "go-micro.dev/v4/errors"
)
type webSearchProviderHandler struct {
r chi.Router
h SearchProviderHandler
}
func (h *webSearchProviderHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.r.ServeHTTP(w, r)
}
func (h *webSearchProviderHandler) Search(w http.ResponseWriter, r *http.Request) {
req := &SearchRequest{}
resp := &SearchResponse{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusPreconditionFailed)
return
}
if err := h.h.Search(
r.Context(),
req,
resp,
); err != nil {
if merr, ok := merrors.As(err); ok && merr.Code == http.StatusNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusBadRequest)
}
return
}
render.Status(r, http.StatusCreated)
render.JSON(w, r, resp)
}
func (h *webSearchProviderHandler) IndexSpace(w http.ResponseWriter, r *http.Request) {
req := &IndexSpaceRequest{}
resp := &IndexSpaceResponse{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusPreconditionFailed)
return
}
if err := h.h.IndexSpace(
r.Context(),
req,
resp,
); err != nil {
if merr, ok := merrors.As(err); ok && merr.Code == http.StatusNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusBadRequest)
}
return
}
render.Status(r, http.StatusCreated)
render.JSON(w, r, resp)
}
func RegisterSearchProviderWeb(r chi.Router, i SearchProviderHandler, middlewares ...func(http.Handler) http.Handler) {
handler := &webSearchProviderHandler{
r: r,
h: i,
}
r.MethodFunc("POST", "/api/v0/search/search", handler.Search)
r.MethodFunc("POST", "/api/v0/search/index-space", handler.IndexSpace)
}
type webIndexProviderHandler struct {
r chi.Router
h IndexProviderHandler
}
func (h *webIndexProviderHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.r.ServeHTTP(w, r)
}
func (h *webIndexProviderHandler) Search(w http.ResponseWriter, r *http.Request) {
req := &SearchIndexRequest{}
resp := &SearchIndexResponse{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusPreconditionFailed)
return
}
if err := h.h.Search(
r.Context(),
req,
resp,
); err != nil {
if merr, ok := merrors.As(err); ok && merr.Code == http.StatusNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusBadRequest)
}
return
}
render.Status(r, http.StatusCreated)
render.JSON(w, r, resp)
}
func RegisterIndexProviderWeb(r chi.Router, i IndexProviderHandler, middlewares ...func(http.Handler) http.Handler) {
handler := &webIndexProviderHandler{
r: r,
h: i,
}
r.MethodFunc("POST", "/api/v0/search/index/search", handler.Search)
}
// SearchRequestJSONMarshaler describes the default jsonpb.Marshaler used by all
// instances of SearchRequest. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchRequestJSONMarshaler = new(jsonpb.Marshaler)
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
// uses the more correct jsonpb package to correctly marshal the message.
func (m *SearchRequest) MarshalJSON() ([]byte, error) {
if m == nil {
return json.Marshal(nil)
}
buf := &bytes.Buffer{}
if err := SearchRequestJSONMarshaler.Marshal(buf, m); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
var _ json.Marshaler = (*SearchRequest)(nil)
// SearchRequestJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
// instances of SearchRequest. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchRequestJSONUnmarshaler = new(jsonpb.Unmarshaler)
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
// uses the more correct jsonpb package to correctly unmarshal the message.
func (m *SearchRequest) UnmarshalJSON(b []byte) error {
return SearchRequestJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
}
var _ json.Unmarshaler = (*SearchRequest)(nil)
// SearchResponseJSONMarshaler describes the default jsonpb.Marshaler used by all
// instances of SearchResponse. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchResponseJSONMarshaler = new(jsonpb.Marshaler)
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
// uses the more correct jsonpb package to correctly marshal the message.
func (m *SearchResponse) MarshalJSON() ([]byte, error) {
if m == nil {
return json.Marshal(nil)
}
buf := &bytes.Buffer{}
if err := SearchResponseJSONMarshaler.Marshal(buf, m); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
var _ json.Marshaler = (*SearchResponse)(nil)
// SearchResponseJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
// instances of SearchResponse. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchResponseJSONUnmarshaler = new(jsonpb.Unmarshaler)
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
// uses the more correct jsonpb package to correctly unmarshal the message.
func (m *SearchResponse) UnmarshalJSON(b []byte) error {
return SearchResponseJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
}
var _ json.Unmarshaler = (*SearchResponse)(nil)
// SearchIndexRequestJSONMarshaler describes the default jsonpb.Marshaler used by all
// instances of SearchIndexRequest. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchIndexRequestJSONMarshaler = new(jsonpb.Marshaler)
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
// uses the more correct jsonpb package to correctly marshal the message.
func (m *SearchIndexRequest) MarshalJSON() ([]byte, error) {
if m == nil {
return json.Marshal(nil)
}
buf := &bytes.Buffer{}
if err := SearchIndexRequestJSONMarshaler.Marshal(buf, m); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
var _ json.Marshaler = (*SearchIndexRequest)(nil)
// SearchIndexRequestJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
// instances of SearchIndexRequest. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchIndexRequestJSONUnmarshaler = new(jsonpb.Unmarshaler)
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
// uses the more correct jsonpb package to correctly unmarshal the message.
func (m *SearchIndexRequest) UnmarshalJSON(b []byte) error {
return SearchIndexRequestJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
}
var _ json.Unmarshaler = (*SearchIndexRequest)(nil)
// SearchIndexResponseJSONMarshaler describes the default jsonpb.Marshaler used by all
// instances of SearchIndexResponse. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchIndexResponseJSONMarshaler = new(jsonpb.Marshaler)
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
// uses the more correct jsonpb package to correctly marshal the message.
func (m *SearchIndexResponse) MarshalJSON() ([]byte, error) {
if m == nil {
return json.Marshal(nil)
}
buf := &bytes.Buffer{}
if err := SearchIndexResponseJSONMarshaler.Marshal(buf, m); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
var _ json.Marshaler = (*SearchIndexResponse)(nil)
// SearchIndexResponseJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
// instances of SearchIndexResponse. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchIndexResponseJSONUnmarshaler = new(jsonpb.Unmarshaler)
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
// uses the more correct jsonpb package to correctly unmarshal the message.
func (m *SearchIndexResponse) UnmarshalJSON(b []byte) error {
return SearchIndexResponseJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
}
var _ json.Unmarshaler = (*SearchIndexResponse)(nil)
// IndexSpaceRequestJSONMarshaler describes the default jsonpb.Marshaler used by all
// instances of IndexSpaceRequest. This struct is safe to replace or modify but
// should not be done so concurrently.
var IndexSpaceRequestJSONMarshaler = new(jsonpb.Marshaler)
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
// uses the more correct jsonpb package to correctly marshal the message.
func (m *IndexSpaceRequest) MarshalJSON() ([]byte, error) {
if m == nil {
return json.Marshal(nil)
}
buf := &bytes.Buffer{}
if err := IndexSpaceRequestJSONMarshaler.Marshal(buf, m); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
var _ json.Marshaler = (*IndexSpaceRequest)(nil)
// IndexSpaceRequestJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
// instances of IndexSpaceRequest. This struct is safe to replace or modify but
// should not be done so concurrently.
var IndexSpaceRequestJSONUnmarshaler = new(jsonpb.Unmarshaler)
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
// uses the more correct jsonpb package to correctly unmarshal the message.
func (m *IndexSpaceRequest) UnmarshalJSON(b []byte) error {
return IndexSpaceRequestJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
}
var _ json.Unmarshaler = (*IndexSpaceRequest)(nil)
// IndexSpaceResponseJSONMarshaler describes the default jsonpb.Marshaler used by all
// instances of IndexSpaceResponse. This struct is safe to replace or modify but
// should not be done so concurrently.
var IndexSpaceResponseJSONMarshaler = new(jsonpb.Marshaler)
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
// uses the more correct jsonpb package to correctly marshal the message.
func (m *IndexSpaceResponse) MarshalJSON() ([]byte, error) {
if m == nil {
return json.Marshal(nil)
}
buf := &bytes.Buffer{}
if err := IndexSpaceResponseJSONMarshaler.Marshal(buf, m); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
var _ json.Marshaler = (*IndexSpaceResponse)(nil)
// IndexSpaceResponseJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
// instances of IndexSpaceResponse. This struct is safe to replace or modify but
// should not be done so concurrently.
var IndexSpaceResponseJSONUnmarshaler = new(jsonpb.Unmarshaler)
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
// uses the more correct jsonpb package to correctly unmarshal the message.
func (m *IndexSpaceResponse) UnmarshalJSON(b []byte) error {
return IndexSpaceResponseJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
}
var _ json.Unmarshaler = (*IndexSpaceResponse)(nil)
@@ -34,12 +34,22 @@
"paths": {
"/api/v0/search/index-space": {
"post": {
"summary": "IndexSpace (re)indexes one or all spaces. The response is streamed, sending\nprogress information after each space has been indexed.",
"operationId": "SearchProvider_IndexSpace",
"responses": {
"200": {
"description": "A successful response.",
"description": "A successful response.(streaming responses)",
"schema": {
"$ref": "#/definitions/v0IndexSpaceResponse"
"type": "object",
"properties": {
"result": {
"$ref": "#/definitions/v0IndexSpaceResponse"
},
"error": {
"$ref": "#/definitions/rpcStatus"
}
},
"title": "Stream result of v0IndexSpaceResponse"
}
},
"default": {
@@ -332,11 +342,39 @@
},
"forceReindex": {
"type": "boolean"
},
"concurrency": {
"type": "integer",
"format": "int32"
}
}
},
"v0IndexSpaceResponse": {
"type": "object"
"type": "object",
"properties": {
"spaceId": {
"type": "string",
"description": "The id of the space that has just been indexed."
},
"spaceDuration": {
"type": "string",
"description": "The duration it took to index this space."
},
"indexedSpaces": {
"type": "string",
"format": "int64",
"description": "The number of spaces that have been indexed so far."
},
"totalSpaces": {
"type": "string",
"format": "int64",
"description": "The total number of spaces that are being indexed."
},
"error": {
"type": "string",
"description": "Contains an error message in case indexing this particular space failed."
}
}
},
"v0Match": {
"type": "object",
@@ -28,7 +28,9 @@ const (
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type SearchProviderClient interface {
Search(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (*SearchResponse, error)
IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...grpc.CallOption) (*IndexSpaceResponse, error)
// IndexSpace (re)indexes one or all spaces. The response is streamed, sending
// progress information after each space has been indexed.
IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[IndexSpaceResponse], error)
}
type searchProviderClient struct {
@@ -49,22 +51,33 @@ func (c *searchProviderClient) Search(ctx context.Context, in *SearchRequest, op
return out, nil
}
func (c *searchProviderClient) IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...grpc.CallOption) (*IndexSpaceResponse, error) {
func (c *searchProviderClient) IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[IndexSpaceResponse], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(IndexSpaceResponse)
err := c.cc.Invoke(ctx, SearchProvider_IndexSpace_FullMethodName, in, out, cOpts...)
stream, err := c.cc.NewStream(ctx, &SearchProvider_ServiceDesc.Streams[0], SearchProvider_IndexSpace_FullMethodName, cOpts...)
if err != nil {
return nil, err
}
return out, nil
x := &grpc.GenericClientStream[IndexSpaceRequest, IndexSpaceResponse]{ClientStream: stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type SearchProvider_IndexSpaceClient = grpc.ServerStreamingClient[IndexSpaceResponse]
// SearchProviderServer is the server API for SearchProvider service.
// All implementations must embed UnimplementedSearchProviderServer
// for forward compatibility.
type SearchProviderServer interface {
Search(context.Context, *SearchRequest) (*SearchResponse, error)
IndexSpace(context.Context, *IndexSpaceRequest) (*IndexSpaceResponse, error)
// IndexSpace (re)indexes one or all spaces. The response is streamed, sending
// progress information after each space has been indexed.
IndexSpace(*IndexSpaceRequest, grpc.ServerStreamingServer[IndexSpaceResponse]) error
mustEmbedUnimplementedSearchProviderServer()
}
@@ -78,8 +91,8 @@ type UnimplementedSearchProviderServer struct{}
func (UnimplementedSearchProviderServer) Search(context.Context, *SearchRequest) (*SearchResponse, error) {
return nil, status.Error(codes.Unimplemented, "method Search not implemented")
}
func (UnimplementedSearchProviderServer) IndexSpace(context.Context, *IndexSpaceRequest) (*IndexSpaceResponse, error) {
return nil, status.Error(codes.Unimplemented, "method IndexSpace not implemented")
func (UnimplementedSearchProviderServer) IndexSpace(*IndexSpaceRequest, grpc.ServerStreamingServer[IndexSpaceResponse]) error {
return status.Error(codes.Unimplemented, "method IndexSpace not implemented")
}
func (UnimplementedSearchProviderServer) mustEmbedUnimplementedSearchProviderServer() {}
func (UnimplementedSearchProviderServer) testEmbeddedByValue() {}
@@ -120,24 +133,17 @@ func _SearchProvider_Search_Handler(srv interface{}, ctx context.Context, dec fu
return interceptor(ctx, in, info, handler)
}
func _SearchProvider_IndexSpace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(IndexSpaceRequest)
if err := dec(in); err != nil {
return nil, err
func _SearchProvider_IndexSpace_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(IndexSpaceRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
if interceptor == nil {
return srv.(SearchProviderServer).IndexSpace(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SearchProvider_IndexSpace_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SearchProviderServer).IndexSpace(ctx, req.(*IndexSpaceRequest))
}
return interceptor(ctx, in, info, handler)
return srv.(SearchProviderServer).IndexSpace(m, &grpc.GenericServerStream[IndexSpaceRequest, IndexSpaceResponse]{ServerStream: stream})
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type SearchProvider_IndexSpaceServer = grpc.ServerStreamingServer[IndexSpaceResponse]
// SearchProvider_ServiceDesc is the grpc.ServiceDesc for SearchProvider service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -149,12 +155,14 @@ var SearchProvider_ServiceDesc = grpc.ServiceDesc{
MethodName: "Search",
Handler: _SearchProvider_Search_Handler,
},
},
Streams: []grpc.StreamDesc{
{
MethodName: "IndexSpace",
Handler: _SearchProvider_IndexSpace_Handler,
StreamName: "IndexSpace",
Handler: _SearchProvider_IndexSpace_Handler,
ServerStreams: true,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "opencloud/services/search/v0/search.proto",
}
+3 -1
View File
@@ -31,7 +31,9 @@ plugins:
opencloud.services.eventhistory.v0;\
opencloud.messages.eventhistory.v0;\
opencloud.services.policies.v0;\
opencloud.messages.policies.v0"
opencloud.messages.policies.v0;\
opencloud.services.search.v0;\
opencloud.messages.search.v0"
- name: openapiv2
path: ../../.bingo/protoc-gen-openapiv2
@@ -9,6 +9,7 @@ import "protoc-gen-openapiv2/options/annotations.proto";
import "google/api/field_behavior.proto";
import "google/api/annotations.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/duration.proto";
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
info: {
@@ -41,7 +42,9 @@ service SearchProvider {
body: "*"
};
};
rpc IndexSpace(IndexSpaceRequest) returns (IndexSpaceResponse) {
// IndexSpace (re)indexes one or all spaces. The response is streamed, sending
// progress information after each space has been indexed.
rpc IndexSpace(IndexSpaceRequest) returns (stream IndexSpaceResponse) {
option (google.api.http) = {
post: "/api/v0/search/index-space",
body: "*"
@@ -105,7 +108,18 @@ message IndexSpaceRequest {
string space_id = 1;
string user_id = 2;
bool force_reindex = 3;
int32 concurrency = 4 [(google.api.field_behavior) = OPTIONAL];
}
message IndexSpaceResponse {
// The id of the space that has just been indexed.
string space_id = 1;
// The duration it took to index this space.
google.protobuf.Duration space_duration = 2;
// The number of spaces that have been indexed so far.
int64 indexed_spaces = 3;
// The total number of spaces that are being indexed.
int64 total_spaces = 4;
// Contains an error message in case indexing this particular space failed.
string error = 5;
}
+32
View File
@@ -73,6 +73,38 @@ export default {
const latestTag = tags.pop() || "v0.0.0";
return compareVersions(latestTag, nextVersion) === -1;
},
getReleaseDescription: async ({ nextVersion }) => {
const note =
"> [!IMPORTANT]\n" +
"> This is a rolling release. Learn here about the [release types and lifecycle](https://docs.opencloud.eu/docs/admin/resources/lifecycle#release-types).\n\n";
// Exclude the "📦️ Dependencies" section from the release description
const section = removeChangelogSubsection(
await getChangelogSection(nextVersion),
"📦️ Dependencies"
);
return `${note}${section}`;
},
};
// helper functions
const getChangelogSection = async (nextVersion: string) => {
const { promises: fs } = await import("fs");
const changelog = await fs.readFile("CHANGELOG.md", "utf-8").catch(() => "");
const section = changelog
.split(/\n(?=## \[)/)
.find((s) => s.startsWith(`## [${nextVersion}]`));
return section?.trim() ?? "";
};
const removeChangelogSubsection = (section: string, heading: string) => {
return section
.split(/\n(?=### )/)
.filter((s) => !s.startsWith(`### ${heading}`))
.join("\n")
.trim();
};
const parseVersion = (tag: string) => {
+3 -3
View File
@@ -56,9 +56,9 @@ type Store struct {
TTL time.Duration `yaml:"ttl" env:"OC_PERSISTENT_STORE_TTL;ACTIVITYLOG_STORE_TTL" desc:"Time to live for events in the store. See the Environment Variable Types description for more details." introductionVersion:"1.0.0"`
AuthUsername string `yaml:"username" env:"OC_PERSISTENT_STORE_AUTH_USERNAME;ACTIVITYLOG_STORE_AUTH_USERNAME" desc:"The username to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
AuthPassword string `yaml:"password" env:"OC_PERSISTENT_STORE_AUTH_PASSWORD;ACTIVITYLOG_STORE_AUTH_PASSWORD" desc:"The password to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;ACTIVITYLOG_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;ACTIVITYLOG_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;ACTIVITYLOG_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided ACTIVITYLOG_STORE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;ACTIVITYLOG_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;ACTIVITYLOG_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;ACTIVITYLOG_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided ACTIVITYLOG_STORE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
// ServiceAccount is the configuration for the used service account
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Ivan Fustero, 2025\n"
"Language-Team: Catalan (https://app.transifex.com/opencloud-eu/teams/204053/ca/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Jörn Friedrich Dreyer <jfd@butonic.de>, 2025\n"
"Language-Team: German (https://app.transifex.com/opencloud-eu/teams/204053/de/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Efstathios Iosifidis <eiosifidis@gmail.com>, 2026\n"
"Language-Team: Greek (https://app.transifex.com/opencloud-eu/teams/204053/el/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Elías Martín, 2025\n"
"Language-Team: Spanish (https://app.transifex.com/opencloud-eu/teams/204053/es/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: eric_G <junk.eg@free.fr>, 2025\n"
"Language-Team: French (https://app.transifex.com/opencloud-eu/teams/204053/fr/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: mitibor, 2026\n"
"Language-Team: Hungarian (https://app.transifex.com/opencloud-eu/teams/204053/hu/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Simone Broglia, 2025\n"
"Language-Team: Italian (https://app.transifex.com/opencloud-eu/teams/204053/it/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: iikaka88, 2025\n"
"Language-Team: Japanese (https://app.transifex.com/opencloud-eu/teams/204053/ja/)\n"
@@ -12,7 +12,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: 4580f07cef35810b72f8a1e8fd521c9a_6684a19 <07c3e3571dc5eebd81f2c3a10488f503_1171750>, 2025\n"
"Language-Team: Korean (https://app.transifex.com/opencloud-eu/teams/204053/ko/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: BoneNI, 2026\n"
"Language-Team: Lao (https://app.transifex.com/opencloud-eu/teams/204053/lo/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Stephan Paternotte <stephan@paternottes.net>, 2025\n"
"Language-Team: Dutch (https://app.transifex.com/opencloud-eu/teams/204053/nl/)\n"
@@ -13,7 +13,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Matt, 2026\n"
"Language-Team: Polish (https://app.transifex.com/opencloud-eu/teams/204053/pl/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Mário Machado, 2025\n"
"Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n"
@@ -12,7 +12,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Lulufox, 2025\n"
"Language-Team: Russian (https://app.transifex.com/opencloud-eu/teams/204053/ru/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Daniel Nylander <po@danielnylander.se>, 2025\n"
"Language-Team: Swedish (https://app.transifex.com/opencloud-eu/teams/204053/sv/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Quan Tran, 2025\n"
"Language-Team: Vietnamese (https://app.transifex.com/opencloud-eu/teams/204053/vi/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-07-19 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: YQS Yang, 2025\n"
"Language-Team: Chinese (https://app.transifex.com/opencloud-eu/teams/204053/zh/)\n"
+33 -15
View File
@@ -11,7 +11,7 @@ PROXY_ENABLE_APP_AUTH=false # mandatory, disables app authentication. In ca
## App Tokens
App Tokens are password specifically generated to be used by 3rd party applications
App Tokens are passwords specifically generated to be used by 3rd party applications
for authentication when accessing the OpenCloud API endpoints. To
be able to use an app token, one must first create a token. There are different
options of creating a token.
@@ -32,16 +32,22 @@ in the `graph` service for allowing the management of App Tokens.
The `auth-app` service provides an API to create (POST), list (GET) and delete (DELETE) tokens at the `/auth-app/tokens` endpoint.
* **Create a token**\
* **Create a token**
The POST request requires:
* A `expiry` key/value pair in the form of `expiry=<number><h|m|s>`\
Example: `expiry=72h`
An `expiry` key/value pair in the form of `expiry=<number><h|m|s>`
Example: `expiry=72h`
```bash
curl --request POST 'https://<your host:9200>/auth-app/tokens?expiry={value}' \
--header 'accept: application/json'
```
Example output:
```
```bash
{
"token": "3s2K7816M4vuSpd5",
"expiration_date": "2024-08-08T13:42:42.796888022+02:00",
@@ -53,18 +59,20 @@ The `auth-app` service provides an API to create (POST), list (GET) and delete (
Note, that this is the only time the app token will be returned in cleartext. To use the token
please copy it from the response.
* **List tokens**\
* **List tokens**
```bash
curl --request GET 'https://<your host:9200>/auth-app/tokens' \
--header 'accept: application/json'
```
Note that the `token` value in the response to the "List Tokens` request is not the actual
Note that the `token` value in the response to the "List Tokens" request is not the actual
app token, but the UUID of the token. So this value cannot be used for authenticating
with the token.
Example output:
```
```bash
[
{
"token": "155f402e-1c5c-411c-92d4-92f3b612cd99"
@@ -81,10 +89,14 @@ The `auth-app` service provides an API to create (POST), list (GET) and delete (
]
```
* **Delete a token**\
* **Delete a token**
The DELETE request requires:
* A `token` key/value pair in the form of `token=<token_issued>`. The value needs to be the hashed value as returned by the `List Tokens` respone.\
A `token` key/value pair in the form of `token=<token_issued>`. The value needs to be the hashed value as returned by the `List Tokens` respone.
Example: `token=8c606bdb-e22e-4094-9304-732fd4702bc9`
```bash
curl --request DELETE 'https://<your host:9200>/auth-app/tokens?token={value}' \
--header 'accept: application/json'
@@ -101,16 +113,22 @@ reasons.
To impersonate, the respective requests from the CLI commands above extend with
the following parameters, where you can use one or the other:
* The `userID` in the form of: `userID={value}`\
Example:\
* The `userID` in the form of: `userID={value}`
Example:
`userID=4c510ada- ... -42cdf82c3d51`
* The `userName` in the form of: `userName={value}`\
Example:\
* The `userName` in the form of: `userName={value}`
Example:
`userName=alan`
Example:\
Example:
A final create request would then look like:
```bash
curl --request POST 'https://<your host:9200>/auth-app/tokens?expiry={value}&userName={value}' \
--header 'accept: application/json'
+2 -3
View File
@@ -2,7 +2,7 @@
The collaboration service connects opencloud with document servers such as Collabora, ONLYOFFICE or Microsoft using the WOPI protocol.
Since this service requires an external document server, it won't start by default when using `opencloud server`. You must start it manually with the `opencloud collaboration server` command.
Since this service requires an external document server, it is not enabled by default. You need to add it to `OC_RUN_SERVICES`, `OC_ADD_RUN_SERVICES` or start it in a separate process with the `opencloud collaboration server` command.
Because the collaboration service needs to be started manually, the following prerequisite applies: On collaboration service startup, particular environment variables are required to be populated. If environment variables have a default like the `MICRO_REGISTRY_ADDRESS`, the default will be used, if not set otherwise. Use for all others the instance values as defined. If these environment variables are not provided or misconfigured, the collaboration service will not start up.
@@ -14,9 +14,8 @@ Required environment variables:
## Requirements
The collaboration service requires the target document server (ONLYOFFICE, Collabora, etc.) to be up and running. Additionally, some OpenCloud services are also required to be running in order to register the GRPC service for the `open in app` action in the webUI. The following internal and external services need to be available:
The collaboration periodically checks the target document server (ONLYOFFICE, Collabora, etc.) to update the available edit options. Additionally, some OpenCloud services are required to be running in order to register the GRPC service for the `open in app` action in the webUI. The following internal and external services need to be available:
* External document server.
* The gateway service.
* The app-registry service.
+1 -1
View File
@@ -29,5 +29,5 @@ type Config struct {
Context context.Context `yaml:"-"`
MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OC_MACHINE_AUTH_API_KEY;COLLABORATION_MACHINE_AUTH_API_KEY" desc:"The machine auth API key used to validate internal requests necessary to access resources from other services." introductionVersion:"%%NEXT%%"`
MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OC_MACHINE_AUTH_API_KEY;COLLABORATION_MACHINE_AUTH_API_KEY" desc:"The machine auth API key used to validate internal requests necessary to access resources from other services." introductionVersion:"7.3.0"`
}
+7 -7
View File
@@ -2,11 +2,11 @@ package config
// Events combines the configuration options for the event bus.
type Events struct {
Endpoint string `yaml:"endpoint" env:"OC_EVENTS_ENDPOINT;COLLABORATION_EVENTS_ENDPOINT" desc:"The address of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture." introductionVersion:"%%NEXT%%"`
Cluster string `yaml:"cluster" env:"OC_EVENTS_CLUSTER;COLLABORATION_EVENTS_CLUSTER" desc:"The clusterID of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture. Mandatory when using NATS as event system." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_EVENTS_TLS_INSECURE;COLLABORATION_EVENTS_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_EVENTS_TLS_ROOT_CA_CERTIFICATE;COLLABORATION_EVENTS_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided COLLABORATION_EVENTS_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_EVENTS_ENABLE_TLS;COLLABORATION_EVENTS_ENABLE_TLS" desc:"Enable TLS for the connection to the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"%%NEXT%%"`
AuthUsername string `yaml:"username" env:"OC_EVENTS_AUTH_USERNAME;COLLABORATION_EVENTS_AUTH_USERNAME" desc:"The username to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"%%NEXT%%"`
AuthPassword string `yaml:"password" env:"OC_EVENTS_AUTH_PASSWORD;COLLABORATION_EVENTS_AUTH_PASSWORD" desc:"The password to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"%%NEXT%%"`
Endpoint string `yaml:"endpoint" env:"OC_EVENTS_ENDPOINT;COLLABORATION_EVENTS_ENDPOINT" desc:"The address of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture." introductionVersion:"7.3.0"`
Cluster string `yaml:"cluster" env:"OC_EVENTS_CLUSTER;COLLABORATION_EVENTS_CLUSTER" desc:"The clusterID of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture. Mandatory when using NATS as event system." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_EVENTS_TLS_INSECURE;COLLABORATION_EVENTS_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_EVENTS_TLS_ROOT_CA_CERTIFICATE;COLLABORATION_EVENTS_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided COLLABORATION_EVENTS_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_EVENTS_ENABLE_TLS;COLLABORATION_EVENTS_ENABLE_TLS" desc:"Enable TLS for the connection to the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"7.3.0"`
AuthUsername string `yaml:"username" env:"OC_EVENTS_AUTH_USERNAME;COLLABORATION_EVENTS_AUTH_USERNAME" desc:"The username to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"7.3.0"`
AuthPassword string `yaml:"password" env:"OC_EVENTS_AUTH_PASSWORD;COLLABORATION_EVENTS_AUTH_PASSWORD" desc:"The password to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"7.3.0"`
}
+2 -2
View File
@@ -1,6 +1,6 @@
package config
type Font struct {
AssetPath string `yaml:"asset_path" env:"COLLABORATION_FONT_ASSET_PATH" desc:"Serve fonts from a path on the filesystem instead of the builtin assets. If not defined, the root directory derives from $OC_BASE_DATA_PATH/collaboration/fonts" introductionVersion:"%%NEXT%%"`
PreviewText string `yaml:"preview_text" env:"COLLABORATION_FONT_PREVIEW_TEXT" desc:"The text that will be displayed in the font preview." introductionVersion:"%%NEXT%%"`
AssetPath string `yaml:"asset_path" env:"COLLABORATION_FONT_ASSET_PATH" desc:"Serve fonts from a path on the filesystem instead of the builtin assets. If not defined, the root directory derives from $OC_BASE_DATA_PATH/collaboration/fonts" introductionVersion:"7.3.0"`
PreviewText string `yaml:"preview_text" env:"COLLABORATION_FONT_PREVIEW_TEXT" desc:"The text that will be displayed in the font preview." introductionVersion:"7.3.0"`
}
+3 -3
View File
@@ -11,7 +11,7 @@ type Store struct {
TTL time.Duration `yaml:"ttl" env:"OC_PERSISTENT_STORE_TTL;COLLABORATION_STORE_TTL" desc:"Time to live for events in the store. Defaults to '30m' (30 minutes). See the Environment Variable Types description for more details." introductionVersion:"1.0.0"`
AuthUsername string `yaml:"username" env:"OC_PERSISTENT_STORE_AUTH_USERNAME;COLLABORATION_STORE_AUTH_USERNAME" desc:"The username to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
AuthPassword string `yaml:"password" env:"OC_PERSISTENT_STORE_AUTH_PASSWORD;COLLABORATION_STORE_AUTH_PASSWORD" desc:"The password to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;COLLABORATION_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;COLLABORATION_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;COLLABORATION_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided COLLABORATION_STORE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;COLLABORATION_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;COLLABORATION_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;COLLABORATION_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided COLLABORATION_STORE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
@@ -1578,7 +1578,6 @@ func (f *FileConnector) GetAvatar(ctx context.Context, userID string) (*Connecto
}
return nil, NewConnectorError(http.StatusBadGateway, "failed to fetch avatar")
}
defer photoFile.Close()
data, err := io.ReadAll(photoFile)
if err != nil {
+3 -3
View File
@@ -43,9 +43,9 @@ type Store struct {
TTL time.Duration `yaml:"ttl" env:"OC_PERSISTENT_STORE_TTL;EVENTHISTORY_STORE_TTL" desc:"Time to live for events in the store. Defaults to '336h' (2 weeks). See the Environment Variable Types description for more details." introductionVersion:"1.0.0"`
AuthUsername string `yaml:"username" env:"OC_PERSISTENT_STORE_AUTH_USERNAME;EVENTHISTORY_STORE_AUTH_USERNAME" desc:"The username to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
AuthPassword string `yaml:"password" env:"OC_PERSISTENT_STORE_AUTH_PASSWORD;EVENTHISTORY_STORE_AUTH_PASSWORD" desc:"The password to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;EVENTHISTORY_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;EVENTHISTORY_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;EVENTHISTORY_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided EVENTHISTORY_STORE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;EVENTHISTORY_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;EVENTHISTORY_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;EVENTHISTORY_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided EVENTHISTORY_STORE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
// Events combines the configuration options for the event bus.
+3 -3
View File
@@ -133,9 +133,9 @@ type OCS struct {
StatCacheDisablePersistence bool `yaml:"stat_cache_disable_persistence" env:"OC_CACHE_DISABLE_PERSISTENCE;FRONTEND_OCS_STAT_CACHE_DISABLE_PERSISTENCE" desc:"Disable persistence of the cache. Only applies when using the 'nats-js-kv' store type. Defaults to false." introductionVersion:"1.0.0" deprecationVersion:"1.0.0" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"FRONTEND_OCS_STAT_CACHE_DISABLE_PERSISTENCE, the OCS API is deprecated" deprecationReplacement:""`
StatCacheAuthUsername string `yaml:"stat_cache_auth_username" env:"OC_CACHE_AUTH_USERNAME;FRONTEND_OCS_STAT_CACHE_AUTH_USERNAME" desc:"The username to use for authentication. Only applies when using the 'nats-js-kv' store type." introductionVersion:"1.0.0" deprecationVersion:"1.0.0" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"FRONTEND_OCS_STAT_CACHE_AUTH_USERNAME, the OCS API is deprecated" deprecationReplacement:""`
StatCacheAuthPassword string `yaml:"stat_cache_auth_password" env:"OC_CACHE_AUTH_PASSWORD;FRONTEND_OCS_STAT_CACHE_AUTH_PASSWORD" desc:"The password to use for authentication. Only applies when using the 'nats-js-kv' store type." introductionVersion:"1.0.0" deprecationVersion:"1.0.0" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"FRONTEND_OCS_STAT_CACHE_AUTH_PASSWORD, the OCS API is deprecated" deprecationReplacement:""`
StatCacheEnableTLS bool `yaml:"stat_cache_enable_tls" env:"OC_CACHE_ENABLE_TLS;FRONTEND_OCS_STAT_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"%%NEXT%%"`
StatCacheTLSInsecure bool `yaml:"stat_cache_tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;FRONTEND_OCS_STAT_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
StatCacheTLSRootCACertificate string `yaml:"stat_cache_tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;FRONTEND_OCS_STAT_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided FRONTEND_OCS_STAT_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
StatCacheEnableTLS bool `yaml:"stat_cache_enable_tls" env:"OC_CACHE_ENABLE_TLS;FRONTEND_OCS_STAT_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"7.3.0"`
StatCacheTLSInsecure bool `yaml:"stat_cache_tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;FRONTEND_OCS_STAT_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
StatCacheTLSRootCACertificate string `yaml:"stat_cache_tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;FRONTEND_OCS_STAT_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided FRONTEND_OCS_STAT_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
CacheWarmupDriver string `yaml:"cache_warmup_driver,omitempty"` // not supported by the OpenCloud product, therefore not part of docs
CacheWarmupDrivers CacheWarmupDrivers `yaml:"cache_warmup_drivers,omitempty"` // not supported by the OpenCloud product, therefore not part of docs
+6 -6
View File
@@ -84,9 +84,9 @@ type Cache struct {
ProviderCacheDisablePersistence bool `yaml:"provider_cache_disable_persistence" env:"OC_CACHE_DISABLE_PERSISTENCE;GATEWAY_PROVIDER_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the provider cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"1.0.0"`
ProviderCacheAuthUsername string `yaml:"provider_cache_auth_username" env:"OC_CACHE_AUTH_USERNAME;GATEWAY_PROVIDER_CACHE_AUTH_USERNAME" desc:"The username to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
ProviderCacheAuthPassword string `yaml:"provider_cache_auth_password" env:"OC_CACHE_AUTH_PASSWORD;GATEWAY_PROVIDER_CACHE_AUTH_PASSWORD" desc:"The password to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
ProviderCacheEnableTLS bool `yaml:"provider_cache_enable_tls" env:"OC_CACHE_ENABLE_TLS;GATEWAY_PROVIDER_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"%%NEXT%%"`
ProviderCacheTLSInsecure bool `yaml:"provider_cache_tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;GATEWAY_PROVIDER_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
ProviderCacheTLSRootCACertificate string `yaml:"provider_cache_tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;GATEWAY_PROVIDER_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GATEWAY_PROVIDER_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
ProviderCacheEnableTLS bool `yaml:"provider_cache_enable_tls" env:"OC_CACHE_ENABLE_TLS;GATEWAY_PROVIDER_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"7.3.0"`
ProviderCacheTLSInsecure bool `yaml:"provider_cache_tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;GATEWAY_PROVIDER_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
ProviderCacheTLSRootCACertificate string `yaml:"provider_cache_tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;GATEWAY_PROVIDER_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GATEWAY_PROVIDER_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
CreateHomeCacheStore string `yaml:"create_home_cache_store" env:"OC_CACHE_STORE;GATEWAY_CREATE_HOME_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"1.0.0"`
CreateHomeCacheNodes []string `yaml:"create_home_cache_nodes" env:"OC_CACHE_STORE_NODES;GATEWAY_CREATE_HOME_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"1.0.0"`
@@ -95,7 +95,7 @@ type Cache struct {
CreateHomeCacheDisablePersistence bool `yaml:"create_home_cache_disable_persistence" env:"OC_CACHE_DISABLE_PERSISTENCE;GATEWAY_CREATE_HOME_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the create home cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"1.0.0"`
CreateHomeCacheAuthUsername string `yaml:"create_home_cache_auth_username" env:"OC_CACHE_AUTH_USERNAME;GATEWAY_CREATE_HOME_CACHE_AUTH_USERNAME" desc:"The username to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
CreateHomeCacheAuthPassword string `yaml:"create_home_cache_auth_password" env:"OC_CACHE_AUTH_PASSWORD;GATEWAY_CREATE_HOME_CACHE_AUTH_PASSWORD" desc:"The password to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
CreateHomeCacheEnableTLS bool `yaml:"create_home_cache_enable_tls" env:"OC_CACHE_ENABLE_TLS;GATEWAY_CREATE_HOME_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"%%NEXT%%"`
CreateHomeCacheTLSInsecure bool `yaml:"create_home_cache_tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;GATEWAY_CREATE_HOME_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
CreateHomeCacheTLSRootCACertificate string `yaml:"create_home_cache_tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;GATEWAY_CREATE_HOME_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GATEWAY_CREATE_HOME_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
CreateHomeCacheEnableTLS bool `yaml:"create_home_cache_enable_tls" env:"OC_CACHE_ENABLE_TLS;GATEWAY_CREATE_HOME_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"7.3.0"`
CreateHomeCacheTLSInsecure bool `yaml:"create_home_cache_tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;GATEWAY_CREATE_HOME_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
CreateHomeCacheTLSRootCACertificate string `yaml:"create_home_cache_tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;GATEWAY_CREATE_HOME_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GATEWAY_CREATE_HOME_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
+3 -3
View File
@@ -12,7 +12,7 @@ type Cache struct {
DisablePersistence bool `yaml:"disable_persistence" env:"OC_CACHE_DISABLE_PERSISTENCE;GRAPH_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"1.0.0"`
AuthUsername string `yaml:"username" env:"OC_CACHE_AUTH_USERNAME;GRAPH_CACHE_AUTH_USERNAME" desc:"The username to authenticate with the cache. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
AuthPassword string `yaml:"password" env:"OC_CACHE_AUTH_PASSWORD;GRAPH_CACHE_AUTH_PASSWORD" desc:"The password to authenticate with the cache. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_CACHE_ENABLE_TLS;GRAPH_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;GRAPH_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;GRAPH_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GRAPH_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_CACHE_ENABLE_TLS;GRAPH_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;GRAPH_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;GRAPH_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GRAPH_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
+3 -3
View File
@@ -176,7 +176,7 @@ type Store struct {
Database string `yaml:"database" env:"GRAPH_STORE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"1.0.0"`
AuthUsername string `yaml:"username" env:"OC_PERSISTENT_STORE_AUTH_USERNAME;GRAPH_STORE_AUTH_USERNAME" desc:"The username to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
AuthPassword string `yaml:"password" env:"OC_PERSISTENT_STORE_AUTH_PASSWORD;GRAPH_STORE_AUTH_PASSWORD" desc:"The password to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;GRAPH_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;GRAPH_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;GRAPH_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GRAPH_STORE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;GRAPH_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;GRAPH_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;GRAPH_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GRAPH_STORE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
@@ -15,6 +15,7 @@ var (
// but can be enabled by the user.
_disabledByDefaultUnifiedRoleRoleIDs = []string{
unifiedrole.UnifiedRoleSecureViewerID,
unifiedrole.UnifiedRoleSpaceViewerWithVersionsID,
unifiedrole.UnifiedRoleSpaceEditorWithoutVersionsID,
unifiedrole.UnifiedRoleViewerListGrantsID,
unifiedrole.UnifiedRoleEditorListGrantsID,
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Ivan Fustero, 2025\n"
"Language-Team: Catalan (https://app.transifex.com/opencloud-eu/teams/204053/ca/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Pot editar"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Pot editar sense versions"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Pot gestionar"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Pot pujar"
@@ -55,23 +55,25 @@ msgstr "Pot pujar"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Pot veure"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Pot veure (de forma segura)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "No pot accedir"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Denega tot accés."
@@ -81,74 +83,75 @@ msgid "Here you can add a description for this Space."
msgstr "Aquí podeu afegir una descripció per a aquest espai."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Visualitza i descarrega."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr "View only documents, images and PDFs. Watermarks will be applied."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Visualitza, descarrega i edita."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Visualitza, descarrega i mostra totes les persones convidades."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Visualitza, descarrega i puja."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Visualitza, descarrega, edita i mostra totes les persones convidades."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Visualitza, descarrega, puja, edita, afegeix i suprimeix."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Visualitza, descarrega, puja, edita, afegeix, suprimeix i gestiona els "
"membres."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Visualitza, descarregar, pujar, editar, afegir, esborrar i mostrar totes les"
" persones convidades."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Visualitza, baixa, puja, edita, afegeix, suprimeix incloent l'historial."
@@ -13,7 +13,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: OpenCloud Ops, 2026\n"
"Language-Team: German (https://app.transifex.com/opencloud-eu/teams/204053/de/)\n"
@@ -30,26 +30,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Kann bearbeiten"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Kann bearbeiten ohne Historie"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Kann verwalten"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Kann hochladen"
@@ -57,23 +57,25 @@ msgstr "Kann hochladen"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Kann anzeigen"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Kann anzeigen (sichere Ansicht)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Kann nicht zugreifen"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Jeder Zugriff verboten"
@@ -83,50 +85,51 @@ msgid "Here you can add a description for this Space."
msgstr "Hier können Sie eine Beschreibung für diesen Space einfügen."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr "Ansehen, herunterladen und Historie ansehen."
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Ansehen und herunterladen."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Ansehen von Dokumenten, Bildern und PDFs. Wasserzeichen werden angewendet."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr "Ansehen, herunterladen, bearbeiten und Historie ansehen."
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Ansehen, herunterladen und bearbeiten."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Ansehen, herunterladen und anzeigen aller eingeladenen Personen."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Ansehen, herunterladen und hochladen."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Ansehen, herunterladen, bearbeiten und anzeigen aller eingeladenen Personen."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
"Ansehen, herunterladen, hochladen, bearbeiten, hinzufügen, löschen und "
@@ -135,26 +138,26 @@ msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Ansehen, herunterladen, hochladen, bearbeiten, hinzufügen, löschen."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Ansehen, herunterladen, hochladen, bearbeiten, hinzufügen, löschen, teilen "
"und Mitglieder verwalten."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Ansehen, herunterladen, hochladen, bearbeiten, löschen und anzeigen aller "
"eingeladenen Benutzer."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Ansehen, herunterladen, hochladen, bearbeiten, hinzufügen, löschen - "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Efstathios Iosifidis <eiosifidis@gmail.com>, 2026\n"
"Language-Team: Greek (https://app.transifex.com/opencloud-eu/teams/204053/el/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Δυνατότητα επεξεργασίας"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Δυνατότητα επεξεργασίας χωρίς εκδόσεις"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Δυνατότητα διαχείρισης"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Δυνατότητα μεταφόρτωσης"
@@ -55,23 +55,25 @@ msgstr "Δυνατότητα μεταφόρτωσης"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Δυνατότητα προβολής"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Δυνατότητα προβολής (ασφαλής)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Δεν υπάρχει πρόσβαση"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Άρνηση κάθε πρόσβασης."
@@ -81,76 +83,77 @@ msgid "Here you can add a description for this Space."
msgstr "Εδώ μπορείτε να προσθέσετε μια περιγραφή για αυτόν τον Χώρο."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Προβολή και λήψη."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Προβολή μόνο εγγράφων, εικόνων και PDF. Θα εφαρμοστούν υδατογραφήματα."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Προβολή, λήψη και επεξεργασία."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Προβολή, λήψη και εμφάνιση όλων των προσκεκλημένων ατόμων."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Προβολή, λήψη και μεταφόρτωση."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Προβολή, λήψη, επεξεργασία και εμφάνιση όλων των προσκεκλημένων ατόμων."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Προβολή, λήψη, μεταφόρτωση, επεξεργασία, προσθήκη και διαγραφή."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Προβολή, λήψη, μεταφόρτωση, επεξεργασία, προσθήκη, διαγραφή και διαχείριση "
"μελών."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Προβολή, λήψη, μεταφόρτωση, επεξεργασία, προσθήκη, διαγραφή και εμφάνιση "
"όλων των προσκεκλημένων ατόμων."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Προβολή, λήψη, μεταφόρτωση, επεξεργασία, προσθήκη, διαγραφή "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Elías Martín, 2025\n"
"Language-Team: Spanish (https://app.transifex.com/opencloud-eu/teams/204053/es/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Puede editar"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Se puede editar sin versiones"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Se puede gestionar"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Se puede subir"
@@ -55,23 +55,25 @@ msgstr "Se puede subir"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Se puede visualizar"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Se puede visualizar (de forma segura)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "No se puede acceder"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Prohibir todo el acceso"
@@ -81,74 +83,75 @@ msgid "Here you can add a description for this Space."
msgstr "Aquí puedes agregar una descripción a este Espacio."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Ver y descargar"
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Ver solamente documentos, imágenes y archivos PDF. Será aplicada una marca "
"de agua."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Ver. descargar y editar."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Ver, descargar y mostrar a todas las personas invitadas."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Ver, descargar y subir."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Ver, descargar, editar y mostrar a todas las perosnas invitadas."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Ver, descargar, subuir, editar, añadir y eliminar."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr "Ver, descargar, subir, editar, añadir, eliminar y gestionar miembros."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Ver, descargar, subir, editar, añadir, eliminar y mostrar a todas las "
"personas invitadas."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Ver, descargar, subir, editar, añadir y borrar incluyendo el historial."
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Voi muokata"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Voi muokata ilman versioita"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Voi hallita"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Voi lähettää"
@@ -55,23 +55,25 @@ msgstr "Voi lähettää"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Voi nähdä"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Voi nähdä (turvallinen)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Ei pääsyä"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Estä kaikki pääsy."
@@ -81,71 +83,72 @@ msgid "Here you can add a description for this Space."
msgstr "Täällä voit lisätä kuvauksen avaruudelle."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Näytä ja lataa."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr "Näytä vain asiakirjat, kuvat ja PDF:t. Vesileimat lisätään."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Näytä, lataa ja muokkaa."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Näytä, lataa ja näytä kaikki kutsutut henkilöt."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Näytä, lataa ja lähetä."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Näytä, lataa, muokkaa ja näytä kaikki kaikki kutsutut henkilöt."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Näytä, lataa lähetä, muokkaa, lisää ja poista."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr "Näytä, lataa, lähetä, muokkaa, lisää, poista ja hallitse jäseniä."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Näytä, lataa, lähetä, muokkaa, lisää, poista ja näytä kaikki kutsutut "
"henkilöt."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr "Näytä, lataa, lähetä, muokkaa, lisää, poista mukaan lukien historia."
@@ -13,7 +13,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Jérôme HERBINET, 2026\n"
"Language-Team: French (https://app.transifex.com/opencloud-eu/teams/204053/fr/)\n"
@@ -30,26 +30,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Peut éditer"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Peut éditer sans versions"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Peut gérer"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Peut téléverser"
@@ -57,23 +57,25 @@ msgstr "Peut téléverser"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Peut visualiser"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Peut visualiser (sécurisé)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Accès impossible"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Refuser tout accès."
@@ -83,77 +85,78 @@ msgid "Here you can add a description for this Space."
msgstr "Vous pouvez ajouter une description pour cet espace."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Consulter et télécharger."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Visualiser uniquement les documents, les images et les fichiers PDF. Des "
"filigranes seront appliqués."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Consulter, télécharger et modifier."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Consulter, télécharger et montrer toutes les personnes invitées."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Consulter, télécharger et téléverser."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Consulter, télécharger, modifier et montrer toutes les personnes invitées."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Consulter, télécharger, téléverser, modifier, ajouter et supprimer."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Consulter, télécharger, téléverser, modifier, ajouter, supprimer et gérer "
"les membres."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Consulter, télécharger, téléverser, modifier, ajouter, supprimer et montrer "
"toutes les personnes invitées."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Consulter, télécharger, téléverser, modifier, ajouter, supprimer, y compris "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Simone Broglia, 2025\n"
"Language-Team: Italian (https://app.transifex.com/opencloud-eu/teams/204053/it/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Può modificare"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Può modificare senza versioni"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Può gestire"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Può caricare"
@@ -55,23 +55,25 @@ msgstr "Può caricare"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Può visualizzare"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Può visualizzare (protetto)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Accesso non consentito"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Blocca tutti gli accessi"
@@ -81,74 +83,75 @@ msgid "Here you can add a description for this Space."
msgstr "Qui puoi aggiungere una descrizione per questo Spazio."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Visualizza e scarica."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Visualizza solo documenti, immagini e PDF. Verranno applicate filigrane."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Visualizza, scarica e modifica."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Visualizza, scarica e mostra tutte le persone invitate."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Visualizza, scarica e carica."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Visualizza, scarica, modifica e mostra tutte le persone invitate."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Visualizza, scarica, carica, modifica, aggiungi ed elimina."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Visualizza, scarica, carica, modifica, aggiungi, elimina e gestisci i "
"membri."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Visualizza, scarica, carica, modifica, aggiungi, elimina e mostra tutte le "
"persone invitate."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr "View, download, upload, edit, add, delete including the history."
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: iikaka88, 2025\n"
"Language-Team: Japanese (https://app.transifex.com/opencloud-eu/teams/204053/ja/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "編集可"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "編集 (履歴なし)"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "管理可能"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "アップロード可能"
@@ -55,23 +55,25 @@ msgstr "アップロード可能"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "閲覧可能"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "セキュア閲覧(閲覧のみ)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "アクセス不可"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "すべてのアクセスを拒否"
@@ -81,69 +83,70 @@ msgid "Here you can add a description for this Space."
msgstr "説明を追加"
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "閲覧とダウンロード"
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr "ドキュメント、画像、PDFの閲覧のみ。透かし(ウォーターマーク)が適用"
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "閲覧、ダウンロード、編集"
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "閲覧、ダウンロード、および全招待ユーザーの表示"
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "閲覧、ダウンロード、アップロード"
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "閲覧、ダウンロード、編集、および全招待ユーザーの表示"
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "閲覧、ダウンロード、アップロード、編集、追加、削除"
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr "閲覧、ダウンロード、アップロード、編集、追加、削除、およびメンバー管理"
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr "閲覧、ダウンロード、アップロード、編集、追加、削除、および全招待ユーザーの表示"
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr "閲覧、ダウンロード、アップロード、編集、追加、削除(履歴を含む)"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: gapho shin, 2025\n"
"Language-Team: Korean (https://app.transifex.com/opencloud-eu/teams/204053/ko/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "편집 가능"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "버전 없이 편집 가능"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "관리 가능"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "업로드 가능"
@@ -55,23 +55,25 @@ msgstr "업로드 가능"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "보기 가능"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "보기 가능 (보안)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "접근 불가"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "모든 접근 거부"
@@ -81,69 +83,70 @@ msgid "Here you can add a description for this Space."
msgstr "여기에 이 공간에 대한 설명을 추가할 수 있습니다."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "보기 및 다운로드."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr "문서, 이미지 및 PDF만 보기. 워터마크가 적용됩니다."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "보기, 다운로드 및 편집."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "모든 초대받은 사람들을 보고, 다운로드하고, 보여줍니다."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "보기, 다운로드 및 업로드."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "모든 초대받은 사람들을 보고, 다운로드하고, 편집하고, 보여줍니다."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "보기, 다운로드, 업로드, 편집, 추가 및 삭제."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr "회원 보기, 다운로드, 업로드, 편집, 추가, 삭제 및 관리."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr "모든 초대받은 사람들을 보고, 다운로드하고, 업로드하고, 편집하고, 추가하고, 삭제하고, 보여줍니다."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr "기록을 포함하여 보기, 다운로드, 업로드, 편집, 추가, 삭제합니다."
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-03 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Stephan Paternotte <stephan@paternottes.net>, 2026\n"
"Language-Team: Dutch (https://app.transifex.com/opencloud-eu/teams/204053/nl/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Kan bewerken"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Kan bewerken zonder versies"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Kan beheren"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Kan uploaden"
@@ -55,23 +55,25 @@ msgstr "Kan uploaden"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Kan weergeven"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Kan weergeven (beveiligd)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Heeft geen toegang"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Alle toegang weigeren."
@@ -81,50 +83,51 @@ msgid "Here you can add a description for this Space."
msgstr "Hier kunt u een beschrijving voor deze ruimte toevoegen."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr "Incl. geschiedenis weergeven en downloaden."
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Weergeven en downloaden."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Alleen documenten, afbeeldingen en PDF's weergeven. Met toepassing van "
"watermerken."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr "Incl. geschiedenis weergeven, downloaden en bewerken."
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Weergeven, downloaden en bewerken."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Weergeven, downloaden en alle genodigde personen zien."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Weergeven, downloaden en uploaden."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Weergeven, downloaden, bewerken en alle genodigde personen zien."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
"Incl. geschiedenis weergeven, downloaden, uploaden, bewerken, toevoegen en "
@@ -133,26 +136,26 @@ msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Weergeven, downloaden, uploaden, bewerken, toevoegen en verwijderen."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Weergeven, downloaden, uploaden, bewerken, toevoegen, verwijderen en leden "
"beheren."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Weergeven, downloaden, uploaden, bewerken, toevoegen, verwijderen en alle "
"genodigde personen zien."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Weergeven, downloaden, uploaden, bewerken, toevoegen, verwijderen, incl. "
@@ -15,7 +15,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Matt, 2026\n"
"Language-Team: Polish (https://app.transifex.com/opencloud-eu/teams/204053/pl/)\n"
@@ -32,26 +32,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Może edytować"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Może edytować bez wersji"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Może zarządzać"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Może przesyłać pliki"
@@ -59,23 +59,25 @@ msgstr "Może przesyłać pliki"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Może oglądać"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Mogę zobaczyć ( źródło) "
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Nie ma dostępu"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Odmów dostępu wszystkim."
@@ -85,76 +87,77 @@ msgid "Here you can add a description for this Space."
msgstr "Tutaj możesz dodać opis dla tej Przestrzeni"
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Zobacz i pobierz"
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Wyświetlanie tylko dokumentów, obrazów i PDF. Zostaną nałożone znaki wodne."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Wyświetl , Pobierz i edytuj "
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Wyświetlanie, pobieranie i pokazywanie wszystkich zaproszonych."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Wyświetlanie, pobieranie i przesyłanie."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Wyświetlanie, pobieranie, edycja i pokazywanie wszystkich zaproszonych."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Wyświetlanie, pobieranie, przesyłanie, edycja, dodawanie i usuwanie."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Wyświetlanie, pobieranie, przesyłanie, edycja, dodawanie, usuwanie i "
"zarządzanie członkami."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Wyświetlanie, pobieranie, przesyłanie, edycja, dodawanie, usuwanie i "
"wyświetlanie wszystkich zaproszonych osób."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Wyświetlanie, pobieranie, przesyłanie, edycja, dodawanie, usuwanie włącznie "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Mário Machado, 2025\n"
"Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Pode editar"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Pode editar sem versões"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Pode gerir"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Pode carregar"
@@ -55,23 +55,25 @@ msgstr "Pode carregar"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Pode visualizar"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Pode visualizar (seguro)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Não pode aceder"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Negar todo o acesso."
@@ -81,77 +83,78 @@ msgid "Here you can add a description for this Space."
msgstr "Aqui pode adicionar uma descrição para este Espaço."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Visualizar e descarregar."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Visualizar apenas documentos, imagens e PDFs. Serão aplicadas marcas de "
"água."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Visualizar, descarregar e editar."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Visualizar, descarregar e mostrar todas as pessoas convidadas."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Visualizar, descarregar e carregar."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Visualizar, descarregar, editar e mostrar todas as pessoas convidadas."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Visualizar, descarregar, carregar, editar, adicionar e eliminar."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Visualizar, descarregar, carregar, editar, adicionar, eliminar e gerir "
"membros."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Visualizar, descarregar, carregar, editar, adicionar, eliminar e mostrar "
"todas as pessoas convidadas."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Visualizar, descarregar, carregar, editar, adicionar, eliminar, incluindo o "
@@ -12,7 +12,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Lulufox, 2025\n"
"Language-Team: Russian (https://app.transifex.com/opencloud-eu/teams/204053/ru/)\n"
@@ -29,26 +29,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Может редактировать"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Может редактировать без версионирования"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Может управлять"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Может загружать"
@@ -56,23 +56,25 @@ msgstr "Может загружать"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Можно смотреть"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Можно смотреть (защищено)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Не имеет доступа"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Отказать во всех доступах"
@@ -82,77 +84,78 @@ msgid "Here you can add a description for this Space."
msgstr "Здесь вы можете добавить описание для Пространства"
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Просмотреть и скачать"
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Просмотреть только документы, изображения и файлы PDF. Будут присутствовать "
"вотермарки."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Просмотреть, скачать и редактировать."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Просмотреть, скачать и показать всех приглашенных людей."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Просмотреть, скачать и загрузить."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Просмотреть, скачать, отредактировать и показать всех приглашенных людей."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Просмотреть, скачать, загрузить, редактировать, добавить и удалить."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Просмотреть, скачать, загрузить, редактировать, добавить, удалить и "
"управлять командой."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Просмотреть, скачать, загрузить, редактировать, добавить, удалить и показать"
" всех приглашенных людей."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Просмотреть, скачать, загрузить, редактировать, добавить, удалить включая "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Daniel Nylander <po@danielnylander.se>, 2025\n"
"Language-Team: Swedish (https://app.transifex.com/opencloud-eu/teams/204053/sv/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Kan redigera"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Kan redigera utan versioner"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Kan hantera"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Kan skicka upp"
@@ -55,23 +55,25 @@ msgstr "Kan skicka upp"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Kan visa"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Kan visa (säkert)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Kan inte komma åt"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Neka all åtkomst."
@@ -81,75 +83,76 @@ msgid "Here you can add a description for this Space."
msgstr "Här kan du lägga till en beskrivning av denna arbetsyta."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Visa och hämta ner."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Visa endast dokument, bilder och PDF. Vattenstämplar kommer att tillämpas."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Visa, hämta ner och redigera."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Visa, hämta ner och visa alla inbjudna personer."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Visa. hämta ner och skicka upp."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Visa, hämta ner, redigera och visa alla inbjudna personer."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Visa, hämta ner, skicka upp, redigera, lägga till och ta bort."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Visa, hämta ner, skicka upp, redigera, lägga till, ta bort och hantera "
"medlemmar."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Visa, hämta ner, skicka upp, redigera, lägga till, ta bort och visa alla "
"inbjudna personer."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Visa, hämta ner, skicka upp, redigera, lägga till, ta bort inklusive "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: LinkinWires <darkinsonic13@gmail.com>, 2025\n"
"Language-Team: Ukrainian (https://app.transifex.com/opencloud-eu/teams/204053/uk/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Може редагувати"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Може редагувати (без версій)"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Може керувати"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Може вивантажувати"
@@ -55,23 +55,25 @@ msgstr "Може вивантажувати"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Може переглядати"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Може переглядати (обмежено)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Не має доступу"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Заборонити будь-який доступ."
@@ -81,80 +83,81 @@ msgid "Here you can add a description for this Space."
msgstr "Тут можна додати опис до цього простору."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Може переглядати та завантажувати файли."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Може переглядати лише документи, зображення та PDF-файли. Будуть застосовані"
" водяні знаки."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Може переглядати, завантажувати та редагувати файли."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Може переглядати, завантажувати та показувати усіх запрошених людей."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Може переглядати, завантажувати та вивантажувати файли."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Може переглядати, завантажувати, редагувати та показувати усіх запрошених "
"людей."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr ""
"Може переглядати, завантажувати, вивантажувати, редагувати, додавати та "
"видаляти файли."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Може переглядати, завантажувати, вивантажувати, редагувати, додавати та "
"видаляти файли, а також може керувати учасниками."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Може переглядати, завантажувати, редагувати, додавати, видаляти та "
"показувати усіх запрошених людей."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Може переглядати, завантажувати, вивантажувати, редагувати, додавати та "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Quan Tran, 2025\n"
"Language-Team: Vietnamese (https://app.transifex.com/opencloud-eu/teams/204053/vi/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Có quyền chỉnh sửa"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Có quyền chỉnh sửa không tạo phiên bản"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Có quyền quản lý"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Có quyền đăng tải"
@@ -55,23 +55,25 @@ msgstr "Có quyền đăng tải"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Có quyền xem"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Có quyền xem (bảo mật)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Không có quyền truy cập"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Cấm mọi quyền truy cập."
@@ -81,71 +83,72 @@ msgid "Here you can add a description for this Space."
msgstr ""
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Xem và tải về."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr "Chỉ được xem tài liệu, hình ảnh và PDF. Sẽ hiển thị hình mờ."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Xem, tải về và chỉnh sửa."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Xem, tải về và hiển thị danh sách người được mời."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Xem, tải về và tải lên."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Xem, tải về, chỉnh sửa và hiển thị danh sách người được mời."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Xem, tải về, tải lên, chỉnh sửa, thêm và xóa."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr "Xem, tải về, tải lên, chỉnh sửa, thêm, xóa và quản lý thành viên."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Xem, tải về, tải lên, chỉnh sửa, thêm, xóa và hiển thị danh sách người được "
"mời."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr "Xem, tải về, tải lên, chỉnh sửa, thêm và xóa bao gồm lịch sử."
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-07-22 23:15+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: YQS Yang, 2025\n"
"Language-Team: Chinese (https://app.transifex.com/opencloud-eu/teams/204053/zh/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "可编辑"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "可编辑(无版本控制)"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "可管理"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "可上传"
@@ -55,23 +55,25 @@ msgstr "可上传"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "可查看"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "可查看(安全)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "无法访问"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "拒绝所有访问。"
@@ -81,69 +83,70 @@ msgid "Here you can add a description for this Space."
msgstr "此处可为该空间添加描述。"
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "查看和下载。"
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr "仅可查看文档、图片和PDF,且会添加水印。"
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "查看、下载和编辑。"
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "查看、下载并显示所有受邀人员。"
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "查看、下载和上传。"
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "查看、下载、编辑并显示所有受邀人员。"
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "查看、下载、上传、编辑、添加和删除。"
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr "查看、下载、上传、编辑、添加、删除和管理成员。"
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr "查看、下载、上传、编辑、添加、删除并显示所有受邀人员。"
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr "查看、下载、上传、编辑、添加和删除(含历史版本)。"
@@ -5,6 +5,7 @@ import (
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
libregraph "github.com/opencloud-eu/libre-graph-api-go"
"github.com/opencloud-eu/reva/v2/pkg/conversions"
)
@@ -210,6 +211,8 @@ func cs3RoleToDisplayName(role *conversions.Role) string {
return _viewerListGrantsUnifiedRoleDisplayName
case conversions.RoleSpaceViewer:
return _spaceViewerUnifiedRoleDisplayName
case conversions.RoleSpaceViewerWithVersions:
return _spaceViewerWithVersionsUnifiedRoleDisplayName
case conversions.RoleEditor:
return _editorUnifiedRoleDisplayName
case conversions.RoleEditorWithVersions:
@@ -71,7 +71,7 @@ func TestCS3ResourcePermissionsToRole(t *testing.T) {
cs3Conversions.RoleFileEditorWithVersions: {cs3Conversions.NewFileEditorWithVersionsRole().CS3ResourcePermissions(), unifiedrole.RoleFileEditorWithVersions, unifiedrole.UnifiedRoleConditionFile},
cs3Conversions.RoleManager: {cs3Conversions.NewManagerRole().CS3ResourcePermissions(), unifiedrole.RoleManager, unifiedrole.UnifiedRoleConditionDrive},
cs3Conversions.RoleSpaceViewer: {cs3Conversions.NewSpaceViewerRole().CS3ResourcePermissions(), unifiedrole.RoleSpaceViewer, unifiedrole.UnifiedRoleConditionDrive},
cs3Conversions.RoleSpaceEditor: {cs3Conversions.NewSpaceEditorRole().CS3ResourcePermissions(), unifiedrole.RoleSpaceEditor, unifiedrole.UnifiedRoleConditionDrive},
cs3Conversions.RoleSpaceEditor: {cs3Conversions.NewSpaceEditorRole().CS3ResourcePermissions(), unifiedrole.RoleSpaceEditorWithVersions, unifiedrole.UnifiedRoleConditionDrive},
cs3Conversions.RoleSecureViewer + "1": {cs3Conversions.NewSecureViewerRole().CS3ResourcePermissions(), unifiedrole.RoleSecureViewer, unifiedrole.UnifiedRoleConditionFile},
cs3Conversions.RoleSecureViewer + "2": {cs3Conversions.NewSecureViewerRole().CS3ResourcePermissions(), unifiedrole.RoleSecureViewer, unifiedrole.UnifiedRoleConditionFolder},
cs3Conversions.RoleDenied: {cs3Conversions.NewDeniedRole().CS3ResourcePermissions(), unifiedrole.RoleDenied, unifiedrole.UnifiedRoleConditionFolder},
+17 -16
View File
@@ -1,22 +1,23 @@
package unifiedrole
var (
RoleViewer = roleViewer
RoleViewerWithVersions = roleViewerWithVersions
RoleViewerListGrants = roleViewerListGrants
RoleSpaceViewer = roleSpaceViewer
RoleEditor = roleEditor
RoleEditorWithVersions = roleEditorWithVersions
RoleEditorListGrants = roleEditorListGrants
RoleSpaceEditor = roleSpaceEditor
RoleSpaceEditorWithoutVersions = roleSpaceEditorWithoutVersions
RoleFileEditor = roleFileEditor
RoleFileEditorWithVersions = roleFileEditorWithVersions
RoleFileEditorListGrants = roleFileEditorListGrants
RoleEditorLite = roleEditorLite
RoleManager = roleManager
RoleSecureViewer = roleSecureViewer
RoleDenied = roleDenied
RoleViewer = roleViewer
RoleViewerWithVersions = roleViewerWithVersions
RoleViewerListGrants = roleViewerListGrants
RoleSpaceViewer = roleSpaceViewer
RoleSpaceViewerWithVersions = roleSpaceViewerWithVersions
RoleEditor = roleEditor
RoleEditorWithVersions = roleEditorWithVersions
RoleEditorListGrants = roleEditorListGrants
RoleSpaceEditor = roleSpaceEditor
RoleSpaceEditorWithVersions = roleSpaceEditorWithVersions
RoleFileEditor = roleFileEditor
RoleFileEditorWithVersions = roleFileEditorWithVersions
RoleFileEditorListGrants = roleFileEditorListGrants
RoleEditorLite = roleEditorLite
RoleManager = roleManager
RoleSecureViewer = roleSecureViewer
RoleDenied = roleDenied
BuildInRoles = buildInRoles
+33 -6
View File
@@ -6,9 +6,10 @@ import (
"strings"
libregraph "github.com/opencloud-eu/libre-graph-api-go"
"github.com/opencloud-eu/reva/v2/pkg/conversions"
"google.golang.org/protobuf/proto"
"github.com/opencloud-eu/reva/v2/pkg/conversions"
"github.com/opencloud-eu/opencloud/pkg/l10n"
graphl10n "github.com/opencloud-eu/opencloud/services/graph/pkg/l10n"
)
@@ -22,6 +23,8 @@ const (
UnifiedRoleViewerListGrantsID = "d5041006-ebb3-4b4a-b6a4-7c180ecfb17d"
// UnifiedRoleSpaceViewerID Unified role space viewer id.
UnifiedRoleSpaceViewerID = "a8d5fe5e-96e3-418d-825b-534dbdf22b99"
// UnifiedRoleSpaceViewerWithVersionsID
UnifiedRoleSpaceViewerWithVersionsID = "3de465fc-6e17-4839-8b8a-a77cc497878b"
// UnifiedRoleEditorID Unified role editor id.
UnifiedRoleEditorID = "fb6c3e19-e378-47e5-b277-9732f9de6e21"
// UnifiedRoleEditorWithVersionsID
@@ -121,6 +124,12 @@ var (
// UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
_spaceViewerUnifiedRoleDisplayName = l10n.Template("Can view")
// UnifiedRole SpaceViewer, Role Description (resolves directly)
_spaceViewerWithVersionsUnifiedRoleDescription = l10n.Template("View and download including the history.")
// UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
_spaceViewerWithVersionsUnifiedRoleDisplayName = l10n.Template("Can view")
// UnifiedRole Editor, Role Description (resolves directly)
_editorUnifiedRoleDescription = l10n.Template("View, download, upload, edit, add and delete.")
@@ -214,11 +223,12 @@ var (
roleViewerWithVersions,
roleViewerListGrants,
roleSpaceViewer,
roleSpaceViewerWithVersions,
roleEditor,
roleEditorListGrants,
roleEditorWithVersions,
roleSpaceEditorWithVersions,
roleSpaceEditor,
roleSpaceEditorWithoutVersions,
roleFileEditor,
roleFileEditorWithVersions,
roleFileEditorListGrants,
@@ -345,6 +355,23 @@ var (
}
}()
// roleSpaceViewer creates a spaceviewer role
roleSpaceViewerWithVersions = func() *libregraph.UnifiedRoleDefinition {
r := conversions.NewSpaceViewerWithVersionsRole()
return &libregraph.UnifiedRoleDefinition{
Id: proto.String(UnifiedRoleSpaceViewerWithVersionsID),
Description: proto.String(_spaceViewerWithVersionsUnifiedRoleDescription),
DisplayName: proto.String(cs3RoleToDisplayName(r)),
RolePermissions: []libregraph.UnifiedRolePermission{
{
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
Condition: proto.String(UnifiedRoleConditionDrive),
},
},
LibreGraphWeight: proto.Int32(40),
}
}()
// roleEditorLite creates an editor-lite role
roleEditorLite = func() *libregraph.UnifiedRoleDefinition {
r := conversions.NewEditorLiteRole()
@@ -420,8 +447,8 @@ var (
}
}()
// roleSpaceEditorWithoutVersions creates an editor without versions role
roleSpaceEditorWithoutVersions = func() *libregraph.UnifiedRoleDefinition {
// roleSpaceEditor creates an editor without versions role
roleSpaceEditor = func() *libregraph.UnifiedRoleDefinition {
r := conversions.NewSpaceEditorWithoutVersionsRole()
return &libregraph.UnifiedRoleDefinition{
Id: proto.String(UnifiedRoleSpaceEditorWithoutVersionsID),
@@ -437,8 +464,8 @@ var (
}
}()
// roleSpaceEditor creates an editor role
roleSpaceEditor = func() *libregraph.UnifiedRoleDefinition {
// roleSpaceEditorWithVersions creates an editor role
roleSpaceEditorWithVersions = func() *libregraph.UnifiedRoleDefinition {
r := conversions.NewSpaceEditorRole()
return &libregraph.UnifiedRoleDefinition{
Id: proto.String(UnifiedRoleSpaceEditorID),
+6 -1
View File
@@ -38,6 +38,10 @@ func TestGetDefinition(t *testing.T) {
ids: []string{unifiedrole.UnifiedRoleFileEditorWithVersionsID},
unifiedRoleDefinition: unifiedrole.RoleFileEditorWithVersions,
},
"pass space-viewer-with-versions": {
ids: []string{unifiedrole.UnifiedRoleSpaceViewerWithVersionsID},
unifiedRoleDefinition: unifiedrole.RoleSpaceViewerWithVersions,
},
"fail unknown": {
ids: []string{"unknown"},
expectError: unifiedrole.ErrUnknownRole,
@@ -203,8 +207,9 @@ func TestGetRolesByPermissions(t *testing.T) {
constraints: unifiedrole.UnifiedRoleConditionDrive,
unifiedRoleDefinition: []*libregraph.UnifiedRoleDefinition{
unifiedrole.RoleSpaceViewer,
unifiedrole.RoleSpaceEditorWithoutVersions,
unifiedrole.RoleSpaceViewerWithVersions,
unifiedrole.RoleSpaceEditor,
unifiedrole.RoleSpaceEditorWithVersions,
unifiedrole.RoleManager,
},
},
+3 -1
View File
@@ -1,2 +1,4 @@
*.mo
dev-translation.json
# i18next-cli extracted keys (intermediate, regenerated on demand)
translation.*.json
+12 -8
View File
@@ -15,27 +15,31 @@ POS ?= $(wildcard *.po)
.PHONY: build
build: json
.PYTHON: json
.PHONY: json
json:
@for po in $(POS); do \
lang=$$(echo $$po | sed "s/\.po//"); \
$(PNPM) i18next-conv -K --skipUntranslated -l $$lang -s i18n/$$po -t ../src/locales/$$lang/translation.json; \
$(PNPM) i18next-conv -K --skipUntranslated -l $$lang -s $$po -t ../src/locales/$$lang/translation.json; \
done
$(PNPM) node i18n/build-json.js ../src/locales/locales.json $(POS)
$(PNPM) node build-json.js ../src/locales/locales.json $(POS)
dev-translation.json: FORCE
$(PNPM) i18next --fail-on-warnings
.PHONY: extract-keys
extract-keys:
$(PNPM) i18next-cli extract -q || true
translation.en.json: FORCE
$(MAKE) extract-keys
.PHONY: extract
extract: pot
.PHONY: pot
pot: dev-translation.json
pot: translation.en.json
@tmpfile1=$(shell mktemp).po; \
tmpfile2=$(shell mktemp).po; \
trap 'rm -f "$$tmpfile1" "$$tmpfile2"' EXIT; \
$(PNPM) i18next-conv --project "LibreGraph Connect Identifier" -K -l en -s i18n/dev-translation.json -t $$tmpfile1; \
$(PNPM) node i18n/build-pot.js $$tmpfile1 $$tmpfile2; \
$(PNPM) i18next-conv --project "LibreGraph Connect Identifier" -K -l en -s translation.en.json -t $$tmpfile1; \
$(PNPM) node build-pot.js $$tmpfile1 $$tmpfile2; \
$(MSGCAT) --no-wrap -o $(POT) $$tmpfile2
.PHONY: merge
+92
View File
@@ -0,0 +1,92 @@
# IDP Translations
## Overview
The IDP service uses i18next for internationalization with gettext (`.po`)
files as the source of truth for translations. The workflow is:
```text
Source code t() calls → extract keys → .pot template
→ merge into .po → convert to JSON → app bundles
```
## File Structure
- `i18n/*.po` — translation files per language (committed)
- `i18n/translation.pot` — extracted keys template (committed)
- `i18n/translation.en.json` — intermediate EN keys (gitignored)
- `src/locales/*/translation.json` — JSON translations at runtime (committed)
- `src/locales/locales.json` — language metadata for locale selector (committed)
## Adding New Translation Keys
### 1. Add a key in source code
```jsx
t("konnect.new.key", "Default fallback text")
```
The first argument is the i18next key path (dot notation for nested JSON). The
second argument is the default/fallback English text — this is what translators
see in `.po` files as `msgid`.
### 2. Extract new keys into the `.pot` template
```bash
make -C i18n extract
```
This runs `i18next-cli extract` to scan all `src/**/*.{js,jsx,ts,tsx}` files,
writes extracted English keys to `i18n/translation.en.json`, then converts
them into `translation.pot`.
### 3. Merge new keys into existing `.po` files
```bash
make -C i18n merge
```
This runs `msgmerge` on each `.po` file to add any new keys from the updated
`.pot` template. Translators then fill in translations for the new entries.
### 4. Convert `.po` files to JSON for the app
```bash
make -C i18n json
```
This runs `i18next-conv` on each `.po` file to produce
`src/locales/{lang}/translation.json`. This step is also run automatically by
`make build`.
## Runtime Loading
The app loads translations via dynamic webpack imports:
```typescript
// src/i18n.ts
import(`./locales/${language}/translation.json`)
```
When the user selects a language, i18next fetches the corresponding JSON file.
The locale selector reads available languages from `src/locales/locales.json`.
## Build and CI
- **`make build`** → runs `make json` to convert `.po` files to JSON before
webpack bundling
- **CI (Woodpecker)** runs `make node-generate-prod` which calls
`pnpm install && pnpm build` — no translation extraction happens in CI, only
the committed JSON files are bundled
## Tools
- `i18next-cli` — extracts keys from source code (AST-based)
- `i18next-conv` — converts between `.po` and i18next JSON
- `msgmerge` / `msgcat` — standard gettext merge/collate tools
- `gettext-parser` — cleans headers in generated POT file
## Configuration
- `i18n/i18next.config.ts` — extraction config (input globs, output path)
- `src/i18n.ts` — runtime setup (detection, fallbacks, backend loader)
+2 -12
View File
@@ -57,11 +57,6 @@ msgstr "Konto auswählen"
msgid "Clicking \"Allow\" will redirect you to: {{redirectURI}}"
msgstr "Wenn Sie \"Einverstanden\" klicken werden Sie zu {{redirectURI}} weitergeleitet"
#. From: konnect##login##usernameField##placeholder##email
#: konnect##login##usernameField##placeholder##email
msgid "Email"
msgstr "E-Mail"
#. From: konnect##error##login##validate##missingUsername
#: konnect##error##login##validate##missingUsername
msgid "Enter a valid value."
@@ -92,11 +87,6 @@ msgstr "Hallo {{displayName}}"
msgid "Hi {{displayName}}"
msgstr "Hallo {{displayName}}"
#. From: konnect##login##usernameField##placeholder##identity
#: konnect##login##usernameField##placeholder##identity
msgid "Identity"
msgstr "Identität"
#. From: konnect##scopeDescription##offlineAccess
#: konnect##scopeDescription##offlineAccess
msgid "Keep the allowed access persistently and forever"
@@ -164,8 +154,8 @@ msgstr "Unerwarteter Antwort-Status: {{state}}"
msgid "Use another account"
msgstr "Anderes Konto"
#. From: konnect##login##usernameField##placeholder##username
#: konnect##login##usernameField##placeholder##username
#. From: konnect##login##usernameField##label
#: konnect##login##usernameField##label
msgid "Username"
msgstr "Benutzername"
+2 -12
View File
@@ -56,11 +56,6 @@ msgstr ""
msgid "Clicking \"Allow\" will redirect you to: {{redirectURI}}"
msgstr ""
#. From: konnect##login##usernameField##placeholder##email
#: konnect##login##usernameField##placeholder##email
msgid "Email"
msgstr ""
#. From: konnect##error##login##validate##missingUsername
#: konnect##error##login##validate##missingUsername
msgid "Enter a valid value."
@@ -91,11 +86,6 @@ msgstr ""
msgid "Hi {{displayName}}"
msgstr ""
#. From: konnect##login##usernameField##placeholder##identity
#: konnect##login##usernameField##placeholder##identity
msgid "Identity"
msgstr ""
#. From: konnect##scopeDescription##offlineAccess
#: konnect##scopeDescription##offlineAccess
msgid "Keep the allowed access persistently and forever"
@@ -163,8 +153,8 @@ msgstr ""
msgid "Use another account"
msgstr ""
#. From: konnect##login##usernameField##placeholder##username
#: konnect##login##usernameField##placeholder##username
#. From: konnect##login##usernameField##label
#: konnect##login##usernameField##label
msgid "Username"
msgstr ""
+2 -12
View File
@@ -57,11 +57,6 @@ msgstr "Choisir un compte"
msgid "Clicking \"Allow\" will redirect you to: {{redirectURI}}"
msgstr "En cliquant \"Autoriser\" vous serez redirigé vers: {{redirectURI}}"
#. From: konnect##login##usernameField##placeholder##email
#: konnect##login##usernameField##placeholder##email
msgid "Email"
msgstr ""
#. From: konnect##error##login##validate##missingUsername
#: konnect##error##login##validate##missingUsername
msgid "Enter a valid value."
@@ -92,11 +87,6 @@ msgstr "Bonjour {{displayName}}"
msgid "Hi {{displayName}}"
msgstr "Bonjour {{displayName}}"
#. From: konnect##login##usernameField##placeholder##identity
#: konnect##login##usernameField##placeholder##identity
msgid "Identity"
msgstr ""
#. From: konnect##scopeDescription##offlineAccess
#: konnect##scopeDescription##offlineAccess
msgid "Keep the allowed access persistently and forever"
@@ -164,8 +154,8 @@ msgstr "Erreur d'état inattendue : {{state}}"
msgid "Use another account"
msgstr "Utiliser un autre compte"
#. From: konnect##login##usernameField##placeholder##username
#: konnect##login##usernameField##placeholder##username
#. From: konnect##login##usernameField##label
#: konnect##login##usernameField##label
msgid "Username"
msgstr "Utilisateur"
+10
View File
@@ -0,0 +1,10 @@
import { defineConfig } from 'i18next-cli';
export default defineConfig({
locales: ['en'],
extract: {
currentLocale: 'en',
input: ['../src/**/*.{js,jsx,ts,tsx}'],
output: 'translation.{{language}}.json',
},
});
+2 -12
View File
@@ -57,11 +57,6 @@ msgstr ""
msgid "Clicking \"Allow\" will redirect you to: {{redirectURI}}"
msgstr ""
#. From: konnect##login##usernameField##placeholder##email
#: konnect##login##usernameField##placeholder##email
msgid "Email"
msgstr ""
#. From: konnect##error##login##validate##missingUsername
#: konnect##error##login##validate##missingUsername
msgid "Enter a valid value."
@@ -92,11 +87,6 @@ msgstr ""
msgid "Hi {{displayName}}"
msgstr ""
#. From: konnect##login##usernameField##placeholder##identity
#: konnect##login##usernameField##placeholder##identity
msgid "Identity"
msgstr ""
#. From: konnect##scopeDescription##offlineAccess
#: konnect##scopeDescription##offlineAccess
msgid "Keep the allowed access persistently and forever"
@@ -164,8 +154,8 @@ msgstr ""
msgid "Use another account"
msgstr ""
#. From: konnect##login##usernameField##placeholder##username
#: konnect##login##usernameField##placeholder##username
#. From: konnect##login##usernameField##label
#: konnect##login##usernameField##label
msgid "Username"
msgstr ""
+2 -12
View File
@@ -57,11 +57,6 @@ msgstr "Account kiezen"
msgid "Clicking \"Allow\" will redirect you to: {{redirectURI}}"
msgstr "Door op \"Toestaan\" te klikken word je doorverwezen naar: {{redirectURI}}"
#. From: konnect##login##usernameField##placeholder##email
#: konnect##login##usernameField##placeholder##email
msgid "Email"
msgstr ""
#. From: konnect##error##login##validate##missingUsername
#: konnect##error##login##validate##missingUsername
msgid "Enter a valid value."
@@ -92,11 +87,6 @@ msgstr "Hallo {{displayName}}"
msgid "Hi {{displayName}}"
msgstr "Hoi {{displayName}}"
#. From: konnect##login##usernameField##placeholder##identity
#: konnect##login##usernameField##placeholder##identity
msgid "Identity"
msgstr ""
#. From: konnect##scopeDescription##offlineAccess
#: konnect##scopeDescription##offlineAccess
msgid "Keep the allowed access persistently and forever"
@@ -164,8 +154,8 @@ msgstr "Onverwachte respons status: {{state}}"
msgid "Use another account"
msgstr "Gebruik een ander account"
#. From: konnect##login##usernameField##placeholder##username
#: konnect##login##usernameField##placeholder##username
#. From: konnect##login##usernameField##label
#: konnect##login##usernameField##label
msgid "Username"
msgstr "Gebruikersnaam"
+151 -156
View File
@@ -3,192 +3,187 @@ msgstr ""
"Project-Id-Version: LibreGraph Connect Identifier\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2022-03-09T19:33:04.641Z\n"
"POT-Creation-Date: 2026-07-08T15:11:00.860Z\n"
"MIME-Version: 1.0\n"
#. From: konnect##loading##error##headline
#: konnect##loading##error##headline
msgid "Failed to connect to server"
msgstr ""
#. From: konnect##login##retryButton##label
#: konnect##login##retryButton##label
msgid "Retry"
msgstr ""
#. From: konnect##login##usernameField##placeholder##email
#: konnect##login##usernameField##placeholder##email
msgid "Email"
msgstr ""
#. From: konnect##login##usernameField##placeholder##identity
#: konnect##login##usernameField##placeholder##identity
msgid "Identity"
msgstr ""
#. From: konnect##login##usernameField##placeholder##username
#: konnect##login##usernameField##placeholder##username
msgid "Username"
msgstr ""
#. From: konnect##login##headline
#: konnect##login##headline
msgid "Sign in"
msgstr ""
#. From: konnect##login##passwordField##label
#: konnect##login##passwordField##label
msgid "Password"
msgstr ""
#. From: konnect##login##nextButton##label
#: konnect##login##nextButton##label
msgid "Next"
msgstr ""
#. From: konnect##scopeDescription##aliasBasic
#: konnect##scopeDescription##aliasBasic
msgid "Access your basic account information"
msgstr ""
#. From: konnect##scopeDescription##offlineAccess
#: konnect##scopeDescription##offlineAccess
msgid "Keep the allowed access persistently and forever"
msgstr ""
#. From: konnect##scopeDescription##scope
#: konnect##scopeDescription##scope
msgid "Scope: {{scope}}"
msgstr ""
#. From: konnect##goodbye##headline
#: konnect##goodbye##headline
msgid "Goodbye"
msgstr ""
#. From: konnect##goodbye##subHeader
#: konnect##goodbye##subHeader
msgid "you have been signed out from your account"
msgstr ""
#. From: konnect##goodbye##message##close
#: konnect##goodbye##message##close
msgid "You can close this window now."
msgstr ""
#. From: konnect##goodbye##message##confirm
#: konnect##goodbye##message##confirm
msgid "Press the button below, to sign out from your account now."
msgstr ""
#. From: konnect##goodbye##confirm##headline
#: konnect##goodbye##confirm##headline
msgid "Hello {{displayName}}"
msgstr ""
#. From: konnect##goodbye##confirm##subHeader
#: konnect##goodbye##confirm##subHeader
msgid "please confirm sign out"
msgstr ""
#. From: konnect##goodbye##signoutButton##label
#. konnect##welcome##signoutButton##label
#: konnect##goodbye##signoutButton##label
#: konnect##welcome##signoutButton##label
msgid "Sign out"
msgstr ""
#. From: konnect##chooseaccount##headline
#: konnect##chooseaccount##headline
#. From: translation##konnect##chooseaccount##headline
#: translation##konnect##chooseaccount##headline
msgid "Choose an account"
msgstr ""
#. From: konnect##chooseaccount##subHeader
#: konnect##chooseaccount##subHeader
#. From: translation##konnect##chooseaccount##subHeader
#: translation##konnect##chooseaccount##subHeader
msgid "to sign in"
msgstr ""
#. From: konnect##chooseaccount##useOther##persona##label
#: konnect##chooseaccount##useOther##persona##label
msgid "?"
msgstr ""
#. From: konnect##chooseaccount##useOther##label
#: konnect##chooseaccount##useOther##label
#. From: translation##konnect##chooseaccount##useOther##label
#: translation##konnect##chooseaccount##useOther##label
msgid "Use another account"
msgstr ""
#. From: konnect##consent##headline
#: konnect##consent##headline
msgid "Hi {{displayName}}"
#. From: translation##konnect##chooseaccount##useOther##persona##label
#: translation##konnect##chooseaccount##useOther##persona##label
msgid "?"
msgstr ""
#. From: konnect##consent##message
#: konnect##consent##message
msgid "<0><0><0></0></0></0> wants to"
msgstr ""
#. From: konnect##consent##tooltip##client
#: konnect##consent##tooltip##client
msgid "Clicking \"Allow\" will redirect you to: {{redirectURI}}"
msgstr ""
#. From: konnect##consent##question
#: konnect##consent##question
msgid "Allow <1><0></0></1> to do this?"
msgstr ""
#. From: konnect##consent##consequence
#: konnect##consent##consequence
msgid "By clicking Allow, you allow this app to use your information."
msgstr ""
#. From: konnect##consent##cancelButton##label
#: konnect##consent##cancelButton##label
msgid "Cancel"
msgstr ""
#. From: konnect##consent##allowButton##label
#: konnect##consent##allowButton##label
#. From: translation##konnect##consent##allowButton##label
#: translation##konnect##consent##allowButton##label
msgid "Allow"
msgstr ""
#. From: konnect##welcome##headline
#: konnect##welcome##headline
msgid "Welcome {{displayName}}"
#. From: translation##konnect##consent##cancelButton##label
#: translation##konnect##consent##cancelButton##label
msgid "Cancel"
msgstr ""
#. From: konnect##welcome##message
#: konnect##welcome##message
msgid "You are signed in - awesome!"
#. From: translation##konnect##consent##consequence
#: translation##konnect##consent##consequence
msgid "By clicking Allow, you allow this app to use your information."
msgstr ""
#. From: konnect##error##login##validate##missingUsername
#: konnect##error##login##validate##missingUsername
msgid "Enter a valid value."
#. From: translation##konnect##consent##headline
#: translation##konnect##consent##headline
msgid "Hi {{displayName}}"
msgstr ""
#. From: konnect##error##login##validate##missingPassword
#: konnect##error##login##validate##missingPassword
msgid "Enter your password."
#. From: translation##konnect##consent##message
#: translation##konnect##consent##message
msgid "<0><0><0></0></0></0> wants to"
msgstr ""
#. From: konnect##error##login##failed
#: konnect##error##login##failed
msgid "Logon failed. Please verify your credentials and try again."
#. From: translation##konnect##consent##question
#: translation##konnect##consent##question
msgid "Allow <1><0></0></1> to do this?"
msgstr ""
#. From: konnect##error##http##networkError
#: konnect##error##http##networkError
#. From: translation##konnect##consent##tooltip##client
#: translation##konnect##consent##tooltip##client
msgid "Clicking \"Allow\" will redirect you to: {{redirectURI}}"
msgstr ""
#. From: translation##konnect##error##http##networkError
#: translation##konnect##error##http##networkError
msgid "Network error. Please check your connection and try again."
msgstr ""
#. From: konnect##error##http##unexpectedResponseStatus
#: konnect##error##http##unexpectedResponseStatus
#. From: translation##konnect##error##http##unexpectedResponseState
#: translation##konnect##error##http##unexpectedResponseState
msgid "Unexpected response state: {{state}}"
msgstr ""
#. From: translation##konnect##error##http##unexpectedResponseStatus
#: translation##konnect##error##http##unexpectedResponseStatus
msgid "Unexpected HTTP response: {{status}}. Please check your connection and try again."
msgstr ""
#. From: konnect##error##http##unexpectedResponseState
#: konnect##error##http##unexpectedResponseState
msgid "Unexpected response state: {{state}}"
#. From: translation##konnect##error##login##failed
#: translation##konnect##error##login##failed
msgid "Logon failed. Please verify your credentials and try again."
msgstr ""
#. From: translation##konnect##error##login##validate##missingPassword
#: translation##konnect##error##login##validate##missingPassword
msgid "Enter your password."
msgstr ""
#. From: translation##konnect##error##login##validate##missingUsername
#: translation##konnect##error##login##validate##missingUsername
msgid "Enter a valid value."
msgstr ""
#. From: translation##konnect##footer##slogan
#: translation##konnect##footer##slogan
msgid "<strong>OpenCloud</strong> - excellent file sharing"
msgstr ""
#. From: translation##konnect##goodbye##confirm##headline
#: translation##konnect##goodbye##confirm##headline
msgid "Hello {{displayName}}"
msgstr ""
#. From: translation##konnect##goodbye##confirm##subHeader
#: translation##konnect##goodbye##confirm##subHeader
msgid "please confirm sign out"
msgstr ""
#. From: translation##konnect##goodbye##headline
#: translation##konnect##goodbye##headline
msgid "Goodbye"
msgstr ""
#. From: translation##konnect##goodbye##message##close
#: translation##konnect##goodbye##message##close
msgid "You can close this window now."
msgstr ""
#. From: translation##konnect##goodbye##message##confirm
#: translation##konnect##goodbye##message##confirm
msgid "Press the button below, to sign out from your account now."
msgstr ""
#. From: translation##konnect##goodbye##signoutButton##label
#. translation##konnect##welcome##signoutButton##label
#: translation##konnect##goodbye##signoutButton##label
#: translation##konnect##welcome##signoutButton##label
msgid "Sign out"
msgstr ""
#. From: translation##konnect##goodbye##subHeader
#: translation##konnect##goodbye##subHeader
msgid "you have been signed out from your account"
msgstr ""
#. From: translation##konnect##loading##error##headline
#: translation##konnect##loading##error##headline
msgid "Failed to connect to server"
msgstr ""
#. From: translation##konnect##login##headline
#: translation##konnect##login##headline
msgid "Sign in"
msgstr ""
#. From: translation##konnect##login##nextButton##label
#: translation##konnect##login##nextButton##label
msgid "Log in"
msgstr ""
#. From: translation##konnect##login##passwordField##label
#: translation##konnect##login##passwordField##label
msgid "Password"
msgstr ""
#. From: translation##konnect##login##retryButton##label
#: translation##konnect##login##retryButton##label
msgid "Retry"
msgstr ""
#. From: translation##konnect##login##usernameField##label
#: translation##konnect##login##usernameField##label
msgid "Username"
msgstr ""
#. From: translation##konnect##scopeDescription##aliasBasic
#: translation##konnect##scopeDescription##aliasBasic
msgid "Access your basic account information"
msgstr ""
#. From: translation##konnect##scopeDescription##offlineAccess
#: translation##konnect##scopeDescription##offlineAccess
msgid "Keep the allowed access persistently and forever"
msgstr ""
#. From: translation##konnect##scopeDescription##scope
#: translation##konnect##scopeDescription##scope
msgid "Scope: {{scope}}"
msgstr ""
#. From: translation##konnect##welcome##headline
#: translation##konnect##welcome##headline
msgid "Welcome {{displayName}}"
msgstr ""
#. From: translation##konnect##welcome##message
#: translation##konnect##welcome##message
msgid "You are signed in - awesome!"
msgstr ""
+2 -12
View File
@@ -55,11 +55,6 @@ msgstr ""
msgid "Clicking \"Allow\" will redirect you to: {{redirectURI}}"
msgstr ""
#. From: konnect##login##usernameField##placeholder##email
#: konnect##login##usernameField##placeholder##email
msgid "Email"
msgstr ""
#. From: konnect##error##login##validate##missingUsername
#: konnect##error##login##validate##missingUsername
msgid "Enter a valid value."
@@ -90,11 +85,6 @@ msgstr ""
msgid "Hi {{displayName}}"
msgstr ""
#. From: konnect##login##usernameField##placeholder##identity
#: konnect##login##usernameField##placeholder##identity
msgid "Identity"
msgstr ""
#. From: konnect##scopeDescription##offlineAccess
#: konnect##scopeDescription##offlineAccess
msgid "Keep the allowed access persistently and forever"
@@ -162,8 +152,8 @@ msgstr ""
msgid "Use another account"
msgstr ""
#. From: konnect##login##usernameField##placeholder##username
#: konnect##login##usernameField##placeholder##username
#. From: konnect##login##usernameField##label
#: konnect##login##usernameField##label
msgid "Username"
msgstr ""
+10 -9
View File
@@ -30,19 +30,19 @@
},
"dependencies": {
"@material-ui/core": "^4.12.4",
"@types/node": "^25.7.0",
"@types/react": "^17.0.91",
"@types/node": "^25.9.5",
"@types/react": "^17.0.93",
"@types/react-dom": "^17.0.26",
"@types/react-redux": "^7.1.34",
"@types/redux-logger": "^3.0.13",
"axios": "^1.18.1",
"i18next": "^26.3.0",
"axios": "^1.19.0",
"i18next": "^26.3.6",
"i18next-browser-languagedetector": "^8.2.1",
"i18next-resources-to-backend": "^1.2.1",
"query-string": "^9.3.1",
"i18next-resources-to-backend": "^1.2.3",
"query-string": "^9.4.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-i18next": "^17.0.8",
"react-i18next": "^17.0.11",
"react-redux": "^8.1.3",
"react-router": "^5.3.4",
"react-router-dom": "5.2.1",
@@ -61,9 +61,10 @@
"css-minimizer-webpack-plugin": "^8.0.0",
"dotenv": "17.4.2",
"dotenv-expand": "^13.0.0",
"html-webpack-plugin": "^5.6.7",
"gettext-parser": "^9.1.1",
"html-webpack-plugin": "^5.6.8",
"i18next-cli": "^1.67.3",
"i18next-conv": "^17.0.0",
"i18next-parser": "^9.4.0",
"license-checker-rseidelsohn": "5.0.1",
"mini-css-extract-plugin": "2.9.2",
"pnp-webpack-plugin": "1.7.0",
+1466 -1803
View File
File diff suppressed because it is too large. Load diff
+9 -5
View File
@@ -20,13 +20,17 @@ supportedArchitectures:
- musl
overrides:
fast-uri: ">=3.1.2"
undici: ">=7.28.0"
postcss: ">=8.5.10"
brace-expansion: ">=5.0.7"
fast-uri: ">=3.1.4"
js-yaml: ">=4.3.0"
postcss: ">=8.5.18"
"serialize-javascript@<7.0.3": ">=7.0.3"
shell-quote: ">=1.8.4"
shell-quote: ">=1.9.0"
svgo: ">=4.0.2"
undici: ">=7.28.0"
"@babel/plugin-transform-modules-systemjs": ">=7.29.4"
"@xmldom/xmldom": ">=0.8.13"
"@xmldom/xmldom": "^0.8.13"
allowBuilds:
'@swc/core': false
esbuild: true
Loaded 100 of 796 files, more files were not shown because too many files have changed in this diff. Show more