#!/usr/bin/env python3 """Mint LiveKit JWTs for the integration test against a local dev server. Usage: livekit-server --dev --bind 127.0.0.1 & eval "$(python3 scripts/livekit-dev-room.py)" ctest --test-dir build -R test_integration_livekit --output-on-failure Prints shell `export` lines for the four STPLUGIN_IT_* variables core/tests/test_integration_livekit.cpp looks for. With no arguments it uses `livekit-server --dev`'s built-in devkey/secret credentials. Standard library only (hmac + hashlib + base64) -- there is deliberately no pip install step here, so this runs anywhere the repo is checked out. """ import argparse import base64 import hashlib import hmac import json import os import time def b64url(raw: bytes) -> str: return base64.urlsafe_b64encode(raw).rstrip(b"=").decode("ascii") def mint(api_key: str, api_secret: str, identity: str, room: str, *, publish: bool, subscribe: bool) -> str: now = int(time.time()) header = {"alg": "HS256", "typ": "JWT"} claims = { "iss": api_key, "sub": identity, "name": identity, "nbf": now - 10, "exp": now + 3600, "video": { "room": room, "roomJoin": True, "canPublish": publish, "canSubscribe": subscribe, "canPublishData": False, }, } signing_input = f"{b64url(json.dumps(header, separators=(',', ':')).encode())}." \ f"{b64url(json.dumps(claims, separators=(',', ':')).encode())}" signature = hmac.new(api_secret.encode(), signing_input.encode(), hashlib.sha256).digest() return f"{signing_input}.{b64url(signature)}" def main() -> None: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--url", default=os.environ.get("LIVEKIT_URL", "ws://127.0.0.1:7880")) parser.add_argument("--api-key", default=os.environ.get("LIVEKIT_API_KEY", "devkey")) parser.add_argument("--api-secret", default=os.environ.get("LIVEKIT_API_SECRET", "secret")) parser.add_argument("--room", default="obs-plugin-it") parser.add_argument("--publisher-identity", default="cam-test") parser.add_argument("--subscriber-identity", default="obs:obs-plugin-it:test") args = parser.parse_args() publish_token = mint(args.api_key, args.api_secret, args.publisher_identity, args.room, publish=True, subscribe=False) # Deliberately the same grant shape the real server mints for the plugin # (apps/server/src/obs/plugin.routes.ts -> mintCaptionsToken): subscribe # only, never publish. subscribe_token = mint(args.api_key, args.api_secret, args.subscriber_identity, args.room, publish=False, subscribe=True) print(f'export STPLUGIN_IT_URL="{args.url}"') print(f'export STPLUGIN_IT_PUBLISH_TOKEN="{publish_token}"') print(f'export STPLUGIN_IT_SUBSCRIBE_TOKEN="{subscribe_token}"') print(f'export STPLUGIN_IT_PUBLISHER_IDENTITY="{args.publisher_identity}"') if __name__ == "__main__": main()