using SameBeat.Domain.Wyjatki; namespace SameBeat.Domain.Encje; /// /// Lekka tozsamosc czatu (ETAP 6) -- NIE to samo co UczestnikOczekujacy z poczekalni. Czat jest /// dostepny dla kazdego widza, nie tylko dla ludzi z kamera na scenie, wiec potrzebuje wlasnego, /// prostszego mechanizmu "kim jest ta przegladarka": bez sekretu sesji, bez tozsamosci LiveKit, bez /// statusu w poczekalni. Tworzona przy pierwszym wejsciu na czat (POST /api/chat/dolacz). /// public class UczestnikCzatu { public const int MaksymalnaDlugoscNicku = 40; public Guid Id { get; private set; } public Guid WydarzenieId { get; private set; } public string Nick { get; private set; } = string.Empty; public DateTime DolaczylUtc { get; private set; } public bool Wyciszony { get; private set; } public bool Zbanowany { get; private set; } // Prywatny konstruktor bez parametrow -- wymagany przez EF Core do materializacji encji z bazy. private UczestnikCzatu() { } private UczestnikCzatu(Guid id, Guid wydarzenieId, string nick, DateTime dolaczylUtc) { Id = id; WydarzenieId = wydarzenieId; Nick = nick; DolaczylUtc = dolaczylUtc; } /// /// Tworzy nowa tozsamosc czatu. Walidacja nicku tutaj chroni przed powstaniem encji w niepoprawnym /// stanie niezaleznie od tego, ktory serwis aplikacji jej uzyje -- ten sam wzorzec i te same reguly /// co UczestnikOczekujacy.Dolacz z ETAPU 2 (niepusty, limit dlugosci, bez '<'/'>'). /// public static UczestnikCzatu Dolacz(Guid wydarzenieId, string nick) { if (wydarzenieId == Guid.Empty) { throw new NieprawidlowyStanEncjiWyjatek("Uczestnik czatu musi byc powiazany z konkretnym wydarzeniem."); } var nickOczyszczony = OczyscNick(nick); return new UczestnikCzatu(Guid.NewGuid(), wydarzenieId, nickOczyszczony, DateTime.UtcNow); } private static string OczyscNick(string nick) { if (string.IsNullOrWhiteSpace(nick)) { throw new NieprawidlowyStanEncjiWyjatek("Nick jest wymagany."); } var przycietyNick = nick.Trim(); if (przycietyNick.Length > MaksymalnaDlugoscNicku) { throw new NieprawidlowyStanEncjiWyjatek($"Nick moze miec maksymalnie {MaksymalnaDlugoscNicku} znakow."); } // Podstawowa sanityzacja przed wstrzyknieciem HTML -- ten sam nick idzie pozniej do wiadomosci // czatu, wiec odrzucamy znaki, ktorymi dalo by sie otworzyc znacznik, juz przy wejsciu do systemu. if (przycietyNick.Contains('<') || przycietyNick.Contains('>')) { throw new NieprawidlowyStanEncjiWyjatek("Nick nie moze zawierac znakow '<' ani '>'."); } return przycietyNick; } /// Host wyciszyl te tozsamosc -- dalsze wiadomosci beda odrzucane przez SerwisCzatu, dopoki nie zostanie odciszona. public void Wycisz() => Wyciszony = true; public void Odcisz() => Wyciszony = false; /// /// Ban tozsamosci czatu -- CELOWO osobny mechanizm od Zbanuj() w UczestnikOczekujacy (ETAP 2): /// tamten dotyczy prawa do kamery/mikrofonu w poczekalni, ten wylacznie prawa do pisania na czacie. /// Ta sama przegladarka moze w teorii miec obie tozsamosci niezaleznie od siebie. /// public void Zbanuj() => Zbanowany = true; }