diff --git a/main.go b/main.go
index 5f13167..662f2a6 100644
--- a/main.go
+++ b/main.go
@@ -34,7 +34,7 @@ func setupSettings(adminPass string, confFile string) error {
if err != nil {
return fmt.Errorf("unable to load settings: %w", err)
}
- if len(settings.StreamKey) == 0 {
+ if !settings.NewStreamKey && len(settings.StreamKey) == 0 {
return fmt.Errorf("missing stream key is settings.json")
}
diff --git a/readme.md b/readme.md
index 617d874..b551ffd 100644
--- a/readme.md
+++ b/readme.md
@@ -182,6 +182,7 @@ MovieNight’s configuration is controlled by `settings.json`:
- `LogLevel`: the log level, defaults to `debug`.
- `MaxMessageCount`: the number of messages displayed in the chat window.
- `NewPin`: if true, regenerates `RoomAccessPin` when the server starts.
+ - `NewStreamKey`: if true, uses a random `StreamKey` when the server starts. The command line option takes precedence, and will be used if it is set.
- `PageTitle`: The base string used in the `
` element of the page. When the stream title is set with `/playing`, it is appended; e.g., `Movie Night | The Man Who Killed Hitler and Then the Bigfoot`
- `RegenAdminPass`: if true, regenerates `AdminPassword` when the server starts.
- `RoomAccess`: the access policy of the chat room; this is managed by the application and should not be edited manually.
diff --git a/settings.go b/settings.go
index 5abeb52..d386f4a 100644
--- a/settings.go
+++ b/settings.go
@@ -21,8 +21,9 @@ var sstore *sessions.CookieStore
type Settings struct {
// Non-Saved settings
- filename string
- cmdLineKey string // stream key from the command line
+ filename string
+ cmdLineKey string // stream key from the command line
+ rndStreamKey string // random stream key; only used if NewStreamKey is set
// Saved settings
AdminPassword string
@@ -33,6 +34,7 @@ type Settings struct {
LogLevel common.LogLevel
MaxMessageCount int
NewPin bool // Auto generate a new pin on start. Overwrites RoomAccessPin if set.
+ NewStreamKey bool // Auto generate a new stream key on start. Used instead of StreamKey if set.
PageTitle string // primary value for the page element
RegenAdminPass bool // regenerate admin password on start?
RoomAccess AccessMode
@@ -172,6 +174,11 @@ func LoadSettings(filename string) (*Settings, error) {
s.TitleLength = 50
}
+ // Set a random stream key
+ if s.NewStreamKey {
+ s.rndStreamKey = randStringRunes(20)
+ }
+
// Is this a good way to do this? Probably not...
if len(s.SessionKey) == 0 {
out := ""
@@ -294,6 +301,10 @@ func (s *Settings) GetStreamKey() string {
if len(s.cmdLineKey) > 0 {
return s.cmdLineKey
}
+ if s.NewStreamKey {
+ return s.rndStreamKey
+ }
+
return s.StreamKey
}
@@ -311,3 +322,16 @@ func (s *Settings) generateNewPin() (string, error) {
}
return s.RoomAccessPin, nil
}
+
+// Adapted from: https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go/22892986#22892986
+var letterRunes = []rune("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
+
+func randStringRunes(n int) string {
+ length := big.NewInt(int64(len(letterRunes)))
+ b := make([]rune, n)
+ for i := range b {
+ letter_idx, _ := rand.Int(rand.Reader, length)
+ b[i] = letterRunes[letter_idx.Int64()]
+ }
+ return string(b)
+}