Files
uPortal2/backend/internal/jitsi/service.go
T
2026-10-21 19:41:26 +03:00

123 lines
3.1 KiB
Go

package jitsi
import (
"context"
"fmt"
"log/slog"
"time"
"goAuth/internal/user"
"github.com/golang-jwt/jwt/v5"
)
type Service struct {
r *Repository
Secret string
AppID string
AppName string
Domain string
}
type claims struct {
jwt.RegisteredClaims
Room string `json:"room,omitempty"`
Context *roomContext `json:"context,omitempty"`
}
type roomContext struct {
User *jitsiUser `json:"user,omitempty"`
}
type jitsiUser struct {
Id string `json:"id"`
Name string `json:"name"`
Email string `json:"email,omitempty"`
Avatar string `json:"avatar,omitempty"`
Moderator bool `json:"moderator"`
}
func NewService(r *Repository, secret, appId, appName, domain string) (*Service, error) {
return &Service{r: r, Secret: secret, AppID: appId, AppName: appName, Domain: domain}, nil
}
func (s *Service) MeetUrl(room, jwtToken string) string {
domain := s.Domain
if domain == "" {
domain = "meet.jit.si"
}
return fmt.Sprintf("https://%s/%s?jwt=%s", domain, room, jwtToken)
}
func (s *Service) GenerateToken(userID, userName, room string, moderator bool, avatar string) (string, error) {
if s.Secret == "" {
return "", ErrSecretNotConfigured
}
if s.AppID == "" {
return "", ErrAppIDNotConfigured
}
now := time.Now().UTC()
claims := claims{
RegisteredClaims: jwt.RegisteredClaims{
Issuer: s.AppID,
Subject: userID,
Audience: jwt.ClaimStrings{s.AppID},
IssuedAt: jwt.NewNumericDate(now),
NotBefore: jwt.NewNumericDate(now),
ExpiresAt: jwt.NewNumericDate(now.Add(1 * time.Hour)),
ID: fmt.Sprintf("%s-%d", userID, now.Unix()),
},
Room: room,
Context: &roomContext{
User: &jitsiUser{
Id: userID,
Name: userName,
Avatar: avatar,
Moderator: moderator,
},
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
signed, err := token.SignedString([]byte(s.Secret))
if err != nil {
slog.Error("sign jitsi token", slog.String("op", "service.GenerateToken"), slog.String("user_id", userID), slog.String("room", room), slog.Any("error", err))
return "", fmt.Errorf("sign jitsi token: %w", err)
}
return signed, nil
}
func (s *Service) RecordRoomJoin(ctx context.Context, u *user.User, room string) error {
if u == nil {
slog.Error("nil user", slog.String("op", "service.RecordRoomJoin"), slog.String("room", room))
return ErrInternal
}
return s.r.RecordJoin(ctx, u.Id, room, time.Now().UTC())
}
func (s *Service) RoomHistory(ctx context.Context, u *user.User, limit, offset int64) ([]*RoomHistory, error) {
if u == nil {
slog.Error("nil user", slog.String("op", "service.RoomHistory"))
return nil, ErrInternal
}
return s.r.List(ctx, u.Id, limit, offset)
}
func (s *Service) DeleteRoom(ctx context.Context, u *user.User, room string) error {
if u == nil {
slog.Error("nil user", slog.String("op", "service.DeleteRoom"), slog.String("room", room))
return ErrInternal
}
return s.r.DeleteRoom(ctx, u.Id, room)
}
func (s *Service) ClearHistory(ctx context.Context, u *user.User) error {
if u == nil {
slog.Error("nil user", slog.String("op", "service.ClearHistory"))
return ErrInternal
}
return s.r.DeleteAll(ctx, u.Id)
}