diff --git a/lib/Share/Listener.php b/lib/Share/Listener.php index a59e9acf264..c0903798e5b 100644 --- a/lib/Share/Listener.php +++ b/lib/Share/Listener.php @@ -55,12 +55,25 @@ protected function overwriteShareTarget(BeforeShareCreatedEvent $event): void { // point under their own attachment folder. $ownerUid = $share->getShareOwner(); $relativePath = $share->getNode()->getName(); - if ($this->config->isConversationSubfoldersEnabled() && $ownerUid !== null) { + if ($share->getShareType() === IShare::TYPE_ROOM && $this->config->isConversationSubfoldersEnabled() && $ownerUid !== null) { $attachmentFolder = ltrim($this->config->getAttachmentFolder($ownerUid), '/'); $internalPath = $share->getNode()->getPath(); $prefix = '/' . $ownerUid . '/files/' . $attachmentFolder . '/'; if (str_starts_with($internalPath, $prefix)) { - $relativePath = substr($internalPath, strlen($prefix)); + $candidate = substr($internalPath, strlen($prefix)); + // Only keep the full relative path when the file sits inside a + // user subfolder (first segment is "-") inside the + // conversation subfolder (first segment is "-"). + // Other subdirectories (e.g. Recording//) are not part of + // the conversation subfolder hierarchy and must fall back to the + // flat filename so that recipients see the file at Talk/. + $segments = explode('/', $candidate, 3); + $potentialConversationFolder = $segments[0]; + $potentialUserFolder = $segments[1] ?? ''; + if (str_ends_with($potentialConversationFolder, '-' . $share->getSharedWith()) + && str_ends_with($potentialUserFolder, '-' . $share->getShareOwner())) { + $relativePath = $candidate; + } } } diff --git a/tests/integration/features/callapi/recording.feature b/tests/integration/features/callapi/recording.feature index 6cdfbf570c7..22a790a5095 100644 --- a/tests/integration/features/callapi/recording.feature +++ b/tests/integration/features/callapi/recording.feature @@ -495,6 +495,21 @@ Feature: callapi/recording | room1 | users | participant1 | participant1-displayname | record-audio | {file} | "IGNORE" | | room1 | users | participant1 | participant1-displayname | record-audio | {file} | "IGNORE" | | room1 | users | participant1 | participant1-displayname | record-audio | {file} | "IGNORE" | + Given user "participant2" exists + And user "participant1" adds user "participant2" to room "room1" with 200 (v4) + + # Check paths on the actual file system + When user "participant2" gets the DAV properties for "/" + Then the list of returned files for "participant2" is + | / | + | /Talk/ | + | /welcome.txt | + When user "participant2" gets the DAV properties for "/Talk" + Then the list of returned files for "participant2" is + | /Talk/ | + | /Talk/join_call%20-%20summary.md | + | /Talk/join_call.md | + | /Talk/join_call.ogg | Scenario: Store recording with success but fail to transcript Given Fake summary task provider is enabled