Lue dans les fichiers PHP du paquet au commit c6445bd247c5 : ses espaces de noms, classes, interfaces et énumérations, leurs constantes, propriétés et méthodes publiques avec leur PHPDoc, et les options que prennent ses fabriques. Rien n’en est exécuté.
ApiclassOne Jitsi Meet instance, as configured: its address, how its rooms are named, and how a participant's token is made. Nothing here calls the instance - a Jitsi room exists from the moment its first participant comes in, and a token is signed on this side.
16 methods · 3 properties · 2 constants
JitsiGatewayFactoryclassJitsi Meet: an instance of one's own, a public one, or 8x8's Jitsi as a Service - embedded in the page through the IFrame API, several people, the media through the instance's bridge (a third party unless the instance is yours).
23 options
JwtclassThe JSON Web Token (RFC 7519) a Jitsi Meet instance checks, signed with what PHP has: HS256 with the instance's application secret (hash_hmac), RS256 with a private key (openssl) - the two validations Jitsi's token plugin knows, shared secret and public key.
3 methods · 2 constants
JoinActionclassA frame on the instance's own interface: its address (the token as the jwt parameter, the overrides after the #), and, to drive it from the page, this package's script with what the IFrame API's JitsiMeetExternalAPI(domain, options) takes - roomName, jwt, userInfo, lang, configOverwrite, interfaceConfigOverwrite. The token, when the instance checks one, is made for this participant and this room, and lapses a while after the meeting's end. With "embed: false" - an instance that refuses to be framed - the answer is that address alone, to send the participant to.
3 methods
NotifyActionclassA webhook of Jitsi as a Service: a POST with a JSON body, signed in the X-Jaas-Signature header ("t=<timestamp>,v1=<signature>": the base64 HMAC-SHA256 of "<timestamp>.<body>" with the endpoint's signing secret).
3 methods
OpenActionclassA Jitsi room is not made beforehand: it exists from the moment its first participant comes in, and is gone when the last one leaves. Opening is naming it - the same key, the same room - and nothing is asked of the instance.
3 methods
Omnimeet\Jitsi
Api class
final class Api Api.php:24
One Jitsi Meet instance, as configured: its address, how its rooms are named, and how a participant's token is made. Nothing here calls the instance - a Jitsi room exists from the moment its first participant comes in, and a token is signed on this side.
Three kinds of instance, told apart by the options: - open (no app_secret, no private_key): anyone with the room's name gets in - the name is the only secret; - with token authentication (app_id and app_secret, or a private_key the instance validates against its key server): a JWT per participant; - Jitsi as a Service (8x8.vc, an AppID "vpaas-magic-cookie-..."): rooms under the AppID, RS256 tokens with JaaS's own claims.
const ENGINE = 'jitsi'const JAAS_DOMAIN = '8x8.vc'public readonly string $domainpublic readonly ?string $appIdpublic readonly bool $jaas
Api::__construct()
public function __construct(readonly Config $config)Api::signs()
public function signs(): boolWhether participants enter with a token.
Api::room()
public function room(Meeting $meeting): stringThe room of a meeting: the same key, the same room; lower case, as Jitsi reads room names. It says nothing of the key - and cannot be guessed unless the key can: set room_secret when keys are guessable.
Api::roomName()
public function roomName(string $reference): stringThe room as the IFrame API and the address name it: under the AppID on JaaS.
Api::reference()
public function reference(string $fqn): stringThe reference of a room named by JaaS ("<AppID>/<room>").
Api::origin()
public function origin(): stringApi::scriptUrl()
public function scriptUrl(): stringThe IFrame API's script, served by the instance itself.
Api::url()
public function url(string $reference, ?string $token = null, ?string $locale = null): stringThe address of the room, for a bare frame or a link: the token as the jwt parameter, the configuration overrides after the #, each as config.<key>=<JSON value>.
Api::configOverwrite()
public function configOverwrite(?string $locale = null): array- Returns
config.js overrides: the configured ones, and the participant's language
Api::interfaceConfigOverwrite()
public function interfaceConfigOverwrite(): arrayApi::expiry()
public function expiry(Meeting $meeting, ?int $now = null): intWhen a token made now for this meeting lapses: a while after the meeting's end, or token_ttl seconds from now.
Api::token()
public function token(Meeting $meeting, Participant $participant, ?int $now = null): ?stringThe participant's token for this room, or null on an open instance.
Self-hosted (lib-jitsi-meet's token plugin): iss, the application's id; aud; sub, the instance's domain or tenant; room; exp; and the display information under context.user (id, name). JaaS: aud "jitsi", iss "chat", sub the AppID, nbf, context.user.moderator as the string "true" or "false", context.features, and a kid in the header.
Api::embeds()
public function embeds(): boolWhether the instance may be shown in a frame: some forbid it (X-Frame-Options, frame-ancestors).
Api::webhookSecret()
public function webhookSecret(): ?stringApi::webhookTolerance()
public function webhookTolerance(): intApi::script()
public static function script(): stringThe JavaScript that drives the frame, as the package ships it: the application serves this file.
JitsiGatewayFactory class
final class JitsiGatewayFactory extends GatewayFactory JitsiGatewayFactory.php:50
Jitsi Meet: an instance of one's own, a public one, or 8x8's Jitsi as a Service - embedded in the page through the IFrame API, several people, the media through the instance's bridge (a third party unless the instance is yours).
options: domain: meet.example.org # required: the instance (8x8.vc for JaaS) # an instance with token authentication, shared secret (HS256): app_id: my_app # Prosody's app_id: the token's iss app_secret: '%env(JITSI_APP_SECRET)%' # Prosody's app_secret audience: jitsi # aud, as asap_accepted_audiences has it issuer: ~ # iss, when it is not app_id subject: ~ # sub, when it is not the domain (a tenant) # or a key pair (RS256) - the instance's key server, or JaaS: private_key: '%env(JITSI_PRIVATE_KEY)%' # PEM, or the path of its file key_id: my_key # the token's kid (JaaS: "<AppID>/<key id>") # Jitsi as a Service: domain 8x8.vc, app_id the AppID (vpaas-magic-cookie-...) features: { recording: false, livestreaming: false, transcription: false, outbound-call: false } webhook_secret: '%env(JAAS_WEBHOOK_SECRET)%' # whsec_...: notify() checks X-Jaas-Signature with it webhook_tolerance: 300 # seconds a callback may be old; 0: any age # all: token_ttl: 7200 # seconds a token lasts when the meeting has no end room_prefix: '' # before the room's name room_secret: ~ # set it when meeting keys can be guessed config: { disableInviteFunctions: true, disableThirdPartyRequests: true } # config.js overrides interface_config: } # interface_config.js overrides embed: true # false: the instance forbids being framed - an address to go to instead
Without app_secret nor private_key the instance is taken as open: anyone who knows the room's name gets in, the name is the only secret.
What Jitsi's documentation does not show stays unsupported: closing a room and reading its state from the server (close(), fetch()) - the page of a moderator ends the conference through the IFrame API instead - and callbacks outside JaaS (notify() needs webhook_secret).
Options
| Option | Default | |
|---|---|---|
app_id | null | |
app_secret | null | |
private_key | null | |
key_id | null | |
jaas | null | |
audience | null | |
issuer | null | |
subject | null | |
features | ['recording' => false, 'livestreaming' => false, 'transcription' => false, 'outbound-call' => false] | |
webhook_secret | null | |
webhook_tolerance | 300 | |
token_ttl | 7200 | |
room_prefix | '' | |
room_secret | null | |
config | ['disableInviteFunctions' => true, 'disableThirdPartyRequests' => true] | |
interface_config | [] | |
embed | true | |
omnimeet.capabilities | static fn(Config $c) => new Capabilities(maxParticipants: null, thirdParty: true, endToEnd: false, recording: true === (((array) $c['features'])['recording']… | |
omnimeet.api | static fn(Config $c) => new Api($c) | |
omnimeet.action.open | new OpenAction() | |
omnimeet.action.join | new JoinAction() | |
omnimeet.action.notify | static fn(Config $c) => '' !== (string) $c['webhook_secret'] ? new NotifyAction() : null | A callback can only be checked with JaaS's signing secret: without one the gateway hears none. |
domain | required |
Jwt class
final class Jwt Jwt.php:13
The JSON Web Token (RFC 7519) a Jitsi Meet instance checks, signed with what PHP has: HS256 with the instance's application secret (hash_hmac), RS256 with a private key (openssl) - the two validations Jitsi's token plugin knows, shared secret and public key.
const HS256 = 'HS256'const RS256 = 'RS256'
Jwt::sign()
public static function sign(array $claims, string $key, string $algorithm = self::HS256, ?string $kid = null): string$keythe shared secret (HS256), or the private key in PEM or the path of its file (RS256)
$kidRS256: the name of the public key the instance validates against
Jwt::verify()
public static function verify(string $token, string $key): ?arrayThe claims of a token this side signed, or null when the signature does not hold: for tests, and for whoever wants to check what is sent.
$keythe shared secret (HS256), or the public key in PEM (RS256)
Jwt::header()
public static function header(string $token): array- Returns
the header of a token, unchecked
Omnimeet\Jitsi\Action
JoinAction class
final class JoinAction implements ActionInterface, ApiAwareInterface JoinAction.php:24
A frame on the instance's own interface: its address (the token as the jwt parameter, the overrides after the #), and, to drive it from the page, this package's script with what the IFrame API's JitsiMeetExternalAPI(domain, options) takes - roomName, jwt, userInfo, lang, configOverwrite, interfaceConfigOverwrite. The token, when the instance checks one, is made for this participant and this room, and lapses a while after the meeting's end. With "embed: false" - an instance that refuses to be framed - the answer is that address alone, to send the participant to.
JoinAction::__construct()
public function __construct()JoinAction::supports()
public function supports(Request $request): boolJoinAction::execute()
public function execute(Request $request): voidNotifyAction class
final class NotifyAction implements ActionInterface, ApiAwareInterface NotifyAction.php:25
A webhook of Jitsi as a Service: a POST with a JSON body, signed in the X-Jaas-Signature header ("t=<timestamp>,v1=<signature>": the base64 HMAC-SHA256 of "<timestamp>.<body>" with the endpoint's signing secret).
A signature that does not hold, or older than the tolerance, is refused. The meeting is named by "fqn" (<AppID>/<room>), the same callback sent twice by "idempotencyKey".
NotifyAction::__construct()
public function __construct()NotifyAction::supports()
public function supports(Request $request): boolNotifyAction::execute()
public function execute(Request $request): voidOpenAction class
final class OpenAction implements ActionInterface, ApiAwareInterface OpenAction.php:19
A Jitsi room is not made beforehand: it exists from the moment its first participant comes in, and is gone when the last one leaves. Opening is naming it - the same key, the same room - and nothing is asked of the instance.
OpenAction::__construct()
public function __construct()OpenAction::supports()
public function supports(Request $request): boolOpenAction::execute()
public function execute(Request $request): void