Commit graph

1863 commits

Author SHA1 Message Date
Côme Chilliet
4427050f84 fix(encryption): Correctly handle file opening and copying failures
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-07-03 15:19:34 +02:00
Ferdinand Thiessen
5981b7eb51
chore: apply new CSFixer rules
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>

# Conflicts:
#	apps/settings/lib/SetupChecks/PhpOpcacheSetup.php
2025-07-01 16:26:50 +02:00
Robin Appelman
6d0119bf8d
fix: handle dav external storage roots with spaces
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-06-30 18:01:01 +02:00
Daniel Kesselberg
de54bdb06b
fix: handle ambiguous IResponse.getBody return types
Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
2025-06-30 11:50:11 +02:00
Robin Appelman
2e1c316582 fix: remove double cache write in ObjectStoreStorage::touch
the file_put_contents already puts all of those values into the cache

Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-06-18 22:22:51 +02:00
Kent Delante
ea98e4b3f5
Merge pull request #53419 from nextcloud/leftybournes/fix/object_storage_large_uploads
fix(s3): retry failed multipart uploads with decreased concurrency
2025-06-18 21:07:06 +08:00
Ferdinand Thiessen
35a27b5fd5
fix(FilenameValidator): use _ as default replacement for invalid chars
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-06-18 09:44:57 +02:00
Daniel Calviño Sánchez
d7ae952dc8 fix(ObjectStore): Make S3 "connect_timeout" option configurable
The hardcoded connection timeout of 5 seconds may not be enough in some
cases, so now it is got from the ObjectStore arguments in Nextcloud
configuration, falling back to 5 if not set.

The connection timeout is set in seconds, but decimal precision can be
used for subsecond accuracy (for example, 4.2 for 4200 milliseconds).

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
2025-06-16 20:17:50 +02:00
Kent Delante
06b5ce5859 fix(s3): retry failed multipart uploads with decreased concurrency
Signed-off-by: Kent Delante <kent.delante@proton.me>
2025-06-10 17:39:59 +08:00
Joas Schilling
f230abeef8
fix: Run cleanByMoundId query on all shards
Signed-off-by: Joas Schilling <coding@schilljs.com>
2025-06-06 14:36:34 +02:00
skjnldsv
e41e8de0e2 fix(dav): file drop nickname
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
2025-06-05 09:09:17 +02:00
Louis
f4cb78b905
Merge pull request #52242 from nextcloud/artonge/fix/copy_subfolders_s3 2025-06-02 11:55:54 +02:00
Robin Appelman
5b3f4cd8fe perf: set the folder size in the same query as we create it
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-05-28 15:52:00 +02:00
Louis Chemineau
1f8b823992 fix(S3): Use original folder size during copy
This prevent having copied folders with a wrongly set size of 0KB.

- Fix https://github.com/nextcloud/server/issues/51916

Signed-off-by: Louis Chemineau <louis@chmn.me>
2025-05-28 15:52:00 +02:00
Robin Appelman
7599162c7b feat: move primary object store configuration to a single place
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-05-28 15:32:31 +02:00
Jonas
c952570e67
fix(node): emit hooks on Node::copy()
When calling `Files\Node\Node::copy()`, `Files\View::copy()` gets called,
but `Files\View::fakeRoot` is empty so the hooks are not emitted if no
path is given to `Files\View::shouldEmitHooks()`.

This results in node-related events like `NodeCopiedEvent` not being
fired when copying files via `Files\Node\Node::copy()`.

`Files\View::shouldEmitHooks()` is given a path as parameter in almost
all places except when called from the `copy()` function. This commit
changes it and passes the copy target path.

Fixes: nextcloud/collectives#1756

