diff --git a/lib/Controller/SignalingController.php b/lib/Controller/SignalingController.php index fbe356f42fe..12aeb675d45 100644 --- a/lib/Controller/SignalingController.php +++ b/lib/Controller/SignalingController.php @@ -526,6 +526,8 @@ protected function getUsersInRoom(Room $room, int $pingTimestamp): array { 'sessionId' => $session->getSessionId(), 'inCall' => $session->getInCall(), 'participantPermissions' => $participant->getPermissions(), + 'actorType' => $participant->getAttendee()->getActorType(), + 'actorId' => $participant->getAttendee()->getActorId(), ]; } diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php index 86b3893ac41..76f81f5aeec 100644 --- a/lib/ResponseDefinitions.php +++ b/lib/ResponseDefinitions.php @@ -275,6 +275,8 @@ * } * * @psalm-type TalkSignalingSession = array{ + * actorId: string, + * actorType: string, * inCall: int, * lastPing: int, * participantPermissions: int, diff --git a/lib/Signaling/BackendNotifier.php b/lib/Signaling/BackendNotifier.php index f5f97624742..0d58b778e28 100644 --- a/lib/Signaling/BackendNotifier.php +++ b/lib/Signaling/BackendNotifier.php @@ -336,9 +336,10 @@ public function participantsModified(Room $room, array $sessionIds): void { 'participantType' => $attendee->getParticipantType(), 'participantPermissions' => Attendee::PERMISSIONS_CUSTOM, 'displayName' => $attendee->getDisplayName(), + 'actorType' => $attendee->getActorType(), + 'actorId' => $attendee->getActorId(), ]; - if ($attendee->getActorType() === Attendee::ACTOR_USERS - || $attendee->getActorType() === Attendee::ACTOR_FEDERATED_USERS) { + if ($attendee->getActorType() === Attendee::ACTOR_USERS) { $data['userId'] = $attendee->getActorId(); } @@ -428,9 +429,10 @@ public function roomInCallChanged(Room $room, int $flags, array $sessionIds, boo 'nextcloudSessionId' => $session->getSessionId(), 'participantType' => $attendee->getParticipantType(), 'participantPermissions' => $participant->getPermissions(), + 'actorType' => $attendee->getActorType(), + 'actorId' => $attendee->getActorId(), ]; - if ($attendee->getActorType() === Attendee::ACTOR_USERS - || $attendee->getActorType() === Attendee::ACTOR_FEDERATED_USERS) { + if ($attendee->getActorType() === Attendee::ACTOR_USERS) { $data['userId'] = $attendee->getActorId(); } diff --git a/openapi-full.json b/openapi-full.json index 8d3df0085ff..bfd878b1007 100644 --- a/openapi-full.json +++ b/openapi-full.json @@ -1344,6 +1344,8 @@ "SignalingSession": { "type": "object", "required": [ + "actorId", + "actorType", "inCall", "lastPing", "participantPermissions", @@ -1352,6 +1354,12 @@ "userId" ], "properties": { + "actorId": { + "type": "string" + }, + "actorType": { + "type": "string" + }, "inCall": { "type": "integer", "format": "int64" diff --git a/openapi.json b/openapi.json index 649b3365bbd..47e89cb2bbe 100644 --- a/openapi.json +++ b/openapi.json @@ -1231,6 +1231,8 @@ "SignalingSession": { "type": "object", "required": [ + "actorId", + "actorType", "inCall", "lastPing", "participantPermissions", @@ -1239,6 +1241,12 @@ "userId" ], "properties": { + "actorId": { + "type": "string" + }, + "actorType": { + "type": "string" + }, "inCall": { "type": "integer", "format": "int64" diff --git a/src/components/CallView/shared/VideoVue.vue b/src/components/CallView/shared/VideoVue.vue index c8a1d2026df..a36263536b5 100644 --- a/src/components/CallView/shared/VideoVue.vue +++ b/src/components/CallView/shared/VideoVue.vue @@ -358,7 +358,9 @@ export default { }, participantActorType() { - if (this.participant?.actorType) { + if (this.model.attributes.actorType) { + return this.model.attributes.actorType + } else if (this.participant?.actorType) { return this.participant.actorType } else if (this.peerData?.actorType) { return this.peerData.actorType @@ -370,6 +372,10 @@ export default { }, participantUserId() { + if (this.model.attributes.actorId) { + return this.model.attributes.actorId + } + if (this.model.attributes.userId) { return this.model.attributes.userId } diff --git a/src/types/openapi/openapi-full.ts b/src/types/openapi/openapi-full.ts index 6321a14a6b1..2b83c4f7269 100644 --- a/src/types/openapi/openapi-full.ts +++ b/src/types/openapi/openapi-full.ts @@ -2168,6 +2168,8 @@ export type components = { }; RoomLastMessage: components["schemas"]["ChatMessage"] | components["schemas"]["ChatProxyMessage"]; SignalingSession: { + actorId: string; + actorType: string; /** Format: int64 */ inCall: number; /** Format: int64 */ diff --git a/src/types/openapi/openapi.ts b/src/types/openapi/openapi.ts index 2de1735aebd..e19e43a62ef 100644 --- a/src/types/openapi/openapi.ts +++ b/src/types/openapi/openapi.ts @@ -1649,6 +1649,8 @@ export type components = { }; RoomLastMessage: components["schemas"]["ChatMessage"] | components["schemas"]["ChatProxyMessage"]; SignalingSession: { + actorId: string; + actorType: string; /** Format: int64 */ inCall: number; /** Format: int64 */ diff --git a/src/utils/webrtc/models/CallParticipantModel.js b/src/utils/webrtc/models/CallParticipantModel.js index e31f0a9740e..64e170f3429 100644 --- a/src/utils/webrtc/models/CallParticipantModel.js +++ b/src/utils/webrtc/models/CallParticipantModel.js @@ -33,6 +33,8 @@ export default function CallParticipantModel(options) { screenPeer: null, // "undefined" is used for values not known yet; "null" or "false" // are used for known but negative/empty values. + actorType: undefined, + actorId: undefined, userId: undefined, name: undefined, internal: undefined, @@ -349,6 +351,11 @@ CallParticipantModel.prototype = { } }, + setActor(actorType, actorId) { + this.set('actorType', actorType) + this.set('actorId', actorId) + }, + setUserId(userId) { this.set('userId', userId) }, diff --git a/src/utils/webrtc/webrtc.js b/src/utils/webrtc/webrtc.js index 314a94caf1b..6bc015b66bc 100644 --- a/src/utils/webrtc/webrtc.js +++ b/src/utils/webrtc/webrtc.js @@ -293,6 +293,7 @@ function usersChanged(signaling, newUsers, disconnectedSessionIds) { webRtc: webrtc, }) } + callParticipantModel.setActor(user.actorType, user.actorId) callParticipantModel.setUserId(userId) callParticipantModel.setNextcloudSessionId(nextcloudSessionId) if (user.internal) { diff --git a/tests/integration/features/callapi/update-call-flags.feature b/tests/integration/features/callapi/update-call-flags.feature index 28372592349..cc033300027 100644 --- a/tests/integration/features/callapi/update-call-flags.feature +++ b/tests/integration/features/callapi/update-call-flags.feature @@ -26,12 +26,12 @@ Feature: callapi/update-call-flags Then signaling server received the following requests | token | data | | public room | {"type":"message","message":{"data":{"type":"chat","chat":{"refresh":true}}}} | - | public room | {"type":"incall","incall":{"incall":7,"changed":[{"inCall":7,"lastPing":LAST_PING(),"sessionId":"SESSION(owner)","nextcloudSessionId":"SESSION(owner)","participantType":1,"participantPermissions":254,"userId":"owner"}],"users":[{"inCall":7,"lastPing":LAST_PING(),"sessionId":"SESSION(owner)","nextcloudSessionId":"SESSION(owner)","participantType":1,"participantPermissions":254,"userId":"owner"}]}} | + | public room | {"type":"incall","incall":{"incall":7,"changed":[{"inCall":7,"lastPing":LAST_PING(),"sessionId":"SESSION(owner)","nextcloudSessionId":"SESSION(owner)","participantType":1,"participantPermissions":254,"actorType":"users","actorId":"owner","userId":"owner"}],"users":[{"inCall":7,"lastPing":LAST_PING(),"sessionId":"SESSION(owner)","nextcloudSessionId":"SESSION(owner)","participantType":1,"participantPermissions":254,"actorType":"users","actorId":"owner","userId":"owner"}]}} | And reset signaling server requests When user "owner" updates call flags in room "public room" to "1" with 200 (v4) Then signaling server received the following requests | token | data | - | public room | {"type":"incall","incall":{"incall":1,"changed":[{"inCall":1,"lastPing":LAST_PING(),"sessionId":"SESSION(owner)","nextcloudSessionId":"SESSION(owner)","participantType":1,"participantPermissions":254,"userId":"owner"}],"users":[{"inCall":1,"lastPing":LAST_PING(),"sessionId":"SESSION(owner)","nextcloudSessionId":"SESSION(owner)","participantType":1,"participantPermissions":254,"userId":"owner"}]}} | + | public room | {"type":"incall","incall":{"incall":1,"changed":[{"inCall":1,"lastPing":LAST_PING(),"sessionId":"SESSION(owner)","nextcloudSessionId":"SESSION(owner)","participantType":1,"participantPermissions":254,"actorType":"users","actorId":"owner","userId":"owner"}],"users":[{"inCall":1,"lastPing":LAST_PING(),"sessionId":"SESSION(owner)","nextcloudSessionId":"SESSION(owner)","participantType":1,"participantPermissions":254,"actorType":"users","actorId":"owner","userId":"owner"}]}} | And user "moderator" joins call "public room" with 200 (v4) And user "invited user" joins call "public room" with 200 (v4) And user "not invited but joined user" joins call "public room" with 200 (v4) diff --git a/tests/integration/features/conversation-4/promotion-demotion.feature b/tests/integration/features/conversation-4/promotion-demotion.feature index 9913f479cf5..26d758526de 100644 --- a/tests/integration/features/conversation-4/promotion-demotion.feature +++ b/tests/integration/features/conversation-4/promotion-demotion.feature @@ -23,7 +23,7 @@ Feature: conversation-2/promotion-demotion # "participantsModified" once the clients no longer expect a # "roomModified" message for participant type changes. | room | {"type":"update","update":{"userids":["participant1","participant2"],"properties":{"name":"Private conversation","type":3,"lobby-state":0,"lobby-timer":null,"read-only":0,"listable":0,"active-since":null,"sip-enabled":0,"description":""}}} | - | room | {"type":"participants","participants":{"changed":[],"users":[{"inCall":0,"lastPing":0,"sessionId":"0","participantType":1,"participantPermissions":1,"displayName":"participant1-displayname","userId":"participant1"},{"inCall":0,"lastPing":0,"sessionId":"0","participantType":2,"participantPermissions":1,"displayName":"participant2-displayname","userId":"participant2"}]}} | + | room | {"type":"participants","participants":{"changed":[],"users":[{"inCall":0,"lastPing":0,"sessionId":"0","participantType":1,"participantPermissions":1,"displayName":"participant1-displayname","actorType":"users","actorId":"participant1","userId":"participant1"},{"inCall":0,"lastPing":0,"sessionId":"0","participantType":2,"participantPermissions":1,"displayName":"participant2-displayname","actorType":"users","actorId":"participant2","userId":"participant2"}]}} | And user "participant2" is participant of the following rooms (v4) | id | type | participantType | | room | 3 | 2 |