diff --git a/go.mod b/go.mod
index ba8dcc90..5eb8a69f 100755
--- a/go.mod
+++ b/go.mod
@@ -15,5 +15,5 @@ require (
github.com/tdewolff/parse v2.3.4+incompatible // indirect
github.com/tdewolff/test v1.0.6 // indirect
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
- golang.org/x/net v0.0.0-20210222171744-9060382bd457
+ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
)
diff --git a/go.sum b/go.sum
index 3e3b9ac3..d433f41a 100755
--- a/go.sum
+++ b/go.sum
@@ -59,6 +59,8 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210222171744-9060382bd457 h1:hMm9lBjyNLe/c9C6bElQxp4wsrleaJn1vXMZIQkNN44=
golang.org/x/net v0.0.0-20210222171744-9060382bd457/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 41f8228d..1014e9b0 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -2,19 +2,68 @@ package config
import (
"encoding/json"
- "fmt"
"io/ioutil"
- "math/rand"
- "os"
- "path"
- "time"
+ "net"
+ "reflect"
"github.com/gochan-org/gochan/pkg/gclog"
)
+const (
+ randomStringSize = 16
+)
+
var (
- Config GochanConfig
- cfgPath string
+ Config *GochanConfig
+ cfgPath string
+ cfgDefaults = map[string]interface{}{
+ "Port": 8080,
+ "FirstPage": []string{"index.html", "board.html", "firstrun.html"},
+ "DocumentRoot": "html",
+ "TemplateDir": "templates",
+ "LogDir": "log",
+
+ "SillyTags": []string{},
+
+ "SiteName": "Gochan",
+ "SiteWebFolder": "/",
+
+ "NewThreadDelay": 30,
+ "ReplyDelay": 7,
+
+ "MaxLineLength": 150,
+
+ "ThreadsPerPage": 15,
+
+ "RepliesOnBoardPage": 3,
+ "StickyRepliesOnBoardPage": 1,
+
+ "ThumbWidth": 200,
+ "ThumbHeight": 200,
+ "ThumbWidthReply": 125,
+ "ThumbHeightReply": 125,
+ "ThumbWidthCatalog": 50,
+ "ThumbHeightCatalog": 50,
+
+ "BanMsg": "USER WAS BANNED FOR THIS POST",
+ "EmbedWidth": 200,
+ "EmbedHeight": 164,
+ "ExpandButton": true,
+ "NewTabOnOutlinks": true,
+
+ "MinifyHTML": true,
+ "MinifyJS": true,
+
+ "CaptchaWidth": 240,
+ "CaptchaHeight": 80,
+
+ "DateTimeFormat": "Mon, January 02, 2006 15:04 PM",
+ "CaptchaMinutesExpire": 15,
+ "EnableGeoIP": true,
+ "GeoIPDBlocation": "/usr/share/GeoIP/GeoIP.dat",
+ "MaxRecentPosts": 3,
+ "MaxLogDays": 15,
+ }
)
// Style represents a theme (Pipes, Dark, etc)
@@ -23,87 +72,102 @@ type Style struct {
Filename string
}
-// GochanConfig stores crucial info and is read from/written to gochan.json
+// GochanConfig stores important info and is read from/written to gochan.json.
+// If a field has an entry in the defaults map, that value will be used here.
+// If a field has a critical struct tag set to "true", a warning will be printed
+// if it exists in the defaults map and an error will be printed if it doesn't.
type GochanConfig struct {
- ListenIP string
- Port int
- FirstPage []string
- Username string
- UseFastCGI bool
- DebugMode bool `description:"Disables several spam/browser checks that can cause problems when hosting an instance locally."`
+ ListenIP string `critical:"true"`
+ Port int `critical:"true"`
+ FirstPage []string `critical:"true"`
+ Username string `critical:"true"`
+ UseFastCGI bool `critical:"true"`
+ DebugMode bool `description:"Disables several spam/browser checks that can cause problems when hosting an instance locally."`
- DocumentRoot string
- TemplateDir string
- LogDir string
+ DocumentRoot string `critical:"true"`
+ TemplateDir string `critical:"true"`
+ LogDir string `critical:"true"`
- DBtype string
- DBhost string
- DBname string
- DBusername string
- DBpassword string
- DBprefix string
+ DBtype string `critical:"true"`
+ DBhost string `critical:"true"`
+ DBname string `critical:"true"`
+ DBusername string `critical:"true"`
+ DBpassword string `critical:"true"`
+ DBprefix string `description:"Each table's name in the database will start with this, if it is set"`
- Lockdown bool `description:"Disables posting." default:"unchecked"`
- LockdownMessage string `description:"Message displayed when someone tries to post while the site is on lockdown."`
- Sillytags []string `description:"List of randomly selected staff tags separated by line, e.g. ## Mod, to be randomly assigned to posts if UseSillytags is checked. Don't include the \"## \""`
- UseSillytags bool `description:"Use Sillytags" default:"unchecked"`
- Modboard string `description:"A super secret clubhouse board that only staff can view/post to." default:"staff"`
-
- SiteName string `description:"The name of the site that appears in the header of the front page." default:"Gochan"`
+ SiteName string `description:"The name of the site that appears in the header of the front page."`
SiteSlogan string `description:"The text that appears below SiteName on the home page"`
- SiteHeaderURL string `description:"To be honest, I'm not even sure what this does. It'll probably be removed later."`
- SiteWebfolder string `description:"The HTTP root appearing in the browser (e.g. https://gochan.org/<SiteWebFolder>" default:"/"`
- SiteDomain string `description:"The server's domain (duh). Do not edit this unless you know what you are doing or BAD THINGS WILL HAPPEN!" default:"127.0.0.1" critical:"true"`
+ SiteWebfolder string `critical:"true" description:"The HTTP root appearing in the browser (e.g. https://gochan.org/"`
+ SiteDomain string `critical:"true" description:"The server's domain. Do not edit this unless you know what you are doing or BAD THINGS WILL HAPPEN!"`
- Styles []Style `description:"List of styles (one per line) that should be accessed online at <SiteWebFolder>/css/<Style>/"`
- DefaultStyle string `description:"Filename of the default Style. This should appear in the list above or bad things might happen."`
+ Lockdown bool `description:"Disables posting."`
+ LockdownMessage string `description:"Message displayed when someone tries to post while the site is on lockdown."`
+ Sillytags []string `description:"List of randomly selected fake staff tags separated by line, e.g. ## Mod, to be randomly assigned to posts if UseSillytags is checked. Don't include the \"## \""`
+ UseSillytags bool `description:"Use Sillytags"`
+ Modboard string `description:"A super secret clubhouse board that only staff can view/post to."`
- AllowDuplicateImages bool `description:"Disabling this will cause gochan to reject a post if the image has already been uploaded for another post.
This may end up being removed or being made board-specific in the future." default:"checked"`
- AllowVideoUploads bool `description:"Allows users to upload .webm videos.
This may end up being removed or being made board-specific in the future."`
- NewThreadDelay int `description:"The amount of time in seconds that is required before an IP can make a new thread.
This may end up being removed or being made board-specific in the future." default:"30"`
- ReplyDelay int `description:"Same as the above, but for replies." default:"7"`
- MaxLineLength int `description:"Any line in a post that exceeds this will be split into two (or more) lines.
I'm not really sure why this is here, so it may end up being removed." default:"150"`
- ReservedTrips []string `description:"Secure tripcodes (!!Something) can be reserved here.
Each reservation should go on its own line and should look like this:
TripPassword1##Tripcode1
TripPassword2##Tripcode2"`
+ Styles []Style `critical:"true" description:"List of styles (one per line) that should be accessed online at /css/