@rapidmx/meet-plugin 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +382 -0
- package/README.md +38 -0
- package/apps/meet/[token].tsx +144 -0
- package/apps/meet/_CallControls.tsx +69 -0
- package/apps/meet/_CallView.tsx +338 -0
- package/apps/meet/_MeetChrome.tsx +30 -0
- package/apps/meet/_MeetLobby.tsx +223 -0
- package/apps/meet/_ParticipantTile.tsx +66 -0
- package/apps/meet/_layout.tsx +34 -0
- package/apps/meet/_meetApi.ts +66 -0
- package/apps/meet/index.tsx +22 -0
- package/apps/settings-video-conferencing/_PersonalRoomCard.tsx +140 -0
- package/apps/settings-video-conferencing/_layout.tsx +47 -0
- package/apps/settings-video-conferencing/index.tsx +192 -0
- package/apps/shared/media/activeSpeaker.ts +45 -0
- package/apps/shared/media/deviceMedia.ts +141 -0
- package/apps/shared/media/levelMeter.ts +91 -0
- package/apps/shared/push/GuestSignalingClient.ts +338 -0
- package/apps/shared/webrtc/MeshConnectionManager.ts +350 -0
- package/apps/shared/webrtc/realPeerConnection.ts +37 -0
- package/apps/shared/webrtc/types.ts +90 -0
- package/dist/apps/meet/[token].d.ts +33 -0
- package/dist/apps/meet/[token].js +101 -0
- package/dist/apps/meet/_CallControls.d.ts +18 -0
- package/dist/apps/meet/_CallControls.js +6 -0
- package/dist/apps/meet/_CallView.d.ts +41 -0
- package/dist/apps/meet/_CallView.js +225 -0
- package/dist/apps/meet/_MeetChrome.d.ts +13 -0
- package/dist/apps/meet/_MeetChrome.js +10 -0
- package/dist/apps/meet/_MeetLobby.d.ts +29 -0
- package/dist/apps/meet/_MeetLobby.js +120 -0
- package/dist/apps/meet/_ParticipantTile.d.ts +18 -0
- package/dist/apps/meet/_ParticipantTile.js +25 -0
- package/dist/apps/meet/_layout.d.ts +9 -0
- package/dist/apps/meet/_layout.js +8 -0
- package/dist/apps/meet/_meetApi.d.ts +47 -0
- package/dist/apps/meet/_meetApi.js +23 -0
- package/dist/apps/meet/index.d.ts +5 -0
- package/dist/apps/meet/index.js +8 -0
- package/dist/apps/settings-video-conferencing/_PersonalRoomCard.d.ts +24 -0
- package/dist/apps/settings-video-conferencing/_PersonalRoomCard.js +77 -0
- package/dist/apps/settings-video-conferencing/_layout.d.ts +16 -0
- package/dist/apps/settings-video-conferencing/_layout.js +8 -0
- package/dist/apps/settings-video-conferencing/index.d.ts +16 -0
- package/dist/apps/settings-video-conferencing/index.js +92 -0
- package/dist/apps/shared/media/activeSpeaker.d.ts +20 -0
- package/dist/apps/shared/media/activeSpeaker.js +39 -0
- package/dist/apps/shared/media/deviceMedia.d.ts +65 -0
- package/dist/apps/shared/media/deviceMedia.js +110 -0
- package/dist/apps/shared/media/levelMeter.d.ts +40 -0
- package/dist/apps/shared/media/levelMeter.js +61 -0
- package/dist/apps/shared/push/GuestSignalingClient.d.ts +89 -0
- package/dist/apps/shared/push/GuestSignalingClient.js +291 -0
- package/dist/apps/shared/webrtc/MeshConnectionManager.d.ts +97 -0
- package/dist/apps/shared/webrtc/MeshConnectionManager.js +262 -0
- package/dist/apps/shared/webrtc/realPeerConnection.d.ts +7 -0
- package/dist/apps/shared/webrtc/realPeerConnection.js +26 -0
- package/dist/apps/shared/webrtc/types.d.ts +94 -0
- package/dist/apps/shared/webrtc/types.js +9 -0
- package/dist/lib/index.js +25 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/models/mongo/VideoMeetingInviteeMongo.js +87 -0
- package/dist/lib/models/mongo/VideoMeetingInviteeMongo.js.map +1 -0
- package/dist/lib/models/mongo/VideoMeetingMongo.js +126 -0
- package/dist/lib/models/mongo/VideoMeetingMongo.js.map +1 -0
- package/dist/lib/models/sql/VideoMeetingInviteeSQL.js +87 -0
- package/dist/lib/models/sql/VideoMeetingInviteeSQL.js.map +1 -0
- package/dist/lib/models/sql/VideoMeetingSQL.js +127 -0
- package/dist/lib/models/sql/VideoMeetingSQL.js.map +1 -0
- package/dist/lib/models/types.js +19 -0
- package/dist/lib/models/types.js.map +1 -0
- package/dist/lib/mongo.js +13 -0
- package/dist/lib/mongo.js.map +1 -0
- package/dist/lib/routes/BaseVideoMeetingRoute.js +743 -0
- package/dist/lib/routes/BaseVideoMeetingRoute.js.map +1 -0
- package/dist/lib/routes/mongo/VideoMeetingRouteMongo.js +31 -0
- package/dist/lib/routes/mongo/VideoMeetingRouteMongo.js.map +1 -0
- package/dist/lib/routes/sql/VideoMeetingRouteSQL.js +31 -0
- package/dist/lib/routes/sql/VideoMeetingRouteSQL.js.map +1 -0
- package/dist/lib/sql.js +13 -0
- package/dist/lib/sql.js.map +1 -0
- package/dist/lib/util/BookingIntegrationUtils.js +115 -0
- package/dist/lib/util/BookingIntegrationUtils.js.map +1 -0
- package/dist/lib/util/IceServerUtils.js +68 -0
- package/dist/lib/util/IceServerUtils.js.map +1 -0
- package/dist/lib/util/PublicUrlUtils.js +37 -0
- package/dist/lib/util/PublicUrlUtils.js.map +1 -0
- package/dist/lib/util/RouteAccessUtils.js +32 -0
- package/dist/lib/util/RouteAccessUtils.js.map +1 -0
- package/dist/lib/util/TokenUtils.js +33 -0
- package/dist/lib/util/TokenUtils.js.map +1 -0
- package/dist/types/index.d.ts +20 -0
- package/dist/types/models/mongo/VideoMeetingInviteeMongo.d.ts +16 -0
- package/dist/types/models/mongo/VideoMeetingMongo.d.ts +23 -0
- package/dist/types/models/sql/VideoMeetingInviteeSQL.d.ts +16 -0
- package/dist/types/models/sql/VideoMeetingSQL.d.ts +23 -0
- package/dist/types/models/types.d.ts +131 -0
- package/dist/types/mongo.d.ts +8 -0
- package/dist/types/routes/BaseVideoMeetingRoute.d.ts +368 -0
- package/dist/types/routes/mongo/VideoMeetingRouteMongo.d.ts +10 -0
- package/dist/types/routes/sql/VideoMeetingRouteSQL.d.ts +10 -0
- package/dist/types/sql.d.ts +8 -0
- package/dist/types/util/BookingIntegrationUtils.d.ts +51 -0
- package/dist/types/util/IceServerUtils.d.ts +57 -0
- package/dist/types/util/PublicUrlUtils.d.ts +11 -0
- package/dist/types/util/RouteAccessUtils.d.ts +8 -0
- package/dist/types/util/TokenUtils.d.ts +23 -0
- package/package.json +181 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** A single ICE server entry, matching the shape the browser `RTCPeerConnection` `iceServers` constructor option
|
|
2
|
+
* expects (`RTCIceServer`), so the join response can be handed to it directly with no reshaping. */
|
|
3
|
+
export interface IceServerConfig {
|
|
4
|
+
urls: string;
|
|
5
|
+
username?: string;
|
|
6
|
+
credential?: string;
|
|
7
|
+
}
|
|
8
|
+
/** The `mail:videoconf:turn:*` settings, exactly as configured (empty strings for anything unset). */
|
|
9
|
+
export interface TurnSettings {
|
|
10
|
+
url: string;
|
|
11
|
+
username: string;
|
|
12
|
+
credential: string;
|
|
13
|
+
sharedSecret: string;
|
|
14
|
+
}
|
|
15
|
+
/** Always-available, free public STUN servers - discovery only, no media relay. Two independent providers, so a
|
|
16
|
+
* call still has STUN available if one of them is ever unreachable. */
|
|
17
|
+
export declare const DEFAULT_STUN_SERVERS: readonly IceServerConfig[];
|
|
18
|
+
/** How long a minted TURN REST credential remains valid for, in seconds. One hour comfortably covers ICE
|
|
19
|
+
* negotiation and reconnection attempts for the length of a typical call without minting a fresh credential on
|
|
20
|
+
* every join. */
|
|
21
|
+
export declare const DEFAULT_TURN_CREDENTIAL_TTL_SECONDS: number;
|
|
22
|
+
/**
|
|
23
|
+
* Generates a coturn-style time-limited REST API credential: `username` is `<unix-expiry-timestamp>:<userPart>`,
|
|
24
|
+
* and `credential` is `base64(HMAC-SHA1(sharedSecret, username))`. This is coturn's own documented
|
|
25
|
+
* `static-auth-secret` mechanism (the `turnserver -a -X` REST credential algorithm) - implemented here exactly,
|
|
26
|
+
* not guessed at: the TURN server derives the same HMAC independently at connection time using the timestamp
|
|
27
|
+
* embedded in the username it's handed, so no round trip to the TURN server is needed to mint one.
|
|
28
|
+
*
|
|
29
|
+
* @param sharedSecret The operator's `mail:videoconf:turn:shared_secret`.
|
|
30
|
+
* @param userPart The identity portion of the username - the configured `mail:videoconf:turn:username`, or a
|
|
31
|
+
* generated one when that's unset (see `buildIceServers()`).
|
|
32
|
+
* @param ttlSeconds How long the credential remains valid for, from `now`.
|
|
33
|
+
* @param now The time to compute the expiry from. Defaults to the real current time; a test may pass a fixed
|
|
34
|
+
* value for a deterministic assertion.
|
|
35
|
+
*/
|
|
36
|
+
export declare function turnRestCredential(sharedSecret: string, userPart: string, ttlSeconds?: number, now?: Date): {
|
|
37
|
+
username: string;
|
|
38
|
+
credential: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Builds the full ICE server list for a join response: the hardcoded public STUN servers, plus a TURN entry when
|
|
42
|
+
* `settings.url` is configured. When a `sharedSecret` is also configured, the TURN entry carries a fresh,
|
|
43
|
+
* time-limited credential (`turnRestCredential()`) rather than the static `username`/`credential` pair, which is
|
|
44
|
+
* used verbatim only when no shared secret is set. A TURN url with neither a shared secret nor a static
|
|
45
|
+
* credential is still included with no credentials at all - some self-hosted TURN servers are deliberately run
|
|
46
|
+
* without authentication for testing, and it costs nothing to pass the url through as configured.
|
|
47
|
+
*
|
|
48
|
+
* @param settings The `mail:videoconf:turn:*` settings, exactly as configured.
|
|
49
|
+
* @param options `ttlSeconds`/`now` are forwarded to `turnRestCredential()`. `randomUserPart` supplies the
|
|
50
|
+
* generated identity portion of a shared-secret credential's username when `settings.username` is unset -
|
|
51
|
+
* defaults to a fresh random hex string; a test may override it for a deterministic assertion.
|
|
52
|
+
*/
|
|
53
|
+
export declare function buildIceServers(settings: TurnSettings, options?: {
|
|
54
|
+
ttlSeconds?: number;
|
|
55
|
+
now?: Date;
|
|
56
|
+
randomUserPart?: () => string;
|
|
57
|
+
}): IceServerConfig[];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes a `mail:videoconf:public_url`-shaped setting into a base URL (origin plus path, no trailing slash),
|
|
3
|
+
* or `undefined` when it's unset or unsafe to advertise - mirroring `@rapidmx/autodiscover`'s `BaseAutodiscoverRoute`
|
|
4
|
+
* private `baseUrl` getter exactly (that helper isn't exported from `@rapidmx/restapi` for reuse, so this is a
|
|
5
|
+
* small, independent copy of the same validation): the value must parse as a URL, use `https:` (plain `http:` is
|
|
6
|
+
* only tolerated for a loopback host, for local development), and carry no credentials, query string or fragment -
|
|
7
|
+
* any of which would produce a broken or insecure join link once a token is appended.
|
|
8
|
+
*
|
|
9
|
+
* @param rawUrl The configured setting value, e.g. `https://mail.example.com/meet`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildBaseUrl(rawUrl: string | undefined): string | undefined;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type JWTUser } from "@rapidrest/core";
|
|
2
|
+
/**
|
|
3
|
+
* `user` without its trusted roles (and without its elevation), for handing to code that would otherwise treat
|
|
4
|
+
* the caller as a superuser: `ACLUtils.hasPermission()`, `RepoUtils` with `{ user }` and no `ignoreACL`. Everything
|
|
5
|
+
* else about the identity - uid, other roles, scopes - is unchanged, so an owner or delegate record still
|
|
6
|
+
* matches. Returns `user` itself when it has nothing to strip.
|
|
7
|
+
*/
|
|
8
|
+
export declare function stripTrustedRoles(user: JWTUser | undefined, trustedRoles: readonly string[]): JWTUser | undefined;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The exact shape `mintJoinToken()` produces: 32 random bytes, base64url without padding - mirroring
|
|
3
|
+
* `booking-plugin`'s `Booking.manageToken` shape/entropy exactly (see its `BaseBookingRoute.MANAGE_TOKEN_PATTERN`).
|
|
4
|
+
* Checked before any lookup, so a candidate value is always a plain literal by the time it reaches a query.
|
|
5
|
+
*/
|
|
6
|
+
export declare const JOIN_TOKEN_PATTERN: RegExp;
|
|
7
|
+
/**
|
|
8
|
+
* The exact shape `mintPublicSlug()` produces: 8 random bytes, base64url without padding - deliberately a
|
|
9
|
+
* different length than `JOIN_TOKEN_PATTERN` (11 characters vs. 43), so the two can never collide and
|
|
10
|
+
* `BaseVideoMeetingRoute.join()` can tell which kind of value it was handed from its length alone, without
|
|
11
|
+
* ambiguity, rather than trying both lookups against a value that only matched one of them (see that method's
|
|
12
|
+
* doc comment for the disambiguation this enables).
|
|
13
|
+
*/
|
|
14
|
+
export declare const PUBLIC_SLUG_PATTERN: RegExp;
|
|
15
|
+
/** Mints a private meeting invitee's `joinToken`: 32 random bytes, base64url. Matches `JOIN_TOKEN_PATTERN`. */
|
|
16
|
+
export declare function mintJoinToken(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Mints a public meeting's `publicSlug`: 8 random bytes, base64url (~48 bits of entropy). Matches
|
|
19
|
+
* `PUBLIC_SLUG_PATTERN`. Random rather than name-derived (unlike `booking-plugin`'s human-authored
|
|
20
|
+
* `BookingType.slug`) since nothing about a video meeting is memorable or worth choosing by hand - it only ever
|
|
21
|
+
* appears embedded in a link.
|
|
22
|
+
*/
|
|
23
|
+
export declare function mintPublicSlug(): string;
|
package/package.json
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rapidmx/meet-plugin",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "RapidMX plugin that provides WebRTC video conferencing, joinable from a calendar invite or a shared link.",
|
|
5
|
+
"repository": "https://github.com/RapidMX/meet-plugin.git",
|
|
6
|
+
"author": "RapidREST <rapidrests@gmail.com>",
|
|
7
|
+
"license": "MPL-2.0",
|
|
8
|
+
"contributors": [
|
|
9
|
+
"Jean-Philippe Steinmetz"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "yarn lint && rimraf dist && tsc && tsc -p tsconfig.apps.json",
|
|
13
|
+
"lint": "eslint ./src ./apps ./test",
|
|
14
|
+
"local-audit": "yarn install && yarn npm audit -A -R \"$@\"",
|
|
15
|
+
"checkup": "yarn dlx @yarnpkg/doctor \"$@\"",
|
|
16
|
+
"dependency-check": "yarn dlx depcheck \"$@\"",
|
|
17
|
+
"report-coverage": "cat ./coverage/lcov.info | coveralls",
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"test:prod": "npm run lint && vitest run --coverage",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"release": "npx @rapidrest/cli release",
|
|
22
|
+
"prepublish": "yarn build"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@rapidmx/react-shared": ">=0.6.0 <1",
|
|
26
|
+
"@rapidmx/restapi": ">=0.17.0 <1",
|
|
27
|
+
"@rapidmx/web-client": ">=0.11.0 <1",
|
|
28
|
+
"@rapidrest/core": "5.x",
|
|
29
|
+
"@rapidrest/service-core": "2.x",
|
|
30
|
+
"react": "19.x",
|
|
31
|
+
"react-dom": "19.x"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@rapidmx/react-shared": "^0.13.0",
|
|
35
|
+
"@rapidmx/restapi": "^0.19.0",
|
|
36
|
+
"@rapidmx/web-client": "^0.13.0",
|
|
37
|
+
"@rapidrest/core": "^5.2.2",
|
|
38
|
+
"@rapidrest/service-core": "^2.1.1",
|
|
39
|
+
"@swc/core": "^1.16.2",
|
|
40
|
+
"@testing-library/dom": "^10.4.1",
|
|
41
|
+
"@testing-library/jest-dom": "^7.0.1",
|
|
42
|
+
"@testing-library/react": "^16.3.3",
|
|
43
|
+
"@testing-library/user-event": "^14.6.7",
|
|
44
|
+
"@types/nconf": "^0.10.7",
|
|
45
|
+
"@types/node": "^26.5.0",
|
|
46
|
+
"@types/react": "^19.2.18",
|
|
47
|
+
"@types/react-dom": "^19.2.7",
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "^8.70.0",
|
|
49
|
+
"@typescript-eslint/parser": "^8.70.0",
|
|
50
|
+
"@vitest/coverage-v8": "^5.0.0",
|
|
51
|
+
"better-sqlite3": "^13.0.3",
|
|
52
|
+
"eslint": "^10.10.0",
|
|
53
|
+
"eslint-config-prettier": "^10.1.8",
|
|
54
|
+
"eslint-plugin-import": "^2.32.0",
|
|
55
|
+
"eslint-plugin-jsdoc": "^64.3.6",
|
|
56
|
+
"globals": "^17.12.0",
|
|
57
|
+
"jsdom": "^30.0.1",
|
|
58
|
+
"lodash-es": "^4.18.1",
|
|
59
|
+
"mongodb": "^7.6.0",
|
|
60
|
+
"mongodb-memory-server": "^11.2.0",
|
|
61
|
+
"nconf": "^0.13.0",
|
|
62
|
+
"openapi3-ts": "^4.6.1",
|
|
63
|
+
"prom-client": "^15.1.3",
|
|
64
|
+
"react": "^19.2.8",
|
|
65
|
+
"react-dom": "^19.2.8",
|
|
66
|
+
"redis": "^6.2.1",
|
|
67
|
+
"reflect-metadata": "^0.2.2",
|
|
68
|
+
"rimraf": "^6.1.3",
|
|
69
|
+
"ts-node": "^10.9.2",
|
|
70
|
+
"tsx": "^4.23.13",
|
|
71
|
+
"typeorm": "^1.1.1",
|
|
72
|
+
"typescript": "^6.0.3",
|
|
73
|
+
"unplugin-swc": "^1.6.0",
|
|
74
|
+
"uuid": "^14.0.2",
|
|
75
|
+
"vite": "^8.2.2",
|
|
76
|
+
"vitest": "^5.0.0",
|
|
77
|
+
"winston": "^3.19.0"
|
|
78
|
+
},
|
|
79
|
+
"resolutions": {
|
|
80
|
+
"@rapidmx/react-shared": "^0.11.0",
|
|
81
|
+
"@rapidmx/restapi": "^0.17.0",
|
|
82
|
+
"@rapidmx/web-client": "^0.11.0"
|
|
83
|
+
},
|
|
84
|
+
"packageManager": "yarn@4.5.3",
|
|
85
|
+
"engines": {
|
|
86
|
+
"node": ">=24.0.0"
|
|
87
|
+
},
|
|
88
|
+
"publishConfig": {
|
|
89
|
+
"registry": "https://registry.npmjs.org/"
|
|
90
|
+
},
|
|
91
|
+
"type": "module",
|
|
92
|
+
"main": "dist/lib/index.js",
|
|
93
|
+
"exports": {
|
|
94
|
+
".": {
|
|
95
|
+
"import": "./dist/lib/index.js",
|
|
96
|
+
"types": "./dist/types/index.d.ts"
|
|
97
|
+
},
|
|
98
|
+
"./mongo": {
|
|
99
|
+
"import": "./dist/lib/mongo.js",
|
|
100
|
+
"types": "./dist/types/mongo.d.ts"
|
|
101
|
+
},
|
|
102
|
+
"./sql": {
|
|
103
|
+
"import": "./dist/lib/sql.js",
|
|
104
|
+
"types": "./dist/types/sql.d.ts"
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"typings": "dist/types/index.d.ts",
|
|
108
|
+
"files": [
|
|
109
|
+
"apps",
|
|
110
|
+
"dist"
|
|
111
|
+
],
|
|
112
|
+
"rapidmx": {
|
|
113
|
+
"plugin": {
|
|
114
|
+
"apiVersion": 1,
|
|
115
|
+
"displayName": "Video Conferencing",
|
|
116
|
+
"description": "Private and public WebRTC video meetings. A private meeting mints one link per invitee for a calendar invite's location and body; a public meeting shares a single link. Joining needs no account - a guest picks a name, checks their camera and microphone, and enters.",
|
|
117
|
+
"mailboxScopedData": true,
|
|
118
|
+
"settings": [
|
|
119
|
+
{
|
|
120
|
+
"key": "mail:videoconf:public_url",
|
|
121
|
+
"label": "Public join page URL",
|
|
122
|
+
"type": "string",
|
|
123
|
+
"default": "",
|
|
124
|
+
"help": "The address of the public join pages, for example https://mail.example.com/meet. Calendar invites include a join link only when this is set."
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"key": "mail:videoconf:turn:url",
|
|
128
|
+
"label": "TURN server URL",
|
|
129
|
+
"type": "string",
|
|
130
|
+
"default": "",
|
|
131
|
+
"help": "A turn: or turns: URL (e.g. turns:turn.example.com:5349) relaying media for a participant behind a restrictive NAT or firewall, for whom a direct peer-to-peer connection fails. Public STUN servers are used for everyone else and need no configuration. Leave empty to serve calls with STUN only - most calls will still connect, but some participants may not."
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"key": "mail:videoconf:turn:username",
|
|
135
|
+
"label": "TURN server username",
|
|
136
|
+
"type": "string",
|
|
137
|
+
"default": "",
|
|
138
|
+
"help": "Used as-is unless a shared secret is also set below, in which case it is combined with a per-join expiring credential instead (coturn's time-limited REST credential mechanism) and this value is ignored."
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"key": "mail:videoconf:turn:credential",
|
|
142
|
+
"label": "TURN server credential (static)",
|
|
143
|
+
"type": "string",
|
|
144
|
+
"default": "",
|
|
145
|
+
"help": "The TURN server's password for the username above. Ignored when a shared secret is set below."
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"key": "mail:videoconf:turn:shared_secret",
|
|
149
|
+
"label": "TURN server shared secret (for expiring credentials)",
|
|
150
|
+
"type": "string",
|
|
151
|
+
"default": "",
|
|
152
|
+
"help": "coturn's static-auth-secret, if configured. When set, every join mints its own short-lived username/credential pair (an HMAC-SHA1 of a timestamp with this secret) instead of handing out one permanent password to every participant - the recommended setup. Leave empty to use the static username/credential above instead."
|
|
153
|
+
}
|
|
154
|
+
],
|
|
155
|
+
"ui": {
|
|
156
|
+
"apps": [
|
|
157
|
+
{
|
|
158
|
+
"id": "meet",
|
|
159
|
+
"host": "public",
|
|
160
|
+
"mount": "/meet",
|
|
161
|
+
"dir": "apps/meet"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"id": "video-conferencing",
|
|
165
|
+
"host": "www",
|
|
166
|
+
"mount": "/settings/video-conferencing",
|
|
167
|
+
"dir": "apps/settings-video-conferencing"
|
|
168
|
+
}
|
|
169
|
+
],
|
|
170
|
+
"settingsSections": [
|
|
171
|
+
{
|
|
172
|
+
"id": "video-conferencing",
|
|
173
|
+
"label": "Video Conferencing",
|
|
174
|
+
"href": "/settings/video-conferencing",
|
|
175
|
+
"icon": "HiOutlineVideoCamera"
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|