Signed-off-by: Jonas <jonas@freesources.org>
2025-05-27 12:14:14 +02:00
Ferdinand Thiessen
e143921896
feat(IUser): add getQuotaBytes method to get machine readable quota
Proper replacement for deprecated `OC_Util::getUserQuota`.
Also we still use this in some cases we can now replace, moreover it
just makes sense to have a machine readable format in the API instead of
only the human readable format which is less precise.
Alings also with `getQuota` of the quota storage, which already returned
the machine readable format.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-05-22 12:50:38 +02:00
provokateurin
ecfa58d3d7
fix(SetupManager): Include home and root providers when registering mounts
Signed-off-by: provokateurin <kate@provokateurin.de>
2025-05-20 09:46:53 +02:00
Elizabeth Danzberger
5c7216f3fd
feat: only load template fields when requested
Signed-off-by: Elizabeth Danzberger <lizzy7128@tutanota.de>
2025-05-19 17:51:25 -04:00
provokateurin
6818aa9b12
feat(UserMountCache): Emit events for added, removed and updated mounts
Signed-off-by: provokateurin <kate@provokateurin.de>
2025-05-19 13:54:51 +02:00
Ferdinand Thiessen
01db539d0a
chore: move streamCopy implementation from OC_Helper to OCP\Files
The function was already there but called the legacy version.
So moved the implementation and migrated all usages of it.
Sadly the interface was slightly different so adjusted it to be
compatible with both legacy and the OCP one.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-05-16 13:03:05 +02:00
Robin Appelman
5329c373cc fix: improve error message when cache rename source can't be found
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-05-15 15:06:55 +02:00
John Molakvoæ
cac44fd924
Merge pull request #52822 from nextcloud/feat/mime-names 2025-05-15 11:41:12 +02:00
John Molakvoæ (skjnldsv)
24bc1d606e
feat(core): add human readable mimes
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
2025-05-14 22:55:06 +02:00
John Molakvoæ
b3b63020c9
Merge pull request #52812 from nextcloud/chore/oc-helper-rmdirr 2025-05-14 21:53:47 +02:00
Côme Chilliet
2cd491f491
Merge pull request #48560 from nextcloud/fix/migrate-encryption-away-from-hooks
feat(encryption): Migrate from hooks to events
2025-05-14 19:25:51 +02:00
Andy Scherzinger
14f79829f3
Merge pull request #52775 from nextcloud/nested-jail-root
fix unjailedroot of nested jails if there are other wrappers in between
2025-05-14 17:36:55 +02:00
Kate
bfa494f247
Merge pull request #52800 from nextcloud/debt/noid/simple-file-generic-exception 2025-05-14 15:25:41 +02:00
Ferdinand Thiessen
072d4e8cba
chore: move implementation from OC legacy to OCP\Files
- move implementation to the OCP variant that called the legacy before
- add the missing deprecation notice
- add missing parameter to align both signatures
- use OCP\Files where this method is still used

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-05-14 14:55:45 +02:00
Ferdinand Thiessen
85a6b0d0eb
chore: deprecate \OC_Helper::canExecute
replace this legacy method with just the IBinaryFinder

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-05-14 09:55:14 +02:00
Côme Chilliet
a86d917907 fix(encryption): Only prevent cache deletion if target is not object store in moveFromStorage
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-05-13 23:37:52 +02:00
Côme Chilliet
a79b5dea7c fix(encryption): Improve Update class and event listenening
to avoid back&forth between path and Node object

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-05-13 23:37:52 +02:00
Côme Chilliet
e6275f8759 fix: Preserve file id when moving from object store even if encryption wrapper is present
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-05-13 23:37:52 +02:00
Côme Chilliet
9bb0721d66 fix: Fix mtime preservation when moving a directory across storages with encryption registered
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-05-13 23:37:52 +02:00
Côme Chilliet
8779ae38a4 fix(encryption): Fix filesize for part files in Encryption wrapper
Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-05-13 23:37:52 +02:00
Daniel Kesselberg
866063c198
fix: annotate possible exceptions
File.getContent can throw a GenericFileException since https://github.com/nextcloud/server/pull/37943.

Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
2025-05-13 22:27:19 +02:00
Robin Appelman
1e72620169 fix: fix unjailedroot of nested jails if there are other wrappers in between
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-05-13 18:29:00 +02:00
Robin Appelman
0001c22668 test: add test for nested cache jail unjailedroot
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-05-13 18:29:00 +02:00
Ferdinand Thiessen
6cf1870322
feat(FilenameValidator): allow to sanitize filenames
Share the filename sanitizing with the OCP filename validator.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-05-13 14:14:17 +02:00
Côme Chilliet
2f1c74d43f
Merge pull request #51920 from nextcloud/newfolder-race-improvements
fix: improve handling of newFolder race condition handling
2025-05-13 09:16:54 +02:00
Robin Appelman
768b101a9d
Merge pull request #52706 from nextcloud/info-file-more-encryption-checks
feat: add more encryption checks to info:file
2025-05-12 13:17:26 +02:00
Robin Appelman
e6bdfcd8ed
Merge pull request #52665 from nextcloud/mountpoint-mkdir-quota
fix: create mountpoint folder even if the user has a quota of 0
2025-05-12 13:17:02 +02:00
Robin Appelman
b0b8159d6a
fix: throw a better error if we can't get the encrypted header size
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-05-09 22:33:45 +02:00
Robin Appelman
d9c53ef748
feat: add more encryption checks to info:file
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-05-09 16:35:31 +02:00
Robin Appelman
99364adc1c
fix: improve handling of newFolder race condition handling
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-05-08 15:19:40 +02:00
Robin Appelman
cd75876c1e fix: create mountpoint folder even if the user has a quota of 0
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-05-08 15:15:36 +02:00
Kate
87bad33496
Merge pull request #52047 from nextcloud/sub-mount-filter-no-storage 2025-05-06 15:25:23 +02:00
Kate
c1a9dfd993
Merge pull request #52441 from nextcloud/scan-locked-error 2025-05-06 15:23:16 +02:00
Kate
9592390070
Merge pull request #51779 from nextcloud/object-store-filename 2025-05-06 15:21:01 +02:00
Louis Chemineau
5c73f2c37f
fix: Forward 'extra' argument when optimizing query
This allows DAV SEARCH queries containing optimizable comparisons on files metadata like:

