From 4b4c1440c8d37967d36b1670e99de81575fed27c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 Nov 2024 07:51:26 +0100 Subject: [PATCH 01/19] fix(openapi): Remove empty array on recording backend responses Signed-off-by: Joas Schilling --- lib/Controller/RecordingController.php | 38 +++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/Controller/RecordingController.php b/lib/Controller/RecordingController.php index 665ba5faa0f..7b7d4bc7c28 100644 --- a/lib/Controller/RecordingController.php +++ b/lib/Controller/RecordingController.php @@ -54,7 +54,7 @@ public function __construct( * * @param int $serverId ID of the server * @psalm-param non-negative-int $serverId - * @return DataResponse|DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse|DataResponse * * 200: Welcome message returned * 404: Recording server not found or not configured @@ -63,7 +63,7 @@ public function __construct( public function getWelcomeMessage(int $serverId): DataResponse { $recordingServers = $this->talkConfig->getRecordingServers(); if (empty($recordingServers) || !isset($recordingServers[$serverId])) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(null, Http::STATUS_NOT_FOUND); } $url = rtrim($recordingServers[$serverId]['server'], '/'); @@ -151,7 +151,7 @@ protected function getInputStream(): string { /** * Update the recording status as a backend * - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse * * 200: Recording status updated successfully * 400: Updating recording status is not possible @@ -196,7 +196,7 @@ public function backend(): DataResponse { } /** - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse */ private function backendStarted(array $started): DataResponse { $token = $started['token']; @@ -243,11 +243,11 @@ private function backendStarted(array $started): DataResponse { $this->roomService->setCallRecording($room, $status, $participant); - return new DataResponse(); + return new DataResponse(null); } /** - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse */ private function backendStopped(array $stopped): DataResponse { $token = $stopped['token']; @@ -284,11 +284,11 @@ private function backendStopped(array $stopped): DataResponse { $this->roomService->setCallRecording($room, Room::RECORDING_NONE, $participant); - return new DataResponse(); + return new DataResponse(null); } /** - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse */ private function backendFailed(array $failed): DataResponse { $token = $failed['token']; @@ -311,7 +311,7 @@ private function backendFailed(array $failed): DataResponse { $this->roomService->setCallRecording($room, Room::RECORDING_FAILED); - return new DataResponse(); + return new DataResponse(null); } /** @@ -319,7 +319,7 @@ private function backendFailed(array $failed): DataResponse { * * @param int $status Type of the recording * @psalm-param Room::RECORDING_* $status - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse * * 200: Recording started successfully * 400: Starting recording is not possible @@ -332,13 +332,13 @@ public function start(int $status): DataResponse { } catch (InvalidArgumentException $e) { return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST); } - return new DataResponse(); + return new DataResponse(null); } /** * Stop the recording * - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse * * 200: Recording stopped successfully * 400: Stopping recording is not possible @@ -351,14 +351,14 @@ public function stop(): DataResponse { } catch (InvalidArgumentException $e) { return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST); } - return new DataResponse(); + return new DataResponse(null); } /** * Store the recording * * @param ?string $owner User that will own the recording file. `null` is actually not allowed and will always result in a "400 Bad Request". It's only allowed code-wise to handle requests where the post data exceeded the limits, so we can return a proper error instead of "500 Internal Server Error". - * @return DataResponse, array{}>|DataResponse|DataResponse + * @return DataResponse|DataResponse|DataResponse * * 200: Recording stored successfully * 400: Storing recording is not possible @@ -398,7 +398,7 @@ public function store(?string $owner): DataResponse { } catch (InvalidArgumentException $e) { return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST); } - return new DataResponse(); + return new DataResponse(null); } /** @@ -406,7 +406,7 @@ public function store(?string $owner): DataResponse { * * @param int $timestamp Timestamp of the notification to be dismissed * @psalm-param non-negative-int $timestamp - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse * * 200: Notification dismissed successfully * 400: Dismissing notification is not possible @@ -424,7 +424,7 @@ public function notificationDismiss(int $timestamp): DataResponse { } catch (InvalidArgumentException $e) { return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST); } - return new DataResponse(); + return new DataResponse(null); } /** @@ -434,7 +434,7 @@ public function notificationDismiss(int $timestamp): DataResponse { * @psalm-param non-negative-int $fileId * @param int $timestamp Timestamp of the notification to be dismissed * @psalm-param non-negative-int $timestamp - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse * * 200: Recording shared to chat successfully * 400: Sharing recording to chat is not possible @@ -452,6 +452,6 @@ public function shareToChat(int $fileId, int $timestamp): DataResponse { } catch (InvalidArgumentException $e) { return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST); } - return new DataResponse(); + return new DataResponse(null); } } From 590272de33a410686f325083a462af472cb7f9af Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 Nov 2024 07:56:26 +0100 Subject: [PATCH 02/19] fix(openapi): Fix documentation of ban API Signed-off-by: Joas Schilling --- lib/Controller/BanController.php | 6 +++--- lib/Service/BanService.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Controller/BanController.php b/lib/Controller/BanController.php index 6520cb68522..bd50262da82 100644 --- a/lib/Controller/BanController.php +++ b/lib/Controller/BanController.php @@ -77,7 +77,7 @@ public function banActor(string $actorType, string $actorId, string $internalNot * * Required capability: `ban-v1` * - * @return DataResponse + * @return DataResponse, array{}> * * 200: List all bans */ @@ -95,7 +95,7 @@ public function listBans(): DataResponse { * Required capability: `ban-v1` * * @param int $banId ID of the ban to be removed - * @return DataResponse, array{}> + * @return DataResponse * * 200: Unban successfully or not found */ @@ -103,6 +103,6 @@ public function listBans(): DataResponse { #[RequireModeratorParticipant] public function unbanActor(int $banId): DataResponse { $this->banService->findAndDeleteBanByIdForRoom($banId, $this->room->getId()); - return new DataResponse([], Http::STATUS_OK); + return new DataResponse(null, Http::STATUS_OK); } } diff --git a/lib/Service/BanService.php b/lib/Service/BanService.php index 883f1629dea..876a4f9bfeb 100644 --- a/lib/Service/BanService.php +++ b/lib/Service/BanService.php @@ -224,7 +224,7 @@ public function isActorBanned(Room $room, string $actorType, string $actorId): b /** * Retrieve all bans for a specific room. * - * @return Ban[] + * @return list */ public function getBansForRoom(int $roomId): array { return $this->banMapper->findByRoomId($roomId); From d49f16219748348a34e8d07ebd48ebb9af4183f1 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 Nov 2024 08:01:35 +0100 Subject: [PATCH 03/19] fix(openapi): Adjust internal HostedSignalingServerController Signed-off-by: Joas Schilling --- lib/Controller/HostedSignalingServerController.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Controller/HostedSignalingServerController.php b/lib/Controller/HostedSignalingServerController.php index 46b5eb64201..0f1760790ae 100644 --- a/lib/Controller/HostedSignalingServerController.php +++ b/lib/Controller/HostedSignalingServerController.php @@ -41,7 +41,7 @@ public function __construct( /** * Get the authentication credentials * - * @return DataResponse|DataResponse, array{}> + * @return DataResponse|DataResponse * * 200: Authentication credentials returned * 412: Getting authentication credentials is not possible @@ -59,7 +59,7 @@ public function auth(): DataResponse { ]); } - return new DataResponse([], Http::STATUS_PRECONDITION_FAILED); + return new DataResponse(null, Http::STATUS_PRECONDITION_FAILED); } /** @@ -101,7 +101,7 @@ public function requestTrial(string $url, string $name, string $email, string $l /** * Delete the account * - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse * * 204: Account deleted successfully * 400: Deleting account is not possible @@ -135,6 +135,6 @@ public function deleteAccount(): DataResponse { $this->logger->info('Deleted hosted signaling server account with ID ' . $accountId); - return new DataResponse([], Http::STATUS_NO_CONTENT); + return new DataResponse(null, Http::STATUS_NO_CONTENT); } } From 3be2e567775219ea4a732cb8f0fa8d5bf803f973 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 Nov 2024 08:05:03 +0100 Subject: [PATCH 04/19] fix(openapi): Fix breakout rooms being lists Signed-off-by: Joas Schilling --- lib/Controller/BreakoutRoomController.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Controller/BreakoutRoomController.php b/lib/Controller/BreakoutRoomController.php index 9d12507d8ce..07b418eb27a 100644 --- a/lib/Controller/BreakoutRoomController.php +++ b/lib/Controller/BreakoutRoomController.php @@ -45,7 +45,7 @@ public function __construct( * @psalm-param BreakoutRoom::MODE_* $mode * @param int<1, 20> $amount Number of breakout rooms - Constants {@see BreakoutRoom::MINIMUM_ROOM_AMOUNT} and {@see BreakoutRoom::MAXIMUM_ROOM_AMOUNT} * @param string $attendeeMap Mapping of the attendees to breakout rooms - * @return DataResponse|DataResponse + * @return DataResponse, array{}>|DataResponse * * 200: Breakout rooms configured successfully * 400: Configuring breakout rooms errored @@ -87,7 +87,7 @@ public function removeBreakoutRooms(): DataResponse { * Broadcast a chat message to all breakout rooms * * @param string $message Message to broadcast - * @return DataResponse|DataResponse + * @return DataResponse, array{}>|DataResponse * * 201: Chat message broadcasted successfully * 400: Broadcasting chat message is not possible @@ -111,7 +111,7 @@ public function broadcastChatMessage(string $message): DataResponse { * Apply an attendee map to the breakout rooms * * @param string $attendeeMap JSON encoded mapping of the attendees to breakout rooms `array` - * @return DataResponse|DataResponse + * @return DataResponse, array{}>|DataResponse * * 200: Attendee map applied successfully * 400: Applying attendee map is not possible @@ -181,7 +181,7 @@ public function resetRequestForAssistance(): DataResponse { /** * Start the breakout rooms * - * @return DataResponse|DataResponse + * @return DataResponse, array{}>|DataResponse * * 200: Breakout rooms started successfully * 400: Starting breakout rooms is not possible @@ -202,7 +202,7 @@ public function startBreakoutRooms(): DataResponse { /** * Stop the breakout rooms * - * @return DataResponse|DataResponse + * @return DataResponse, array{}>|DataResponse * * 200: Breakout rooms stopped successfully * 400: Stopping breakout rooms is not possible @@ -247,7 +247,7 @@ public function switchBreakoutRoom(string $target): DataResponse { } /** - * @return TalkRoom[] + * @return list */ protected function formatMultipleRooms(array $rooms): array { $return = []; From 7b086a43952deb476005a3210de05f9ea046e42d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 Nov 2024 08:07:57 +0100 Subject: [PATCH 05/19] fix(openapi): Remove empty array return from federation Signed-off-by: Joas Schilling --- lib/Controller/FederationController.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/Controller/FederationController.php b/lib/Controller/FederationController.php index ae5e46f9030..5c45e5f03ee 100644 --- a/lib/Controller/FederationController.php +++ b/lib/Controller/FederationController.php @@ -70,7 +70,7 @@ public function getResponseFormat(): string { * * @param int $id ID of the share * @psalm-param non-negative-int $id - * @return DataResponse|DataResponse|DataResponse + * @return DataResponse|DataResponse * * 200: Invite accepted successfully * 400: Invite can not be accepted (maybe it was accepted already) @@ -82,14 +82,14 @@ public function getResponseFormat(): string { public function acceptShare(int $id): DataResponse { $user = $this->userSession->getUser(); if (!$user instanceof IUser) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(['error' => 'user'], Http::STATUS_NOT_FOUND); } try { $participant = $this->federationManager->acceptRemoteRoomShare($user, $id); } catch (CannotReachRemoteException) { return new DataResponse(['error' => 'remote'], Http::STATUS_GONE); } catch (UnauthorizedException $e) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(['error' => 'user'], Http::STATUS_NOT_FOUND); } catch (\InvalidArgumentException $e) { return new DataResponse(['error' => $e->getMessage()], $e->getMessage() === 'invitation' ? Http::STATUS_NOT_FOUND : Http::STATUS_BAD_REQUEST); } @@ -108,7 +108,7 @@ public function acceptShare(int $id): DataResponse { * * @param int $id ID of the share * @psalm-param non-negative-int $id - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse * * 200: Invite declined successfully * 400: Invite was already accepted, use the "Remove the current user from a room" endpoint instead @@ -119,16 +119,16 @@ public function acceptShare(int $id): DataResponse { public function rejectShare(int $id): DataResponse { $user = $this->userSession->getUser(); if (!$user instanceof IUser) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(['error' => 'user'], Http::STATUS_NOT_FOUND); } try { $this->federationManager->rejectRemoteRoomShare($user, $id); } catch (UnauthorizedException $e) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(['error' => 'user'], Http::STATUS_NOT_FOUND); } catch (\InvalidArgumentException $e) { return new DataResponse(['error' => $e->getMessage()], $e->getMessage() === 'invitation' ? Http::STATUS_NOT_FOUND : Http::STATUS_BAD_REQUEST); } - return new DataResponse(); + return new DataResponse(null); } /** From 9cb64ed66028c76fed53bd5e39f453151f4cab3d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 Nov 2024 08:09:53 +0100 Subject: [PATCH 06/19] fix(openapi): Remove empty array from internal Guests API Signed-off-by: Joas Schilling --- lib/Controller/GuestController.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Controller/GuestController.php b/lib/Controller/GuestController.php index 403a33262e4..8142962c198 100644 --- a/lib/Controller/GuestController.php +++ b/lib/Controller/GuestController.php @@ -30,7 +30,7 @@ public function __construct( * Set the display name as a guest * * @param string $displayName New display name - * @return DataResponse, array{}> + * @return DataResponse * * 200: Display name updated successfully * 403: Not a guest @@ -41,15 +41,15 @@ public function __construct( public function setDisplayName(string $displayName): DataResponse { $participant = $this->getParticipant(); if (!$participant instanceof Participant) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(null, Http::STATUS_NOT_FOUND); } if (!$participant->isGuest()) { - return new DataResponse([], Http::STATUS_FORBIDDEN); + return new DataResponse(null, Http::STATUS_FORBIDDEN); } $this->guestManager->updateName($this->getRoom(), $participant, $displayName); - return new DataResponse(); + return new DataResponse(null); } } From 07a2623e6f42c55c5a3e1b1d59a5f91558c5f88d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 Nov 2024 08:13:50 +0100 Subject: [PATCH 07/19] fix(openapi): Remove empty arrays from files integration API Signed-off-by: Joas Schilling --- lib/Controller/FilesIntegrationController.php | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/lib/Controller/FilesIntegrationController.php b/lib/Controller/FilesIntegrationController.php index 99cd239ac73..51153f3ee2b 100644 --- a/lib/Controller/FilesIntegrationController.php +++ b/lib/Controller/FilesIntegrationController.php @@ -76,15 +76,16 @@ public function __construct( * owner of such a file. * * @param string $fileId ID of the file - * @return DataResponse|DataResponse, array{}> - * 200: Room token returned - * 400: Rooms not allowed for shares + * @return DataResponse|DataResponse * @throws OCSNotFoundException Share not found + * + * 200: Room token returned + * 400: Rooms not allowed for shares */ #[NoAdminRequired] public function getRoomByFileId(string $fileId): DataResponse { if ($this->config->getAppValue('spreed', 'conversations_files', '1') !== '1') { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(null, Http::STATUS_BAD_REQUEST); } $currentUser = $this->userSession->getUser(); @@ -142,10 +143,11 @@ public function getRoomByFileId(string $fileId): DataResponse { * thus logged-in users as seen as guests. * * @param string $shareToken Token of the file share - * @return DataResponse|DataResponse, array{}> - * 200: Room token and user info returned - * 400: Rooms not allowed for shares - * 404: Share not found + * @return DataResponse|DataResponse + * + * 200: Room token and user info returned + * 400: Rooms not allowed for shares + * 404: Share not found */ #[PublicPage] #[UseSession] @@ -153,7 +155,7 @@ public function getRoomByFileId(string $fileId): DataResponse { public function getRoomByShareToken(string $shareToken): DataResponse { if ($this->config->getAppValue('spreed', 'conversations_files', '1') !== '1' || $this->config->getAppValue('spreed', 'conversations_files_public_shares', '1') !== '1') { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(null, Http::STATUS_BAD_REQUEST); } try { @@ -165,27 +167,27 @@ public function getRoomByShareToken(string $shareToken): DataResponse { } } } catch (ShareNotFound $e) { - $response = new DataResponse([], Http::STATUS_NOT_FOUND); + $response = new DataResponse(null, Http::STATUS_NOT_FOUND); $response->throttle(['token' => $shareToken, 'action' => 'shareinfo']); return $response; } try { if ($share->getNodeType() !== FileInfo::TYPE_FILE) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(null, Http::STATUS_NOT_FOUND); } $fileId = (string)$share->getNodeId(); try { $room = $this->manager->getRoomByObject('file', $fileId); - } catch (RoomNotFoundException $e) { + } catch (RoomNotFoundException) { $name = $share->getNode()->getName(); $name = $this->roomService->prepareConversationName($name); $room = $this->roomService->createConversation(Room::TYPE_PUBLIC, $name, null, 'file', $fileId); } - } catch (NotFoundException $e) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + } catch (NotFoundException) { + return new DataResponse(null, Http::STATUS_NOT_FOUND); } $this->talkSession->setFileShareTokenForRoom($room->getToken(), $shareToken); From 6c2ad380ca2b5ce0f497fe27dff3ade6e9a408d4 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 Nov 2024 08:22:53 +0100 Subject: [PATCH 08/19] fix(openapi): Fix user avatar API to not return empty arrays Signed-off-by: Joas Schilling --- lib/Controller/TempAvatarController.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/Controller/TempAvatarController.php b/lib/Controller/TempAvatarController.php index 223d803e8d9..d72bdd41a1b 100644 --- a/lib/Controller/TempAvatarController.php +++ b/lib/Controller/TempAvatarController.php @@ -36,7 +36,7 @@ public function __construct( /** * Upload your avatar as a user * - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse * * 200: Avatar uploaded successfully * 400: Uploading avatar is not possible @@ -96,7 +96,7 @@ public function postAvatar(): DataResponse { $avatar = $this->avatarManager->getAvatar($this->userId); $avatar->set($image); - return new DataResponse(); + return new DataResponse(null); } catch (NotSquareException $e) { return new DataResponse(['message' => $e->getMessage()], Http::STATUS_BAD_REQUEST); } catch (\Exception $e) { @@ -111,7 +111,7 @@ public function postAvatar(): DataResponse { /** * Delete your avatar as a user * - * @return DataResponse, array{}> + * @return DataResponse|DataResponse * * 200: Avatar deleted successfully * 400: Deleting avatar is not possible @@ -122,12 +122,12 @@ public function deleteAvatar(): DataResponse { try { $avatar = $this->avatarManager->getAvatar($this->userId); $avatar->remove(); - return new DataResponse(); + return new DataResponse(null); } catch (\Exception $e) { $this->logger->error('Failed to delete avatar', [ 'exception' => $e, ]); - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(['error' => 'avatar'], Http::STATUS_BAD_REQUEST); } } } From 0da1cf1498d85028e4e5bd9c3232c502482fc8e3 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 Nov 2024 08:50:27 +0100 Subject: [PATCH 09/19] fix(openapi): Change things that don't raise any questions Signed-off-by: Joas Schilling --- lib/Capabilities.php | 6 +++--- lib/Model/BanMapper.php | 3 +++ lib/ResponseDefinitions.php | 20 ++++++++++---------- lib/Service/PollService.php | 8 ++++---- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/Capabilities.php b/lib/Capabilities.php index 1d9e42fcfd7..9982db71c2a 100644 --- a/lib/Capabilities.php +++ b/lib/Capabilities.php @@ -272,18 +272,18 @@ public function getCapabilities(): array { $capabilities['config']['signaling']['hello-v2-token-key'] = $pubKey; } - /** @var ?string[] $predefinedBackgrounds */ + /** @var ?list $predefinedBackgrounds */ $predefinedBackgrounds = null; $cachedPredefinedBackgrounds = $this->talkCache->get('predefined_backgrounds'); if ($cachedPredefinedBackgrounds !== null) { // Try using cached value - /** @var string[]|null $predefinedBackgrounds */ + /** @var list|null $predefinedBackgrounds */ $predefinedBackgrounds = json_decode($cachedPredefinedBackgrounds, true); } if (!is_array($predefinedBackgrounds)) { // Cache was empty or invalid, regenerate - /** @var string[] $predefinedBackgrounds */ + /** @var list $predefinedBackgrounds */ $predefinedBackgrounds = []; if (file_exists(__DIR__ . '/../img/backgrounds')) { $directoryIterator = new \DirectoryIterator(__DIR__ . '/../img/backgrounds'); diff --git a/lib/Model/BanMapper.php b/lib/Model/BanMapper.php index 4662a87cc85..46295244973 100644 --- a/lib/Model/BanMapper.php +++ b/lib/Model/BanMapper.php @@ -39,6 +39,9 @@ public function findForBannedActorAndRoom(string $bannedActorType, string $banne return $this->findEntity($query); } + /** + * @return list + */ public function findByRoomId(int $roomId, ?string $bannedActorType = null): array { $query = $this->db->getQueryBuilder(); $query->select('*') diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php index 3bf27613baa..1dabd974698 100644 --- a/lib/ResponseDefinitions.php +++ b/lib/ResponseDefinitions.php @@ -113,7 +113,7 @@ * isReplyable: bool, * markdown: bool, * reactions: array|\stdClass, - * reactionsSelf?: string[], + * reactionsSelf?: list, * referenceId: string, * timestamp: int, * token: string, @@ -156,7 +156,7 @@ * inviterDisplayName: string, * } * - * @psalm-type TalkMatterbridgeConfigFields = array> + * @psalm-type TalkMatterbridgeConfigFields = list> * * @psalm-type TalkMatterbridge = array{ * enabled: bool, @@ -184,7 +184,7 @@ * participantType: int, * permissions: int, * roomToken: string, - * sessionIds: string[], + * sessionIds: list, * status?: string, * statusClearAt?: ?int, * statusIcon?: ?string, @@ -321,15 +321,15 @@ * server: string, * signalingMode: string, * sipDialinInfo: string, - * stunservers: array{urls: string[]}[], + * stunservers: list}>, * ticket: string, - * turnservers: array{urls: string[], username: string, credential: mixed}[], + * turnservers: list, username: string, credential: mixed}>, * userId: ?string, * } * * @psalm-type TalkCapabilities = array{ - * features: string[], - * features-local: string[], + * features: list, + * features-local: list, * config: array{ * attachments: array{ * allowed: bool, @@ -340,8 +340,8 @@ * breakout-rooms: bool, * recording: bool, * recording-consent: int, - * supported-reactions: string[], - * predefined-backgrounds: string[], + * supported-reactions: list, + * predefined-backgrounds: list, * can-upload-background: bool, * sip-enabled: bool, * sip-dialout-enabled: bool, @@ -374,7 +374,7 @@ * hello-v2-token-key?: string, * }, * }, - * config-local: array, + * config-local: array>, * version: string, * } */ diff --git a/lib/Service/PollService.php b/lib/Service/PollService.php index 8f226bf3606..3048a2ed9fa 100644 --- a/lib/Service/PollService.php +++ b/lib/Service/PollService.php @@ -93,7 +93,7 @@ public function createPoll(int $roomId, string $actorType, string $actorId, stri /** * @param int $roomId - * @return Poll[] + * @return list */ public function getDraftsForRoom(int $roomId): array { return $this->pollMapper->getDraftsByRoomId($roomId); @@ -135,7 +135,7 @@ public function updatePoll(Participant $participant, Poll $poll): void { /** * @param Participant $participant * @param Poll $poll - * @return Vote[] + * @return list */ public function getVotesForActor(Participant $participant, Poll $poll): array { return $this->voteMapper->findByPollIdForActor( @@ -147,7 +147,7 @@ public function getVotesForActor(Participant $participant, Poll $poll): array { /** * @param Poll $poll - * @return Vote[] + * @return list */ public function getVotes(Poll $poll): array { return $this->voteMapper->findByPollId($poll->getId()); @@ -157,7 +157,7 @@ public function getVotes(Poll $poll): array { * @param Participant $participant * @param Poll $poll * @param int[] $optionIds Options the user voted for - * @return Vote[] + * @return list * @throws \RuntimeException */ public function votePoll(Participant $participant, Poll $poll, array $optionIds): array { From c47ecdb2cf15338bad25ad8c753f0ba10e67b0f2 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 Nov 2024 23:36:46 +0100 Subject: [PATCH 10/19] fix(openapi): Fix signaling handling Signed-off-by: Joas Schilling --- lib/Controller/SignalingController.php | 34 ++++++++++++++------------ lib/ResponseDefinitions.php | 18 ++++++++------ 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/lib/Controller/SignalingController.php b/lib/Controller/SignalingController.php index 3a594ba8c05..2731d42ff77 100644 --- a/lib/Controller/SignalingController.php +++ b/lib/Controller/SignalingController.php @@ -45,6 +45,7 @@ use Psr\Log\LoggerInterface; /** + * @psalm-import-type TalkSignalingFederationSettings from ResponseDefinitions * @psalm-import-type TalkSignalingSession from ResponseDefinitions * @psalm-import-type TalkSignalingSettings from ResponseDefinitions */ @@ -107,7 +108,7 @@ private function validateRecordingBackendRequest(string $data): bool { * Get the signaling settings * * @param string $token Token of the room - * @return DataResponse|DataResponse, array{}> + * @return DataResponse|DataResponse * * 200: Signaling settings returned * 401: Recording request invalid @@ -123,7 +124,7 @@ public function getSettings(string $token = ''): DataResponse { if (!empty($this->request->getHeader('Talk-Recording-Random')) || !empty($this->request->getHeader('Talk-Recording-Checksum'))) { if (!$this->validateRecordingBackendRequest('')) { - $response = new DataResponse([], Http::STATUS_UNAUTHORIZED); + $response = new DataResponse(null, Http::STATUS_UNAUTHORIZED); $response->throttle(['action' => 'talkRecordingSecret']); return $response; } @@ -158,7 +159,7 @@ public function getSettings(string $token = ''): DataResponse { $room = null; } } catch (RoomNotFoundException|ParticipantNotFoundException) { - $response = new DataResponse([], Http::STATUS_NOT_FOUND); + $response = new DataResponse(null, Http::STATUS_NOT_FOUND); $response->throttle(['token' => $token, 'action' => $action]); return $response; } @@ -222,15 +223,18 @@ public function getSettings(string $token = ''): DataResponse { return new DataResponse($data); } - private function getFederationSettings(?Room $room): array { + /** + * @psalm-return ?TalkSignalingFederationSettings + */ + private function getFederationSettings(?Room $room): ?array { if ($room === null || !$room->isFederatedConversation()) { - return []; + return null; } try { $participant = $this->participantService->getParticipant($room, $this->userId); } catch (ParticipantNotFoundException $e) { - return []; + return null; } /** @var \OCA\Talk\Federation\Proxy\TalkV1\Controller\SignalingController $proxy */ @@ -238,7 +242,7 @@ private function getFederationSettings(?Room $room): array { $response = $proxy->getSettings($room, $participant); if ($response->getStatus() === Http::STATUS_NOT_FOUND) { - return []; + return null; } /** @var TalkSignalingSettings $data */ @@ -262,7 +266,7 @@ private function getFederationSettings(?Room $room): array { * * @param int $serverId ID of the signaling server * @psalm-param non-negative-int $serverId - * @return DataResponse, array{}>|DataResponse, array{}>|DataResponse + * @return DataResponse, array{}>|DataResponse|DataResponse * * 200: Welcome message returned * 404: Signaling server not found @@ -271,7 +275,7 @@ private function getFederationSettings(?Room $room): array { public function getWelcomeMessage(int $serverId): DataResponse { $signalingServers = $this->talkConfig->getSignalingServers(); if (empty($signalingServers) || !isset($signalingServers[$serverId])) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(null, Http::STATUS_NOT_FOUND); } $url = rtrim($signalingServers[$serverId]['server'], '/'); @@ -349,7 +353,7 @@ public function getWelcomeMessage(int $serverId): DataResponse { * * @param string $token Token of the room * @param string $messages JSON encoded messages - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse * * 200: Signaling message sent successfully * 400: Sending signaling message is not possible @@ -409,7 +413,7 @@ public function sendMessages(string $token, string $messages): DataResponse { } } - return new DataResponse($response); + return new DataResponse(null); } /** @@ -494,7 +498,7 @@ private function isTryingToPublishMedia(string $sdp, string $media): bool { * Get signaling messages * * @param string $token Token of the room - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|string}>, array{}>|DataResponse * * 200: Signaling messages returned * 400: Getting signaling messages is not possible @@ -597,7 +601,7 @@ public function pullMessages(string $token): DataResponse { /** * @param Room $room * @param int $pingTimestamp - * @return TalkSignalingSession[] + * @return list */ protected function getUsersInRoom(Room $room, int $pingTimestamp): array { $usersInRoom = []; @@ -699,7 +703,7 @@ protected function getInputStream(): string { * See sections "Backend validation" in * https://nextcloud-spreed-signaling.readthedocs.io/en/latest/standalone-signaling-api-v1/#backend-requests * - * @return DataResponse}, room?: array{version: string, roomid?: string, properties?: array, permissions?: string[], session?: array}}, array{}> + * @return DataResponse}, room?: array{version: string, roomid?: string, properties?: array, permissions?: list, session?: array}}, array{}> * * 200: Always, sorry about that */ @@ -797,7 +801,7 @@ private function backendAuth(array $auth): DataResponse { } /** - * @return DataResponse, permissions: string[], session?: array}}, array{}> + * @return DataResponse, permissions: list, session?: array}}, array{}> */ private function backendRoom(array $roomRequest): DataResponse { $token = $roomRequest['roomid']; // It's actually the room token diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php index 1dabd974698..f2854d51362 100644 --- a/lib/ResponseDefinitions.php +++ b/lib/ResponseDefinitions.php @@ -299,15 +299,17 @@ * userId: string, * } * + * @psalm-type TalkSignalingFederationSettings = array{ + * server: string, + * nextcloudServer: string, + * helloAuthParams: array{ + * token: string, + * }, + * roomId: string, + * } + * * @psalm-type TalkSignalingSettings = array{ - * federation: array{ - * server: string, - * nextcloudServer: string, - * helloAuthParams: array{ - * token: string, - * }, - * roomId: string, - * }|array, + * federation: TalkSignalingFederationSettings|null, * helloAuthParams: array{ * "1.0": array{ * userid: ?string, From 0978b92f9120c1b30da9e5a3a7cf23745f3b134a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 Nov 2024 23:38:06 +0100 Subject: [PATCH 11/19] fix(openapi): Fix signaling API empty responses Signed-off-by: Joas Schilling --- lib/Controller/SettingsController.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index 5a17568d5ef..55c90506f22 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -41,7 +41,7 @@ public function __construct( * * @param 'attachment_folder'|'read_status_privacy'|'typing_privacy'|'play_sounds' $key Key to update * @param string|int|null $value New value for the key - * @return DataResponse, array{}> + * @return DataResponse * * 200: User setting updated successfully * 400: Updating user setting is not possible @@ -49,21 +49,21 @@ public function __construct( #[NoAdminRequired] public function setUserSetting(string $key, string|int|null $value): DataResponse { if (!$this->preferenceListener->validatePreference($this->userId, $key, $value)) { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(null, Http::STATUS_BAD_REQUEST); } $this->config->setUserValue($this->userId, 'spreed', $key, $value); - return new DataResponse(); + return new DataResponse(null); } /** * Update SIP bridge settings * - * @param string[] $sipGroups New SIP groups + * @param list $sipGroups New SIP groups * @param string $dialInInfo New dial info * @param string $sharedSecret New shared secret - * @return DataResponse, array{}> + * @return DataResponse * * 200: Successfully set new SIP settings */ @@ -84,6 +84,6 @@ public function setSIPSettings( $this->config->setAppValue('spreed', 'sip_bridge_dialin_info', $dialInInfo); $this->config->setAppValue('spreed', 'sip_bridge_shared_secret', $sharedSecret); - return new DataResponse(); + return new DataResponse(null); } } From 9db19a9b553808ac9b2a88591813167ac75e1339 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 20 Nov 2024 23:50:47 +0100 Subject: [PATCH 12/19] fix(openapi): Remove empty array from bot responses Signed-off-by: Joas Schilling --- lib/Controller/BotController.php | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/Controller/BotController.php b/lib/Controller/BotController.php index 0b8cf9797e0..8b741e66d2f 100644 --- a/lib/Controller/BotController.php +++ b/lib/Controller/BotController.php @@ -120,7 +120,7 @@ protected function getBotFromHeaders(string $token, string $message): Bot { * @param string $referenceId For the message to be able to later identify it again * @param int $replyTo Parent id which this message is a reply to * @param bool $silent If sent silent the chat message will not create any notifications - * @return DataResponse, array{}> + * @return DataResponse * * 201: Message sent successfully * 400: When the replyTo is invalid or message is empty @@ -133,7 +133,7 @@ protected function getBotFromHeaders(string $token, string $message): Bot { #[PublicPage] public function sendMessage(string $token, string $message, string $referenceId = '', int $replyTo = 0, bool $silent = false): DataResponse { if (trim($message) === '') { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(null, Http::STATUS_BAD_REQUEST); } try { @@ -141,7 +141,7 @@ public function sendMessage(string $token, string $message, string $referenceId } catch (\InvalidArgumentException $e) { /** @var Http::STATUS_BAD_REQUEST|Http::STATUS_UNAUTHORIZED $status */ $status = $e->getCode(); - $response = new DataResponse([], $status); + $response = new DataResponse(null, $status); if ($e->getCode() === Http::STATUS_UNAUTHORIZED) { $response->throttle(['action' => 'bot']); } @@ -159,7 +159,7 @@ public function sendMessage(string $token, string $message, string $referenceId $parent = $this->chatManager->getParentComment($room, (string)$replyTo); } catch (NotFoundException $e) { // Someone is trying to reply cross-rooms or to a non-existing message - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(null, Http::STATUS_BAD_REQUEST); } } @@ -169,12 +169,12 @@ public function sendMessage(string $token, string $message, string $referenceId try { $this->chatManager->sendMessage($room, $this->participant, $actorType, $actorId, $message, $creationDateTime, $parent, $referenceId, $silent, rateLimitGuestMentions: false); } catch (MessageTooLongException) { - return new DataResponse([], Http::STATUS_REQUEST_ENTITY_TOO_LARGE); + return new DataResponse(null, Http::STATUS_REQUEST_ENTITY_TOO_LARGE); } catch (\Exception) { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(null, Http::STATUS_BAD_REQUEST); } - return new DataResponse([], Http::STATUS_CREATED); + return new DataResponse(null, Http::STATUS_CREATED); } /** @@ -183,7 +183,7 @@ public function sendMessage(string $token, string $message, string $referenceId * @param string $token Conversation token * @param int $messageId ID of the message * @param string $reaction Reaction to add - * @return DataResponse, array{}> + * @return DataResponse * * 200: Reaction already exists * 201: Reacted successfully @@ -200,7 +200,7 @@ public function react(string $token, int $messageId, string $reaction): DataResp } catch (\InvalidArgumentException $e) { /** @var Http::STATUS_BAD_REQUEST|Http::STATUS_UNAUTHORIZED $status */ $status = $e->getCode(); - $response = new DataResponse([], $status); + $response = new DataResponse(null, $status); if ($e->getCode() === Http::STATUS_UNAUTHORIZED) { $response->throttle(['action' => 'bot']); } @@ -221,14 +221,14 @@ public function react(string $token, int $messageId, string $reaction): DataResp $reaction ); } catch (NotFoundException) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(null, Http::STATUS_NOT_FOUND); } catch (ReactionAlreadyExistsException) { - return new DataResponse([], Http::STATUS_OK); + return new DataResponse(null, Http::STATUS_OK); } catch (ReactionNotSupportedException|ReactionOutOfContextException|\Exception) { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(null, Http::STATUS_BAD_REQUEST); } - return new DataResponse([], Http::STATUS_CREATED); + return new DataResponse(null, Http::STATUS_CREATED); } /** @@ -237,7 +237,7 @@ public function react(string $token, int $messageId, string $reaction): DataResp * @param string $token Conversation token * @param int $messageId ID of the message * @param string $reaction Reaction to delete - * @return DataResponse, array{}> + * @return DataResponse * * 200: Reaction deleted successfully * 400: Reacting is not possible @@ -253,7 +253,7 @@ public function deleteReaction(string $token, int $messageId, string $reaction): } catch (\InvalidArgumentException $e) { /** @var Http::STATUS_BAD_REQUEST|Http::STATUS_UNAUTHORIZED $status */ $status = $e->getCode(); - $response = new DataResponse([], $status); + $response = new DataResponse(null, $status); if ($e->getCode() === Http::STATUS_UNAUTHORIZED) { $response->throttle(['action' => 'bot']); } @@ -274,18 +274,18 @@ public function deleteReaction(string $token, int $messageId, string $reaction): $reaction ); } catch (ReactionNotSupportedException|ReactionOutOfContextException|NotFoundException) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(null, Http::STATUS_NOT_FOUND); } catch (\Exception) { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(null, Http::STATUS_BAD_REQUEST); } - return new DataResponse([], Http::STATUS_OK); + return new DataResponse(null, Http::STATUS_OK); } /** * List admin bots * - * @return DataResponse + * @return DataResponse, array{}> * * 200: Bot list returned */ @@ -305,7 +305,7 @@ public function adminListBots(): DataResponse { /** * List bots * - * @return DataResponse + * @return DataResponse, array{}> * * 200: Bot list returned */ From 110062ed83c5157d5ed878ed902c87bf15ec4a88 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 21 Nov 2024 00:12:13 +0100 Subject: [PATCH 13/19] fix(openapi): Fix call API empty arrays Signed-off-by: Joas Schilling --- lib/Controller/CallController.php | 64 +++++++++---------- .../TalkV1/Controller/CallController.php | 35 ++++++---- 2 files changed, 54 insertions(+), 45 deletions(-) diff --git a/lib/Controller/CallController.php b/lib/Controller/CallController.php index 277940b7678..2f5d1386472 100644 --- a/lib/Controller/CallController.php +++ b/lib/Controller/CallController.php @@ -67,7 +67,7 @@ public function __construct( /** * Get the peers for a call * - * @return DataResponse + * @return DataResponse, array{}> * * 200: List of peers in the call returned */ @@ -208,7 +208,7 @@ public function downloadParticipantsForCall(string $format = 'csv'): DataDownloa * (Only needed when the `config => call => recording-consent` capability is set to {@see RecordingService::CONSENT_REQUIRED_YES} * or the capability is {@see RecordingService::CONSENT_REQUIRED_OPTIONAL} * and the conversation `recordingConsent` value is {@see RecordingService::CONSENT_REQUIRED_YES} ) - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse * * 200: Call joined successfully * 400: No recording consent was given @@ -231,7 +231,7 @@ public function joinCall(?int $flags = null, bool $silent = false, bool $recordi $session = $this->participant->getSession(); if (!$session instanceof Session) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(null, Http::STATUS_NOT_FOUND); } if ($flags === null) { @@ -257,7 +257,7 @@ public function joinCall(?int $flags = null, bool $silent = false, bool $recordi } catch (\InvalidArgumentException $e) { return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST); } - return new DataResponse(); + return new DataResponse(null); } /** @@ -289,7 +289,7 @@ protected function validateRecordingConsent(bool $recordingConsent): void { * @psalm-param int-mask-of|null $flags * @param bool $silent Join the call silently * @param bool $recordingConsent Agreement to be recorded - * @return DataResponse, array{}>|DataResponse|DataResponse + * @return DataResponse|DataResponse * * 200: Call joined successfully * 400: Conditions to join not met @@ -319,17 +319,17 @@ public function joinFederatedCall(string $sessionId, ?int $flags = null, bool $s $this->participantService->changeInCall($this->room, $this->participant, $flags, false, $silent); $this->roomService->setActiveSince($this->room, $this->participant, $this->timeFactory->getDateTime(), $flags, silent: $silent); } catch (\InvalidArgumentException $e) { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST); } - return new DataResponse(); + return new DataResponse(null); } /** * Ring an attendee * * @param int $attendeeId ID of the attendee to ring - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse * * 200: Attendee rang successfully * 400: Ringing attendee is not possible @@ -348,11 +348,11 @@ public function ringAttendee(int $attendeeId): DataResponse { } if ($this->room->getCallFlag() === Participant::FLAG_DISCONNECTED) { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(['error' => 'in-call'], Http::STATUS_BAD_REQUEST); } if ($this->participant->getSession() && $this->participant->getSession()->getInCall() === Participant::FLAG_DISCONNECTED) { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(['error' => 'in-call'], Http::STATUS_BAD_REQUEST); } try { @@ -360,17 +360,17 @@ public function ringAttendee(int $attendeeId): DataResponse { } catch (\InvalidArgumentException $e) { return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST); } catch (DoesNotExistException) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(null, Http::STATUS_NOT_FOUND); } - return new DataResponse(); + return new DataResponse(null); } /** * Call a SIP dial-out attendee * * @param int $attendeeId ID of the attendee to call - * @return DataResponse + * @return DataResponse|DataResponse * * 201: Dial-out initiated successfully * 400: SIP dial-out not possible @@ -383,27 +383,27 @@ public function ringAttendee(int $attendeeId): DataResponse { #[RequirePermission(permission: RequirePermission::START_CALL)] public function sipDialOut(int $attendeeId): DataResponse { if ($this->room->getCallFlag() === Participant::FLAG_DISCONNECTED) { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(null, Http::STATUS_BAD_REQUEST); } if ($this->participant->getSession() && $this->participant->getSession()->getInCall() === Participant::FLAG_DISCONNECTED) { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(null, Http::STATUS_BAD_REQUEST); } try { $this->participantService->startDialOutRequest($this->dialOutService, $this->room, $attendeeId); } catch (ParticipantNotFoundException) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(null, Http::STATUS_NOT_FOUND); } catch (DialOutFailedException $e) { return new DataResponse([ 'error' => $e->getMessage(), 'message' => $e->getReadableError(), ], Http::STATUS_NOT_IMPLEMENTED); - } catch (\InvalidArgumentException) { - return new DataResponse([], Http::STATUS_NOT_IMPLEMENTED); + } catch (\InvalidArgumentException $e) { + return new DataResponse(['error' => $e], Http::STATUS_NOT_IMPLEMENTED); } - return new DataResponse([], Http::STATUS_CREATED); + return new DataResponse(null, Http::STATUS_CREATED); } /** @@ -411,7 +411,7 @@ public function sipDialOut(int $attendeeId): DataResponse { * * @param int<0, 15> $flags New flags * @psalm-param int-mask-of $flags New flags - * @return DataResponse, array{}> + * @return DataResponse * * 200: In-call flags updated successfully * 400: Updating in-call flags is not possible @@ -423,7 +423,7 @@ public function sipDialOut(int $attendeeId): DataResponse { public function updateCallFlags(int $flags): DataResponse { $session = $this->participant->getSession(); if (!$session instanceof Session) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(null, Http::STATUS_NOT_FOUND); } if ($this->room->isFederatedConversation()) { @@ -441,10 +441,10 @@ public function updateCallFlags(int $flags): DataResponse { try { $this->participantService->updateCallFlags($this->room, $this->participant, $flags); } catch (\Exception $exception) { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(null, Http::STATUS_BAD_REQUEST); } - return new DataResponse(); + return new DataResponse(null); } /** @@ -454,7 +454,7 @@ public function updateCallFlags(int $flags): DataResponse { * @param string $sessionId Federated session id to update the flags with * @param int<0, 15> $flags New flags * @psalm-param int-mask-of $flags New flags - * @return DataResponse, array{}>|DataResponse + * @return DataResponse * * 200: In-call flags updated successfully * 400: Updating in-call flags is not possible @@ -474,17 +474,17 @@ public function updateFederatedCallFlags(string $sessionId, int $flags): DataRes try { $this->participantService->updateCallFlags($this->room, $this->participant, $flags); } catch (\Exception) { - return new DataResponse([], Http::STATUS_BAD_REQUEST); + return new DataResponse(null, Http::STATUS_BAD_REQUEST); } - return new DataResponse(); + return new DataResponse(null); } /** * Leave a call * * @param bool $all whether to also terminate the call for all participants - * @return DataResponse, array{}> + * @return DataResponse * * 200: Call left successfully * 404: Call session not found @@ -495,7 +495,7 @@ public function updateFederatedCallFlags(string $sessionId, int $flags): DataRes public function leaveCall(bool $all = false): DataResponse { $session = $this->participant->getSession(); if (!$session instanceof Session) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return new DataResponse(null, Http::STATUS_NOT_FOUND); } if ($this->room->isFederatedConversation()) { @@ -515,7 +515,7 @@ public function leaveCall(bool $all = false): DataResponse { if (!$result) { // Someone else won the race condition, make sure this user disconnects directly and then return $this->participantService->changeInCall($this->room, $this->participant, Participant::FLAG_DISCONNECTED); - return new DataResponse(); + return new DataResponse(null); } $this->participantService->endCallForEveryone($this->room, $this->participant); $this->roomService->resetActiveSinceInModelOnly($this->room); @@ -526,7 +526,7 @@ public function leaveCall(bool $all = false): DataResponse { } } - return new DataResponse(); + return new DataResponse(null); } /** @@ -534,7 +534,7 @@ public function leaveCall(bool $all = false): DataResponse { * user. * * @param string $sessionId Federated session id to leave with - * @return DataResponse, array{}>|DataResponse + * @return DataResponse * * 200: Call left successfully * 404: Call session not found @@ -555,6 +555,6 @@ public function leaveFederatedCall(string $sessionId): DataResponse { $this->roomService->resetActiveSince($this->room, $this->participant); } - return new DataResponse(); + return new DataResponse(null); } } diff --git a/lib/Federation/Proxy/TalkV1/Controller/CallController.php b/lib/Federation/Proxy/TalkV1/Controller/CallController.php index a2852ec48ec..a2d6ab265c4 100644 --- a/lib/Federation/Proxy/TalkV1/Controller/CallController.php +++ b/lib/Federation/Proxy/TalkV1/Controller/CallController.php @@ -36,7 +36,7 @@ public function __construct( * * @param Room $room the federated room to get the call peers * @param Participant $participant the federated user to get the call peers - * @return DataResponse + * @return DataResponse, array{}> * @throws CannotReachRemoteException * * 200: List of peers in the call returned @@ -48,10 +48,10 @@ public function getPeersForCall(Room $room, Participant $participant): DataRespo $room->getRemoteServer() . '/ocs/v2.php/apps/spreed/api/v4/call/' . $room->getRemoteToken(), ); - /** @var TalkCallPeer[] $data */ + /** @var list $data */ $data = $this->proxy->getOCSData($proxy); - /** @var TalkCallPeer[] $data */ + /** @var list $data */ $data = $this->userConverter->convertAttendees($room, $data, 'actorType', 'actorId', 'displayName'); $statusCode = $proxy->getStatusCode(); @@ -73,7 +73,7 @@ public function getPeersForCall(Room $room, Participant $participant): DataRespo * @psalm-param int-mask-of $flags * @param bool $silent Join the call silently * @param bool $recordingConsent Agreement to be recorded - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse * @throws CannotReachRemoteException * * 200: Federated user is now in the call @@ -101,14 +101,20 @@ public function joinFederatedCall(Room $room, Participant $participant, int $fla throw new CannotReachRemoteException(); } - return new DataResponse([], $statusCode); + if ($statusCode === Http::STATUS_BAD_REQUEST) { + /** @var array{error: string} $data */ + $data = $this->proxy->getOCSData($proxy); + return new DataResponse($data, $statusCode); + } + + return new DataResponse(null, $statusCode); } /** * @see \OCA\Talk\Controller\RoomController::ringAttendee() * * @param int $attendeeId ID of the attendee to ring - * @return DataResponse, array{}>|DataResponse + * @return DataResponse|DataResponse * @throws CannotReachRemoteException * * 200: Attendee rang successfully @@ -128,10 +134,13 @@ public function ringAttendee(Room $room, Participant $participant, int $attendee throw new CannotReachRemoteException(); } - /** @var array{error?: string} $data */ - $data = $this->proxy->getOCSData($proxy); + if ($statusCode === Http::STATUS_BAD_REQUEST) { + /** @var array{error: string} $data */ + $data = $this->proxy->getOCSData($proxy); + return new DataResponse($data, $statusCode); + } - return new DataResponse($data, $statusCode); + return new DataResponse(null, $statusCode); } /** @@ -142,7 +151,7 @@ public function ringAttendee(Room $room, Participant $participant, int $attendee * flags; the participant must have a session * @param int<0, 15> $flags New flags * @psalm-param int-mask-of $flags New flags - * @return DataResponse, array{}> + * @return DataResponse * @throws CannotReachRemoteException * * 200: In-call flags updated successfully for federated user @@ -168,7 +177,7 @@ public function updateFederatedCallFlags(Room $room, Participant $participant, i throw new CannotReachRemoteException(); } - return new DataResponse([], $statusCode); + return new DataResponse(null, $statusCode); } /** @@ -177,7 +186,7 @@ public function updateFederatedCallFlags(Room $room, Participant $participant, i * @param Room $room the federated room to leave the call in * @param Participant $participant the federated user that will leave the * call; the participant must have a session - * @return DataResponse, array{}> + * @return DataResponse * @throws CannotReachRemoteException * * 200: Federated user left the call @@ -201,6 +210,6 @@ public function leaveFederatedCall(Room $room, Participant $participant): DataRe throw new CannotReachRemoteException(); } - return new DataResponse([], $statusCode); + return new DataResponse(null, $statusCode); } } From 336c4777fd931863e3796efd60137e2c9dbd019c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 21 Nov 2024 22:36:37 +0100 Subject: [PATCH 14/19] test: Fix integration test function with returning null :D Signed-off-by: Joas Schilling --- tests/integration/features/bootstrap/FeatureContext.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/features/bootstrap/FeatureContext.php b/tests/integration/features/bootstrap/FeatureContext.php index fbda89f30a2..ad88f6c3269 100644 --- a/tests/integration/features/bootstrap/FeatureContext.php +++ b/tests/integration/features/bootstrap/FeatureContext.php @@ -2114,7 +2114,7 @@ public function userJoinsCall(string $user, string $identifier, int $statusCode, $this->assertStatusCode($this->response, $statusCode); $response = $this->getDataFromResponse($this->response); - if (array_key_exists('sessionId', $response)) { + if (is_array($response) && array_key_exists('sessionId', $response)) { // In the chat guest users are identified by their sessionId. The // sessionId is larger than the size of the actorId column in the // database, though, so the ID stored in the database and returned @@ -2182,7 +2182,7 @@ public function userDialsOut(string $user, string $phoneNumber, string $identifi $this->assertStatusCode($this->response, $statusCode); $response = $this->getDataFromResponse($this->response); - if (array_key_exists('sessionId', $response)) { + if (is_array($response) && array_key_exists('sessionId', $response)) { // In the chat guest users are identified by their sessionId. The // sessionId is larger than the size of the actorId column in the // database, though, so the ID stored in the database and returned From ff438bc23bb75156fc6c3a7101ea35e392c16a24 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 21 Nov 2024 23:08:41 +0100 Subject: [PATCH 15/19] fix(room): Fix undefined variable in federated calls Signed-off-by: Joas Schilling --- .../Proxy/TalkV1/Controller/CallController.php | 10 +++++----- .../Proxy/TalkV1/Controller/ReactionController.php | 6 ++++++ lib/Service/RoomFormatter.php | 2 ++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/Federation/Proxy/TalkV1/Controller/CallController.php b/lib/Federation/Proxy/TalkV1/Controller/CallController.php index a2d6ab265c4..f4c3903f43a 100644 --- a/lib/Federation/Proxy/TalkV1/Controller/CallController.php +++ b/lib/Federation/Proxy/TalkV1/Controller/CallController.php @@ -32,7 +32,7 @@ public function __construct( } /** - * @see \OCA\Talk\Controller\RoomController::getPeersForCall() + * @see \OCA\Talk\Controller\CallController::getPeersForCall() * * @param Room $room the federated room to get the call peers * @param Participant $participant the federated user to get the call peers @@ -64,7 +64,7 @@ public function getPeersForCall(Room $room, Participant $participant): DataRespo } /** - * @see \OCA\Talk\Controller\RoomController::joinFederatedCall() + * @see \OCA\Talk\Controller\CallController::joinFederatedCall() * * @param Room $room the federated room to join the call in * @param Participant $participant the federated user that will join the @@ -111,7 +111,7 @@ public function joinFederatedCall(Room $room, Participant $participant, int $fla } /** - * @see \OCA\Talk\Controller\RoomController::ringAttendee() + * @see \OCA\Talk\Controller\CallController::ringAttendee() * * @param int $attendeeId ID of the attendee to ring * @return DataResponse|DataResponse @@ -144,7 +144,7 @@ public function ringAttendee(Room $room, Participant $participant, int $attendee } /** - * @see \OCA\Talk\Controller\RoomController::updateFederatedCallFlags() + * @see \OCA\Talk\Controller\CallController::updateFederatedCallFlags() * * @param Room $room the federated room to update the call flags in * @param Participant $participant the federated user to update the call @@ -181,7 +181,7 @@ public function updateFederatedCallFlags(Room $room, Participant $participant, i } /** - * @see \OCA\Talk\Controller\RoomController::leaveFederatedCall() + * @see \OCA\Talk\Controller\CallController::leaveFederatedCall() * * @param Room $room the federated room to leave the call in * @param Participant $participant the federated user that will leave the diff --git a/lib/Federation/Proxy/TalkV1/Controller/ReactionController.php b/lib/Federation/Proxy/TalkV1/Controller/ReactionController.php index 234e2ceedfa..2812a7591e1 100644 --- a/lib/Federation/Proxy/TalkV1/Controller/ReactionController.php +++ b/lib/Federation/Proxy/TalkV1/Controller/ReactionController.php @@ -38,6 +38,8 @@ public function __construct( * 201: Reaction added successfully * 400: Adding reaction is not possible * 404: Message not found + * + * @see \OCA\Talk\Controller\ReactionController::react() */ public function react(Room $room, Participant $participant, int $messageId, string $reaction, string $format): DataResponse { $proxy = $this->proxy->post( @@ -78,6 +80,8 @@ public function react(Room $room, Participant $participant, int $messageId, stri * 200: Reaction deleted successfully * 400: Deleting reaction is not possible * 404: Message not found + * + * @see \OCA\Talk\Controller\ReactionController::delete() */ public function delete(Room $room, Participant $participant, int $messageId, string $reaction, string $format): DataResponse { $proxy = $this->proxy->delete( @@ -118,6 +122,8 @@ public function delete(Room $room, Participant $participant, int $messageId, str * * 200: Reactions returned * 404: Message or reaction not found + * + * @see \OCA\Talk\Controller\ReactionController::getReactions() */ public function getReactions(Room $room, Participant $participant, int $messageId, ?string $reaction, string $format): DataResponse { $proxy = $this->proxy->get( diff --git a/lib/Service/RoomFormatter.php b/lib/Service/RoomFormatter.php index d0349d5221a..e9311c2c768 100644 --- a/lib/Service/RoomFormatter.php +++ b/lib/Service/RoomFormatter.php @@ -284,6 +284,7 @@ public function formatRoomV4( $roomData['canStartCall'] = $currentParticipant->canStartCall($this->serverConfig); + $currentUser = null; if ($attendee->getActorType() === Attendee::ACTOR_USERS) { $currentUser = $this->userManager->get($attendee->getActorId()); if ($room->isFederatedConversation()) { @@ -396,6 +397,7 @@ public function formatRoomV4( } catch (DoesNotExistException) { } } + if ($currentUser instanceof IUser && $attendee->getActorType() === Attendee::ACTOR_USERS && $roomData['lastReadMessage'] === ChatManager::UNREAD_FIRST_MESSAGE From 85348826f88a6bd7295d102a67d15889659f1b80 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 21 Nov 2024 00:17:32 +0100 Subject: [PATCH 16/19] chore(assets): Recompile assets Signed-off-by: Joas Schilling --- openapi-administration.json | 12 +- openapi-backend-recording.json | 8 +- openapi-bots.json | 52 +++- openapi-federation.json | 21 +- openapi-full.json | 363 +++++++++++++++--------- openapi.json | 270 +++++++++++------- src/types/openapi/openapi-federation.ts | 6 +- src/types/openapi/openapi-full.ts | 49 ++-- src/types/openapi/openapi.ts | 43 ++- 9 files changed, 510 insertions(+), 314 deletions(-) diff --git a/openapi-administration.json b/openapi-administration.json index f8132697e80..fb1cb56c78b 100644 --- a/openapi-administration.json +++ b/openapi-administration.json @@ -1223,7 +1223,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -1363,7 +1365,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -1479,7 +1483,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } diff --git a/openapi-backend-recording.json b/openapi-backend-recording.json index 0951a7d89ee..1dc3ce44918 100644 --- a/openapi-backend-recording.json +++ b/openapi-backend-recording.json @@ -351,7 +351,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -611,7 +613,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } diff --git a/openapi-bots.json b/openapi-bots.json index e1671a9bd60..6c3840f55f0 100644 --- a/openapi-bots.json +++ b/openapi-bots.json @@ -397,7 +397,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -425,7 +427,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -453,7 +457,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -481,7 +487,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -592,7 +600,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -620,7 +630,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -648,7 +660,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -676,7 +690,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -704,7 +720,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -803,7 +821,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -831,7 +851,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -859,7 +881,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -887,7 +911,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } diff --git a/openapi-federation.json b/openapi-federation.json index f8cdaf8deb0..72ddd1a5249 100644 --- a/openapi-federation.json +++ b/openapi-federation.json @@ -1339,8 +1339,8 @@ } } }, - "410": { - "description": "Remote server could not be reached to notify about the acceptance", + "404": { + "description": "Invite can not be found", "content": { "application/json": { "schema": { @@ -1377,8 +1377,8 @@ } } }, - "404": { - "description": "Invite can not be found", + "410": { + "description": "Remote server could not be reached to notify about the acceptance", "content": { "application/json": { "schema": { @@ -1399,6 +1399,9 @@ }, "data": { "type": "object", + "required": [ + "error" + ], "properties": { "error": { "type": "string" @@ -1485,7 +1488,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -1515,6 +1520,9 @@ }, "data": { "type": "object", + "required": [ + "error" + ], "properties": { "error": { "type": "string" @@ -1550,6 +1558,9 @@ }, "data": { "type": "object", + "required": [ + "error" + ], "properties": { "error": { "type": "string" diff --git a/openapi-full.json b/openapi-full.json index fcc3086ff80..478347a0bc3 100644 --- a/openapi-full.json +++ b/openapi-full.json @@ -1439,6 +1439,37 @@ } ] }, + "SignalingFederationSettings": { + "type": "object", + "required": [ + "server", + "nextcloudServer", + "helloAuthParams", + "roomId" + ], + "properties": { + "server": { + "type": "string" + }, + "nextcloudServer": { + "type": "string" + }, + "helloAuthParams": { + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "string" + } + } + }, + "roomId": { + "type": "string" + } + } + }, "SignalingSession": { "type": "object", "required": [ @@ -1498,43 +1529,8 @@ ], "properties": { "federation": { - "oneOf": [ - { - "type": "object", - "required": [ - "server", - "nextcloudServer", - "helloAuthParams", - "roomId" - ], - "properties": { - "server": { - "type": "string" - }, - "nextcloudServer": { - "type": "string" - }, - "helloAuthParams": { - "type": "object", - "required": [ - "token" - ], - "properties": { - "token": { - "type": "string" - } - } - }, - "roomId": { - "type": "string" - } - } - }, - { - "type": "array", - "maxItems": 0 - } - ] + "$ref": "#/components/schemas/SignalingFederationSettings", + "nullable": true }, "helloAuthParams": { "type": "object", @@ -2454,7 +2450,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4210,7 +4208,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4238,7 +4238,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4268,6 +4270,9 @@ }, "data": { "type": "object", + "required": [ + "error" + ], "properties": { "error": { "type": "string" @@ -4374,7 +4379,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4402,7 +4409,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4430,7 +4439,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4522,7 +4533,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4550,7 +4563,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4755,7 +4770,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4763,8 +4780,8 @@ } } }, - "400": { - "description": "Conditions to join not met", + "404": { + "description": "Call not found", "content": { "application/json": { "schema": { @@ -4784,12 +4801,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "properties": { - "error": { - "type": "string" - } - } + "nullable": true } } } @@ -4798,8 +4810,8 @@ } } }, - "404": { - "description": "Call not found", + "400": { + "description": "Conditions to join not met", "content": { "application/json": { "schema": { @@ -4819,7 +4831,15 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "nullable": true + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } } } } @@ -4926,7 +4946,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4954,7 +4976,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -5072,7 +5096,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -5193,7 +5219,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -5221,7 +5249,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -5351,15 +5381,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - } - } + "nullable": true } } } @@ -5389,15 +5411,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - } - } + "nullable": true } } } @@ -5427,15 +5441,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - } - } + "nullable": true } } } @@ -5466,6 +5472,9 @@ }, "data": { "type": "object", + "required": [ + "error" + ], "properties": { "error": { "type": "string" @@ -8217,7 +8226,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -8374,7 +8385,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -8402,7 +8415,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -8502,7 +8517,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -8530,7 +8547,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -8558,7 +8577,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -10600,7 +10621,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -10716,7 +10739,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -10845,7 +10870,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -10991,7 +11018,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -16620,7 +16649,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -16648,7 +16679,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -16760,7 +16793,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -16788,7 +16823,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -16889,7 +16926,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -17225,7 +17264,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -17320,7 +17361,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -17348,7 +17391,20 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string", + "enum": [ + "avatar" + ] + } + } + } } } } @@ -17833,8 +17889,8 @@ } } }, - "410": { - "description": "Remote server could not be reached to notify about the acceptance", + "404": { + "description": "Invite can not be found", "content": { "application/json": { "schema": { @@ -17871,8 +17927,8 @@ } } }, - "404": { - "description": "Invite can not be found", + "410": { + "description": "Remote server could not be reached to notify about the acceptance", "content": { "application/json": { "schema": { @@ -17893,6 +17949,9 @@ }, "data": { "type": "object", + "required": [ + "error" + ], "properties": { "error": { "type": "string" @@ -17979,7 +18038,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -18009,6 +18070,9 @@ }, "data": { "type": "object", + "required": [ + "error" + ], "properties": { "error": { "type": "string" @@ -18044,6 +18108,9 @@ }, "data": { "type": "object", + "required": [ + "error" + ], "properties": { "error": { "type": "string" @@ -18502,7 +18569,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -18530,7 +18599,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -18558,7 +18629,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -18586,7 +18659,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -18697,7 +18772,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -18725,7 +18802,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -18753,7 +18832,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -18781,7 +18862,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -18809,7 +18892,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -18908,7 +18993,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -18936,7 +19023,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -18964,7 +19053,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -18992,7 +19083,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -19869,7 +19962,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -20009,7 +20104,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -20125,7 +20222,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -20238,7 +20337,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -20498,7 +20599,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } diff --git a/openapi.json b/openapi.json index 6e36a39c9a5..01554cd38a4 100644 --- a/openapi.json +++ b/openapi.json @@ -1326,6 +1326,37 @@ } ] }, + "SignalingFederationSettings": { + "type": "object", + "required": [ + "server", + "nextcloudServer", + "helloAuthParams", + "roomId" + ], + "properties": { + "server": { + "type": "string" + }, + "nextcloudServer": { + "type": "string" + }, + "helloAuthParams": { + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "type": "string" + } + } + }, + "roomId": { + "type": "string" + } + } + }, "SignalingSession": { "type": "object", "required": [ @@ -1385,43 +1416,8 @@ ], "properties": { "federation": { - "oneOf": [ - { - "type": "object", - "required": [ - "server", - "nextcloudServer", - "helloAuthParams", - "roomId" - ], - "properties": { - "server": { - "type": "string" - }, - "nextcloudServer": { - "type": "string" - }, - "helloAuthParams": { - "type": "object", - "required": [ - "token" - ], - "properties": { - "token": { - "type": "string" - } - } - }, - "roomId": { - "type": "string" - } - } - }, - { - "type": "array", - "maxItems": 0 - } - ] + "$ref": "#/components/schemas/SignalingFederationSettings", + "nullable": true }, "helloAuthParams": { "type": "object", @@ -2341,7 +2337,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4097,7 +4095,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4125,7 +4125,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4155,6 +4157,9 @@ }, "data": { "type": "object", + "required": [ + "error" + ], "properties": { "error": { "type": "string" @@ -4261,7 +4266,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4289,7 +4296,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4317,7 +4326,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4409,7 +4420,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4437,7 +4450,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4642,7 +4657,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4650,8 +4667,8 @@ } } }, - "400": { - "description": "Conditions to join not met", + "404": { + "description": "Call not found", "content": { "application/json": { "schema": { @@ -4671,12 +4688,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "properties": { - "error": { - "type": "string" - } - } + "nullable": true } } } @@ -4685,8 +4697,8 @@ } } }, - "404": { - "description": "Call not found", + "400": { + "description": "Conditions to join not met", "content": { "application/json": { "schema": { @@ -4706,7 +4718,15 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "nullable": true + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } } } } @@ -4813,7 +4833,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4841,7 +4863,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -4959,7 +4983,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -5080,7 +5106,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -5108,7 +5136,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -5238,15 +5268,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - } - } + "nullable": true } } } @@ -5276,15 +5298,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - } - } + "nullable": true } } } @@ -5314,15 +5328,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "message": { - "type": "string" - } - } + "nullable": true } } } @@ -5353,6 +5359,9 @@ }, "data": { "type": "object", + "required": [ + "error" + ], "properties": { "error": { "type": "string" @@ -8104,7 +8113,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -8261,7 +8272,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -8289,7 +8302,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -8389,7 +8404,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -8417,7 +8434,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -8445,7 +8464,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -10487,7 +10508,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -10603,7 +10626,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -10732,7 +10757,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -10878,7 +10905,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -16754,7 +16783,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -16782,7 +16813,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -16894,7 +16927,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -16922,7 +16957,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -17023,7 +17060,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -17359,7 +17398,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -17454,7 +17495,9 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "nullable": true + } } } } @@ -17482,7 +17525,20 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": {} + "data": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string", + "enum": [ + "avatar" + ] + } + } + } } } } diff --git a/src/types/openapi/openapi-federation.ts b/src/types/openapi/openapi-federation.ts index f45f2602009..f2a820dc997 100644 --- a/src/types/openapi/openapi-federation.ts +++ b/src/types/openapi/openapi-federation.ts @@ -580,7 +580,7 @@ export interface operations { ocs: { meta: components["schemas"]["OCSMeta"]; data: { - error?: string; + error: string; }; }; }; @@ -644,7 +644,7 @@ export interface operations { ocs: { meta: components["schemas"]["OCSMeta"]; data: { - error?: string; + error: string; }; }; }; @@ -660,7 +660,7 @@ export interface operations { ocs: { meta: components["schemas"]["OCSMeta"]; data: { - error?: string; + error: string; }; }; }; diff --git a/src/types/openapi/openapi-full.ts b/src/types/openapi/openapi-full.ts index 21ea412361b..b3a280c3d37 100644 --- a/src/types/openapi/openapi-full.ts +++ b/src/types/openapi/openapi-full.ts @@ -2280,6 +2280,14 @@ export type components = { isArchived: boolean; }; RoomLastMessage: components["schemas"]["ChatMessage"] | components["schemas"]["ChatProxyMessage"]; + SignalingFederationSettings: { + server: string; + nextcloudServer: string; + helloAuthParams: { + token: string; + }; + roomId: string; + }; SignalingSession: { actorId: string; actorType: string; @@ -2295,14 +2303,7 @@ export type components = { userId: string; }; SignalingSettings: { - federation: { - server: string; - nextcloudServer: string; - helloAuthParams: { - token: string; - }; - roomId: string; - } | unknown[]; + federation: components["schemas"]["SignalingFederationSettings"]; helloAuthParams: { "1.0": { userid: string | null; @@ -3421,7 +3422,7 @@ export interface operations { ocs: { meta: components["schemas"]["OCSMeta"]; data: { - error?: string; + error: string; }; }; }; @@ -3660,7 +3661,7 @@ export interface operations { ocs: { meta: components["schemas"]["OCSMeta"]; data: { - error?: string; + error: string; }; }; }; @@ -3819,10 +3820,7 @@ export interface operations { "application/json": { ocs: { meta: components["schemas"]["OCSMeta"]; - data: { - error?: string; - message?: string; - }; + data: unknown; }; }; }; @@ -3836,10 +3834,7 @@ export interface operations { "application/json": { ocs: { meta: components["schemas"]["OCSMeta"]; - data: { - error?: string; - message?: string; - }; + data: unknown; }; }; }; @@ -3853,10 +3848,7 @@ export interface operations { "application/json": { ocs: { meta: components["schemas"]["OCSMeta"]; - data: { - error?: string; - message?: string; - }; + data: unknown; }; }; }; @@ -3871,7 +3863,7 @@ export interface operations { ocs: { meta: components["schemas"]["OCSMeta"]; data: { - error?: string; + error: string; message?: string; }; }; @@ -8697,7 +8689,10 @@ export interface operations { "application/json": { ocs: { meta: components["schemas"]["OCSMeta"]; - data: unknown; + data: { + /** @enum {string} */ + error: "avatar"; + }; }; }; }; @@ -8886,7 +8881,7 @@ export interface operations { ocs: { meta: components["schemas"]["OCSMeta"]; data: { - error?: string; + error: string; }; }; }; @@ -8950,7 +8945,7 @@ export interface operations { ocs: { meta: components["schemas"]["OCSMeta"]; data: { - error?: string; + error: string; }; }; }; @@ -8966,7 +8961,7 @@ export interface operations { ocs: { meta: components["schemas"]["OCSMeta"]; data: { - error?: string; + error: string; }; }; }; diff --git a/src/types/openapi/openapi.ts b/src/types/openapi/openapi.ts index ea20a29be16..d43bc1046ff 100644 --- a/src/types/openapi/openapi.ts +++ b/src/types/openapi/openapi.ts @@ -1761,6 +1761,14 @@ export type components = { isArchived: boolean; }; RoomLastMessage: components["schemas"]["ChatMessage"] | components["schemas"]["ChatProxyMessage"]; + SignalingFederationSettings: { + server: string; + nextcloudServer: string; + helloAuthParams: { + token: string; + }; + roomId: string; + }; SignalingSession: { actorId: string; actorType: string; @@ -1776,14 +1784,7 @@ export type components = { userId: string; }; SignalingSettings: { - federation: { - server: string; - nextcloudServer: string; - helloAuthParams: { - token: string; - }; - roomId: string; - } | unknown[]; + federation: components["schemas"]["SignalingFederationSettings"]; helloAuthParams: { "1.0": { userid: string | null; @@ -2902,7 +2903,7 @@ export interface operations { ocs: { meta: components["schemas"]["OCSMeta"]; data: { - error?: string; + error: string; }; }; }; @@ -3141,7 +3142,7 @@ export interface operations { ocs: { meta: components["schemas"]["OCSMeta"]; data: { - error?: string; + error: string; }; }; }; @@ -3300,10 +3301,7 @@ export interface operations { "application/json": { ocs: { meta: components["schemas"]["OCSMeta"]; - data: { - error?: string; - message?: string; - }; + data: unknown; }; }; }; @@ -3317,10 +3315,7 @@ export interface operations { "application/json": { ocs: { meta: components["schemas"]["OCSMeta"]; - data: { - error?: string; - message?: string; - }; + data: unknown; }; }; }; @@ -3334,10 +3329,7 @@ export interface operations { "application/json": { ocs: { meta: components["schemas"]["OCSMeta"]; - data: { - error?: string; - message?: string; - }; + data: unknown; }; }; }; @@ -3352,7 +3344,7 @@ export interface operations { ocs: { meta: components["schemas"]["OCSMeta"]; data: { - error?: string; + error: string; message?: string; }; }; @@ -8278,7 +8270,10 @@ export interface operations { "application/json": { ocs: { meta: components["schemas"]["OCSMeta"]; - data: unknown; + data: { + /** @enum {string} */ + error: "avatar"; + }; }; }; }; From 37c61aa92b2884caa61e4541c16a60bfe3d4ba20 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 22 Nov 2024 09:15:23 +0100 Subject: [PATCH 17/19] fix(federation): Fix expected status code Signed-off-by: Joas Schilling --- lib/Federation/Proxy/TalkV1/Controller/CallController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Federation/Proxy/TalkV1/Controller/CallController.php b/lib/Federation/Proxy/TalkV1/Controller/CallController.php index f4c3903f43a..a2fee70ce42 100644 --- a/lib/Federation/Proxy/TalkV1/Controller/CallController.php +++ b/lib/Federation/Proxy/TalkV1/Controller/CallController.php @@ -103,7 +103,7 @@ public function joinFederatedCall(Room $room, Participant $participant, int $fla if ($statusCode === Http::STATUS_BAD_REQUEST) { /** @var array{error: string} $data */ - $data = $this->proxy->getOCSData($proxy); + $data = $this->proxy->getOCSData($proxy, [Http::STATUS_BAD_REQUEST]); return new DataResponse($data, $statusCode); } @@ -136,7 +136,7 @@ public function ringAttendee(Room $room, Participant $participant, int $attendee if ($statusCode === Http::STATUS_BAD_REQUEST) { /** @var array{error: string} $data */ - $data = $this->proxy->getOCSData($proxy); + $data = $this->proxy->getOCSData($proxy, [Http::STATUS_BAD_REQUEST]); return new DataResponse($data, $statusCode); } From ad5f9a56cb29a6b1533f6d324b2a6692102f9f45 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 22 Nov 2024 09:15:54 +0100 Subject: [PATCH 18/19] fix(federation): Allow federation sync to always toggle recording consent Signed-off-by: Joas Schilling --- lib/Service/RoomService.php | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/Service/RoomService.php b/lib/Service/RoomService.php index a813e906596..bba48b4a67d 100644 --- a/lib/Service/RoomService.php +++ b/lib/Service/RoomService.php @@ -291,7 +291,7 @@ public function setSIPEnabled(Room $room, int $newSipEnabled): void { * @psalm-param RecordingService::CONSENT_REQUIRED_* $recordingConsent * @throws RecordingConsentException When the room has an active call or the value is invalid */ - public function setRecordingConsent(Room $room, int $recordingConsent, bool $allowUpdatingBreakoutRooms = false): void { + public function setRecordingConsent(Room $room, int $recordingConsent, bool $allowUpdatingBreakoutRoomsAndFederatedRooms = false): void { $oldRecordingConsent = $room->getRecordingConsent(); if ($recordingConsent === $oldRecordingConsent) { @@ -302,16 +302,18 @@ public function setRecordingConsent(Room $room, int $recordingConsent, bool $all throw new RecordingConsentException(RecordingConsentException::REASON_VALUE); } - if ($recordingConsent !== RecordingService::CONSENT_REQUIRED_NO && $room->getCallFlag() !== Participant::FLAG_DISCONNECTED) { - throw new RecordingConsentException(RecordingConsentException::REASON_CALL); - } + if (!$allowUpdatingBreakoutRoomsAndFederatedRooms) { + if ($recordingConsent !== RecordingService::CONSENT_REQUIRED_NO && $room->getCallFlag() !== Participant::FLAG_DISCONNECTED) { + throw new RecordingConsentException(RecordingConsentException::REASON_CALL); + } - if (!$allowUpdatingBreakoutRooms && $room->getObjectType() === BreakoutRoom::PARENT_OBJECT_TYPE) { - throw new RecordingConsentException(RecordingConsentException::REASON_BREAKOUT_ROOM); - } + if ($room->getObjectType() === BreakoutRoom::PARENT_OBJECT_TYPE) { + throw new RecordingConsentException(RecordingConsentException::REASON_BREAKOUT_ROOM); + } - if ($room->getBreakoutRoomStatus() !== BreakoutRoom::STATUS_STOPPED) { - throw new RecordingConsentException(RecordingConsentException::REASON_BREAKOUT_ROOM); + if ($room->getBreakoutRoomStatus() !== BreakoutRoom::STATUS_STOPPED) { + throw new RecordingConsentException(RecordingConsentException::REASON_BREAKOUT_ROOM); + } } $event = new BeforeRoomModifiedEvent($room, ARoomModifiedEvent::PROPERTY_RECORDING_CONSENT, $recordingConsent, $oldRecordingConsent); From 15410d5e447b969be926e50ccefdbc5f786c5c7e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 22 Nov 2024 10:08:10 +0100 Subject: [PATCH 19/19] fix(federation): Allow federation error responses to be read twice Signed-off-by: Joas Schilling --- lib/Federation/Proxy/TalkV1/ProxyRequest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Federation/Proxy/TalkV1/ProxyRequest.php b/lib/Federation/Proxy/TalkV1/ProxyRequest.php index ea5d606bc2f..55ce4642c05 100644 --- a/lib/Federation/Proxy/TalkV1/ProxyRequest.php +++ b/lib/Federation/Proxy/TalkV1/ProxyRequest.php @@ -123,6 +123,7 @@ protected function request( try { $body = $e->getResponse()->getBody()->getContents(); $data = json_decode($body, true, flags: JSON_THROW_ON_ERROR); + $e->getResponse()->getBody()->rewind(); if (!is_array($data)) { throw new \RuntimeException('JSON response is not an array'); }