Rename publisher role to speaker across the application
This commit is contained in:
parent
69b5bf3071
commit
1161f1bb21
@ -57,16 +57,21 @@ openvidu-appdata/
|
|||||||
### Directory Descriptions
|
### Directory Descriptions
|
||||||
|
|
||||||
#### **Global Preferences** (`global-preferences.json`)
|
#### **Global Preferences** (`global-preferences.json`)
|
||||||
|
|
||||||
Contains system-wide settings and configurations for the OpenVidu Meet application, such as default recording settings, UI preferences, and feature toggles.
|
Contains system-wide settings and configurations for the OpenVidu Meet application, such as default recording settings, UI preferences, and feature toggles.
|
||||||
|
|
||||||
#### **Users** (`users/`)
|
#### **Users** (`users/`)
|
||||||
|
|
||||||
Stores user account information in individual JSON files. Each file is named using the username (e.g., `admin.json`) and contains user-specific data including authentication details, permissions, and preferences.
|
Stores user account information in individual JSON files. Each file is named using the username (e.g., `admin.json`) and contains user-specific data including authentication details, permissions, and preferences.
|
||||||
|
|
||||||
#### **Rooms** (`rooms/`)
|
#### **Rooms** (`rooms/`)
|
||||||
|
|
||||||
Contains room configuration and metadata. Each room is stored in its own directory named after the room ID, containing:
|
Contains room configuration and metadata. Each room is stored in its own directory named after the room ID, containing:
|
||||||
|
|
||||||
- `room-123.json`: Room configuration, settings, and metadata
|
- `room-123.json`: Room configuration, settings, and metadata
|
||||||
|
|
||||||
#### **Recordings** (`recordings/`)
|
#### **Recordings** (`recordings/`)
|
||||||
|
|
||||||
The recordings directory is organized into several subdirectories to manage different aspects of recorded content:
|
The recordings directory is organized into several subdirectories to manage different aspects of recorded content:
|
||||||
|
|
||||||
- **Recording Files** (`room-123/`): Contains the actual video files with naming convention `room-123--{uid}.mp4`
|
- **Recording Files** (`room-123/`): Contains the actual video files with naming convention `room-123--{uid}.mp4`
|
||||||
@ -92,16 +97,13 @@ The recordings directory is organized into several subdirectories to manage diff
|
|||||||
Recordings use a composite identifier format: `recordingId: room-123--{egressId}--{uid}`
|
Recordings use a composite identifier format: `recordingId: room-123--{egressId}--{uid}`
|
||||||
|
|
||||||
Where:
|
Where:
|
||||||
|
|
||||||
- `room-123`: The room identifier
|
- `room-123`: The room identifier
|
||||||
- `{egressId}`: LiveKit egress process identifier
|
- `{egressId}`: LiveKit egress process identifier
|
||||||
- `{uid}`: Unique recording session identifier
|
- `{uid}`: Unique recording session identifier
|
||||||
|
|
||||||
This naming convention ensures uniqueness and provides traceability between the recording file, its metadata, and the originating room session.
|
This naming convention ensures uniqueness and provides traceability between the recording file, its metadata, and the originating room session.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Recordings
|
## Recordings
|
||||||
|
|
||||||
The recording feature is based on the following key concepts:
|
The recording feature is based on the following key concepts:
|
||||||
@ -112,7 +114,6 @@ The recording feature is based on the following key concepts:
|
|||||||
2. **Lock lifetime**:
|
2. **Lock lifetime**:
|
||||||
The lock has not lifetime. It is not automatically released after a certain period. Instead, it remains active until the recording is manually stopped and an `egress_ended` webhook is received, or when the room meeting ends. This design choice allows for flexibility in managing recordings, as the lock can be held for an extended duration if needed. However, it also means that care must be taken to ensure that the lock is released appropriately to avoid blocking future recording attempts. (see **Failure handling** below).
|
The lock has not lifetime. It is not automatically released after a certain period. Instead, it remains active until the recording is manually stopped and an `egress_ended` webhook is received, or when the room meeting ends. This design choice allows for flexibility in managing recordings, as the lock can be held for an extended duration if needed. However, it also means that care must be taken to ensure that the lock is released appropriately to avoid blocking future recording attempts. (see **Failure handling** below).
|
||||||
|
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TD
|
flowchart TD
|
||||||
A["Start New Recording Request"] --> B{"Can room be recorded?"}
|
A["Start New Recording Request"] --> B{"Can room be recorded?"}
|
||||||
@ -165,4 +166,3 @@ graph TD;
|
|||||||
M -->|No more rooms| N[Process completed]
|
M -->|No more rooms| N[Process completed]
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -3,10 +3,10 @@ in: header
|
|||||||
description: |
|
description: |
|
||||||
The role of the participant in the meeting. It can be one of the following values:
|
The role of the participant in the meeting. It can be one of the following values:
|
||||||
- `moderator`: Can manage the room and its participants.
|
- `moderator`: Can manage the room and its participants.
|
||||||
- `publisher`: Can publish media streams to the room.
|
- `speaker`: Can publish media streams to the room.
|
||||||
|
|
||||||
This is required to distinguish roles when multiple are present in the participant token
|
This is required to distinguish roles when multiple are present in the participant token
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
enum: ['moderator', 'publisher']
|
enum: ['moderator', 'speaker']
|
||||||
|
|||||||
@ -19,7 +19,7 @@ content:
|
|||||||
canRecord: true
|
canRecord: true
|
||||||
canChat: true
|
canChat: true
|
||||||
canChangeVirtualBackground: true
|
canChangeVirtualBackground: true
|
||||||
- role: 'publisher'
|
- role: 'speaker'
|
||||||
permissions:
|
permissions:
|
||||||
livekit:
|
livekit:
|
||||||
roomJoin: true
|
roomJoin: true
|
||||||
|
|||||||
@ -18,8 +18,8 @@ content:
|
|||||||
enabled: false
|
enabled: false
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundPreferences:
|
||||||
enabled: true
|
enabled: true
|
||||||
moderatorURL: 'http://localhost:6080/room/room-123?secret=123456'
|
moderatorRoomURL: 'http://localhost:6080/room/room-123?secret=123456'
|
||||||
publisherURL: 'http://localhost:6080/room/room-123?secret=654321'
|
speakerRoomURL: 'http://localhost:6080/room/room-123?secret=654321'
|
||||||
|
|
||||||
fields=roomId:
|
fields=roomId:
|
||||||
summary: Response with only the roomId
|
summary: Response with only the roomId
|
||||||
@ -41,8 +41,8 @@ content:
|
|||||||
virtualBackgroundPreferences:
|
virtualBackgroundPreferences:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
fields=moderatorURL,publisherURL:
|
fields=moderatorRoomURL,speakerRoomURL:
|
||||||
summary: Response containing only moderator and publisher URLs
|
summary: Response containing only moderator and speaker URLs
|
||||||
value:
|
value:
|
||||||
moderatorURL: 'http://localhost:6080/room/room-123?secret=123456'
|
moderatorRoomURL: 'http://localhost:6080/room/room-123?secret=123456'
|
||||||
publisherURL: 'http://localhost:6080/room/room-123?secret=654321'
|
speakerRoomURL: 'http://localhost:6080/room/room-123?secret=654321'
|
||||||
|
|||||||
@ -27,8 +27,8 @@ content:
|
|||||||
enabled: false
|
enabled: false
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundPreferences:
|
||||||
enabled: true
|
enabled: true
|
||||||
moderatorURL: 'http://localhost:6080/room/room-123?secret=123456'
|
moderatorRoomURL: 'http://localhost:6080/room/room-123?secret=123456'
|
||||||
publisherURL: 'http://localhost:6080/room/room-123?secret=654321'
|
speakerRoomURL: 'http://localhost:6080/room/room-123?secret=654321'
|
||||||
- roomId: 'room-456'
|
- roomId: 'room-456'
|
||||||
roomName: 'room'
|
roomName: 'room'
|
||||||
creationDate: 1620001000000
|
creationDate: 1620001000000
|
||||||
@ -40,8 +40,8 @@ content:
|
|||||||
enabled: true
|
enabled: true
|
||||||
virtualBackgroundPreferences:
|
virtualBackgroundPreferences:
|
||||||
enabled: false
|
enabled: false
|
||||||
moderatorURL: 'http://localhost:6080/room/room-456?secret=789012'
|
moderatorRoomURL: 'http://localhost:6080/room/room-456?secret=789012'
|
||||||
publisherURL: 'http://localhost:6080/room/room-456?secret=210987'
|
speakerRoomURL: 'http://localhost:6080/room/room-456?secret=210987'
|
||||||
pagination:
|
pagination:
|
||||||
isTruncated: false
|
isTruncated: false
|
||||||
maxItems: 10
|
maxItems: 10
|
||||||
@ -86,14 +86,14 @@ content:
|
|||||||
nextPageToken: 'abc123'
|
nextPageToken: 'abc123'
|
||||||
maxItems: 10
|
maxItems: 10
|
||||||
|
|
||||||
fields=moderatorURL,publisherURL:
|
fields=moderatorRoomURL,speakerRoomURL:
|
||||||
summary: Response containing only moderator and publisher URLs
|
summary: Response containing only moderator and speaker URLs
|
||||||
value:
|
value:
|
||||||
rooms:
|
rooms:
|
||||||
- moderatorURL: 'http://localhost:6080/room/room-123?secret=123456'
|
- moderatorRoomURL: 'http://localhost:6080/room/room-123?secret=123456'
|
||||||
publisherURL: 'http://localhost:6080/room/room-123?secret=654321'
|
speakerRoomURL: 'http://localhost:6080/room/room-123?secret=654321'
|
||||||
- moderatorURL: 'http://localhost:6080/room/room-456?secret=789012'
|
- moderatorRoomURL: 'http://localhost:6080/room/room-456?secret=789012'
|
||||||
publisherURL: 'http://localhost:6080/room/room-456?secret=210987'
|
speakerRoomURL: 'http://localhost:6080/room/room-456?secret=210987'
|
||||||
pagination:
|
pagination:
|
||||||
isTruncated: false
|
isTruncated: false
|
||||||
maxItems: 10
|
maxItems: 10
|
||||||
|
|||||||
@ -2,12 +2,12 @@ type: object
|
|||||||
properties:
|
properties:
|
||||||
role:
|
role:
|
||||||
type: string
|
type: string
|
||||||
enum: ['moderator', 'publisher']
|
enum: ['moderator', 'speaker']
|
||||||
description: |
|
description: |
|
||||||
A role that a participant can have in a room.
|
A role that a participant can have in a room.
|
||||||
The role determines the permissions of the participant in the room.
|
The role determines the permissions of the participant in the room.
|
||||||
- `moderator`: Can manage the room and its participants.
|
- `moderator`: Can manage the room and its participants.
|
||||||
- `publisher`: Can publish media streams to the room.
|
- `speaker`: Can publish media streams to the room.
|
||||||
example: 'moderator'
|
example: 'moderator'
|
||||||
permissions:
|
permissions:
|
||||||
type: object
|
type: object
|
||||||
|
|||||||
@ -31,14 +31,14 @@ MeetRecordingPreferences:
|
|||||||
enum:
|
enum:
|
||||||
- admin
|
- admin
|
||||||
- admin-moderator
|
- admin-moderator
|
||||||
- admin-moderator-publisher
|
- admin-moderator-speaker
|
||||||
default: admin-moderator-publisher
|
default: admin-moderator-speaker
|
||||||
example: admin-moderator-publisher
|
example: admin-moderator-speaker
|
||||||
description: |
|
description: |
|
||||||
Defines who can access the recording. Options are:
|
Defines who can access the recording. Options are:
|
||||||
- `admin`: Only administrators can access the recording.
|
- `admin`: Only administrators can access the recording.
|
||||||
- `admin-moderator`: Administrators and moderators can access the recording.
|
- `admin-moderator`: Administrators and moderators can access the recording.
|
||||||
- `admin-moderator-publisher`: Administrators, moderators and publishers can access the recording.
|
- `admin-moderator-speaker`: Administrators, moderators and speakers can access the recording.
|
||||||
MeetVirtualBackgroundPreferences:
|
MeetVirtualBackgroundPreferences:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
@ -39,15 +39,15 @@ properties:
|
|||||||
# description: >
|
# description: >
|
||||||
# The maximum number of participants allowed in the room. If the number of participants exceeds
|
# The maximum number of participants allowed in the room. If the number of participants exceeds
|
||||||
# this limit, new participants will not be allowed to join.
|
# this limit, new participants will not be allowed to join.
|
||||||
moderatorURL:
|
moderatorRoomURL:
|
||||||
type: string
|
type: string
|
||||||
example: 'http://localhost:6080/room/room-123?secret=123456'
|
example: 'http://localhost:6080/room/room-123?secret=123456'
|
||||||
description: >
|
description: >
|
||||||
The URL for the moderator participants to join the room. The moderator role has special permissions to manage the
|
The URL for the moderator participants to join the room. The moderator role has special permissions to manage the
|
||||||
room and participants.
|
room and participants.
|
||||||
publisherURL:
|
speakerRoomURL:
|
||||||
type: string
|
type: string
|
||||||
example: 'http://localhost:6080/room/room-123?secret=654321'
|
example: 'http://localhost:6080/room/room-123?secret=654321'
|
||||||
description: >
|
description: >
|
||||||
The URL for the publisher participants to join the room. The publisher role has permissions to publish audio and
|
The URL for the speaker participants to join the room. The speaker role has permissions to publish audio and
|
||||||
video streams to the room.
|
video streams to the room.
|
||||||
|
|||||||
427
backend/package-lock.json
generated
427
backend/package-lock.json
generated
@ -4087,12 +4087,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/abort-controller": {
|
"node_modules/@smithy/abort-controller": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.5.tgz",
|
||||||
"integrity": "sha512-gJnEjZMvigPDQWHrW3oPrFhQtkrgqBkyjj3pCIdF3A5M6vsZODG93KNlfJprv6bp4245bdT32fsHK4kkH3KYDA==",
|
"integrity": "sha512-jcrqdTQurIrBbUm4W2YdLVMQDoL0sA9DTxYd2s+R/y+2U9NLOP7Xf/YqfSg1FZhlZIYEnvk2mwbyvIfdLEPo8g==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4125,15 +4125,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/config-resolver": {
|
"node_modules/@smithy/config-resolver": {
|
||||||
"version": "4.1.4",
|
"version": "4.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.1.5.tgz",
|
||||||
"integrity": "sha512-prmU+rDddxHOH0oNcwemL+SwnzcG65sBF2yXRO7aeXIn/xTlq2pX7JLVbkBnVLowHLg4/OL4+jBmv9hVrVGS+w==",
|
"integrity": "sha512-viuHMxBAqydkB0AfWwHIdwf/PRH2z5KHGUzqyRtS/Wv+n3IHI993Sk76VCA7dD/+GzgGOmlJDITfPcJC1nIVIw==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/node-config-provider": "^4.1.3",
|
"@smithy/node-config-provider": "^4.1.4",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/util-config-provider": "^4.0.0",
|
"@smithy/util-config-provider": "^4.0.0",
|
||||||
"@smithy/util-middleware": "^4.0.4",
|
"@smithy/util-middleware": "^4.0.5",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4141,35 +4141,37 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/core": {
|
"node_modules/@smithy/core": {
|
||||||
"version": "3.7.2",
|
"version": "3.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.8.0.tgz",
|
||||||
"integrity": "sha512-JoLw59sT5Bm8SAjFCYZyuCGxK8y3vovmoVbZWLDPTH5XpPEIwpFd9m90jjVMwoypDuB/SdVgje5Y4T7w50lJaw==",
|
"integrity": "sha512-EYqsIYJmkR1VhVE9pccnk353xhs+lB6btdutJEtsp7R055haMJp2yE16eSxw8fv+G0WUY6vqxyYOP8kOqawxYQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/middleware-serde": "^4.0.8",
|
"@smithy/middleware-serde": "^4.0.9",
|
||||||
"@smithy/protocol-http": "^5.1.2",
|
"@smithy/protocol-http": "^5.1.3",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/util-base64": "^4.0.0",
|
"@smithy/util-base64": "^4.0.0",
|
||||||
"@smithy/util-body-length-browser": "^4.0.0",
|
"@smithy/util-body-length-browser": "^4.0.0",
|
||||||
"@smithy/util-middleware": "^4.0.4",
|
"@smithy/util-middleware": "^4.0.5",
|
||||||
"@smithy/util-stream": "^4.2.3",
|
"@smithy/util-stream": "^4.2.4",
|
||||||
"@smithy/util-utf8": "^4.0.0",
|
"@smithy/util-utf8": "^4.0.0",
|
||||||
"tslib": "^2.6.2"
|
"@types/uuid": "^9.0.1",
|
||||||
|
"tslib": "^2.6.2",
|
||||||
|
"uuid": "^9.0.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/credential-provider-imds": {
|
"node_modules/@smithy/credential-provider-imds": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.7.tgz",
|
||||||
"integrity": "sha512-hKMWcANhUiNbCJouYkZ9V3+/Qf9pteR1dnwgdyzR09R4ODEYx8BbUysHwRSyex4rZ9zapddZhLFTnT4ZijR4pw==",
|
"integrity": "sha512-dDzrMXA8d8riFNiPvytxn0mNwR4B3h8lgrQ5UjAGu6T9z/kRg/Xncf4tEQHE/+t25sY8IH3CowcmWi+1U5B1Gw==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/node-config-provider": "^4.1.3",
|
"@smithy/node-config-provider": "^4.1.4",
|
||||||
"@smithy/property-provider": "^4.0.4",
|
"@smithy/property-provider": "^4.0.5",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/url-parser": "^4.0.4",
|
"@smithy/url-parser": "^4.0.5",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4177,13 +4179,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/eventstream-codec": {
|
"node_modules/@smithy/eventstream-codec": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.0.5.tgz",
|
||||||
"integrity": "sha512-7XoWfZqWb/QoR/rAU4VSi0mWnO2vu9/ltS6JZ5ZSZv0eovLVfDfu0/AX4ub33RsJTOth3TiFWSHS5YdztvFnig==",
|
"integrity": "sha512-miEUN+nz2UTNoRYRhRqVTJCx7jMeILdAurStT2XoS+mhokkmz1xAPp95DFW9Gxt4iF2VBqpeF9HbTQ3kY1viOA==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-crypto/crc32": "5.2.0",
|
"@aws-crypto/crc32": "5.2.0",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/util-hex-encoding": "^4.0.0",
|
"@smithy/util-hex-encoding": "^4.0.0",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
@ -4192,13 +4194,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/eventstream-serde-browser": {
|
"node_modules/@smithy/eventstream-serde-browser": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.0.5.tgz",
|
||||||
"integrity": "sha512-3fb/9SYaYqbpy/z/H3yIi0bYKyAa89y6xPmIqwr2vQiUT2St+avRt8UKwsWt9fEdEasc5d/V+QjrviRaX1JRFA==",
|
"integrity": "sha512-LCUQUVTbM6HFKzImYlSB9w4xafZmpdmZsOh9rIl7riPC3osCgGFVP+wwvYVw6pXda9PPT9TcEZxaq3XE81EdJQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/eventstream-serde-universal": "^4.0.4",
|
"@smithy/eventstream-serde-universal": "^4.0.5",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4206,12 +4208,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/eventstream-serde-config-resolver": {
|
"node_modules/@smithy/eventstream-serde-config-resolver": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.1.3.tgz",
|
||||||
"integrity": "sha512-JGtambizrWP50xHgbzZI04IWU7LdI0nh/wGbqH3sJesYToMi2j/DcoElqyOcqEIG/D4tNyxgRuaqBXWE3zOFhQ==",
|
"integrity": "sha512-yTTzw2jZjn/MbHu1pURbHdpjGbCuMHWncNBpJnQAPxOVnFUAbSIUSwafiphVDjNV93TdBJWmeVAds7yl5QCkcA==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4219,13 +4221,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/eventstream-serde-node": {
|
"node_modules/@smithy/eventstream-serde-node": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.0.5.tgz",
|
||||||
"integrity": "sha512-RD6UwNZ5zISpOWPuhVgRz60GkSIp0dy1fuZmj4RYmqLVRtejFqQ16WmfYDdoSoAjlp1LX+FnZo+/hkdmyyGZ1w==",
|
"integrity": "sha512-lGS10urI4CNzz6YlTe5EYG0YOpsSp3ra8MXyco4aqSkQDuyZPIw2hcaxDU82OUVtK7UY9hrSvgWtpsW5D4rb4g==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/eventstream-serde-universal": "^4.0.4",
|
"@smithy/eventstream-serde-universal": "^4.0.5",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4233,13 +4235,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/eventstream-serde-universal": {
|
"node_modules/@smithy/eventstream-serde-universal": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.0.5.tgz",
|
||||||
"integrity": "sha512-UeJpOmLGhq1SLox79QWw/0n2PFX+oPRE1ZyRMxPIaFEfCqWaqpB7BU9C8kpPOGEhLF7AwEqfFbtwNxGy4ReENA==",
|
"integrity": "sha512-JFnmu4SU36YYw3DIBVao3FsJh4Uw65vVDIqlWT4LzR6gXA0F3KP0IXFKKJrhaVzCBhAuMsrUUaT5I+/4ZhF7aw==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/eventstream-codec": "^4.0.4",
|
"@smithy/eventstream-codec": "^4.0.5",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4247,14 +4249,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/fetch-http-handler": {
|
"node_modules/@smithy/fetch-http-handler": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.1.1.tgz",
|
||||||
"integrity": "sha512-mADw7MS0bYe2OGKkHYMaqarOXuDwRbO6ArD91XhHcl2ynjGCFF+hvqf0LyQcYxkA1zaWjefSkU7Ne9mqgApSgQ==",
|
"integrity": "sha512-61WjM0PWmZJR+SnmzaKI7t7G0UkkNFboDpzIdzSoy7TByUzlxo18Qlh9s71qug4AY4hlH/CwXdubMtkcNEb/sQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/protocol-http": "^5.1.2",
|
"@smithy/protocol-http": "^5.1.3",
|
||||||
"@smithy/querystring-builder": "^4.0.4",
|
"@smithy/querystring-builder": "^4.0.5",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/util-base64": "^4.0.0",
|
"@smithy/util-base64": "^4.0.0",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
@ -4263,14 +4265,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/hash-blob-browser": {
|
"node_modules/@smithy/hash-blob-browser": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.0.5.tgz",
|
||||||
"integrity": "sha512-WszRiACJiQV3QG6XMV44i5YWlkrlsM5Yxgz4jvsksuu7LDXA6wAtypfPajtNTadzpJy3KyJPoWehYpmZGKUFIQ==",
|
"integrity": "sha512-F7MmCd3FH/Q2edhcKd+qulWkwfChHbc9nhguBlVjSUE6hVHhec3q6uPQ+0u69S6ppvLtR3eStfCuEKMXBXhvvA==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/chunked-blob-reader": "^5.0.0",
|
"@smithy/chunked-blob-reader": "^5.0.0",
|
||||||
"@smithy/chunked-blob-reader-native": "^4.0.0",
|
"@smithy/chunked-blob-reader-native": "^4.0.0",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4278,12 +4280,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/hash-node": {
|
"node_modules/@smithy/hash-node": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.5.tgz",
|
||||||
"integrity": "sha512-qnbTPUhCVnCgBp4z4BUJUhOEkVwxiEi1cyFM+Zj6o+aY8OFGxUQleKWq8ltgp3dujuhXojIvJWdoqpm6dVO3lQ==",
|
"integrity": "sha512-cv1HHkKhpyRb6ahD8Vcfb2Hgz67vNIXEp2vnhzfxLFGRukLCNEA5QdsorbUEzXma1Rco0u3rx5VTqbM06GcZqQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/util-buffer-from": "^4.0.0",
|
"@smithy/util-buffer-from": "^4.0.0",
|
||||||
"@smithy/util-utf8": "^4.0.0",
|
"@smithy/util-utf8": "^4.0.0",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
@ -4293,12 +4295,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/hash-stream-node": {
|
"node_modules/@smithy/hash-stream-node": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.0.5.tgz",
|
||||||
"integrity": "sha512-wHo0d8GXyVmpmMh/qOR0R7Y46/G1y6OR8U+bSTB4ppEzRxd1xVAQ9xOE9hOc0bSjhz0ujCPAbfNLkLrpa6cevg==",
|
"integrity": "sha512-IJuDS3+VfWB67UC0GU0uYBG/TA30w+PlOaSo0GPm9UHS88A6rCP6uZxNjNYiyRtOcjv7TXn/60cW8ox1yuZsLg==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/util-utf8": "^4.0.0",
|
"@smithy/util-utf8": "^4.0.0",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
@ -4307,12 +4309,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/invalid-dependency": {
|
"node_modules/@smithy/invalid-dependency": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.5.tgz",
|
||||||
"integrity": "sha512-bNYMi7WKTJHu0gn26wg8OscncTt1t2b8KcsZxvOv56XA6cyXtOAAAaNP7+m45xfppXfOatXF3Sb1MNsLUgVLTw==",
|
"integrity": "sha512-IVnb78Qtf7EJpoEVo7qJ8BEXQwgC4n3igeJNNKEj/MLYtapnx8A67Zt/J3RXAj2xSO1910zk0LdFiygSemuLow==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4332,12 +4334,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/md5-js": {
|
"node_modules/@smithy/md5-js": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.0.5.tgz",
|
||||||
"integrity": "sha512-uGLBVqcOwrLvGh/v/jw423yWHq/ofUGK1W31M2TNspLQbUV1Va0F5kTxtirkoHawODAZcjXTSGi7JwbnPcDPJg==",
|
"integrity": "sha512-8n2XCwdUbGr8W/XhMTaxILkVlw2QebkVTn5tm3HOcbPbOpWg89zr6dPXsH8xbeTsbTXlJvlJNTQsKAIoqQGbdA==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/util-utf8": "^4.0.0",
|
"@smithy/util-utf8": "^4.0.0",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
@ -4346,13 +4348,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/middleware-content-length": {
|
"node_modules/@smithy/middleware-content-length": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.5.tgz",
|
||||||
"integrity": "sha512-F7gDyfI2BB1Kc+4M6rpuOLne5LOcEknH1n6UQB69qv+HucXBR1rkzXBnQTB2q46sFy1PM/zuSJOB532yc8bg3w==",
|
"integrity": "sha512-l1jlNZoYzoCC7p0zCtBDE5OBXZ95yMKlRlftooE5jPWQn4YBPLgsp+oeHp7iMHaTGoUdFqmHOPa8c9G3gBsRpQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/protocol-http": "^5.1.2",
|
"@smithy/protocol-http": "^5.1.3",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4360,18 +4362,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/middleware-endpoint": {
|
"node_modules/@smithy/middleware-endpoint": {
|
||||||
"version": "4.1.17",
|
"version": "4.1.18",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.17.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.18.tgz",
|
||||||
"integrity": "sha512-S3hSGLKmHG1m35p/MObQCBCdRsrpbPU8B129BVzRqRfDvQqPMQ14iO4LyRw+7LNizYc605COYAcjqgawqi+6jA==",
|
"integrity": "sha512-ZhvqcVRPZxnZlokcPaTwb+r+h4yOIOCJmx0v2d1bpVlmP465g3qpVSf7wxcq5zZdu4jb0H4yIMxuPwDJSQc3MQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/core": "^3.7.2",
|
"@smithy/core": "^3.8.0",
|
||||||
"@smithy/middleware-serde": "^4.0.8",
|
"@smithy/middleware-serde": "^4.0.9",
|
||||||
"@smithy/node-config-provider": "^4.1.3",
|
"@smithy/node-config-provider": "^4.1.4",
|
||||||
"@smithy/shared-ini-file-loader": "^4.0.4",
|
"@smithy/shared-ini-file-loader": "^4.0.5",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/url-parser": "^4.0.4",
|
"@smithy/url-parser": "^4.0.5",
|
||||||
"@smithy/util-middleware": "^4.0.4",
|
"@smithy/util-middleware": "^4.0.5",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4379,18 +4381,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/middleware-retry": {
|
"node_modules/@smithy/middleware-retry": {
|
||||||
"version": "4.1.18",
|
"version": "4.1.19",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.18.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.19.tgz",
|
||||||
"integrity": "sha512-bYLZ4DkoxSsPxpdmeapvAKy7rM5+25gR7PGxq2iMiecmbrRGBHj9s75N74Ylg+aBiw9i5jIowC/cLU2NR0qH8w==",
|
"integrity": "sha512-X58zx/NVECjeuUB6A8HBu4bhx72EoUz+T5jTMIyeNKx2lf+Gs9TmWPNNkH+5QF0COjpInP/xSpJGJ7xEnAklQQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/node-config-provider": "^4.1.3",
|
"@smithy/node-config-provider": "^4.1.4",
|
||||||
"@smithy/protocol-http": "^5.1.2",
|
"@smithy/protocol-http": "^5.1.3",
|
||||||
"@smithy/service-error-classification": "^4.0.6",
|
"@smithy/service-error-classification": "^4.0.7",
|
||||||
"@smithy/smithy-client": "^4.4.9",
|
"@smithy/smithy-client": "^4.4.10",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/util-middleware": "^4.0.4",
|
"@smithy/util-middleware": "^4.0.5",
|
||||||
"@smithy/util-retry": "^4.0.6",
|
"@smithy/util-retry": "^4.0.7",
|
||||||
|
"@types/uuid": "^9.0.1",
|
||||||
"tslib": "^2.6.2",
|
"tslib": "^2.6.2",
|
||||||
"uuid": "^9.0.1"
|
"uuid": "^9.0.1"
|
||||||
},
|
},
|
||||||
@ -4399,13 +4402,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/middleware-serde": {
|
"node_modules/@smithy/middleware-serde": {
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.9.tgz",
|
||||||
"integrity": "sha512-iSSl7HJoJaGyMIoNn2B7czghOVwJ9nD7TMvLhMWeSB5vt0TnEYyRRqPJu/TqW76WScaNvYYB8nRoiBHR9S1Ddw==",
|
"integrity": "sha512-uAFFR4dpeoJPGz8x9mhxp+RPjo5wW0QEEIPPPbLXiRRWeCATf/Km3gKIVR5vaP8bN1kgsPhcEeh+IZvUlBv6Xg==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/protocol-http": "^5.1.2",
|
"@smithy/protocol-http": "^5.1.3",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4413,12 +4416,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/middleware-stack": {
|
"node_modules/@smithy/middleware-stack": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.5.tgz",
|
||||||
"integrity": "sha512-kagK5ggDrBUCCzI93ft6DjteNSfY8Ulr83UtySog/h09lTIOAJ/xUSObutanlPT0nhoHAkpmW9V5K8oPyLh+QA==",
|
"integrity": "sha512-/yoHDXZPh3ocRVyeWQFvC44u8seu3eYzZRveCMfgMOBcNKnAmOvjbL9+Cp5XKSIi9iYA9PECUuW2teDAk8T+OQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4426,14 +4429,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/node-config-provider": {
|
"node_modules/@smithy/node-config-provider": {
|
||||||
"version": "4.1.3",
|
"version": "4.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.1.4.tgz",
|
||||||
"integrity": "sha512-HGHQr2s59qaU1lrVH6MbLlmOBxadtzTsoO4c+bF5asdgVik3I8o7JIOzoeqWc5MjVa+vD36/LWE0iXKpNqooRw==",
|
"integrity": "sha512-+UDQV/k42jLEPPHSn39l0Bmc4sB1xtdI9Gd47fzo/0PbXzJ7ylgaOByVjF5EeQIumkepnrJyfx86dPa9p47Y+w==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/property-provider": "^4.0.4",
|
"@smithy/property-provider": "^4.0.5",
|
||||||
"@smithy/shared-ini-file-loader": "^4.0.4",
|
"@smithy/shared-ini-file-loader": "^4.0.5",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4441,15 +4444,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/node-http-handler": {
|
"node_modules/@smithy/node-http-handler": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.1.1.tgz",
|
||||||
"integrity": "sha512-vqfSiHz2v8b3TTTrdXi03vNz1KLYYS3bhHCDv36FYDqxT7jvTll1mMnCrkD+gOvgwybuunh/2VmvOMqwBegxEg==",
|
"integrity": "sha512-RHnlHqFpoVdjSPPiYy/t40Zovf3BBHc2oemgD7VsVTFFZrU5erFFe0n52OANZZ/5sbshgD93sOh5r6I35Xmpaw==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/abort-controller": "^4.0.4",
|
"@smithy/abort-controller": "^4.0.5",
|
||||||
"@smithy/protocol-http": "^5.1.2",
|
"@smithy/protocol-http": "^5.1.3",
|
||||||
"@smithy/querystring-builder": "^4.0.4",
|
"@smithy/querystring-builder": "^4.0.5",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4457,12 +4460,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/property-provider": {
|
"node_modules/@smithy/property-provider": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.5.tgz",
|
||||||
"integrity": "sha512-qHJ2sSgu4FqF4U/5UUp4DhXNmdTrgmoAai6oQiM+c5RZ/sbDwJ12qxB1M6FnP+Tn/ggkPZf9ccn4jqKSINaquw==",
|
"integrity": "sha512-R/bswf59T/n9ZgfgUICAZoWYKBHcsVDurAGX88zsiUtOTA/xUAPyiT+qkNCPwFn43pZqN84M4MiUsbSGQmgFIQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4470,12 +4473,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/protocol-http": {
|
"node_modules/@smithy/protocol-http": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.1.3.tgz",
|
||||||
"integrity": "sha512-rOG5cNLBXovxIrICSBm95dLqzfvxjEmuZx4KK3hWwPFHGdW3lxY0fZNXfv2zebfRO7sJZ5pKJYHScsqopeIWtQ==",
|
"integrity": "sha512-fCJd2ZR7D22XhDY0l+92pUag/7je2BztPRQ01gU5bMChcyI0rlly7QFibnYHzcxDvccMjlpM/Q1ev8ceRIb48w==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4483,12 +4486,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/querystring-builder": {
|
"node_modules/@smithy/querystring-builder": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.5.tgz",
|
||||||
"integrity": "sha512-SwREZcDnEYoh9tLNgMbpop+UTGq44Hl9tdj3rf+yeLcfH7+J8OXEBaMc2kDxtyRHu8BhSg9ADEx0gFHvpJgU8w==",
|
"integrity": "sha512-NJeSCU57piZ56c+/wY+AbAw6rxCCAOZLCIniRE7wqvndqxcKKDOXzwWjrY7wGKEISfhL9gBbAaWWgHsUGedk+A==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/util-uri-escape": "^4.0.0",
|
"@smithy/util-uri-escape": "^4.0.0",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
@ -4497,12 +4500,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/querystring-parser": {
|
"node_modules/@smithy/querystring-parser": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.5.tgz",
|
||||||
"integrity": "sha512-6yZf53i/qB8gRHH/l2ZwUG5xgkPgQF15/KxH0DdXMDHjesA9MeZje/853ifkSY0x4m5S+dfDZ+c4x439PF0M2w==",
|
"integrity": "sha512-6SV7md2CzNG/WUeTjVe6Dj8noH32r4MnUeFKZrnVYsQxpGSIcphAanQMayi8jJLZAWm6pdM9ZXvKCpWOsIGg0w==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4510,24 +4513,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/service-error-classification": {
|
"node_modules/@smithy/service-error-classification": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.7.tgz",
|
||||||
"integrity": "sha512-RRoTDL//7xi4tn5FrN2NzH17jbgmnKidUqd4KvquT0954/i6CXXkh1884jBiunq24g9cGtPBEXlU40W6EpNOOg==",
|
"integrity": "sha512-XvRHOipqpwNhEjDf2L5gJowZEm5nsxC16pAZOeEcsygdjv9A2jdOh3YoDQvOXBGTsaJk6mNWtzWalOB9976Wlg==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1"
|
"@smithy/types": "^4.3.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/shared-ini-file-loader": {
|
"node_modules/@smithy/shared-ini-file-loader": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.5.tgz",
|
||||||
"integrity": "sha512-63X0260LoFBjrHifPDs+nM9tV0VMkOTl4JRMYNuKh/f5PauSjowTfvF3LogfkWdcPoxsA9UjqEOgjeYIbhb7Nw==",
|
"integrity": "sha512-YVVwehRDuehgoXdEL4r1tAAzdaDgaC9EQvhK0lEbfnbrd0bd5+CTQumbdPryX3J2shT7ZqQE+jPW4lmNBAB8JQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4535,16 +4538,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/signature-v4": {
|
"node_modules/@smithy/signature-v4": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.1.3.tgz",
|
||||||
"integrity": "sha512-d3+U/VpX7a60seHziWnVZOHuEgJlclufjkS6zhXvxcJgkJq4UWdH5eOBLzHRMx6gXjsdT9h6lfpmLzbrdupHgQ==",
|
"integrity": "sha512-mARDSXSEgllNzMw6N+mC+r1AQlEBO3meEAkR/UlfAgnMzJUB3goRBWgip1EAMG99wh36MDqzo86SfIX5Y+VEaw==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/is-array-buffer": "^4.0.0",
|
"@smithy/is-array-buffer": "^4.0.0",
|
||||||
"@smithy/protocol-http": "^5.1.2",
|
"@smithy/protocol-http": "^5.1.3",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/util-hex-encoding": "^4.0.0",
|
"@smithy/util-hex-encoding": "^4.0.0",
|
||||||
"@smithy/util-middleware": "^4.0.4",
|
"@smithy/util-middleware": "^4.0.5",
|
||||||
"@smithy/util-uri-escape": "^4.0.0",
|
"@smithy/util-uri-escape": "^4.0.0",
|
||||||
"@smithy/util-utf8": "^4.0.0",
|
"@smithy/util-utf8": "^4.0.0",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
@ -4554,17 +4557,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/smithy-client": {
|
"node_modules/@smithy/smithy-client": {
|
||||||
"version": "4.4.9",
|
"version": "4.4.10",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.4.9.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.4.10.tgz",
|
||||||
"integrity": "sha512-mbMg8mIUAWwMmb74LoYiArP04zWElPzDoA1jVOp3or0cjlDMgoS6WTC3QXK0Vxoc9I4zdrX0tq6qsOmaIoTWEQ==",
|
"integrity": "sha512-iW6HjXqN0oPtRS0NK/zzZ4zZeGESIFcxj2FkWed3mcK8jdSdHzvnCKXSjvewESKAgGKAbJRA+OsaqKhkdYRbQQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/core": "^3.7.2",
|
"@smithy/core": "^3.8.0",
|
||||||
"@smithy/middleware-endpoint": "^4.1.17",
|
"@smithy/middleware-endpoint": "^4.1.18",
|
||||||
"@smithy/middleware-stack": "^4.0.4",
|
"@smithy/middleware-stack": "^4.0.5",
|
||||||
"@smithy/protocol-http": "^5.1.2",
|
"@smithy/protocol-http": "^5.1.3",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/util-stream": "^4.2.3",
|
"@smithy/util-stream": "^4.2.4",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4572,9 +4575,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/types": {
|
"node_modules/@smithy/types": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.3.2.tgz",
|
||||||
"integrity": "sha512-UqKOQBL2x6+HWl3P+3QqFD4ncKq0I8Nuz9QItGv5WuKuMHuuwlhvqcZCoXGfc+P1QmfJE7VieykoYYmrOoFJxA==",
|
"integrity": "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
@ -4584,13 +4587,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/url-parser": {
|
"node_modules/@smithy/url-parser": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.5.tgz",
|
||||||
"integrity": "sha512-eMkc144MuN7B0TDA4U2fKs+BqczVbk3W+qIvcoCY6D1JY3hnAdCuhCZODC+GAeaxj0p6Jroz4+XMUn3PCxQQeQ==",
|
"integrity": "sha512-j+733Um7f1/DXjYhCbvNXABV53NyCRRA54C7bNEIxNPs0YjfRxeMKjjgm2jvTYrciZyCjsicHwQ6Q0ylo+NAUw==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/querystring-parser": "^4.0.4",
|
"@smithy/querystring-parser": "^4.0.5",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4661,14 +4664,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/util-defaults-mode-browser": {
|
"node_modules/@smithy/util-defaults-mode-browser": {
|
||||||
"version": "4.0.25",
|
"version": "4.0.26",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.25.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.26.tgz",
|
||||||
"integrity": "sha512-pxEWsxIsOPLfKNXvpgFHBGFC3pKYKUFhrud1kyooO9CJai6aaKDHfT10Mi5iiipPXN/JhKAu3qX9o75+X85OdQ==",
|
"integrity": "sha512-xgl75aHIS/3rrGp7iTxQAOELYeyiwBu+eEgAk4xfKwJJ0L8VUjhO2shsDpeil54BOFsqmk5xfdesiewbUY5tKQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/property-provider": "^4.0.4",
|
"@smithy/property-provider": "^4.0.5",
|
||||||
"@smithy/smithy-client": "^4.4.9",
|
"@smithy/smithy-client": "^4.4.10",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"bowser": "^2.11.0",
|
"bowser": "^2.11.0",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
@ -4677,17 +4680,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/util-defaults-mode-node": {
|
"node_modules/@smithy/util-defaults-mode-node": {
|
||||||
"version": "4.0.25",
|
"version": "4.0.26",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.25.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.26.tgz",
|
||||||
"integrity": "sha512-+w4n4hKFayeCyELZLfsSQG5mCC3TwSkmRHv4+el5CzFU8ToQpYGhpV7mrRzqlwKkntlPilT1HJy1TVeEvEjWOQ==",
|
"integrity": "sha512-z81yyIkGiLLYVDetKTUeCZQ8x20EEzvQjrqJtb/mXnevLq2+w3XCEWTJ2pMp401b6BkEkHVfXb/cROBpVauLMQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/config-resolver": "^4.1.4",
|
"@smithy/config-resolver": "^4.1.5",
|
||||||
"@smithy/credential-provider-imds": "^4.0.6",
|
"@smithy/credential-provider-imds": "^4.0.7",
|
||||||
"@smithy/node-config-provider": "^4.1.3",
|
"@smithy/node-config-provider": "^4.1.4",
|
||||||
"@smithy/property-provider": "^4.0.4",
|
"@smithy/property-provider": "^4.0.5",
|
||||||
"@smithy/smithy-client": "^4.4.9",
|
"@smithy/smithy-client": "^4.4.10",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4695,13 +4698,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/util-endpoints": {
|
"node_modules/@smithy/util-endpoints": {
|
||||||
"version": "3.0.6",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.0.7.tgz",
|
||||||
"integrity": "sha512-YARl3tFL3WgPuLzljRUnrS2ngLiUtkwhQtj8PAL13XZSyUiNLQxwG3fBBq3QXFqGFUXepIN73pINp3y8c2nBmA==",
|
"integrity": "sha512-klGBP+RpBp6V5JbrY2C/VKnHXn3d5V2YrifZbmMY8os7M6m8wdYFoO6w/fe5VkP+YVwrEktW3IWYaSQVNZJ8oQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/node-config-provider": "^4.1.3",
|
"@smithy/node-config-provider": "^4.1.4",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4721,12 +4724,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/util-middleware": {
|
"node_modules/@smithy/util-middleware": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.5.tgz",
|
||||||
"integrity": "sha512-9MLKmkBmf4PRb0ONJikCbCwORACcil6gUWojwARCClT7RmLzF04hUR4WdRprIXal7XVyrddadYNfp2eF3nrvtQ==",
|
"integrity": "sha512-N40PfqsZHRSsByGB81HhSo+uvMxEHT+9e255S53pfBw/wI6WKDI7Jw9oyu5tJTLwZzV5DsMha3ji8jk9dsHmQQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4734,13 +4737,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/util-retry": {
|
"node_modules/@smithy/util-retry": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.7.tgz",
|
||||||
"integrity": "sha512-+YekoF2CaSMv6zKrA6iI/N9yva3Gzn4L6n35Luydweu5MMPYpiGZlWqehPHDHyNbnyaYlz/WJyYAZnC+loBDZg==",
|
"integrity": "sha512-TTO6rt0ppK70alZpkjwy+3nQlTiqNfoXja+qwuAchIEAIoSZW8Qyd76dvBv3I5bCpE38APafG23Y/u270NspiQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/service-error-classification": "^4.0.6",
|
"@smithy/service-error-classification": "^4.0.7",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4748,14 +4751,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/util-stream": {
|
"node_modules/@smithy/util-stream": {
|
||||||
"version": "4.2.3",
|
"version": "4.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.2.4.tgz",
|
||||||
"integrity": "sha512-cQn412DWHHFNKrQfbHY8vSFI3nTROY1aIKji9N0tpp8gUABRilr7wdf8fqBbSlXresobM+tQFNk6I+0LXK/YZg==",
|
"integrity": "sha512-vSKnvNZX2BXzl0U2RgCLOwWaAP9x/ddd/XobPK02pCbzRm5s55M53uwb1rl/Ts7RXZvdJZerPkA+en2FDghLuQ==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/fetch-http-handler": "^5.1.0",
|
"@smithy/fetch-http-handler": "^5.1.1",
|
||||||
"@smithy/node-http-handler": "^4.1.0",
|
"@smithy/node-http-handler": "^4.1.1",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"@smithy/util-base64": "^4.0.0",
|
"@smithy/util-base64": "^4.0.0",
|
||||||
"@smithy/util-buffer-from": "^4.0.0",
|
"@smithy/util-buffer-from": "^4.0.0",
|
||||||
"@smithy/util-hex-encoding": "^4.0.0",
|
"@smithy/util-hex-encoding": "^4.0.0",
|
||||||
@ -4792,13 +4795,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@smithy/util-waiter": {
|
"node_modules/@smithy/util-waiter": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.0.7.tgz",
|
||||||
"integrity": "sha512-slcr1wdRbX7NFphXZOxtxRNA7hXAAtJAXJDE/wdoMAos27SIquVCKiSqfB6/28YzQ8FCsB5NKkhdM5gMADbqxg==",
|
"integrity": "sha512-mYqtQXPmrwvUljaHyGxYUIIRI3qjBTEb/f5QFi3A6VlxhpmZd5mWXn9W+qUkf2pVE1Hv3SqxefiZOPGdxmO64A==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@smithy/abort-controller": "^4.0.4",
|
"@smithy/abort-controller": "^4.0.5",
|
||||||
"@smithy/types": "^4.3.1",
|
"@smithy/types": "^4.3.2",
|
||||||
"tslib": "^2.6.2"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -7481,9 +7484,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.195",
|
"version": "1.5.197",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.195.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.197.tgz",
|
||||||
"integrity": "sha512-URclP0iIaDUzqcAyV1v2PgduJ9N0IdXmWsnPzPfelvBmjmZzEy6xJcjb1cXj+TbYqXgtLrjHEoaSIdTYhw4ezg==",
|
"integrity": "sha512-m1xWB3g7vJ6asIFz+2pBUbq3uGmfmln1M9SSvBe4QIFWYrRHylP73zL/3nMjDmwz8V+1xAXQDfBd6+HPW0WvDQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -173,7 +173,7 @@ export const getRoomRolesAndPermissions = async (req: Request, res: Response) =>
|
|||||||
|
|
||||||
logger.verbose(`Getting roles and associated permissions for room '${roomId}'`);
|
logger.verbose(`Getting roles and associated permissions for room '${roomId}'`);
|
||||||
const moderatorPermissions = participantService.getParticipantPermissions(roomId, ParticipantRole.MODERATOR);
|
const moderatorPermissions = participantService.getParticipantPermissions(roomId, ParticipantRole.MODERATOR);
|
||||||
const publisherPermissions = participantService.getParticipantPermissions(roomId, ParticipantRole.PUBLISHER);
|
const speakerPermissions = participantService.getParticipantPermissions(roomId, ParticipantRole.SPEAKER);
|
||||||
|
|
||||||
const rolesAndPermissions = [
|
const rolesAndPermissions = [
|
||||||
{
|
{
|
||||||
@ -181,8 +181,8 @@ export const getRoomRolesAndPermissions = async (req: Request, res: Response) =>
|
|||||||
permissions: moderatorPermissions
|
permissions: moderatorPermissions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: ParticipantRole.PUBLISHER,
|
role: ParticipantRole.SPEAKER,
|
||||||
permissions: publisherPermissions
|
permissions: speakerPermissions
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
res.status(200).json(rolesAndPermissions);
|
res.status(200).json(rolesAndPermissions);
|
||||||
|
|||||||
@ -22,24 +22,24 @@ export class MeetRoomHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts publisher and moderator secrets from a MeetRoom object's URLs.
|
* Extracts speaker and moderator secrets from a MeetRoom object's URLs.
|
||||||
*
|
*
|
||||||
* This method parses the 'secret' query parameter from both publisher and moderator
|
* This method parses the 'secret' query parameter from both speaker and moderator
|
||||||
* room URLs associated with the meeting room.
|
* room URLs associated with the meeting room.
|
||||||
*
|
*
|
||||||
* @param room - The MeetRoom object containing publisherRoomUrl and moderatorRoomUrl properties
|
* @param room - The MeetRoom object containing speakerRoomUrl and moderatorRoomUrl properties
|
||||||
* @returns An object containing the extracted secrets with the following properties:
|
* @returns An object containing the extracted secrets with the following properties:
|
||||||
* - publisherSecret: The secret extracted from the publisher room URL
|
* - speakerSecret: The secret extracted from the speaker room URL
|
||||||
* - moderatorSecret: The secret extracted from the moderator room URL
|
* - moderatorSecret: The secret extracted from the moderator room URL
|
||||||
*/
|
*/
|
||||||
static extractSecretsFromRoom(room: MeetRoom): { publisherSecret: string; moderatorSecret: string } {
|
static extractSecretsFromRoom(room: MeetRoom): { speakerSecret: string; moderatorSecret: string } {
|
||||||
const { publisherRoomUrl, moderatorRoomUrl } = room;
|
const { speakerRoomUrl, moderatorRoomUrl } = room;
|
||||||
|
|
||||||
const publisherUrl = new URL(publisherRoomUrl);
|
const speakerUrl = new URL(speakerRoomUrl);
|
||||||
const publisherSecret = publisherUrl.searchParams.get('secret') || '';
|
const speakerSecret = speakerUrl.searchParams.get('secret') || '';
|
||||||
const moderatorUrl = new URL(moderatorRoomUrl);
|
const moderatorUrl = new URL(moderatorRoomUrl);
|
||||||
const moderatorSecret = moderatorUrl.searchParams.get('secret') || '';
|
const moderatorSecret = moderatorUrl.searchParams.get('secret') || '';
|
||||||
return { publisherSecret, moderatorSecret };
|
return { speakerSecret, moderatorSecret };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -98,7 +98,7 @@ export const participantTokenValidator = async (req: Request) => {
|
|||||||
// Check if the participant role is provided in the request headers
|
// Check if the participant role is provided in the request headers
|
||||||
// This is required to distinguish roles when multiple are present in the token
|
// This is required to distinguish roles when multiple are present in the token
|
||||||
const participantRole = req.headers[INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER];
|
const participantRole = req.headers[INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER];
|
||||||
const allRoles = [ParticipantRole.MODERATOR, ParticipantRole.PUBLISHER];
|
const allRoles = [ParticipantRole.MODERATOR, ParticipantRole.SPEAKER];
|
||||||
|
|
||||||
if (!participantRole || !allRoles.includes(participantRole as ParticipantRole)) {
|
if (!participantRole || !allRoles.includes(participantRole as ParticipantRole)) {
|
||||||
throw errorWithControl(errorInvalidParticipantRole(), true);
|
throw errorWithControl(errorInvalidParticipantRole(), true);
|
||||||
|
|||||||
@ -67,7 +67,7 @@ const validForceQueryParam = () =>
|
|||||||
const RecordingAccessSchema: z.ZodType<MeetRecordingAccess> = z.enum([
|
const RecordingAccessSchema: z.ZodType<MeetRecordingAccess> = z.enum([
|
||||||
MeetRecordingAccess.ADMIN,
|
MeetRecordingAccess.ADMIN,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR,
|
MeetRecordingAccess.ADMIN_MODERATOR,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const RecordingPreferencesSchema: z.ZodType<MeetRecordingPreferences> = z
|
const RecordingPreferencesSchema: z.ZodType<MeetRecordingPreferences> = z
|
||||||
@ -116,7 +116,7 @@ const RoomRequestOptionsSchema: z.ZodType<MeetRoomOptions> = z.object({
|
|||||||
)
|
)
|
||||||
.optional(),
|
.optional(),
|
||||||
preferences: RoomPreferencesSchema.optional().default({
|
preferences: RoomPreferencesSchema.optional().default({
|
||||||
recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER },
|
recordingPreferences: { enabled: true, allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER },
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
})
|
})
|
||||||
|
|||||||
@ -82,8 +82,8 @@ export class ParticipantService {
|
|||||||
switch (role) {
|
switch (role) {
|
||||||
case ParticipantRole.MODERATOR:
|
case ParticipantRole.MODERATOR:
|
||||||
return this.generateModeratorPermissions(roomId, addJoinPermission);
|
return this.generateModeratorPermissions(roomId, addJoinPermission);
|
||||||
case ParticipantRole.PUBLISHER:
|
case ParticipantRole.SPEAKER:
|
||||||
return this.generatePublisherPermissions(roomId, addJoinPermission);
|
return this.generateSpeakerPermissions(roomId, addJoinPermission);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Role ${role} not supported`);
|
throw new Error(`Role ${role} not supported`);
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ export class ParticipantService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected generatePublisherPermissions(roomId: string, addJoinPermission = true): ParticipantPermissions {
|
protected generateSpeakerPermissions(roomId: string, addJoinPermission = true): ParticipantPermissions {
|
||||||
return {
|
return {
|
||||||
livekit: {
|
livekit: {
|
||||||
roomJoin: addJoinPermission,
|
roomJoin: addJoinPermission,
|
||||||
|
|||||||
@ -81,7 +81,7 @@ export class RoomService {
|
|||||||
autoDeletionDate,
|
autoDeletionDate,
|
||||||
preferences,
|
preferences,
|
||||||
moderatorRoomUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`,
|
moderatorRoomUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`,
|
||||||
publisherRoomUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`
|
speakerRoomUrl: `${baseUrl}/room/${roomId}?secret=${secureUid(10)}`
|
||||||
};
|
};
|
||||||
|
|
||||||
await this.storageService.saveMeetRoom(meetRoom);
|
await this.storageService.saveMeetRoom(meetRoom);
|
||||||
@ -195,8 +195,8 @@ export class RoomService {
|
|||||||
|
|
||||||
const filteredRoom = UtilsHelper.filterObjectFields(meetRoom, fields);
|
const filteredRoom = UtilsHelper.filterObjectFields(meetRoom, fields);
|
||||||
|
|
||||||
// Remove moderatorRoomUrl if the participant is a publisher to prevent access to moderator links
|
// Remove moderatorRoomUrl if the participant is a speaker to prevent access to moderator links
|
||||||
if (participantRole === ParticipantRole.PUBLISHER) {
|
if (participantRole === ParticipantRole.SPEAKER) {
|
||||||
delete filteredRoom.moderatorRoomUrl;
|
delete filteredRoom.moderatorRoomUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,12 +244,12 @@ export class RoomService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a secret against a room's moderator and publisher secrets and returns the corresponding role.
|
* Validates a secret against a room's moderator and speaker secrets and returns the corresponding role.
|
||||||
*
|
*
|
||||||
* @param roomId - The unique identifier of the room to check
|
* @param roomId - The unique identifier of the room to check
|
||||||
* @param secret - The secret to validate against the room's moderator and publisher secrets
|
* @param secret - The secret to validate against the room's moderator and speaker secrets
|
||||||
* @returns A promise that resolves to the participant role (MODERATOR or PUBLISHER) if the secret is valid
|
* @returns A promise that resolves to the participant role (MODERATOR or SPEAKER) if the secret is valid
|
||||||
* @throws Error if the moderator or publisher secrets cannot be extracted from their URLs
|
* @throws Error if the moderator or speaker secrets cannot be extracted from their URLs
|
||||||
* @throws Error if the provided secret doesn't match any of the room's secrets (unauthorized)
|
* @throws Error if the provided secret doesn't match any of the room's secrets (unauthorized)
|
||||||
*/
|
*/
|
||||||
async getRoomRoleBySecret(roomId: string, secret: string): Promise<ParticipantRole> {
|
async getRoomRoleBySecret(roomId: string, secret: string): Promise<ParticipantRole> {
|
||||||
@ -258,13 +258,13 @@ export class RoomService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getRoomRoleBySecretFromRoom(room: MeetRoom, secret: string): ParticipantRole {
|
getRoomRoleBySecretFromRoom(room: MeetRoom, secret: string): ParticipantRole {
|
||||||
const { moderatorSecret, publisherSecret } = MeetRoomHelper.extractSecretsFromRoom(room);
|
const { moderatorSecret, speakerSecret } = MeetRoomHelper.extractSecretsFromRoom(room);
|
||||||
|
|
||||||
switch (secret) {
|
switch (secret) {
|
||||||
case moderatorSecret:
|
case moderatorSecret:
|
||||||
return ParticipantRole.MODERATOR;
|
return ParticipantRole.MODERATOR;
|
||||||
case publisherSecret:
|
case speakerSecret:
|
||||||
return ParticipantRole.PUBLISHER;
|
return ParticipantRole.SPEAKER;
|
||||||
default:
|
default:
|
||||||
throw errorInvalidRoomSecret(room.roomId, secret);
|
throw errorInvalidRoomSecret(room.roomId, secret);
|
||||||
}
|
}
|
||||||
@ -299,11 +299,11 @@ export class RoomService {
|
|||||||
|
|
||||||
/* A participant can retrieve recordings if
|
/* A participant can retrieve recordings if
|
||||||
- they can delete recordings
|
- they can delete recordings
|
||||||
- they are a publisher and the recording access includes publishers
|
- they are a speaker and the recording access includes speakers
|
||||||
*/
|
*/
|
||||||
const canRetrieveRecordings =
|
const canRetrieveRecordings =
|
||||||
canDeleteRecordings ||
|
canDeleteRecordings ||
|
||||||
(role === ParticipantRole.PUBLISHER && recordingAccess === MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER);
|
(role === ParticipantRole.SPEAKER && recordingAccess === MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
canRetrieveRecordings,
|
canRetrieveRecordings,
|
||||||
|
|||||||
@ -278,7 +278,7 @@ export class MeetStorageService<
|
|||||||
/**
|
/**
|
||||||
* Archives room metadata by storing essential room information in both cache and persistent storage.
|
* Archives room metadata by storing essential room information in both cache and persistent storage.
|
||||||
*
|
*
|
||||||
* This method retrieves the room data, extracts key metadata (moderator/publisher URLs and
|
* This method retrieves the room data, extracts key metadata (moderator/speaker URLs and
|
||||||
* recording preferences), and saves it to an archived location for future reference.
|
* recording preferences), and saves it to an archived location for future reference.
|
||||||
*
|
*
|
||||||
* If `updateOnlyIfExists` is true, it will only save the archived metadata if it already exists,
|
* If `updateOnlyIfExists` is true, it will only save the archived metadata if it already exists,
|
||||||
@ -311,7 +311,7 @@ export class MeetStorageService<
|
|||||||
|
|
||||||
const archivedRoom: Partial<MRoom> = {
|
const archivedRoom: Partial<MRoom> = {
|
||||||
moderatorRoomUrl: room.moderatorRoomUrl,
|
moderatorRoomUrl: room.moderatorRoomUrl,
|
||||||
publisherRoomUrl: room.publisherRoomUrl,
|
speakerRoomUrl: room.speakerRoomUrl,
|
||||||
preferences: {
|
preferences: {
|
||||||
recordingPreferences: room.preferences?.recordingPreferences
|
recordingPreferences: room.preferences?.recordingPreferences
|
||||||
}
|
}
|
||||||
|
|||||||
@ -131,7 +131,7 @@ export const expectValidRoom = (
|
|||||||
expect(room.preferences).toEqual({
|
expect(room.preferences).toEqual({
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
@ -139,9 +139,9 @@ export const expectValidRoom = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
expect(room.moderatorRoomUrl).toBeDefined();
|
expect(room.moderatorRoomUrl).toBeDefined();
|
||||||
expect(room.publisherRoomUrl).toBeDefined();
|
expect(room.speakerRoomUrl).toBeDefined();
|
||||||
expect(room.moderatorRoomUrl).toContain(room.roomId);
|
expect(room.moderatorRoomUrl).toContain(room.roomId);
|
||||||
expect(room.publisherRoomUrl).toContain(room.roomId);
|
expect(room.speakerRoomUrl).toContain(room.roomId);
|
||||||
|
|
||||||
if (markedForDeletion !== undefined) {
|
if (markedForDeletion !== undefined) {
|
||||||
expect(room.autoDeletionDate).toBeDefined();
|
expect(room.autoDeletionDate).toBeDefined();
|
||||||
@ -473,8 +473,8 @@ export const expectValidRoomRolesAndPermissionsResponse = (response: any, roomId
|
|||||||
permissions: getPermissions(roomId, ParticipantRole.MODERATOR)
|
permissions: getPermissions(roomId, ParticipantRole.MODERATOR)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: ParticipantRole.PUBLISHER,
|
role: ParticipantRole.SPEAKER,
|
||||||
permissions: getPermissions(roomId, ParticipantRole.PUBLISHER)
|
permissions: getPermissions(roomId, ParticipantRole.SPEAKER)
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
@ -510,7 +510,7 @@ const getPermissions = (roomId: string, role: ParticipantRole, addJoinPermission
|
|||||||
canChangeVirtualBackground: true
|
canChangeVirtualBackground: true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
case ParticipantRole.PUBLISHER:
|
case ParticipantRole.SPEAKER:
|
||||||
return {
|
return {
|
||||||
livekit: {
|
livekit: {
|
||||||
roomJoin: addJoinPermission,
|
roomJoin: addJoinPermission,
|
||||||
|
|||||||
@ -19,8 +19,8 @@ export interface RoomData {
|
|||||||
room: MeetRoom;
|
room: MeetRoom;
|
||||||
moderatorSecret: string;
|
moderatorSecret: string;
|
||||||
moderatorCookie: string;
|
moderatorCookie: string;
|
||||||
publisherSecret: string;
|
speakerSecret: string;
|
||||||
publisherCookie: string;
|
speakerCookie: string;
|
||||||
recordingId?: string;
|
recordingId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,10 +49,10 @@ export const setupSingleRoom = async (
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Extract the room secrets and generate participant tokens, saved as cookies
|
// Extract the room secrets and generate participant tokens, saved as cookies
|
||||||
const { moderatorSecret, publisherSecret } = MeetRoomHelper.extractSecretsFromRoom(room);
|
const { moderatorSecret, speakerSecret } = MeetRoomHelper.extractSecretsFromRoom(room);
|
||||||
const [moderatorCookie, publisherCookie] = await Promise.all([
|
const [moderatorCookie, speakerCookie] = await Promise.all([
|
||||||
generateParticipantTokenCookie(room.roomId, moderatorSecret, 'MODERATOR'),
|
generateParticipantTokenCookie(room.roomId, moderatorSecret, 'MODERATOR'),
|
||||||
generateParticipantTokenCookie(room.roomId, publisherSecret, 'PUBLISHER')
|
generateParticipantTokenCookie(room.roomId, speakerSecret, 'SPEAKER')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Join participant if needed
|
// Join participant if needed
|
||||||
@ -64,8 +64,8 @@ export const setupSingleRoom = async (
|
|||||||
room,
|
room,
|
||||||
moderatorSecret,
|
moderatorSecret,
|
||||||
moderatorCookie,
|
moderatorCookie,
|
||||||
publisherSecret,
|
speakerSecret,
|
||||||
publisherCookie
|
speakerCookie
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -48,40 +48,40 @@ describe('Participant API Tests', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate a participant token with publisher permissions when using the publisher secret', async () => {
|
it('should generate a participant token with speaker permissions when using the speaker secret', async () => {
|
||||||
const response = await generateParticipantToken({
|
const response = await generateParticipantToken({
|
||||||
roomId: roomData.room.roomId,
|
roomId: roomData.room.roomId,
|
||||||
secret: roomData.publisherSecret,
|
secret: roomData.speakerSecret,
|
||||||
participantName
|
participantName
|
||||||
});
|
});
|
||||||
expectValidParticipantTokenResponse(
|
expectValidParticipantTokenResponse(
|
||||||
response,
|
response,
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
ParticipantRole.PUBLISHER,
|
ParticipantRole.SPEAKER,
|
||||||
participantName
|
participantName
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should generate a participant token with both publisher and moderator permissions
|
it(`should generate a participant token with both speaker and moderator permissions
|
||||||
when using the publisher secret after having a moderator token`, async () => {
|
when using the speaker secret after having a moderator token`, async () => {
|
||||||
const moderatorCookie = await generateParticipantTokenCookie(
|
const moderatorCookie = await generateParticipantTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.moderatorSecret,
|
roomData.moderatorSecret,
|
||||||
`${participantName}_MODERATOR`
|
`${participantName}_MODERATOR`
|
||||||
);
|
);
|
||||||
const publisherResponse = await generateParticipantToken(
|
const speakerResponse = await generateParticipantToken(
|
||||||
{
|
{
|
||||||
roomId: roomData.room.roomId,
|
roomId: roomData.room.roomId,
|
||||||
secret: roomData.publisherSecret,
|
secret: roomData.speakerSecret,
|
||||||
participantName: `${participantName}_PUBLISHER`
|
participantName: `${participantName}_SPEAKER`
|
||||||
},
|
},
|
||||||
moderatorCookie
|
moderatorCookie
|
||||||
);
|
);
|
||||||
expectValidParticipantTokenResponse(
|
expectValidParticipantTokenResponse(
|
||||||
publisherResponse,
|
speakerResponse,
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
ParticipantRole.PUBLISHER,
|
ParticipantRole.SPEAKER,
|
||||||
`${participantName}_PUBLISHER`,
|
`${participantName}_SPEAKER`,
|
||||||
[ParticipantRole.MODERATOR]
|
[ParticipantRole.MODERATOR]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -53,19 +53,19 @@ describe('Participant API Tests', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should refresh participant token with publisher permissions when using the publisher secret', async () => {
|
it('should refresh participant token with speaker permissions when using the speaker secret', async () => {
|
||||||
const response = await refreshParticipantToken(
|
const response = await refreshParticipantToken(
|
||||||
{
|
{
|
||||||
roomId: roomData.room.roomId,
|
roomId: roomData.room.roomId,
|
||||||
secret: roomData.publisherSecret,
|
secret: roomData.speakerSecret,
|
||||||
participantName
|
participantName
|
||||||
},
|
},
|
||||||
roomData.publisherCookie
|
roomData.speakerCookie
|
||||||
);
|
);
|
||||||
expectValidParticipantTokenResponse(
|
expectValidParticipantTokenResponse(
|
||||||
response,
|
response,
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
ParticipantRole.PUBLISHER,
|
ParticipantRole.SPEAKER,
|
||||||
participantName
|
participantName
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -182,13 +182,13 @@ describe('Recording API Tests', () => {
|
|||||||
|
|
||||||
expect(roomMetadata).toBeDefined();
|
expect(roomMetadata).toBeDefined();
|
||||||
expect(roomMetadata!.moderatorRoomUrl).toContain(room.roomId);
|
expect(roomMetadata!.moderatorRoomUrl).toContain(room.roomId);
|
||||||
expect(roomMetadata!.publisherRoomUrl).toContain(room.roomId);
|
expect(roomMetadata!.speakerRoomUrl).toContain(room.roomId);
|
||||||
|
|
||||||
roomMetadata = await meetStorageService.getArchivedRoomMetadata(room.roomId);
|
roomMetadata = await meetStorageService.getArchivedRoomMetadata(room.roomId);
|
||||||
|
|
||||||
expect(roomMetadata).toBeDefined();
|
expect(roomMetadata).toBeDefined();
|
||||||
expect(roomMetadata!.moderatorRoomUrl).toContain(room.roomId);
|
expect(roomMetadata!.moderatorRoomUrl).toContain(room.roomId);
|
||||||
expect(roomMetadata!.publisherRoomUrl).toContain(room.roomId);
|
expect(roomMetadata!.speakerRoomUrl).toContain(room.roomId);
|
||||||
|
|
||||||
const response = await startRecording(room.roomId, moderatorCookie);
|
const response = await startRecording(room.roomId, moderatorCookie);
|
||||||
expectValidStartRecordingResponse(response, room.roomId, room.roomName);
|
expectValidStartRecordingResponse(response, room.roomId, room.roomName);
|
||||||
|
|||||||
@ -74,7 +74,7 @@ describe('Recording API Tests', () => {
|
|||||||
let roomMetadata = await meetStorageService.getArchivedRoomMetadata(room.roomId);
|
let roomMetadata = await meetStorageService.getArchivedRoomMetadata(room.roomId);
|
||||||
expect(roomMetadata).toBeDefined();
|
expect(roomMetadata).toBeDefined();
|
||||||
expect(roomMetadata!.moderatorRoomUrl).toContain(room.roomId);
|
expect(roomMetadata!.moderatorRoomUrl).toContain(room.roomId);
|
||||||
expect(roomMetadata!.publisherRoomUrl).toContain(room.roomId);
|
expect(roomMetadata!.speakerRoomUrl).toContain(room.roomId);
|
||||||
|
|
||||||
// Generate a new recording
|
// Generate a new recording
|
||||||
const response = await startRecording(room.roomId, moderatorCookie);
|
const response = await startRecording(room.roomId, moderatorCookie);
|
||||||
@ -91,7 +91,7 @@ describe('Recording API Tests', () => {
|
|||||||
|
|
||||||
expect(roomMetadata).toBeDefined();
|
expect(roomMetadata).toBeDefined();
|
||||||
expect(roomMetadata!.moderatorRoomUrl).toContain(room.roomId);
|
expect(roomMetadata!.moderatorRoomUrl).toContain(room.roomId);
|
||||||
expect(roomMetadata!.publisherRoomUrl).toContain(room.roomId);
|
expect(roomMetadata!.speakerRoomUrl).toContain(room.roomId);
|
||||||
|
|
||||||
// Delete the second recording
|
// Delete the second recording
|
||||||
deleteResponse = await deleteRecording(secondRecordingId!);
|
deleteResponse = await deleteRecording(secondRecordingId!);
|
||||||
|
|||||||
@ -63,7 +63,7 @@ describe('Recordings API Tests', () => {
|
|||||||
const roomId = roomData.room.roomId;
|
const roomId = roomData.room.roomId;
|
||||||
|
|
||||||
// Generate a recording token for the room
|
// Generate a recording token for the room
|
||||||
const recordingCookie = await generateRecordingTokenCookie(roomId, roomData.publisherSecret);
|
const recordingCookie = await generateRecordingTokenCookie(roomId, roomData.speakerSecret);
|
||||||
|
|
||||||
// Create a new room and start a recording
|
// Create a new room and start a recording
|
||||||
roomData = await setupSingleRoomWithRecording(true);
|
roomData = await setupSingleRoomWithRecording(true);
|
||||||
|
|||||||
@ -72,7 +72,7 @@ describe('Recording API Tests', () => {
|
|||||||
const archivedRoom = await storageService.getArchivedRoomMetadata(room.roomId);
|
const archivedRoom = await storageService.getArchivedRoomMetadata(room.roomId);
|
||||||
expect(archivedRoom).toBeDefined();
|
expect(archivedRoom).toBeDefined();
|
||||||
expect(archivedRoom?.moderatorRoomUrl).toBeDefined();
|
expect(archivedRoom?.moderatorRoomUrl).toBeDefined();
|
||||||
expect(archivedRoom?.publisherRoomUrl).toBeDefined();
|
expect(archivedRoom?.speakerRoomUrl).toBeDefined();
|
||||||
expect(archivedRoom?.preferences).toBeDefined();
|
expect(archivedRoom?.preferences).toBeDefined();
|
||||||
|
|
||||||
const secretsResponse = await stopRecording(recordingId, moderatorCookie);
|
const secretsResponse = await stopRecording(recordingId, moderatorCookie);
|
||||||
|
|||||||
@ -48,7 +48,7 @@ describe('Room API Tests', () => {
|
|||||||
preferences: {
|
preferences: {
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: false },
|
chatPreferences: { enabled: false },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
@ -165,7 +165,7 @@ describe('Room API Tests', () => {
|
|||||||
preferences: {
|
preferences: {
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: 'yes', // invalid boolean
|
enabled: 'yes', // invalid boolean
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
|
|||||||
@ -34,35 +34,38 @@ describe('Room API Tests', () => {
|
|||||||
expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.MODERATOR, true, true);
|
expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.MODERATOR, true, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate a recording token with canRetrieve and canDelete permissions when using the moderator secret and recording access is admin-moderator-publisher', async () => {
|
it('should generate a recording token with canRetrieve and canDelete permissions when using the moderator secret and recording access is admin-moderator-speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await generateRecordingToken(roomData.room.roomId, roomData.moderatorSecret);
|
const response = await generateRecordingToken(roomData.room.roomId, roomData.moderatorSecret);
|
||||||
expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.MODERATOR, true, true);
|
expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.MODERATOR, true, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate a recording token without any permissions when using the publisher secret and recording access is admin-moderator', async () => {
|
it('should generate a recording token without any permissions when using the speaker secret and recording access is admin-moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
||||||
|
|
||||||
const response = await generateRecordingToken(roomData.room.roomId, roomData.publisherSecret);
|
const response = await generateRecordingToken(roomData.room.roomId, roomData.speakerSecret);
|
||||||
expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.PUBLISHER, false, false);
|
expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.SPEAKER, false, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate a recording token with canRetrieve permission but not canDelete when using the publisher secret and recording access is admin-moderator-publisher', async () => {
|
it('should generate a recording token with canRetrieve permission but not canDelete when using the speaker secret and recording access is admin-moderator-speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await generateRecordingToken(roomData.room.roomId, roomData.publisherSecret);
|
const response = await generateRecordingToken(roomData.room.roomId, roomData.speakerSecret);
|
||||||
expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.PUBLISHER, true, false);
|
expectValidRecordingTokenResponse(response, roomData.room.roomId, ParticipantRole.SPEAKER, true, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed even if the room is deleted', async () => {
|
it('should succeed even if the room is deleted', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER);
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
|
roomData.room.roomId,
|
||||||
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
|
);
|
||||||
await deleteRoom(roomData.room.roomId);
|
await deleteRoom(roomData.room.roomId);
|
||||||
|
|
||||||
const response = await generateRecordingToken(roomData.room.roomId, roomData.moderatorSecret);
|
const response = await generateRecordingToken(roomData.room.roomId, roomData.moderatorSecret);
|
||||||
|
|||||||
@ -8,7 +8,7 @@ describe('Room API Tests', () => {
|
|||||||
const DEFAULT_PREFERENCES = {
|
const DEFAULT_PREFERENCES = {
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
@ -39,7 +39,7 @@ describe('Room API Tests', () => {
|
|||||||
preferences: {
|
preferences: {
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: false }
|
virtualBackgroundPreferences: { enabled: false }
|
||||||
|
|||||||
@ -42,9 +42,9 @@ describe('Room API Tests', () => {
|
|||||||
expectValidRoomRoleAndPermissionsResponse(response, roomData.room.roomId, ParticipantRole.MODERATOR);
|
expectValidRoomRoleAndPermissionsResponse(response, roomData.room.roomId, ParticipantRole.MODERATOR);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should retrieve publisher role and associated permissions for a room with a valid publisher secret', async () => {
|
it('should retrieve speaker role and associated permissions for a room with a valid speaker secret', async () => {
|
||||||
const response = await getRoomRoleBySecret(roomData.room.roomId, roomData.publisherSecret);
|
const response = await getRoomRoleBySecret(roomData.room.roomId, roomData.speakerSecret);
|
||||||
expectValidRoomRoleAndPermissionsResponse(response, roomData.room.roomId, ParticipantRole.PUBLISHER);
|
expectValidRoomRoleAndPermissionsResponse(response, roomData.room.roomId, ParticipantRole.SPEAKER);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return a 404 error if the room does not exist', async () => {
|
it('should return a 404 error if the room does not exist', async () => {
|
||||||
|
|||||||
@ -38,7 +38,7 @@ describe('Room API Tests', () => {
|
|||||||
preferences: {
|
preferences: {
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: false }
|
virtualBackgroundPreferences: { enabled: false }
|
||||||
@ -97,13 +97,13 @@ describe('Room API Tests', () => {
|
|||||||
expectSuccessRoomResponse(response, 'deletion-date', validAutoDeletionDate);
|
expectSuccessRoomResponse(response, 'deletion-date', validAutoDeletionDate);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should retrieve a room without moderatorRoomUrl when participant is publisher', async () => {
|
it('should retrieve a room without moderatorRoomUrl when participant is speaker', async () => {
|
||||||
const roomData = await setupSingleRoom();
|
const roomData = await setupSingleRoom();
|
||||||
const response = await getRoom(
|
const response = await getRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
undefined,
|
undefined,
|
||||||
roomData.publisherCookie,
|
roomData.speakerCookie,
|
||||||
ParticipantRole.PUBLISHER
|
ParticipantRole.SPEAKER
|
||||||
);
|
);
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
expect(response.body.moderatorRoomUrl).toBeUndefined();
|
expect(response.body.moderatorRoomUrl).toBeUndefined();
|
||||||
|
|||||||
@ -36,7 +36,7 @@ describe('Room API Tests', () => {
|
|||||||
preferences: {
|
preferences: {
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
@ -85,7 +85,7 @@ describe('Room API Tests', () => {
|
|||||||
preferences: {
|
preferences: {
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
@ -96,7 +96,7 @@ describe('Room API Tests', () => {
|
|||||||
const partialPreferences = {
|
const partialPreferences = {
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
@ -146,7 +146,7 @@ describe('Room API Tests', () => {
|
|||||||
const invalidPreferences = {
|
const invalidPreferences = {
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: 'true', // String instead of boolean
|
enabled: 'true', // String instead of boolean
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: false },
|
chatPreferences: { enabled: false },
|
||||||
virtualBackgroundPreferences: { enabled: false }
|
virtualBackgroundPreferences: { enabled: false }
|
||||||
@ -212,7 +212,7 @@ describe('Room API Tests', () => {
|
|||||||
const preferences = {
|
const preferences = {
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: false },
|
chatPreferences: { enabled: false },
|
||||||
virtualBackgroundPreferences: { enabled: false }
|
virtualBackgroundPreferences: { enabled: false }
|
||||||
|
|||||||
@ -66,11 +66,11 @@ describe('Meeting API Security Tests', () => {
|
|||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when participant is publisher', async () => {
|
it('should fail when participant is speaker', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.delete(`${MEETINGS_PATH}/${roomData.room.roomId}`)
|
.delete(`${MEETINGS_PATH}/${roomData.room.roomId}`)
|
||||||
.set('Cookie', roomData.publisherCookie)
|
.set('Cookie', roomData.speakerCookie)
|
||||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.SPEAKER);
|
||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -110,11 +110,11 @@ describe('Meeting API Security Tests', () => {
|
|||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when participant is publisher', async () => {
|
it('should fail when participant is speaker', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.delete(`${MEETINGS_PATH}/${roomData.room.roomId}/participants/${PARTICIPANT_NAME}`)
|
.delete(`${MEETINGS_PATH}/${roomData.room.roomId}/participants/${PARTICIPANT_NAME}`)
|
||||||
.set('Cookie', roomData.publisherCookie)
|
.set('Cookie', roomData.speakerCookie)
|
||||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.SPEAKER);
|
||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -38,12 +38,12 @@ describe('Participant API Security Tests', () => {
|
|||||||
roomData = await setupSingleRoom();
|
roomData = await setupSingleRoom();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when no authentication is required and participant is publisher', async () => {
|
it('should succeed when no authentication is required and participant is speaker', async () => {
|
||||||
await changeSecurityPreferences(AuthMode.NONE);
|
await changeSecurityPreferences(AuthMode.NONE);
|
||||||
|
|
||||||
const response = await request(app).post(`${PARTICIPANTS_PATH}/token`).send({
|
const response = await request(app).post(`${PARTICIPANTS_PATH}/token`).send({
|
||||||
roomId: roomData.room.roomId,
|
roomId: roomData.room.roomId,
|
||||||
secret: roomData.publisherSecret,
|
secret: roomData.speakerSecret,
|
||||||
participantName: PARTICIPANT_NAME
|
participantName: PARTICIPANT_NAME
|
||||||
});
|
});
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
@ -60,12 +60,12 @@ describe('Participant API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when authentication is required for moderator and participant is publisher', async () => {
|
it('should succeed when authentication is required for moderator and participant is speaker', async () => {
|
||||||
await changeSecurityPreferences(AuthMode.MODERATORS_ONLY);
|
await changeSecurityPreferences(AuthMode.MODERATORS_ONLY);
|
||||||
|
|
||||||
const response = await request(app).post(`${PARTICIPANTS_PATH}/token`).send({
|
const response = await request(app).post(`${PARTICIPANTS_PATH}/token`).send({
|
||||||
roomId: roomData.room.roomId,
|
roomId: roomData.room.roomId,
|
||||||
secret: roomData.publisherSecret,
|
secret: roomData.speakerSecret,
|
||||||
participantName: PARTICIPANT_NAME
|
participantName: PARTICIPANT_NAME
|
||||||
});
|
});
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
@ -93,23 +93,23 @@ describe('Participant API Security Tests', () => {
|
|||||||
expect(response.status).toBe(401);
|
expect(response.status).toBe(401);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when authentication is required for all users, participant is publisher and authenticated', async () => {
|
it('should succeed when authentication is required for all users, participant is speaker and authenticated', async () => {
|
||||||
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
||||||
|
|
||||||
const response = await request(app).post(`${PARTICIPANTS_PATH}/token`).set('Cookie', adminCookie).send({
|
const response = await request(app).post(`${PARTICIPANTS_PATH}/token`).set('Cookie', adminCookie).send({
|
||||||
roomId: roomData.room.roomId,
|
roomId: roomData.room.roomId,
|
||||||
secret: roomData.publisherSecret,
|
secret: roomData.speakerSecret,
|
||||||
participantName: PARTICIPANT_NAME
|
participantName: PARTICIPANT_NAME
|
||||||
});
|
});
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when authentication is required for all users and participant is publisher but not authenticated', async () => {
|
it('should fail when authentication is required for all users and participant is speaker but not authenticated', async () => {
|
||||||
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
||||||
|
|
||||||
const response = await request(app).post(`${PARTICIPANTS_PATH}/token`).send({
|
const response = await request(app).post(`${PARTICIPANTS_PATH}/token`).send({
|
||||||
roomId: roomData.room.roomId,
|
roomId: roomData.room.roomId,
|
||||||
secret: roomData.publisherSecret,
|
secret: roomData.speakerSecret,
|
||||||
participantName: PARTICIPANT_NAME
|
participantName: PARTICIPANT_NAME
|
||||||
});
|
});
|
||||||
expect(response.status).toBe(401);
|
expect(response.status).toBe(401);
|
||||||
@ -153,15 +153,15 @@ describe('Participant API Security Tests', () => {
|
|||||||
INTERNAL_CONFIG.PARTICIPANT_TOKEN_EXPIRATION = initialTokenExpiration;
|
INTERNAL_CONFIG.PARTICIPANT_TOKEN_EXPIRATION = initialTokenExpiration;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when no authentication is required and participant is publisher', async () => {
|
it('should succeed when no authentication is required and participant is speaker', async () => {
|
||||||
await changeSecurityPreferences(AuthMode.NONE);
|
await changeSecurityPreferences(AuthMode.NONE);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
||||||
.set('Cookie', roomData.publisherCookie)
|
.set('Cookie', roomData.speakerCookie)
|
||||||
.send({
|
.send({
|
||||||
roomId: roomData.room.roomId,
|
roomId: roomData.room.roomId,
|
||||||
secret: roomData.publisherSecret,
|
secret: roomData.speakerSecret,
|
||||||
participantName: PARTICIPANT_NAME
|
participantName: PARTICIPANT_NAME
|
||||||
});
|
});
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
@ -181,15 +181,15 @@ describe('Participant API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when authentication is required for moderator and participant is publisher', async () => {
|
it('should succeed when authentication is required for moderator and participant is speaker', async () => {
|
||||||
await changeSecurityPreferences(AuthMode.MODERATORS_ONLY);
|
await changeSecurityPreferences(AuthMode.MODERATORS_ONLY);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
||||||
.set('Cookie', roomData.publisherCookie)
|
.set('Cookie', roomData.speakerCookie)
|
||||||
.send({
|
.send({
|
||||||
roomId: roomData.room.roomId,
|
roomId: roomData.room.roomId,
|
||||||
secret: roomData.publisherSecret,
|
secret: roomData.speakerSecret,
|
||||||
participantName: PARTICIPANT_NAME
|
participantName: PARTICIPANT_NAME
|
||||||
});
|
});
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
@ -223,29 +223,29 @@ describe('Participant API Security Tests', () => {
|
|||||||
expect(response.status).toBe(401);
|
expect(response.status).toBe(401);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when authentication is required for all users, participant is publisher and authenticated', async () => {
|
it('should succeed when authentication is required for all users, participant is speaker and authenticated', async () => {
|
||||||
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
||||||
.set('Cookie', [adminCookie, roomData.publisherCookie])
|
.set('Cookie', [adminCookie, roomData.speakerCookie])
|
||||||
.send({
|
.send({
|
||||||
roomId: roomData.room.roomId,
|
roomId: roomData.room.roomId,
|
||||||
secret: roomData.publisherSecret,
|
secret: roomData.speakerSecret,
|
||||||
participantName: PARTICIPANT_NAME
|
participantName: PARTICIPANT_NAME
|
||||||
});
|
});
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when authentication is required for all users and participant is publisher but not authenticated', async () => {
|
it('should fail when authentication is required for all users and participant is speaker but not authenticated', async () => {
|
||||||
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
.post(`${PARTICIPANTS_PATH}/token/refresh`)
|
||||||
.set('Cookie', roomData.publisherCookie)
|
.set('Cookie', roomData.speakerCookie)
|
||||||
.send({
|
.send({
|
||||||
roomId: roomData.room.roomId,
|
roomId: roomData.room.roomId,
|
||||||
secret: roomData.publisherSecret,
|
secret: roomData.speakerSecret,
|
||||||
participantName: PARTICIPANT_NAME
|
participantName: PARTICIPANT_NAME
|
||||||
});
|
});
|
||||||
expect(response.status).toBe(401);
|
expect(response.status).toBe(401);
|
||||||
|
|||||||
@ -84,12 +84,12 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when participant is publisher', async () => {
|
it('should fail when participant is speaker', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.post(INTERNAL_RECORDINGS_PATH)
|
.post(INTERNAL_RECORDINGS_PATH)
|
||||||
.send({ roomId: roomData.room.roomId })
|
.send({ roomId: roomData.room.roomId })
|
||||||
.set('Cookie', roomData.publisherCookie)
|
.set('Cookie', roomData.speakerCookie)
|
||||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.SPEAKER);
|
||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -138,11 +138,11 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when participant is publisher', async () => {
|
it('should fail when participant is speaker', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.post(`${INTERNAL_RECORDINGS_PATH}/${roomData.recordingId}/stop`)
|
.post(`${INTERNAL_RECORDINGS_PATH}/${roomData.recordingId}/stop`)
|
||||||
.set('Cookie', roomData.publisherCookie)
|
.set('Cookie', roomData.speakerCookie)
|
||||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.SPEAKER);
|
||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -169,24 +169,24 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when recording access is admin-moderator-publisher and participant is publisher', async () => {
|
it('should succeed when recording access is admin-moderator-speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app).get(RECORDINGS_PATH).set('Cookie', recordingCookie);
|
const response = await request(app).get(RECORDINGS_PATH).set('Cookie', recordingCookie);
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when recording access is admin-moderator-publisher and participant is moderator', async () => {
|
it('should succeed when recording access is admin-moderator-speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
@ -197,11 +197,11 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when recording access is admin-moderator and participant is publisher', async () => {
|
it('should fail when recording access is admin-moderator and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app).get(RECORDINGS_PATH).set('Cookie', recordingCookie);
|
const response = await request(app).get(RECORDINGS_PATH).set('Cookie', recordingCookie);
|
||||||
@ -233,14 +233,14 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when recording access is admin-moderator-publisher and participant is publisher', async () => {
|
it('should succeed when recording access is admin-moderator-speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@ -249,10 +249,10 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when recording access is admin-moderator-publisher and participant is moderator', async () => {
|
it('should succeed when recording access is admin-moderator-speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
@ -265,11 +265,11 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when recording access is admin-moderator and participant is publisher', async () => {
|
it('should fail when recording access is admin-moderator and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@ -362,14 +362,14 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(404);
|
expect(response.status).toBe(404);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when recording access is admin-moderator-publisher and participant is publisher', async () => {
|
it('should fail when recording access is admin-moderator-speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@ -378,10 +378,10 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when recording access is admin-moderator-publisher and participant is moderator', async () => {
|
it('should succeed when recording access is admin-moderator-speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
@ -394,11 +394,11 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(404);
|
expect(response.status).toBe(404);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when recording access is admin-moderator and participant is publisher', async () => {
|
it('should fail when recording access is admin-moderator and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@ -449,14 +449,14 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when recording access is admin-moderator-publisher and participant is publisher', async () => {
|
it('should fail when recording access is admin-moderator-speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@ -466,10 +466,10 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when recording access is admin-moderator-publisher and participant is moderator', async () => {
|
it('should succeed when recording access is admin-moderator-speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
@ -483,11 +483,11 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when recording access is admin-moderator and participant is publisher', async () => {
|
it('should fail when recording access is admin-moderator and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@ -527,14 +527,14 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when recording access is admin-moderator-publisher and participant is publisher', async () => {
|
it('should succeed when recording access is admin-moderator-speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@ -543,10 +543,10 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when recording access is admin-moderator-publisher and participant is moderator', async () => {
|
it('should succeed when recording access is admin-moderator-speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
@ -559,11 +559,11 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when recording access is admin-moderator and participant is publisher', async () => {
|
it('should fail when recording access is admin-moderator and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@ -651,14 +651,14 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when recording access is admin-moderator-publisher and participant is publisher', async () => {
|
it('should succeed when recording access is admin-moderator-speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@ -667,10 +667,10 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when recording access is admin-moderator-publisher and participant is moderator', async () => {
|
it('should succeed when recording access is admin-moderator-speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
@ -683,11 +683,11 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when recording access is admin-moderator and participant is publisher', async () => {
|
it('should fail when recording access is admin-moderator and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@ -727,14 +727,14 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when recording access is admin-moderator-publisher and participant is publisher', async () => {
|
it('should succeed when recording access is admin-moderator-speaker and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
@ -744,10 +744,10 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when recording access is admin-moderator-publisher and participant is moderator', async () => {
|
it('should succeed when recording access is admin-moderator-speaker and participant is moderator', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
@ -761,11 +761,11 @@ describe('Recording API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when recording access is admin-moderator and participant is publisher', async () => {
|
it('should fail when recording access is admin-moderator and participant is speaker', async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
await updateRecordingAccessPreferencesInRoom(roomData.room.roomId, MeetRecordingAccess.ADMIN_MODERATOR);
|
||||||
const recordingCookie = await generateRecordingTokenCookie(
|
const recordingCookie = await generateRecordingTokenCookie(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
roomData.publisherSecret
|
roomData.speakerSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
|
|||||||
@ -142,11 +142,11 @@ describe('Room API Security Tests', () => {
|
|||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when participant is publisher', async () => {
|
it('should succeed when participant is speaker', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.get(`${ROOMS_PATH}/${roomData.room.roomId}`)
|
.get(`${ROOMS_PATH}/${roomData.room.roomId}`)
|
||||||
.set('Cookie', roomData.publisherCookie)
|
.set('Cookie', roomData.speakerCookie)
|
||||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.SPEAKER);
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -181,7 +181,7 @@ describe('Room API Security Tests', () => {
|
|||||||
const roomPreferences = {
|
const roomPreferences = {
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
@ -260,21 +260,21 @@ describe('Room API Security Tests', () => {
|
|||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when participant is publisher', async () => {
|
it('should succeed when participant is speaker', async () => {
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.get(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
.get(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
||||||
.set('Cookie', roomData.publisherCookie)
|
.set('Cookie', roomData.speakerCookie)
|
||||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.SPEAKER);
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when participant is publisher of a different room', async () => {
|
it('should fail when participant is speaker of a different room', async () => {
|
||||||
const newRoomData = await setupSingleRoom();
|
const newRoomData = await setupSingleRoom();
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.get(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
.get(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/preferences`)
|
||||||
.set('Cookie', newRoomData.publisherCookie)
|
.set('Cookie', newRoomData.speakerCookie)
|
||||||
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.PUBLISHER);
|
.set(INTERNAL_CONFIG.PARTICIPANT_ROLE_HEADER, ParticipantRole.SPEAKER);
|
||||||
expect(response.status).toBe(403);
|
expect(response.status).toBe(403);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -289,16 +289,16 @@ describe('Room API Security Tests', () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await updateRecordingAccessPreferencesInRoom(
|
await updateRecordingAccessPreferencesInRoom(
|
||||||
roomData.room.roomId,
|
roomData.room.roomId,
|
||||||
MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when no authentication is required and participant is publisher', async () => {
|
it('should succeed when no authentication is required and participant is speaker', async () => {
|
||||||
await changeSecurityPreferences(AuthMode.NONE);
|
await changeSecurityPreferences(AuthMode.NONE);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.post(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/recording-token`)
|
.post(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/recording-token`)
|
||||||
.send({ secret: roomData.publisherSecret });
|
.send({ secret: roomData.speakerSecret });
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -311,12 +311,12 @@ describe('Room API Security Tests', () => {
|
|||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when authentication is required for moderator and participant is publisher', async () => {
|
it('should succeed when authentication is required for moderator and participant is speaker', async () => {
|
||||||
await changeSecurityPreferences(AuthMode.MODERATORS_ONLY);
|
await changeSecurityPreferences(AuthMode.MODERATORS_ONLY);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.post(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/recording-token`)
|
.post(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/recording-token`)
|
||||||
.send({ secret: roomData.publisherSecret });
|
.send({ secret: roomData.speakerSecret });
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -339,22 +339,22 @@ describe('Room API Security Tests', () => {
|
|||||||
expect(response.status).toBe(401);
|
expect(response.status).toBe(401);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed when authentication is required for all users, participant is publisher and authenticated', async () => {
|
it('should succeed when authentication is required for all users, participant is speaker and authenticated', async () => {
|
||||||
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.post(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/recording-token`)
|
.post(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/recording-token`)
|
||||||
.set('Cookie', adminCookie)
|
.set('Cookie', adminCookie)
|
||||||
.send({ secret: roomData.publisherSecret });
|
.send({ secret: roomData.speakerSecret });
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when authentication is required for all users and participant is publisher but not authenticated', async () => {
|
it('should fail when authentication is required for all users and participant is speaker but not authenticated', async () => {
|
||||||
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
await changeSecurityPreferences(AuthMode.ALL_USERS);
|
||||||
|
|
||||||
const response = await request(app)
|
const response = await request(app)
|
||||||
.post(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/recording-token`)
|
.post(`${INTERNAL_ROOMS_PATH}/${roomData.room.roomId}/recording-token`)
|
||||||
.send({ secret: roomData.publisherSecret });
|
.send({ secret: roomData.speakerSecret });
|
||||||
expect(response.status).toBe(401);
|
expect(response.status).toBe(401);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -11,12 +11,7 @@
|
|||||||
<div class="toolbar-left" id="toolbar-left">
|
<div class="toolbar-left" id="toolbar-left">
|
||||||
<mat-form-field class="search-field" appearance="outline" id="search-field">
|
<mat-form-field class="search-field" appearance="outline" id="search-field">
|
||||||
<mat-label>Search rooms</mat-label>
|
<mat-label>Search rooms</mat-label>
|
||||||
<input
|
<input matInput [formControl]="nameFilterControl" placeholder="Search by room name" id="search-input" />
|
||||||
matInput
|
|
||||||
[formControl]="nameFilterControl"
|
|
||||||
placeholder="Search by room name"
|
|
||||||
id="search-input"
|
|
||||||
/>
|
|
||||||
<mat-icon matSuffix>search</mat-icon>
|
<mat-icon matSuffix>search</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
@ -285,11 +280,11 @@
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
(click)="copyPublisherLink(room)"
|
(click)="copySpeakerLink(room)"
|
||||||
id="copy-publisher-link-btn-{{ room.roomId }}"
|
id="copy-speaker-link-btn-{{ room.roomId }}"
|
||||||
>
|
>
|
||||||
<mat-icon>content_copy</mat-icon>
|
<mat-icon>content_copy</mat-icon>
|
||||||
<span>Copy Publisher Link</span>
|
<span>Copy Speaker Link</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<mat-divider id="actions-divider-{{ room.roomId }}"></mat-divider>
|
<mat-divider id="actions-divider-{{ room.roomId }}"></mat-divider>
|
||||||
|
|||||||
@ -17,7 +17,7 @@ describe('RoomsListsComponent', () => {
|
|||||||
autoDeletionDate: undefined,
|
autoDeletionDate: undefined,
|
||||||
roomIdPrefix: 'test',
|
roomIdPrefix: 'test',
|
||||||
moderatorRoomUrl: 'http://localhost/room/test-room-1?secret=mod-123',
|
moderatorRoomUrl: 'http://localhost/room/test-room-1?secret=mod-123',
|
||||||
publisherRoomUrl: 'http://localhost/room/test-room-1?secret=pub-123',
|
speakerRoomUrl: 'http://localhost/room/test-room-1?secret=pub-123',
|
||||||
preferences: {
|
preferences: {
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
recordingPreferences: { enabled: false },
|
recordingPreferences: { enabled: false },
|
||||||
@ -31,7 +31,7 @@ describe('RoomsListsComponent', () => {
|
|||||||
autoDeletionDate: 1643673600000, // 2024-02-01T00:00:00Z
|
autoDeletionDate: 1643673600000, // 2024-02-01T00:00:00Z
|
||||||
roomIdPrefix: 'test',
|
roomIdPrefix: 'test',
|
||||||
moderatorRoomUrl: 'http://localhost/room/test-room-2?secret=mod-456',
|
moderatorRoomUrl: 'http://localhost/room/test-room-2?secret=mod-456',
|
||||||
publisherRoomUrl: 'http://localhost/room/test-room-2?secret=pub-456',
|
speakerRoomUrl: 'http://localhost/room/test-room-2?secret=pub-456',
|
||||||
preferences: {
|
preferences: {
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
recordingPreferences: { enabled: false },
|
recordingPreferences: { enabled: false },
|
||||||
@ -42,11 +42,7 @@ describe('RoomsListsComponent', () => {
|
|||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [RoomsListsComponent, NoopAnimationsModule, MatSnackBarModule]
|
||||||
RoomsListsComponent,
|
|
||||||
NoopAnimationsModule,
|
|
||||||
MatSnackBarModule
|
|
||||||
]
|
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|
||||||
fixture = TestBed.createComponent(RoomsListsComponent);
|
fixture = TestBed.createComponent(RoomsListsComponent);
|
||||||
|
|||||||
@ -34,7 +34,7 @@ export interface RoomTableAction {
|
|||||||
| 'open'
|
| 'open'
|
||||||
| 'edit'
|
| 'edit'
|
||||||
| 'copyModeratorLink'
|
| 'copyModeratorLink'
|
||||||
| 'copyPublisherLink'
|
| 'copySpeakerLink'
|
||||||
| 'viewRecordings'
|
| 'viewRecordings'
|
||||||
| 'delete'
|
| 'delete'
|
||||||
| 'bulkDelete';
|
| 'bulkDelete';
|
||||||
@ -242,8 +242,8 @@ export class RoomsListsComponent implements OnInit, OnChanges {
|
|||||||
this.roomAction.emit({ rooms: [room], action: 'copyModeratorLink' });
|
this.roomAction.emit({ rooms: [room], action: 'copyModeratorLink' });
|
||||||
}
|
}
|
||||||
|
|
||||||
copyPublisherLink(room: MeetRoom) {
|
copySpeakerLink(room: MeetRoom) {
|
||||||
this.roomAction.emit({ rooms: [room], action: 'copyPublisherLink' });
|
this.roomAction.emit({ rooms: [room], action: 'copySpeakerLink' });
|
||||||
}
|
}
|
||||||
|
|
||||||
viewRecordings(room: MeetRoom) {
|
viewRecordings(room: MeetRoom) {
|
||||||
|
|||||||
@ -2,6 +2,6 @@ import { ParticipantPermissions, ParticipantRole } from '../typings/ce';
|
|||||||
|
|
||||||
export interface ParticipantTokenInfo {
|
export interface ParticipantTokenInfo {
|
||||||
token: string; // The generated participant token
|
token: string; // The generated participant token
|
||||||
role: ParticipantRole; // Role of the participant (e.g., 'moderator', 'publisher')
|
role: ParticipantRole; // Role of the participant (e.g., 'moderator', 'speaker')
|
||||||
permissions: ParticipantPermissions; // List of permissions granted to the participant
|
permissions: ParticipantPermissions; // List of permissions granted to the participant
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,7 @@ export class RecordingPreferencesComponent implements OnDestroy {
|
|||||||
title: 'Allow Recording',
|
title: 'Allow Recording',
|
||||||
description:
|
description:
|
||||||
'Enable recording capabilities for this room. Recordings can be started manually or automatically.',
|
'Enable recording capabilities for this room. Recordings can be started manually or automatically.',
|
||||||
icon: 'video_library',
|
icon: 'video_library'
|
||||||
// recommended: true
|
// recommended: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -64,8 +64,8 @@ export class RecordingPreferencesComponent implements OnDestroy {
|
|||||||
label: 'Admin and Moderators'
|
label: 'Admin and Moderators'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER,
|
value: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER,
|
||||||
label: 'Admin, Moderators and Publishers'
|
label: 'Admin, Moderators and Speakers'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@ -86,8 +86,8 @@ export class RoomsComponent implements OnInit {
|
|||||||
case 'copyModeratorLink':
|
case 'copyModeratorLink':
|
||||||
this.copyModeratorLink(action.rooms[0]);
|
this.copyModeratorLink(action.rooms[0]);
|
||||||
break;
|
break;
|
||||||
case 'copyPublisherLink':
|
case 'copySpeakerLink':
|
||||||
this.copyPublisherLink(action.rooms[0]);
|
this.copySpeakerLink(action.rooms[0]);
|
||||||
break;
|
break;
|
||||||
case 'viewRecordings':
|
case 'viewRecordings':
|
||||||
await this.viewRecordings(action.rooms[0]);
|
await this.viewRecordings(action.rooms[0]);
|
||||||
@ -236,9 +236,9 @@ export class RoomsComponent implements OnInit {
|
|||||||
this.notificationService.showSnackbar('Moderator link copied to clipboard');
|
this.notificationService.showSnackbar('Moderator link copied to clipboard');
|
||||||
}
|
}
|
||||||
|
|
||||||
private copyPublisherLink(room: MeetRoom) {
|
private copySpeakerLink(room: MeetRoom) {
|
||||||
this.clipboard.copy(room.publisherRoomUrl);
|
this.clipboard.copy(room.speakerRoomUrl);
|
||||||
this.notificationService.showSnackbar('Publisher link copied to clipboard');
|
this.notificationService.showSnackbar('Speaker link copied to clipboard');
|
||||||
}
|
}
|
||||||
|
|
||||||
private async viewRecordings(room: MeetRoom) {
|
private async viewRecordings(room: MeetRoom) {
|
||||||
|
|||||||
@ -52,7 +52,7 @@ export class ErrorComponent implements OnInit {
|
|||||||
const reasonMap: { [key in ErrorReason]: { title: string; message: string } } = {
|
const reasonMap: { [key in ErrorReason]: { title: string; message: string } } = {
|
||||||
[ErrorReason.MISSING_ROOM_SECRET]: {
|
[ErrorReason.MISSING_ROOM_SECRET]: {
|
||||||
title: 'Missing secret',
|
title: 'Missing secret',
|
||||||
message: 'You need to provide a secret to join the room as a moderator or publisher'
|
message: 'You need to provide a secret to join the room as a moderator or speaker'
|
||||||
},
|
},
|
||||||
[ErrorReason.MISSING_RECORDING_SECRET]: {
|
[ErrorReason.MISSING_RECORDING_SECRET]: {
|
||||||
title: 'Missing secret',
|
title: 'Missing secret',
|
||||||
@ -60,7 +60,7 @@ export class ErrorComponent implements OnInit {
|
|||||||
},
|
},
|
||||||
[ErrorReason.INVALID_ROOM_SECRET]: {
|
[ErrorReason.INVALID_ROOM_SECRET]: {
|
||||||
title: 'Invalid secret',
|
title: 'Invalid secret',
|
||||||
message: 'The secret provided to join the room is neither valid for moderators nor publishers'
|
message: 'The secret provided to join the room is neither valid for moderators nor speakers'
|
||||||
},
|
},
|
||||||
[ErrorReason.INVALID_RECORDING_SECRET]: {
|
[ErrorReason.INVALID_RECORDING_SECRET]: {
|
||||||
title: 'Invalid secret',
|
title: 'Invalid secret',
|
||||||
|
|||||||
@ -44,9 +44,9 @@
|
|||||||
<div *ovToolbarAdditionalButtons>
|
<div *ovToolbarAdditionalButtons>
|
||||||
<!-- Copy Links Button -->
|
<!-- Copy Links Button -->
|
||||||
<button
|
<button
|
||||||
id="copy-publisher-link"
|
id="copy-speaker-link"
|
||||||
mat-icon-button
|
mat-icon-button
|
||||||
(click)="copyPublisherLink()"
|
(click)="copySpeakerLink()"
|
||||||
[disableRipple]="true"
|
[disableRipple]="true"
|
||||||
matTooltip="Copy the meeting link"
|
matTooltip="Copy the meeting link"
|
||||||
>
|
>
|
||||||
@ -96,7 +96,7 @@
|
|||||||
<div class="share-meeting-link-container">
|
<div class="share-meeting-link-container">
|
||||||
<ov-share-meeting-link
|
<ov-share-meeting-link
|
||||||
[meetingUrl]="hostname + '/' + roomId"
|
[meetingUrl]="hostname + '/' + roomId"
|
||||||
(copyClicked)="copyPublisherLink()"
|
(copyClicked)="copySpeakerLink()"
|
||||||
></ov-share-meeting-link>
|
></ov-share-meeting-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -110,7 +110,7 @@
|
|||||||
[titleSize]="'xl'"
|
[titleSize]="'xl'"
|
||||||
[titleWeight]="'bold'"
|
[titleWeight]="'bold'"
|
||||||
[meetingUrl]="hostname + '/' + roomId"
|
[meetingUrl]="hostname + '/' + roomId"
|
||||||
(copyClicked)="copyPublisherLink()"
|
(copyClicked)="copySpeakerLink()"
|
||||||
></ov-share-meeting-link>
|
></ov-share-meeting-link>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -218,7 +218,7 @@
|
|||||||
@if (features().canModerateRoom) {
|
@if (features().canModerateRoom) {
|
||||||
<ov-share-meeting-link
|
<ov-share-meeting-link
|
||||||
[meetingUrl]="hostname + '/' + roomId"
|
[meetingUrl]="hostname + '/' + roomId"
|
||||||
(copyClicked)="copyPublisherLink()"
|
(copyClicked)="copySpeakerLink()"
|
||||||
></ov-share-meeting-link>
|
></ov-share-meeting-link>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -90,7 +90,7 @@ export class MeetingComponent implements OnInit {
|
|||||||
roomSecret = '';
|
roomSecret = '';
|
||||||
participantName = '';
|
participantName = '';
|
||||||
participantToken = '';
|
participantToken = '';
|
||||||
participantRole: ParticipantRole = ParticipantRole.PUBLISHER;
|
participantRole: ParticipantRole = ParticipantRole.SPEAKER;
|
||||||
remoteParticipants: ParticipantModel[] = [];
|
remoteParticipants: ParticipantModel[] = [];
|
||||||
|
|
||||||
showMeeting = false;
|
showMeeting = false;
|
||||||
@ -406,9 +406,9 @@ export class MeetingComponent implements OnInit {
|
|||||||
this.notificationService.showSnackbar('Moderator link copied to clipboard');
|
this.notificationService.showSnackbar('Moderator link copied to clipboard');
|
||||||
}
|
}
|
||||||
|
|
||||||
async copyPublisherLink() {
|
async copySpeakerLink() {
|
||||||
this.clipboard.copy(this.room!.publisherRoomUrl);
|
this.clipboard.copy(this.room!.speakerRoomUrl);
|
||||||
this.notificationService.showSnackbar('Publisher link copied to clipboard');
|
this.notificationService.showSnackbar('Speaker link copied to clipboard');
|
||||||
}
|
}
|
||||||
|
|
||||||
async onRecordingStartRequested(event: RecordingStartRequestedEvent) {
|
async onRecordingStartRequested(event: RecordingStartRequestedEvent) {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ export class ParticipantTokenService {
|
|||||||
protected readonly PARTICIPANTS_API = `${HttpService.INTERNAL_API_PATH_PREFIX}/participants`;
|
protected readonly PARTICIPANTS_API = `${HttpService.INTERNAL_API_PATH_PREFIX}/participants`;
|
||||||
|
|
||||||
protected participantName?: string;
|
protected participantName?: string;
|
||||||
protected participantRole: ParticipantRole = ParticipantRole.PUBLISHER;
|
protected participantRole: ParticipantRole = ParticipantRole.SPEAKER;
|
||||||
protected currentTokenInfo?: ParticipantTokenInfo;
|
protected currentTokenInfo?: ParticipantTokenInfo;
|
||||||
|
|
||||||
protected log;
|
protected log;
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { MeetRecordingAccess, MeetRoomOptions, MeetRoomPreferences } from '@lib/
|
|||||||
const DEFAULT_PREFERENCES: MeetRoomPreferences = {
|
const DEFAULT_PREFERENCES: MeetRoomPreferences = {
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
|
|||||||
@ -56,8 +56,8 @@ test.describe('Web Component E2E Tests', () => {
|
|||||||
expect(joinElements.length).toBe(1);
|
expect(joinElements.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully join as publisher and receive JOINED event', async ({ page }) => {
|
test('should successfully join as speaker and receive JOINED event', async ({ page }) => {
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
await page.waitForSelector('.event-JOINED');
|
await page.waitForSelector('.event-JOINED');
|
||||||
const joinElements = await page.locator('.event-JOINED').all();
|
const joinElements = await page.locator('.event-JOINED').all();
|
||||||
expect(joinElements.length).toBe(1);
|
expect(joinElements.length).toBe(1);
|
||||||
|
|||||||
@ -91,7 +91,7 @@ test.describe('Room Functionality Tests', () => {
|
|||||||
|
|
||||||
test.describe('Basic Room Features', () => {
|
test.describe('Basic Room Features', () => {
|
||||||
test('should show the toolbar and media buttons', async ({ page }) => {
|
test('should show the toolbar and media buttons', async ({ page }) => {
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
await waitForElementInIframe(page, '#toolbar');
|
await waitForElementInIframe(page, '#toolbar');
|
||||||
|
|
||||||
// Check media buttons are present
|
// Check media buttons are present
|
||||||
@ -102,8 +102,8 @@ test.describe('Room Functionality Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should start a videoconference and display video elements', async ({ page, browser }) => {
|
test('should start a videoconference and display video elements', async ({ page, browser }) => {
|
||||||
// First participant (publisher) joins
|
// First participant (speaker) joins
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
|
|
||||||
// Check local video element
|
// Check local video element
|
||||||
const localVideo = await waitForElementInIframe(page, '.OV_stream.local');
|
const localVideo = await waitForElementInIframe(page, '.OV_stream.local');
|
||||||
@ -132,7 +132,7 @@ test.describe('Room Functionality Tests', () => {
|
|||||||
|
|
||||||
test.describe('Screen Sharing', () => {
|
test.describe('Screen Sharing', () => {
|
||||||
test('should be able to share and stop screen sharing', async ({ page }) => {
|
test('should be able to share and stop screen sharing', async ({ page }) => {
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
|
|
||||||
await waitForElementInIframe(page, '#toolbar');
|
await waitForElementInIframe(page, '#toolbar');
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ test.describe('Room Functionality Tests', () => {
|
|||||||
|
|
||||||
test.describe('UI Panels and Components', () => {
|
test.describe('UI Panels and Components', () => {
|
||||||
test('should show and interact with chat panel', async ({ page }) => {
|
test('should show and interact with chat panel', async ({ page }) => {
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
|
|
||||||
// Open chat panel
|
// Open chat panel
|
||||||
await waitForElementInIframe(page, '#chat-panel-btn');
|
await waitForElementInIframe(page, '#chat-panel-btn');
|
||||||
@ -205,7 +205,7 @@ test.describe('Room Functionality Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should show participants panel', async ({ page }) => {
|
test('should show participants panel', async ({ page }) => {
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
|
|
||||||
// Open participants panel
|
// Open participants panel
|
||||||
await waitForElementInIframe(page, '#participants-panel-btn');
|
await waitForElementInIframe(page, '#participants-panel-btn');
|
||||||
@ -219,7 +219,7 @@ test.describe('Room Functionality Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should show settings panel', async ({ page }) => {
|
test('should show settings panel', async ({ page }) => {
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
|
|
||||||
await openMoreOptionsMenu(page);
|
await openMoreOptionsMenu(page);
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ test.describe('Room Functionality Tests', () => {
|
|||||||
|
|
||||||
test.describe('Advanced Features', () => {
|
test.describe('Advanced Features', () => {
|
||||||
test('should apply virtual background and detect visual changes', async ({ page }) => {
|
test('should apply virtual background and detect visual changes', async ({ page }) => {
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
|
|
||||||
// Wait for video element to be ready
|
// Wait for video element to be ready
|
||||||
await waitForElementInIframe(page, '.OV_video-element');
|
await waitForElementInIframe(page, '.OV_video-element');
|
||||||
|
|||||||
@ -92,7 +92,7 @@ test.describe('Recording Access Tests', () => {
|
|||||||
await waitForElementInIframe(page, '#view-recordings-btn', { state: 'hidden' });
|
await waitForElementInIframe(page, '#view-recordings-btn', { state: 'hidden' });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should publisher not be able to access recording when access level is set to admin', async ({ page }) => {
|
test('should speaker not be able to access recording when access level is set to admin', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomPreferences(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
@ -108,7 +108,7 @@ test.describe('Recording Access Tests', () => {
|
|||||||
|
|
||||||
await page.goto(MEET_TESTAPP_URL);
|
await page.goto(MEET_TESTAPP_URL);
|
||||||
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
||||||
await accessRoomAs('publisher', page);
|
await accessRoomAs('speaker', page);
|
||||||
|
|
||||||
await waitForElementInIframe(page, '#view-recordings-btn', { state: 'hidden' });
|
await waitForElementInIframe(page, '#view-recordings-btn', { state: 'hidden' });
|
||||||
});
|
});
|
||||||
@ -134,7 +134,7 @@ test.describe('Recording Access Tests', () => {
|
|||||||
await waitForElementInIframe(page, 'app-room-recordings', { state: 'visible' });
|
await waitForElementInIframe(page, 'app-room-recordings', { state: 'visible' });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should publisher not be able to access recording when access level is set to moderator', async ({ page }) => {
|
test('should speaker not be able to access recording when access level is set to moderator', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomPreferences(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
@ -150,12 +150,12 @@ test.describe('Recording Access Tests', () => {
|
|||||||
|
|
||||||
await page.goto(MEET_TESTAPP_URL);
|
await page.goto(MEET_TESTAPP_URL);
|
||||||
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
||||||
await accessRoomAs('publisher', page);
|
await accessRoomAs('speaker', page);
|
||||||
|
|
||||||
await waitForElementInIframe(page, '#view-recordings-btn', { state: 'hidden' });
|
await waitForElementInIframe(page, '#view-recordings-btn', { state: 'hidden' });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should allow moderators to access recording when access level is set to publisher', async ({ page }) => {
|
test('should allow moderators to access recording when access level is set to speaker', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomPreferences(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
@ -176,14 +176,14 @@ test.describe('Recording Access Tests', () => {
|
|||||||
await waitForElementInIframe(page, 'app-room-recordings', { state: 'visible' });
|
await waitForElementInIframe(page, 'app-room-recordings', { state: 'visible' });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should allow publisher to access recording when access level is set to publisher', async ({ page }) => {
|
test('should allow speaker to access recording when access level is set to speaker', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomPreferences(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
},
|
},
|
||||||
@ -192,7 +192,7 @@ test.describe('Recording Access Tests', () => {
|
|||||||
|
|
||||||
await page.goto(MEET_TESTAPP_URL);
|
await page.goto(MEET_TESTAPP_URL);
|
||||||
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
||||||
await viewRecordingsAs('publisher', page);
|
await viewRecordingsAs('speaker', page);
|
||||||
|
|
||||||
await waitForElementInIframe(page, 'app-room-recordings', { state: 'visible' });
|
await waitForElementInIframe(page, 'app-room-recordings', { state: 'visible' });
|
||||||
});
|
});
|
||||||
|
|||||||
@ -79,7 +79,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
},
|
},
|
||||||
@ -88,7 +88,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
|
|
||||||
await page.goto(MEET_TESTAPP_URL);
|
await page.goto(MEET_TESTAPP_URL);
|
||||||
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
|
|
||||||
// Check that chat button is visible
|
// Check that chat button is visible
|
||||||
const chatButton = await waitForElementInIframe(page, '#chat-panel-btn', { state: 'visible' });
|
const chatButton = await waitForElementInIframe(page, '#chat-panel-btn', { state: 'visible' });
|
||||||
@ -103,7 +103,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
chatPreferences: { enabled: false },
|
chatPreferences: { enabled: false },
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
},
|
},
|
||||||
@ -112,7 +112,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
|
|
||||||
await page.goto(MEET_TESTAPP_URL);
|
await page.goto(MEET_TESTAPP_URL);
|
||||||
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
|
|
||||||
// Check that chat button is not visible
|
// Check that chat button is not visible
|
||||||
const chatButton = await waitForElementInIframe(page, '#chat-panel-btn', { state: 'hidden' });
|
const chatButton = await waitForElementInIframe(page, '#chat-panel-btn', { state: 'hidden' });
|
||||||
@ -132,7 +132,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
},
|
},
|
||||||
@ -159,14 +159,14 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
await leaveRoom(page, 'moderator');
|
await leaveRoom(page, 'moderator');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not show recording button for publisher', async ({ page }) => {
|
test('should not show recording button for speaker', async ({ page }) => {
|
||||||
await updateRoomPreferences(
|
await updateRoomPreferences(
|
||||||
roomId,
|
roomId,
|
||||||
{
|
{
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
},
|
},
|
||||||
@ -175,9 +175,9 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
|
|
||||||
await page.goto(MEET_TESTAPP_URL);
|
await page.goto(MEET_TESTAPP_URL);
|
||||||
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
|
|
||||||
// Check that recording button is not visible for publisher
|
// Check that recording button is not visible for speaker
|
||||||
const recordingButton = await waitForElementInIframe(page, '#recording-btn', { state: 'hidden' });
|
const recordingButton = await waitForElementInIframe(page, '#recording-btn', { state: 'hidden' });
|
||||||
await expect(recordingButton).toBeHidden();
|
await expect(recordingButton).toBeHidden();
|
||||||
await leaveRoom(page);
|
await leaveRoom(page);
|
||||||
@ -191,7 +191,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
},
|
},
|
||||||
@ -232,7 +232,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
},
|
},
|
||||||
@ -241,7 +241,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
|
|
||||||
await page.goto(MEET_TESTAPP_URL);
|
await page.goto(MEET_TESTAPP_URL);
|
||||||
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
|
|
||||||
// Click more options to reveal virtual background button
|
// Click more options to reveal virtual background button
|
||||||
await openMoreOptionsMenu(page);
|
await openMoreOptionsMenu(page);
|
||||||
@ -261,7 +261,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: false }
|
virtualBackgroundPreferences: { enabled: false }
|
||||||
},
|
},
|
||||||
@ -270,7 +270,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
|
|
||||||
await page.goto(MEET_TESTAPP_URL);
|
await page.goto(MEET_TESTAPP_URL);
|
||||||
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
|
|
||||||
// Click more options to reveal virtual background button
|
// Click more options to reveal virtual background button
|
||||||
await openMoreOptionsMenu(page);
|
await openMoreOptionsMenu(page);
|
||||||
@ -290,7 +290,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
},
|
},
|
||||||
@ -299,7 +299,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
|
|
||||||
await page.goto(MEET_TESTAPP_URL);
|
await page.goto(MEET_TESTAPP_URL);
|
||||||
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
|
|
||||||
await applyVirtualBackground(page, '2');
|
await applyVirtualBackground(page, '2');
|
||||||
await waitForVirtualBackgroundToApply(page);
|
await waitForVirtualBackgroundToApply(page);
|
||||||
@ -311,7 +311,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: { enabled: false }
|
virtualBackgroundPreferences: { enabled: false }
|
||||||
},
|
},
|
||||||
@ -323,7 +323,7 @@ test.describe('UI Feature Preferences Tests', () => {
|
|||||||
await page.reload();
|
await page.reload();
|
||||||
|
|
||||||
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
await prepareForJoiningRoom(page, MEET_TESTAPP_URL, roomId);
|
||||||
await joinRoomAs('publisher', participantName, page);
|
await joinRoomAs('speaker', participantName, page);
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(2000);
|
||||||
|
|
||||||
const isVBApplied = await isVirtualBackgroundApplied(page);
|
const isVBApplied = await isVirtualBackgroundApplied(page);
|
||||||
|
|||||||
@ -92,7 +92,7 @@ export async function interactWithElementInIframe(
|
|||||||
const getDefaultRoomPreferences = (): MeetRoomPreferences => ({
|
const getDefaultRoomPreferences = (): MeetRoomPreferences => ({
|
||||||
recordingPreferences: {
|
recordingPreferences: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_PUBLISHER
|
allowAccessTo: MeetRecordingAccess.ADMIN_MODERATOR_SPEAKER
|
||||||
},
|
},
|
||||||
chatPreferences: { enabled: true },
|
chatPreferences: { enabled: true },
|
||||||
virtualBackgroundPreferences: { enabled: true }
|
virtualBackgroundPreferences: { enabled: true }
|
||||||
@ -222,10 +222,10 @@ export const prepareForJoiningRoom = async (page: Page, url: string, roomId: str
|
|||||||
await page.waitForSelector(`#${roomId}`);
|
await page.waitForSelector(`#${roomId}`);
|
||||||
await page.click('.dropdown-button');
|
await page.click('.dropdown-button');
|
||||||
await page.waitForSelector('#join-as-moderator');
|
await page.waitForSelector('#join-as-moderator');
|
||||||
await page.waitForSelector('#join-as-publisher');
|
await page.waitForSelector('#join-as-speaker');
|
||||||
};
|
};
|
||||||
|
|
||||||
export const joinRoomAs = async (role: 'moderator' | 'publisher', pName: string, page: Page) => {
|
export const joinRoomAs = async (role: 'moderator' | 'speaker', pName: string, page: Page) => {
|
||||||
await page.click('#join-as-' + role);
|
await page.click('#join-as-' + role);
|
||||||
const component = page.locator('openvidu-meet');
|
const component = page.locator('openvidu-meet');
|
||||||
await expect(component).toBeVisible();
|
await expect(component).toBeVisible();
|
||||||
@ -244,13 +244,13 @@ export const joinRoomAs = async (role: 'moderator' | 'publisher', pName: string,
|
|||||||
await waitForElementInIframe(page, 'ov-session', { state: 'visible' });
|
await waitForElementInIframe(page, 'ov-session', { state: 'visible' });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const accessRoomAs = async (role: 'moderator' | 'publisher', page: Page) => {
|
export const accessRoomAs = async (role: 'moderator' | 'speaker', page: Page) => {
|
||||||
await page.click('#join-as-' + role);
|
await page.click('#join-as-' + role);
|
||||||
const component = page.locator('openvidu-meet');
|
const component = page.locator('openvidu-meet');
|
||||||
await expect(component).toBeVisible();
|
await expect(component).toBeVisible();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const viewRecordingsAs = async (role: 'moderator' | 'publisher', page: Page) => {
|
export const viewRecordingsAs = async (role: 'moderator' | 'speaker', page: Page) => {
|
||||||
await page.click('#join-as-' + role);
|
await page.click('#join-as-' + role);
|
||||||
const component = page.locator('openvidu-meet');
|
const component = page.locator('openvidu-meet');
|
||||||
await expect(component).toBeVisible();
|
await expect(component).toBeVisible();
|
||||||
@ -258,7 +258,7 @@ export const viewRecordingsAs = async (role: 'moderator' | 'publisher', page: Pa
|
|||||||
await interactWithElementInIframe(page, '#view-recordings-btn', { action: 'click' });
|
await interactWithElementInIframe(page, '#view-recordings-btn', { action: 'click' });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const leaveRoom = async (page: Page, role: 'moderator' | 'publisher' = 'publisher') => {
|
export const leaveRoom = async (page: Page, role: 'moderator' | 'speaker' = 'speaker') => {
|
||||||
const button = await waitForElementInIframe(page, '#leave-btn');
|
const button = await waitForElementInIframe(page, '#leave-btn');
|
||||||
await button.click();
|
await button.click();
|
||||||
|
|
||||||
|
|||||||
@ -113,9 +113,7 @@ describe('OpenViduMeet Event Handling', () => {
|
|||||||
// Set attributes
|
// Set attributes
|
||||||
const roomUrl = 'https://example.com/room/testRoom-123?secret=123456';
|
const roomUrl = 'https://example.com/room/testRoom-123?secret=123456';
|
||||||
component.setAttribute('room-url', roomUrl);
|
component.setAttribute('room-url', roomUrl);
|
||||||
component.setAttribute('user', 'testUser');
|
component.setAttribute('participant-name', 'testUser');
|
||||||
component.setAttribute('role', 'publisher');
|
|
||||||
component.setAttribute('token', 'test-token');
|
|
||||||
|
|
||||||
// Trigger update
|
// Trigger update
|
||||||
(component as any).updateIframeSrc();
|
(component as any).updateIframeSrc();
|
||||||
@ -125,8 +123,6 @@ describe('OpenViduMeet Event Handling', () => {
|
|||||||
const src = iframe?.src;
|
const src = iframe?.src;
|
||||||
|
|
||||||
expect(src).toContain(roomUrl);
|
expect(src).toContain(roomUrl);
|
||||||
expect(src).toContain('user=testUser');
|
expect(src).toContain('participant-name=testUser');
|
||||||
expect(src).toContain('role=publisher');
|
|
||||||
expect(src).toContain('token=test-token');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -91,21 +91,21 @@
|
|||||||
<input
|
<input
|
||||||
type="hidden"
|
type="hidden"
|
||||||
name="roomUrl"
|
name="roomUrl"
|
||||||
value="{{ publisherRoomUrl }}"
|
value="{{ speakerRoomUrl }}"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type="hidden"
|
type="hidden"
|
||||||
name="participantRole"
|
name="participantRole"
|
||||||
value="publisher"
|
value="speaker"
|
||||||
/>
|
/>
|
||||||
<input type="hidden" name="roomId" value="{{ roomId }}" />
|
<input type="hidden" name="roomId" value="{{ roomId }}" />
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
id="join-as-publisher"
|
id="join-as-speaker"
|
||||||
class="dropdown-item"
|
class="dropdown-item"
|
||||||
>
|
>
|
||||||
Publisher
|
Speaker
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</li>
|
</li>
|
||||||
@ -271,8 +271,8 @@
|
|||||||
<option value="admin-moderator">
|
<option value="admin-moderator">
|
||||||
Admin & Moderator
|
Admin & Moderator
|
||||||
</option>
|
</option>
|
||||||
<option value="admin-moderator-publisher" selected>
|
<option value="admin-moderator-speaker" selected>
|
||||||
Admin, Moderator & Publisher
|
Admin, Moderator & Speaker
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -26,7 +26,10 @@ export const getHome = async (_req: Request, res: Response) => {
|
|||||||
apiUrl: process.env.MEET_API_URL || 'http://localhost:6080/api/v1',
|
apiUrl: process.env.MEET_API_URL || 'http://localhost:6080/api/v1',
|
||||||
apiKey: process.env.MEET_API_KEY || 'meet-api-key'
|
apiKey: process.env.MEET_API_KEY || 'meet-api-key'
|
||||||
});
|
});
|
||||||
res.status(500).send('Internal Server Error - Failed to fetch rooms: ' + (error instanceof Error ? error.message : 'Unknown error'));
|
res.status(500).send(
|
||||||
|
'Internal Server Error - Failed to fetch rooms: ' +
|
||||||
|
(error instanceof Error ? error.message : 'Unknown error')
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -50,7 +53,10 @@ export const postCreateRoom = async (req: Request, res: Response) => {
|
|||||||
stack: error instanceof Error ? error.stack : 'No stack trace',
|
stack: error instanceof Error ? error.stack : 'No stack trace',
|
||||||
requestBody: req.body
|
requestBody: req.body
|
||||||
});
|
});
|
||||||
res.status(500).send('Internal Server Error - Failed to create room: ' + (error instanceof Error ? error.message : 'Unknown error'));
|
res.status(500).send(
|
||||||
|
'Internal Server Error - Failed to create room: ' +
|
||||||
|
(error instanceof Error ? error.message : 'Unknown error')
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -77,7 +83,10 @@ export const deleteRoomCtrl = async (req: Request, res: Response) => {
|
|||||||
stack: error instanceof Error ? error.stack : 'No stack trace',
|
stack: error instanceof Error ? error.stack : 'No stack trace',
|
||||||
requestBody: req.body
|
requestBody: req.body
|
||||||
});
|
});
|
||||||
res.status(500).send('Internal Server Error - Failed to delete room: ' + (error instanceof Error ? error.message : 'Unknown error'));
|
res.status(500).send(
|
||||||
|
'Internal Server Error - Failed to delete room: ' +
|
||||||
|
(error instanceof Error ? error.message : 'Unknown error')
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -105,7 +114,10 @@ export const deleteAllRoomsCtrl = async (_req: Request, res: Response) => {
|
|||||||
message: error instanceof Error ? error.message : 'Unknown error',
|
message: error instanceof Error ? error.message : 'Unknown error',
|
||||||
stack: error instanceof Error ? error.stack : 'No stack trace'
|
stack: error instanceof Error ? error.stack : 'No stack trace'
|
||||||
});
|
});
|
||||||
res.status(500).send('Internal Server Error - Failed to delete all rooms: ' + (error instanceof Error ? error.message : 'Unknown error'));
|
res.status(500).send(
|
||||||
|
'Internal Server Error - Failed to delete all rooms: ' +
|
||||||
|
(error instanceof Error ? error.message : 'Unknown error')
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -133,7 +145,10 @@ export const deleteAllRecordingsCtrl = async (_req: Request, res: Response) => {
|
|||||||
message: error instanceof Error ? error.message : 'Unknown error',
|
message: error instanceof Error ? error.message : 'Unknown error',
|
||||||
stack: error instanceof Error ? error.stack : 'No stack trace'
|
stack: error instanceof Error ? error.stack : 'No stack trace'
|
||||||
});
|
});
|
||||||
res.status(500).send('Internal Server Error - Failed to delete all recordings: ' + (error instanceof Error ? error.message : 'Unknown error'));
|
res.status(500).send(
|
||||||
|
'Internal Server Error - Failed to delete all recordings: ' +
|
||||||
|
(error instanceof Error ? error.message : 'Unknown error')
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -150,7 +165,7 @@ const processFormPreferences = (body: any): any => {
|
|||||||
enabled: body['preferences.recordingPreferences.enabled'] === 'on',
|
enabled: body['preferences.recordingPreferences.enabled'] === 'on',
|
||||||
// Only include allowAccessTo if recording is enabled
|
// Only include allowAccessTo if recording is enabled
|
||||||
...(body['preferences.recordingPreferences.enabled'] === 'on' && {
|
...(body['preferences.recordingPreferences.enabled'] === 'on' && {
|
||||||
allowAccessTo: body['preferences.recordingPreferences.allowAccessTo'] || 'admin-moderator-publisher'
|
allowAccessTo: body['preferences.recordingPreferences.allowAccessTo'] || 'admin-moderator-speaker'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
virtualBackgroundPreferences: {
|
virtualBackgroundPreferences: {
|
||||||
|
|||||||
@ -32,5 +32,5 @@ export interface ParticipantPermissions {
|
|||||||
*/
|
*/
|
||||||
export const enum ParticipantRole {
|
export const enum ParticipantRole {
|
||||||
MODERATOR = 'moderator',
|
MODERATOR = 'moderator',
|
||||||
PUBLISHER = 'publisher'
|
SPEAKER = 'speaker'
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,7 @@ export interface MeetRecordingPreferences {
|
|||||||
export const enum MeetRecordingAccess {
|
export const enum MeetRecordingAccess {
|
||||||
ADMIN = 'admin', // Only admins can access the recording
|
ADMIN = 'admin', // Only admins can access the recording
|
||||||
ADMIN_MODERATOR = 'admin-moderator', // Admins and moderators can access
|
ADMIN_MODERATOR = 'admin-moderator', // Admins and moderators can access
|
||||||
ADMIN_MODERATOR_PUBLISHER = 'admin-moderator-publisher', // Admins, moderators and publishers can access
|
ADMIN_MODERATOR_SPEAKER = 'admin-moderator-speaker' // Admins, moderators and speakers can access
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MeetChatPreferences {
|
export interface MeetChatPreferences {
|
||||||
|
|||||||
@ -21,7 +21,7 @@ export interface MeetRoom extends BaseRoomOptions {
|
|||||||
roomName: string;
|
roomName: string;
|
||||||
creationDate: number;
|
creationDate: number;
|
||||||
moderatorRoomUrl: string;
|
moderatorRoomUrl: string;
|
||||||
publisherRoomUrl: string;
|
speakerRoomUrl: string;
|
||||||
markedForDeletion?: boolean;
|
markedForDeletion?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
export enum WebComponentProperty {
|
export enum WebComponentProperty {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The OpenVidu Meet room URL to connect to (moderator or publisher url)
|
* The OpenVidu Meet room URL to connect to (moderator or speaker url)
|
||||||
* @required This attribute is required unless `recording-url` is provided.
|
* @required This attribute is required unless `recording-url` is provided.
|
||||||
*/
|
*/
|
||||||
ROOM_URL = 'room-url',
|
ROOM_URL = 'room-url',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user