```xml
				<d:or>
					<d:eq>
						<d:prop>
							<nc:metadata-photos-place />
						</d:prop>
						<d:literal>La Valette-du-Var</d:literal>
					</d:eq>
					<d:eq>
						<d:prop>
							<nc:metadata-photos-place />
						</d:prop>
						<d:literal>Évenos</d:literal>
					</d:eq>
				</d:or>
```

Signed-off-by: Louis Chemineau <louis@chmn.me>
2025-04-29 18:17:23 +02:00
Robin Appelman
bb4cf2830a
fix: better error message when trying to scan a folder that is already being scanned
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-04-25 18:40:03 +02:00
Anna Larch
49baa914cf fix(objectstorage): add retry attempts to S3 connection
Signed-off-by: Anna Larch <anna@nextcloud.com>
2025-04-23 12:15:06 +02:00
Louis
f8391e60ce
Merge pull request #51020 from nextcloud/artonge/fix/transfer_ownership 2025-04-14 16:14:45 +02:00
Robin Appelman
c1dbc27fd6
fix: don't construct storage when checking if a sub-mount is applicable
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-04-08 18:21:41 +02:00
Julius Knorr
7ff80cc016
fix: Catch old cached paths and fetch the new one
Signed-off-by: Julius Knorr <jus@bitgrid.net>
2025-04-08 09:17:35 +02:00
Julius Knorr
7fa3f89ef9
fix: Proper order for checking path prefix for getting file by id from cache
Signed-off-by: Julius Knorr <jus@bitgrid.net>
2025-04-07 20:47:11 +02:00
Ferdinand Thiessen
3a09acebd2
fix(cache): always require updates if mtime is null
- Resolves https://github.com/nextcloud/server/issues/51941

Due to strong typings we introduced the parameter needs to be an
integer. Previously it was `null` which was equal to `0`.
So if there is no storage mtime we need to update the cache.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-04-04 13:41:32 +02:00
Robin Appelman
c3f06b370c
feat: add debug logging for adding/removing items from the user mounts cache
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-04-03 17:58:46 +02:00
Ferdinand Thiessen
97ad171d32
refactor(IMimeTypeDetector): use consistent capitalization
- use consistantly `mimeType` as it is called MIME type
- fix issues where implementation and interface had different parameter
  names (this is an issue since PHP has named parameters).

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-04-02 13:22:16 +02:00
Louis Chemineau
8fdf2a7eae fix: Transfer ownership with S3 as primary
When using S3 as primary storage, transferring ownership with the `--move` option fail with the following error:

`SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '8-45b963397aa40d4a0063e0d85e4fe7a1' for key 'fs_storage_path_hash'`

The `--move` option moves the entire home folder from one account to another.
The error means that the move failed because the destination folder already exist in `oc_filecache`.

