2023-02-05 08:53:50 +00:00
package config
import (
"bytes"
"encoding/json"
"html/template"
"os"
"git.kirsle.net/apps/barertc/pkg/log"
"github.com/BurntSushi/toml"
2023-07-30 17:32:08 +00:00
"github.com/google/uuid"
2023-02-05 08:53:50 +00:00
)
2023-02-09 04:01:06 +00:00
// Version of the config format - when new fields are added, it will attempt
// to write the settings.toml to disk so new defaults populate.
2024-09-21 03:33:42 +00:00
var currentVersion = 15
2023-02-09 04:01:06 +00:00
2023-02-05 08:53:50 +00:00
// Config for your BareRTC app.
type Config struct {
2023-02-09 04:01:06 +00:00
Version int // will re-save your settings.toml on migrations
2023-02-05 08:53:50 +00:00
JWT struct {
2023-07-01 01:41:06 +00:00
Enabled bool
Strict bool
SecretKey string
LandingPageURL string
2023-02-05 08:53:50 +00:00
}
2023-02-06 04:26:00 +00:00
Title string
2023-02-06 21:27:29 +00:00
Branding string
2023-02-06 01:42:09 +00:00
WebsiteURL string
2023-02-11 06:46:39 +00:00
2024-09-10 04:08:31 +00:00
CORSHosts [ ] string
AdminAPIKey string
PermitNSFW bool
BlockableAdmins bool
2023-02-06 01:42:09 +00:00
2023-02-09 04:01:06 +00:00
UseXForwardedFor bool
2023-09-30 19:46:45 +00:00
WebSocketReadLimit int64
WebSocketSendTimeout int
MaxImageWidth int
PreviewImageWidth int
2023-03-22 04:29:24 +00:00
2023-06-14 04:57:31 +00:00
TURN TurnConfig
2023-02-05 08:53:50 +00:00
PublicChannels [ ] Channel
2023-08-13 04:35:41 +00:00
WebhookURLs [ ] WebhookURL
2023-09-03 19:08:23 +00:00
VIP VIP
2023-09-30 02:10:34 +00:00
MessageFilters [ ] * MessageFilter
2024-05-17 06:33:19 +00:00
ModerationRule [ ] * ModerationRule
2023-11-11 22:59:49 +00:00
2024-03-29 06:20:09 +00:00
DirectMessageHistory DirectMessageHistory
2024-09-21 03:33:42 +00:00
Strings Strings
2023-11-11 22:59:49 +00:00
Logging Logging
2023-02-05 08:53:50 +00:00
}
2023-06-14 04:57:31 +00:00
type TurnConfig struct {
URLs [ ] string
Username string
Credential string
}
2023-09-03 19:08:23 +00:00
type VIP struct {
Name string
Branding string
Icon string
MutuallySecret bool
}
2024-03-29 06:20:09 +00:00
type DirectMessageHistory struct {
Enabled bool
SQLiteDatabase string
RetentionDays int
DisclaimerMessage string
}
2023-02-05 08:53:50 +00:00
// GetChannels returns a JavaScript safe array of the default PublicChannels.
func ( c Config ) GetChannels ( ) template . JS {
data , _ := json . Marshal ( c . PublicChannels )
return template . JS ( data )
}
2023-09-03 19:48:21 +00:00
// GetChannel looks up and returns a channel by ID.
func ( c Config ) GetChannel ( id string ) ( Channel , bool ) {
for _ , ch := range c . PublicChannels {
if ch . ID == id {
return ch , true
}
}
return Channel { } , false
}
2023-02-05 08:53:50 +00:00
// Channel config for a default public room.
type Channel struct {
2024-05-14 01:51:54 +00:00
ID string // Like "lobby"
Name string // Like "Main Chat Room"
Icon string ` toml:",omitempty" ` // CSS class names for room icon (optional)
VIP bool // For VIP users only
PermitPhotos bool // photos are allowed to be shared
2023-02-06 01:42:09 +00:00
// ChatServer messages to send to the user immediately upon connecting.
WelcomeMessages [ ] string
2023-02-05 08:53:50 +00:00
}
2023-08-13 04:35:41 +00:00
// WebhookURL allows tighter integration with your website.
type WebhookURL struct {
Name string
Enabled bool
URL string
}
2024-09-21 03:33:42 +00:00
// Strings config for customizing certain user-facing messaging around the app.
type Strings struct {
ModRuleErrorCameraAlwaysNSFW string
ModRuleErrorNoBroadcast string
ModRuleErrorNoVideo string
ModRuleErrorNoImage string
}
2023-11-11 22:59:49 +00:00
// Logging configs to monitor channels or usernames.
type Logging struct {
Enabled bool
Directory string
Channels [ ] string
Usernames [ ] string
}
2024-05-17 06:33:19 +00:00
// ModerationRule applies certain rules to moderate specific users.
type ModerationRule struct {
Username string
CameraAlwaysNSFW bool
2024-09-19 05:16:33 +00:00
NoBroadcast bool
NoVideo bool
NoImage bool
2024-05-17 06:33:19 +00:00
}
2023-02-05 08:53:50 +00:00
// Current loaded configuration.
var Current = DefaultConfig ( )
// DefaultConfig returns sensible defaults and will write the initial
// settings.toml file to disk.
func DefaultConfig ( ) Config {
var c = Config {
2023-07-30 17:32:08 +00:00
Title : "BareRTC" ,
Branding : "BareRTC" ,
WebsiteURL : "https://www.example.com" ,
AdminAPIKey : uuid . New ( ) . String ( ) ,
2023-02-10 07:03:06 +00:00
CORSHosts : [ ] string {
"https://www.example.com" ,
} ,
2023-09-30 19:46:45 +00:00
WebSocketReadLimit : 1024 * 1024 * 40 , // 40 MB.
WebSocketSendTimeout : 10 , // seconds
MaxImageWidth : 1280 ,
PreviewImageWidth : 360 ,
2023-02-05 08:53:50 +00:00
PublicChannels : [ ] Channel {
{
ID : "lobby" ,
Name : "Lobby" ,
2023-02-06 01:42:09 +00:00
WelcomeMessages : [ ] string {
"Welcome to the chat server!" ,
"Please follow the basic rules:\n\n1. Have fun\n2. Be kind" ,
} ,
2023-02-05 08:53:50 +00:00
} ,
{
ID : "offtopic" ,
Name : "Off Topic" ,
2023-02-06 01:42:09 +00:00
WelcomeMessages : [ ] string {
"Welcome to the Off Topic channel!" ,
} ,
2024-05-14 01:51:54 +00:00
PermitPhotos : true ,
2023-02-05 08:53:50 +00:00
} ,
2023-09-03 19:48:21 +00:00
{
2024-05-14 01:51:54 +00:00
ID : "vip" ,
Name : "VIPs Only" ,
VIP : true ,
PermitPhotos : true ,
2023-09-03 19:48:21 +00:00
WelcomeMessages : [ ] string {
"This channel is only for operators and VIPs." ,
} ,
} ,
2023-02-05 08:53:50 +00:00
} ,
2023-06-14 04:57:31 +00:00
TURN : TurnConfig {
URLs : [ ] string {
"stun:stun.l.google.com:19302" ,
} ,
} ,
2023-08-13 04:35:41 +00:00
WebhookURLs : [ ] WebhookURL {
{
Name : "report" ,
URL : "https://example.com/barertc/report" ,
} ,
2023-10-07 20:22:41 +00:00
{
Name : "profile" ,
URL : "https://example.com/barertc/user-profile" ,
} ,
2023-08-13 04:35:41 +00:00
} ,
2023-09-03 19:08:23 +00:00
VIP : VIP {
Name : "VIP" ,
Branding : "<em>VIP Members</em>" ,
Icon : "fa fa-circle" ,
} ,
2023-09-30 02:10:34 +00:00
MessageFilters : [ ] * MessageFilter {
{
PublicChannels : true ,
PrivateChannels : true ,
KeywordPhrases : [ ] string {
` \bswear words\b ` ,
` \b(swearing|cursing)\b ` ,
` suck my ([^\s]+) ` ,
} ,
CensorMessage : true ,
ChatServerResponse : "Watch your language." ,
} ,
} ,
2024-05-17 06:33:19 +00:00
ModerationRule : [ ] * ModerationRule {
{
Username : "example" ,
} ,
} ,
2024-09-21 03:33:42 +00:00
Strings : Strings {
ModRuleErrorCameraAlwaysNSFW : "A chat server moderation rule is currently in place which forces your camera to stay marked as Explicit. Please contact a chat moderator if you have any questions about this." ,
ModRuleErrorNoBroadcast : "A chat server moderation rule is currently in place which restricts your ability to share your webcam. Please contact a chat operator for more information." ,
ModRuleErrorNoVideo : "A chat server moderation rule is currently in place which restricts your ability to watch webcams. Please contact a chat operator for more information." ,
ModRuleErrorNoImage : "A chat server moderation rule is currently in place which restricts your ability to share images. Please contact a chat operator for more information." ,
} ,
2024-03-29 06:20:09 +00:00
DirectMessageHistory : DirectMessageHistory {
Enabled : false ,
SQLiteDatabase : "database.sqlite" ,
RetentionDays : 90 ,
DisclaimerMessage : ` <i class="fa fa-info-circle mr-1"></i> <strong>Reminder:</strong> please conduct yourself honorably in Direct Messages. ` ,
} ,
2023-11-11 22:59:49 +00:00
Logging : Logging {
Directory : "./logs" ,
Channels : [ ] string { "lobby" , "offtopic" } ,
Usernames : [ ] string { } ,
} ,
2023-02-05 08:53:50 +00:00
}
2023-02-06 01:42:09 +00:00
c . JWT . Strict = true
2023-02-05 08:53:50 +00:00
return c
}
// LoadSettings reads a settings.toml from disk if available.
func LoadSettings ( ) error {
data , err := os . ReadFile ( "./settings.toml" )
if err != nil {
// Settings file didn't exist, create the default one.
if os . IsNotExist ( err ) {
WriteSettings ( )
return nil
}
return err
}
_ , err = toml . Decode ( string ( data ) , & Current )
2023-08-13 04:35:41 +00:00
if err != nil {
return err
}
2023-02-09 04:01:06 +00:00
// Have we added new config fields? Save the settings.toml.
2023-03-22 04:29:24 +00:00
if Current . Version != currentVersion {
2023-02-09 04:01:06 +00:00
log . Warn ( "New options are available for your settings.toml file. Your settings will be re-saved now." )
Current . Version = currentVersion
if err := WriteSettings ( ) ; err != nil {
log . Error ( "Couldn't write your settings.toml file: %s" , err )
}
}
2023-02-05 08:53:50 +00:00
return err
}
// WriteSettings will commit the settings.toml to disk.
func WriteSettings ( ) error {
log . Error ( "Note: initial settings.toml was written to disk." )
var buf = new ( bytes . Buffer )
err := toml . NewEncoder ( buf ) . Encode ( Current )
if err != nil {
return err
}
return os . WriteFile ( "./settings.toml" , buf . Bytes ( ) , 0644 )
}
2024-05-17 06:33:19 +00:00
// GetModerationRule returns a matching ModerationRule for the given user, or nil if no rule is found.
func ( c Config ) GetModerationRule ( username string ) * ModerationRule {
for _ , rule := range c . ModerationRule {
if rule . Username == username {
return rule
}
}
return nil
}