Send admin reports on /nsfw command + Fixes

* On the /nsfw command, BareRTC will issue an admin report to your main website
  so you have visibility into when this command is used.
* On the server side, fix the "Open" command so it will prevent webcams from
  connecting if the offerer had been Booted by the answerer, in addition to the
  previous blocks about Mute and Block. Admin users can still connect always.
* Add a debug command `/watch username` to manually open somebody's camera on
  chat. Note: the chat server enforces the permission to actually do so.
* Remove the /debug-dangerous-force-deadlock admin command.
This commit is contained in:
Noah 2025-02-17 12:50:06 -08:00
parent 74a756d1ef
commit 859e9dee5b
5 changed files with 47 additions and 27 deletions

View File

@ -97,19 +97,6 @@ func (s *Server) ProcessCommand(sub *Subscriber, msg messages.Message) bool {
case "/deop":
s.DeopCommand(words, sub)
return true
case "/debug-dangerous-force-deadlock":
// TEMPORARY debug command to willfully force a deadlock.
s.Broadcast(messages.Message{
Action: messages.ActionError,
Username: "ChatServer",
Message: "NOTICE: The admin is testing a force deadlock of the chat server; things may become unresponsive soon.",
})
go func() {
time.Sleep(2 * time.Second)
s.subscribersMu.Lock()
s.subscribersMu.Lock()
}()
return true
}
}
@ -153,6 +140,19 @@ func (s *Server) NSFWCommand(words []string, sub *Subscriber) {
other.SendMe()
s.SendWhoList()
sub.ChatServer("%s now has their camera marked as Explicit", username)
// Send an admin report to your main website.
if err := PostWebhookReport(WebhookRequestReport{
FromUsername: sub.Username,
AboutUsername: username,
Channel: "n/a",
Timestamp: time.Now().Format(time.RFC3339),
Reason: "NSFW Command Issued",
Message: fmt.Sprintf("The admin @%s marks the webcam red for user @%s", sub.Username, username),
Comment: "An admin marked their webcam as explicit.",
}); err != nil {
log.Error("Error delivering a report to your website about the /nsfw command by %s: %s", sub.Username, err)
}
}
}

View File

@ -539,7 +539,7 @@ func (s *Server) IsVideoNotAllowed(sub *Subscriber, other *Subscriber) (bool, st
Error: "You do not have permission to view that camera.",
},
{
If: (other.Mutes(sub.Username) || other.Blocks(sub)) && !sub.IsAdmin(),
If: (other.Mutes(sub.Username) || other.Boots(sub.Username) || other.Blocks(sub)) && !sub.IsAdmin(),
Error: "You do not have permission to view that camera.",
},
}
@ -654,18 +654,14 @@ func (s *Server) OnReport(sub *Subscriber, msg messages.Message) {
}
// Post to the report webhook.
if _, err := PostWebhook(WebhookReport, WebhookRequest{
Action: WebhookReport,
APIKey: config.Current.AdminAPIKey,
Report: WebhookRequestReport{
FromUsername: sub.Username,
AboutUsername: msg.Username,
Channel: msg.Channel,
Timestamp: msg.Timestamp,
Reason: msg.Reason,
Message: msg.Message,
Comment: msg.Comment,
},
if err := PostWebhookReport(WebhookRequestReport{
FromUsername: sub.Username,
AboutUsername: msg.Username,
Channel: msg.Channel,
Timestamp: msg.Timestamp,
Reason: msg.Reason,
Message: msg.Message,
Comment: msg.Comment,
}); err != nil {
sub.ChatServer("Error sending the report to the website: %s", err)
} else {

View File

@ -250,10 +250,14 @@ func (sub *Subscriber) SendCut() {
// ChatServer is a convenience function to deliver a ChatServer error to the client.
func (sub *Subscriber) ChatServer(message string, v ...interface{}) {
if len(v) > 0 {
message = fmt.Sprintf(message, v...)
}
sub.SendJSON(messages.Message{
Action: messages.ActionError,
Username: "ChatServer",
Message: fmt.Sprintf(message, v...),
Message: message,
})
}

View File

@ -81,3 +81,13 @@ func PostWebhook(name string, payload any) ([]byte, error) {
return body, nil
}
// PostWebhookReport posts a report message via webhook to your website.
func PostWebhookReport(report WebhookRequestReport) error {
_, err := PostWebhook(WebhookReport, WebhookRequest{
Action: WebhookReport,
APIKey: config.Current.AdminAPIKey,
Report: report,
})
return err
}

View File

@ -1211,6 +1211,16 @@ export default {
return;
}
// DEBUGGING: manually open a user camera. Note: chat server will still
// enforce permissions and access.
match = this.message.match(/^\/watch (.+?)$/i);
if (match) {
let username = match[1];
this.openVideoByUsername(username, true);
this.message = "";
return;
}
// Clear user chat history.
if (this.message.toLowerCase().indexOf("/clear-history") === 0) {
this.clearMessageHistory();