- With S3 as primary storage, folders only exists as entries in `oc_filecache`.
- With S3 as primary storage, `moveFromStorage(...)` only moves the cache entry, as nothing needs to be moved on disk. This cache move does not delete potentially pre-existing destination folder.
- With Local storage, `moveFromStorage(...)` calls `rename(...)` which delete pre-existing folder.

- `transfer(...)`: 687a4d9ac7/apps/files/lib/Service/OwnershipTransferService.php (L112)
- `oneTimeUserSetup(...)`: 687a4d9ac7/lib/private/Files/SetupManager.php (L261-L262)
- `mkdir(...)`: 687a4d9ac7/lib/private/Files/ObjectStore/ObjectStoreStorage.php (L91-L135)
- `moveFromStorage(...)`: 687a4d9ac7/lib/private/Files/ObjectStore/ObjectStoreStorage.php (L635-L636)

Delete pre-existing folder in `moveFromStorage(...)`

Signed-off-by: Louis Chemineau <louis@chmn.me>
2025-04-01 13:53:56 +02:00
Robin Appelman
8aae332622
feat: store original storage id and path in object store metadata
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-03-31 15:10:58 +02:00
Robin Appelman
94114b99f7
feat: more generic way of passing metadata to object storage backends for new objects
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-03-31 14:55:18 +02:00
Robin Appelman
fcde776683
feat: add command to list objects
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-03-31 14:30:40 +02:00
Robin Appelman
c3bc362f48
feat: add command to get object metadata
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-03-31 14:30:40 +02:00
Robin Appelman
2e9222a29a
feat: add getParentId to ICacheEntry
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-03-28 16:47:07 +01:00
Ferdinand Thiessen
254dd85664
fix(IFilenameValidator): correctly handle case insensitivity
- forbidden names and forbidden base names are case **insensitive**
  so we need to check all lowercase here.
- add test that config value is also read case insensitive.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-03-21 01:00:58 +01:00
Ferdinand Thiessen
d5efd17942
fix(IMimeTypeDetector): use correct return type
In PHP array keys that are integers are always kept as integer,
meaning the type of the key of `$a = ["1" => "one"]` will be integer not
string.
While are hacks to circumvent this (case std object with string keys to
an assoc. array) those hacks are performance wise awefull and also not
needed as in PHP you can always access that element with `$a[1]` or
`$a["1"]`.

So TL;DR;: do not lie about return types.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-03-18 15:34:28 +01:00
Git'Fellow
dda2148f6f
Merge pull request #51333 from nextcloud/filePointerCheck
fix(files): Make sure file pointer exists
2025-03-17 17:04:24 +01:00
Robin Appelman
8edca98e8e
fix: fix getNodeFromCacheEntryAndMount using relative path
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-03-10 18:19:20 +01:00
Git'Fellow
4d52b185af
fix(files): Make sure file pointer exists
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
2025-03-07 19:16:30 +01:00
Andy Scherzinger
fdb246c1cf
Merge pull request #50702 from Institutional-Investment-Group/feat/support-aws-session-token9
feat(object_store): Add support for session token (STS) in AWS credentials
2025-03-05 17:40:05 +01:00
Marcel Müller
3391279068 fix: No IFactory in constructor
Signed-off-by: Marcel Müller <marcel-mueller@gmx.de>
2025-03-05 11:04:55 +01:00
Joas Schilling
0522b0373e
fix(files): Don't do session related work in the constructor of the View
Signed-off-by: Joas Schilling <coding@schilljs.com>
2025-03-05 09:06:16 +01:00
Hector Manuel
12a92a2e8b
Merge branch 'master' into feat/support-aws-session-token 2025-03-04 18:27:54 +01:00
Benjamin Gaussorgues
9bdee76535
perf(files): faster query to fetch incomplete directories
Signed-off-by: Benjamin Gaussorgues <benjamin.gaussorgues@nextcloud.com>
2025-02-13 10:11:02 +01:00
Daniel
90a1aea574
Merge pull request #50498 from nextcloud/bug/48678/restore-dav-error-response-2
Don't rethrow a type error
2025-02-11 17:28:44 +01:00
Robin Appelman
9e1ae74a1c
fix: make locked exception path relative to the view
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-02-11 14:38:27 +01:00
Robin Appelman
2786ca579a
fix: don't use cached root info from shared cache if the watcher has detected an update
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-02-06 19:41:43 +01:00
Hector Valcarcel
6b4c859a41 feat(object_store): Add support for session token in AWS credentials
- Pass session token, either null or with value, to the AWS Credentials constructor

