mirror of
https://github.com/openlibrecommunity/olcrtc.git
synced 2026-05-26 07:08:11 +00:00
98 lines
3.4 KiB
Go
98 lines
3.4 KiB
Go
// Package jitsi implements a pass-through auth provider for self-hosted Jitsi
|
|
// Meet instances.
|
|
//
|
|
// Public Jitsi Meet servers do not require authentication for guest access;
|
|
// the only "credentials" the engine needs are the host+room pair extracted
|
|
// from a user-supplied room URL. This provider does no HTTP at all - it just
|
|
// parses the URL and forwards host+room to the engine via auth.Credentials.
|
|
//
|
|
// Supported RoomURL forms:
|
|
//
|
|
// - "https://meet.example.com/myroom"
|
|
// - "http://meet.example.com/myroom"
|
|
// - "meet.example.com/myroom"
|
|
//
|
|
// Optional URL path prefixes (e.g. "/jitsi") are preserved as part of the
|
|
// host when present, so deployments behind a path-mounted reverse proxy work
|
|
// transparently - the j library accepts any host string the WebSocket dial
|
|
// can resolve.
|
|
package jitsi
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/openlibrecommunity/olcrtc/internal/auth"
|
|
)
|
|
|
|
// CredentialKeyRoom is the auth.Credentials.Extra key that carries the Jitsi
|
|
// room name (the conference identifier on the host).
|
|
const CredentialKeyRoom = "room"
|
|
|
|
// ErrInvalidRoomURL is returned when the supplied RoomURL cannot be parsed
|
|
// into a host+room pair.
|
|
var ErrInvalidRoomURL = errors.New("jitsi: invalid room URL (expected host/room or https://host/room)")
|
|
|
|
// Provider produces engine credentials for a Jitsi Meet room.
|
|
type Provider struct{}
|
|
|
|
// Engine reports which engine consumes credentials from this auth provider.
|
|
func (Provider) Engine() string { return "jitsi" }
|
|
|
|
const defaultServiceURL = "https://meet1.arbitr.ru"
|
|
|
|
// DefaultServiceURL returns the default Jitsi Meet service URL used by config
|
|
// defaults and interactive helpers. Users should verify which server is
|
|
// accessible in their network: https://meet1.arbitr.ru or https://meet.cryptopro.ru
|
|
func (Provider) DefaultServiceURL() string { return defaultServiceURL }
|
|
|
|
// Issue parses cfg.RoomURL into host+room and returns engine credentials.
|
|
//
|
|
// The URL field of the returned Credentials carries the Jitsi host (e.g.
|
|
// "meet.example.com"); the room name lives in Extra under CredentialKeyRoom.
|
|
// Token is unused - Jitsi guest access requires no token.
|
|
func (Provider) Issue(_ context.Context, cfg auth.Config) (auth.Credentials, error) {
|
|
host, room, err := parseRoomURL(cfg.RoomURL)
|
|
if err != nil {
|
|
return auth.Credentials{}, err
|
|
}
|
|
return auth.Credentials{
|
|
URL: host,
|
|
Token: "",
|
|
Extra: map[string]string{CredentialKeyRoom: room},
|
|
}, nil
|
|
}
|
|
|
|
// parseRoomURL splits a Jitsi room URL into (host, room).
|
|
//
|
|
// Accepts URLs with or without scheme. The host part is the segment before
|
|
// the first "/" after stripping the scheme; the room is everything that
|
|
// follows, with leading/trailing slashes trimmed.
|
|
func parseRoomURL(raw string) (string, string, error) {
|
|
raw = strings.TrimSpace(raw)
|
|
if raw == "" {
|
|
return "", "", auth.ErrRoomIDRequired
|
|
}
|
|
if idx := strings.Index(raw, "://"); idx >= 0 {
|
|
raw = raw[idx+3:]
|
|
}
|
|
raw = strings.TrimPrefix(raw, "//")
|
|
raw = strings.TrimPrefix(raw, "/")
|
|
slash := strings.Index(raw, "/")
|
|
if slash <= 0 {
|
|
return "", "", fmt.Errorf("%w: %q", ErrInvalidRoomURL, raw)
|
|
}
|
|
host := strings.TrimSpace(raw[:slash])
|
|
room := strings.Trim(raw[slash+1:], "/")
|
|
if host == "" || room == "" {
|
|
return "", "", fmt.Errorf("%w: %q", ErrInvalidRoomURL, raw)
|
|
}
|
|
return host, room, nil
|
|
}
|
|
|
|
func init() { //nolint:gochecknoinits // auth registration is the canonical Go pattern for plugins
|
|
auth.Register("jitsi", Provider{})
|
|
}
|