From b5bc12ccb45606f2bf3fb86bdba132bb90813d80 Mon Sep 17 00:00:00 2001 From: kristian-zendato Date: Mon, 14 Sep 2026 11:38:02 +0000 Subject: [PATCH 1/2] fix(sharing): Use link_defaultExpDays for default expiration in web UI Signed-off-by: kristian-zendato --- apps/files_sharing/lib/Capabilities.php | 8 +++++++- apps/files_sharing/src/services/ConfigService.ts | 16 +++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/lib/Capabilities.php b/apps/files_sharing/lib/Capabilities.php index 9352213489cd8..7f0e4e9133a8a 100644 --- a/apps/files_sharing/lib/Capabilities.php +++ b/apps/files_sharing/lib/Capabilities.php @@ -126,7 +126,13 @@ public function getCapabilities() { $public['multiple_links'] = true; $public['expire_date']['enabled'] = $this->shareManager->shareApiLinkDefaultExpireDate(); if ($public['expire_date']['enabled']) { - $public['expire_date']['days'] = $this->shareManager->shareApiLinkDefaultExpireDays(); + $maxDays = $this->shareManager->shareApiLinkDefaultExpireDays(); + $defaultDays = (int)$this->config->getAppValue('core', 'link_defaultExpDays', (string)$maxDays); + if ($defaultDays > $maxDays) { + $defaultDays = $maxDays; + } + $public['expire_date']['days'] = $maxDays; + $public['expire_date']['default_days'] = $defaultDays; $public['expire_date']['enforced'] = $this->shareManager->shareApiLinkDefaultExpireDateEnforced(); } diff --git a/apps/files_sharing/src/services/ConfigService.ts b/apps/files_sharing/src/services/ConfigService.ts index bf47a23c3fcd4..2b7689224acbd 100644 --- a/apps/files_sharing/src/services/ConfigService.ts +++ b/apps/files_sharing/src/services/ConfigService.ts @@ -141,8 +141,11 @@ export default class Config { * Get the default link share expiration date */ get defaultExpirationDate(): Date | null { - if (this.isDefaultExpireDateEnabled && this.defaultExpireDate !== null) { - return new Date(new Date().setDate(new Date().getDate() + this.defaultExpireDate)) + if (this.isDefaultExpireDateEnabled) { + const days = this.linkDefaultExpDays ?? this.defaultExpireDate + if (days !== null) { + return new Date(new Date().setDate(new Date().getDate() + days)) + } } return null } @@ -254,12 +257,19 @@ export default class Config { } /** - * Get the default days to link shares expiration + * Get the maximum days to link shares expiration */ get defaultExpireDate(): number | null { return window.OC.appConfig.core.defaultExpireDate } + /** + * Get the default days to link shares expiration + */ + get linkDefaultExpDays(): number | null { + return this._capabilities?.files_sharing?.public?.expire_date?.default_days ?? null + } + /** * Get the default days to internal shares expiration */ From 14939c55e3a546e58f03dad6666adad583d56f43 Mon Sep 17 00:00:00 2001 From: kristian-zendato Date: Mon, 14 Sep 2026 11:52:04 +0000 Subject: [PATCH 2/2] fix(sharing): Separate max and default expiration dates in link share UI Signed-off-by: kristian-zendato --- apps/files_sharing/lib/Capabilities.php | 1 + apps/files_sharing/openapi.json | 4 ++++ apps/files_sharing/src/mixins/SharesMixin.js | 2 +- .../src/services/ConfigService.ts | 11 +++++++++ apps/files_sharing/tests/CapabilitiesTest.php | 24 ++++++++++++++++++- build/psalm-baseline.xml | 1 + openapi.json | 4 ++++ 7 files changed, 45 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/lib/Capabilities.php b/apps/files_sharing/lib/Capabilities.php index 7f0e4e9133a8a..c2bca6a835d9b 100644 --- a/apps/files_sharing/lib/Capabilities.php +++ b/apps/files_sharing/lib/Capabilities.php @@ -47,6 +47,7 @@ public function __construct( * expire_date?: array{ * enabled: bool, * days?: int, + * default_days?: int, * enforced?: bool, * }, * expire_date_internal?: array{ diff --git a/apps/files_sharing/openapi.json b/apps/files_sharing/openapi.json index 08972084b7974..f86e92e5fbf44 100644 --- a/apps/files_sharing/openapi.json +++ b/apps/files_sharing/openapi.json @@ -80,6 +80,10 @@ "type": "integer", "format": "int64" }, + "default_days": { + "type": "integer", + "format": "int64" + }, "enforced": { "type": "boolean" } diff --git a/apps/files_sharing/src/mixins/SharesMixin.js b/apps/files_sharing/src/mixins/SharesMixin.js index 40b46033500d3..1226e5818bbc9 100644 --- a/apps/files_sharing/src/mixins/SharesMixin.js +++ b/apps/files_sharing/src/mixins/SharesMixin.js @@ -151,7 +151,7 @@ export default { maxExpirationDateEnforced() { if (this.isExpiryDateEnforced) { if (this.isPublicShare) { - return this.config.defaultExpirationDate + return this.config.maxExpirationDate } if (this.isRemoteShare) { return this.config.defaultRemoteExpirationDateString diff --git a/apps/files_sharing/src/services/ConfigService.ts b/apps/files_sharing/src/services/ConfigService.ts index 2b7689224acbd..2a8d04e525445 100644 --- a/apps/files_sharing/src/services/ConfigService.ts +++ b/apps/files_sharing/src/services/ConfigService.ts @@ -35,6 +35,7 @@ type FileSharingCapabilities = { expire_date: { enabled: boolean days: number + default_days: number enforced: boolean } multiple_links: boolean @@ -150,6 +151,16 @@ export default class Config { return null } + /** + * Get the maximum link share expiration date + */ + get maxExpirationDate(): Date | null { + if (this.isDefaultExpireDateEnabled && this.defaultExpireDate !== null) { + return new Date(new Date().setDate(new Date().getDate() + this.defaultExpireDate)) + } + return null + } + /** * Get the default internal expiration date */ diff --git a/apps/files_sharing/tests/CapabilitiesTest.php b/apps/files_sharing/tests/CapabilitiesTest.php index 99b1712e38e9f..c8bf8006bd228 100644 --- a/apps/files_sharing/tests/CapabilitiesTest.php +++ b/apps/files_sharing/tests/CapabilitiesTest.php @@ -191,6 +191,7 @@ public function testLinkExpireDate(): void { ['core', 'shareapi_allow_links', 'yes', 'yes'], ['core', 'shareapi_expire_after_n_days', '7', '7'], ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''], + ['core', 'link_defaultExpDays', '7', '7'], ]; $typedMap = [ @@ -202,7 +203,28 @@ public function testLinkExpireDate(): void { $this->assertArrayHasKey('expire_date', $result['public']); $this->assertIsArray($result['public']['expire_date']); $this->assertTrue($result['public']['expire_date']['enabled']); - $this->assertArrayHasKey('days', $result['public']['expire_date']); + $this->assertSame(7, $result['public']['expire_date']['days']); + $this->assertSame(7, $result['public']['expire_date']['default_days']); + $this->assertFalse($result['public']['expire_date']['enforced']); + } + + public function testLinkExpireDateWithDefaultDays(): void { + $map = [ + ['core', 'shareapi_enabled', 'yes', 'yes'], + ['core', 'shareapi_allow_links', 'yes', 'yes'], + ['core', 'shareapi_expire_after_n_days', '7', '7'], + ['core', 'shareapi_enforce_links_password_excluded_groups', '', ''], + ['core', 'link_defaultExpDays', '7', '3'], + ]; + + $typedMap = [ + ['core', 'shareapi_default_expire_date', true], + ['core', 'shareapi_enforce_expire_date', false], + ]; + + $result = $this->getResults($map, $typedMap); + $this->assertSame(7, $result['public']['expire_date']['days']); + $this->assertSame(3, $result['public']['expire_date']['default_days']); $this->assertFalse($result['public']['expire_date']['enforced']); } diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml index c06c6df854fc4..c03231ff5803a 100644 --- a/build/psalm-baseline.xml +++ b/build/psalm-baseline.xml @@ -1600,6 +1600,7 @@ + diff --git a/openapi.json b/openapi.json index 1f862fa904b68..843e75029165d 100644 --- a/openapi.json +++ b/openapi.json @@ -2332,6 +2332,10 @@ "type": "integer", "format": "int64" }, + "default_days": { + "type": "integer", + "format": "int64" + }, "enforced": { "type": "boolean" }