Signed-off-by: Hector Valcarcel <hmvalcarcel@gmail.com>
2025-02-06 16:24:19 +01:00
John Molakvoæ
1e30936b78
fix: psalm and OCP @since declarations
Co-authored-by: Ferdinand Thiessen <opensource@fthiessen.de>
Signed-off-by: John Molakvoæ <skjnldsv@users.noreply.github.com>
2025-02-06 15:21:18 +01:00
skjnldsv
6baafd82b6 fix: make sure we process mime extensions as string
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
2025-02-05 12:35:41 +01:00
Richard Steinmetz
f1c025dfd3
fix(s3): treat empty sse_c_key as not set
Co-authored-by: Christian Becker <christian@dabecka.de>
Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud>
2025-01-28 22:59:59 +01:00
Ferdinand Thiessen
b48ee2e924
fix: Harden files scanner for invalid null access
Co-authored-by: Ferdinand Thiessen <opensource@fthiessen.de>
Co-authored-by: Kate <26026535+provokateurin@users.noreply.github.com>
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-01-28 20:08:46 +01:00
Ferdinand Thiessen
f33e9a96ae
Merge pull request #50273 from nextcloud/artonge/fix/metadata_field_search
fix: Metadata field search
2025-01-25 10:43:59 +01:00
Louis Chemineau
a635710117
fix: Metadata field search
Signed-off-by: Louis Chemineau <louis@chmn.me>
2025-01-20 14:41:55 +01:00
Git'Fellow
dcde6d8d74
fix(TemplateManager): Remove warning message
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
2025-01-20 13:05:28 +01:00
John Molakvoæ
e5dceaf287
fix: php lint extra tab fix
Co-authored-by: Ferdinand Thiessen <opensource@fthiessen.de>
Signed-off-by: John Molakvoæ <skjnldsv@users.noreply.github.com>
2025-01-17 21:37:39 +01:00
skjnldsv
abd3cb60fc fix(files): more conversion tests and translate error messages
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
2025-01-17 18:22:58 +01:00
Elizabeth Danzberger
14976390ff
chore: remove unnecessary method
Signed-off-by: Elizabeth Danzberger <lizzy7128@tutanota.de>
2025-01-16 15:25:15 -05:00
Elizabeth Danzberger
f9adb006b0
fix: prevent missing target file extension
Signed-off-by: Elizabeth Danzberger <lizzy7128@tutanota.de>
2025-01-16 15:23:38 -05:00
skjnldsv
7cbcbdc051 fix(files): conversion api simplification and conflict check
Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
2025-01-16 18:35:40 +01:00
Elizabeth Danzberger
fdfeb7f265
feat(api): File conversion API
Signed-off-by: Elizabeth Danzberger <lizzy7128@tutanota.de>
2025-01-15 16:38:18 -05:00
Robin Appelman
f20c483513
fix: use proper way to get numeric storage id for mountpoint
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-01-13 17:59:17 +01:00
provokateurin
1e28657093
fix(PathHelper): Remove null bytes when normalizing path
Signed-off-by: provokateurin <kate@provokateurin.de>
2025-01-13 15:21:21 +01:00
Côme Chilliet
c9757586cd
Merge pull request #49903 from nextcloud/encryption-version-version
fix: restore updated encrypted version when copying versions
2025-01-07 16:42:04 +01:00
Robin Appelman
757076af29
fix: explicitly ignore nested mounts when transfering ownership
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-01-06 14:45:35 +01:00
Robin Appelman
d6418fcd99
fix: translate mount move error messages
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-01-03 15:36:38 +01:00
Robin Appelman
16d0363937
fix: improve checks for moving shares/storages into other mounts
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-01-03 15:36:32 +01:00
Robin Appelman
012a402cec fix: restore updated encrypted version when copying versions
Signed-off-by: Robin Appelman <robin@icewind.nl>
2025-01-03 15:21:01 +01:00
Robin Appelman
54a1ca0da0 fix: don't skip scanner users filesystem if they have a mountpoint at /<user>/files/
Signed-off-by: Robin Appelman <robin@icewind.nl>
2024-12-27 15:18:09 +01:00