Edit
diff --git a/gen_router.go b/gen_router.go
index 8293b34e..74f39f81 100644
--- a/gen_router.go
+++ b/gen_router.go
@@ -125,6 +125,14 @@ var RouteMap = map[string]interface{}{
"routes.AccountEditEmailTokenSubmit": routes.AccountEditEmailTokenSubmit,
"routes.AccountLogins": routes.AccountLogins,
"routes.LevelList": routes.LevelList,
+ "routes.Convos": routes.Convos,
+ "routes.ConvosCreate": routes.ConvosCreate,
+ "routes.Convo": routes.Convo,
+ "routes.ConvosCreateSubmit": routes.ConvosCreateSubmit,
+ "routes.ConvosDeleteSubmit": routes.ConvosDeleteSubmit,
+ "routes.ConvosCreateReplySubmit": routes.ConvosCreateReplySubmit,
+ "routes.ConvosDeleteReplySubmit": routes.ConvosDeleteReplySubmit,
+ "routes.ConvosEditReplySubmit": routes.ConvosEditReplySubmit,
"routes.ViewProfile": routes.ViewProfile,
"routes.BanUserSubmit": routes.BanUserSubmit,
"routes.UnbanUser": routes.UnbanUser,
@@ -278,53 +286,61 @@ var routeMapEnum = map[string]int{
"routes.AccountEditEmailTokenSubmit": 99,
"routes.AccountLogins": 100,
"routes.LevelList": 101,
- "routes.ViewProfile": 102,
- "routes.BanUserSubmit": 103,
- "routes.UnbanUser": 104,
- "routes.ActivateUser": 105,
- "routes.IPSearch": 106,
- "routes.CreateTopicSubmit": 107,
- "routes.EditTopicSubmit": 108,
- "routes.DeleteTopicSubmit": 109,
- "routes.StickTopicSubmit": 110,
- "routes.UnstickTopicSubmit": 111,
- "routes.LockTopicSubmit": 112,
- "routes.UnlockTopicSubmit": 113,
- "routes.MoveTopicSubmit": 114,
- "routes.LikeTopicSubmit": 115,
- "routes.AddAttachToTopicSubmit": 116,
- "routes.RemoveAttachFromTopicSubmit": 117,
- "routes.ViewTopic": 118,
- "routes.CreateReplySubmit": 119,
- "routes.ReplyEditSubmit": 120,
- "routes.ReplyDeleteSubmit": 121,
- "routes.ReplyLikeSubmit": 122,
- "routes.AddAttachToReplySubmit": 123,
- "routes.RemoveAttachFromReplySubmit": 124,
- "routes.ProfileReplyCreateSubmit": 125,
- "routes.ProfileReplyEditSubmit": 126,
- "routes.ProfileReplyDeleteSubmit": 127,
- "routes.PollVote": 128,
- "routes.PollResults": 129,
- "routes.AccountLogin": 130,
- "routes.AccountRegister": 131,
- "routes.AccountLogout": 132,
- "routes.AccountLoginSubmit": 133,
- "routes.AccountLoginMFAVerify": 134,
- "routes.AccountLoginMFAVerifySubmit": 135,
- "routes.AccountRegisterSubmit": 136,
- "routes.AccountPasswordReset": 137,
- "routes.AccountPasswordResetSubmit": 138,
- "routes.AccountPasswordResetToken": 139,
- "routes.AccountPasswordResetTokenSubmit": 140,
- "routes.DynamicRoute": 141,
- "routes.UploadedFile": 142,
- "routes.StaticFile": 143,
- "routes.RobotsTxt": 144,
- "routes.SitemapXml": 145,
- "routes.OpenSearchXml": 146,
- "routes.BadRoute": 147,
- "routes.HTTPSRedirect": 148,
+ "routes.Convos": 102,
+ "routes.ConvosCreate": 103,
+ "routes.Convo": 104,
+ "routes.ConvosCreateSubmit": 105,
+ "routes.ConvosDeleteSubmit": 106,
+ "routes.ConvosCreateReplySubmit": 107,
+ "routes.ConvosDeleteReplySubmit": 108,
+ "routes.ConvosEditReplySubmit": 109,
+ "routes.ViewProfile": 110,
+ "routes.BanUserSubmit": 111,
+ "routes.UnbanUser": 112,
+ "routes.ActivateUser": 113,
+ "routes.IPSearch": 114,
+ "routes.CreateTopicSubmit": 115,
+ "routes.EditTopicSubmit": 116,
+ "routes.DeleteTopicSubmit": 117,
+ "routes.StickTopicSubmit": 118,
+ "routes.UnstickTopicSubmit": 119,
+ "routes.LockTopicSubmit": 120,
+ "routes.UnlockTopicSubmit": 121,
+ "routes.MoveTopicSubmit": 122,
+ "routes.LikeTopicSubmit": 123,
+ "routes.AddAttachToTopicSubmit": 124,
+ "routes.RemoveAttachFromTopicSubmit": 125,
+ "routes.ViewTopic": 126,
+ "routes.CreateReplySubmit": 127,
+ "routes.ReplyEditSubmit": 128,
+ "routes.ReplyDeleteSubmit": 129,
+ "routes.ReplyLikeSubmit": 130,
+ "routes.AddAttachToReplySubmit": 131,
+ "routes.RemoveAttachFromReplySubmit": 132,
+ "routes.ProfileReplyCreateSubmit": 133,
+ "routes.ProfileReplyEditSubmit": 134,
+ "routes.ProfileReplyDeleteSubmit": 135,
+ "routes.PollVote": 136,
+ "routes.PollResults": 137,
+ "routes.AccountLogin": 138,
+ "routes.AccountRegister": 139,
+ "routes.AccountLogout": 140,
+ "routes.AccountLoginSubmit": 141,
+ "routes.AccountLoginMFAVerify": 142,
+ "routes.AccountLoginMFAVerifySubmit": 143,
+ "routes.AccountRegisterSubmit": 144,
+ "routes.AccountPasswordReset": 145,
+ "routes.AccountPasswordResetSubmit": 146,
+ "routes.AccountPasswordResetToken": 147,
+ "routes.AccountPasswordResetTokenSubmit": 148,
+ "routes.DynamicRoute": 149,
+ "routes.UploadedFile": 150,
+ "routes.StaticFile": 151,
+ "routes.RobotsTxt": 152,
+ "routes.SitemapXml": 153,
+ "routes.OpenSearchXml": 154,
+ "routes.BadRoute": 155,
+ "routes.HTTPSRedirect": 156,
}
var reverseRouteMapEnum = map[int]string{
0: "routes.Overview",
@@ -429,53 +445,61 @@ var reverseRouteMapEnum = map[int]string{
99: "routes.AccountEditEmailTokenSubmit",
100: "routes.AccountLogins",
101: "routes.LevelList",
- 102: "routes.ViewProfile",
- 103: "routes.BanUserSubmit",
- 104: "routes.UnbanUser",
- 105: "routes.ActivateUser",
- 106: "routes.IPSearch",
- 107: "routes.CreateTopicSubmit",
- 108: "routes.EditTopicSubmit",
- 109: "routes.DeleteTopicSubmit",
- 110: "routes.StickTopicSubmit",
- 111: "routes.UnstickTopicSubmit",
- 112: "routes.LockTopicSubmit",
- 113: "routes.UnlockTopicSubmit",
- 114: "routes.MoveTopicSubmit",
- 115: "routes.LikeTopicSubmit",
- 116: "routes.AddAttachToTopicSubmit",
- 117: "routes.RemoveAttachFromTopicSubmit",
- 118: "routes.ViewTopic",
- 119: "routes.CreateReplySubmit",
- 120: "routes.ReplyEditSubmit",
- 121: "routes.ReplyDeleteSubmit",
- 122: "routes.ReplyLikeSubmit",
- 123: "routes.AddAttachToReplySubmit",
- 124: "routes.RemoveAttachFromReplySubmit",
- 125: "routes.ProfileReplyCreateSubmit",
- 126: "routes.ProfileReplyEditSubmit",
- 127: "routes.ProfileReplyDeleteSubmit",
- 128: "routes.PollVote",
- 129: "routes.PollResults",
- 130: "routes.AccountLogin",
- 131: "routes.AccountRegister",
- 132: "routes.AccountLogout",
- 133: "routes.AccountLoginSubmit",
- 134: "routes.AccountLoginMFAVerify",
- 135: "routes.AccountLoginMFAVerifySubmit",
- 136: "routes.AccountRegisterSubmit",
- 137: "routes.AccountPasswordReset",
- 138: "routes.AccountPasswordResetSubmit",
- 139: "routes.AccountPasswordResetToken",
- 140: "routes.AccountPasswordResetTokenSubmit",
- 141: "routes.DynamicRoute",
- 142: "routes.UploadedFile",
- 143: "routes.StaticFile",
- 144: "routes.RobotsTxt",
- 145: "routes.SitemapXml",
- 146: "routes.OpenSearchXml",
- 147: "routes.BadRoute",
- 148: "routes.HTTPSRedirect",
+ 102: "routes.Convos",
+ 103: "routes.ConvosCreate",
+ 104: "routes.Convo",
+ 105: "routes.ConvosCreateSubmit",
+ 106: "routes.ConvosDeleteSubmit",
+ 107: "routes.ConvosCreateReplySubmit",
+ 108: "routes.ConvosDeleteReplySubmit",
+ 109: "routes.ConvosEditReplySubmit",
+ 110: "routes.ViewProfile",
+ 111: "routes.BanUserSubmit",
+ 112: "routes.UnbanUser",
+ 113: "routes.ActivateUser",
+ 114: "routes.IPSearch",
+ 115: "routes.CreateTopicSubmit",
+ 116: "routes.EditTopicSubmit",
+ 117: "routes.DeleteTopicSubmit",
+ 118: "routes.StickTopicSubmit",
+ 119: "routes.UnstickTopicSubmit",
+ 120: "routes.LockTopicSubmit",
+ 121: "routes.UnlockTopicSubmit",
+ 122: "routes.MoveTopicSubmit",
+ 123: "routes.LikeTopicSubmit",
+ 124: "routes.AddAttachToTopicSubmit",
+ 125: "routes.RemoveAttachFromTopicSubmit",
+ 126: "routes.ViewTopic",
+ 127: "routes.CreateReplySubmit",
+ 128: "routes.ReplyEditSubmit",
+ 129: "routes.ReplyDeleteSubmit",
+ 130: "routes.ReplyLikeSubmit",
+ 131: "routes.AddAttachToReplySubmit",
+ 132: "routes.RemoveAttachFromReplySubmit",
+ 133: "routes.ProfileReplyCreateSubmit",
+ 134: "routes.ProfileReplyEditSubmit",
+ 135: "routes.ProfileReplyDeleteSubmit",
+ 136: "routes.PollVote",
+ 137: "routes.PollResults",
+ 138: "routes.AccountLogin",
+ 139: "routes.AccountRegister",
+ 140: "routes.AccountLogout",
+ 141: "routes.AccountLoginSubmit",
+ 142: "routes.AccountLoginMFAVerify",
+ 143: "routes.AccountLoginMFAVerifySubmit",
+ 144: "routes.AccountRegisterSubmit",
+ 145: "routes.AccountPasswordReset",
+ 146: "routes.AccountPasswordResetSubmit",
+ 147: "routes.AccountPasswordResetToken",
+ 148: "routes.AccountPasswordResetTokenSubmit",
+ 149: "routes.DynamicRoute",
+ 150: "routes.UploadedFile",
+ 151: "routes.StaticFile",
+ 152: "routes.RobotsTxt",
+ 153: "routes.SitemapXml",
+ 154: "routes.OpenSearchXml",
+ 155: "routes.BadRoute",
+ 156: "routes.HTTPSRedirect",
}
var osMapEnum = map[string]int{
"unknown": 0,
@@ -633,7 +657,7 @@ type HTTPSRedirect struct {}
func (red *HTTPSRedirect) ServeHTTP(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Connection", "close")
- counters.RouteViewCounter.Bump(148)
+ counters.RouteViewCounter.Bump(156)
dest := "https://" + req.Host + req.URL.String()
http.Redirect(w, req, dest, http.StatusTemporaryRedirect)
}
@@ -828,6 +852,11 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
h.Set("X-Frame-Options", "deny")
h.Set("X-XSS-Protection", "1; mode=block") // TODO: Remove when we add a CSP? CSP's are horrendously glitchy things, tread with caution before removing
h.Set("X-Content-Type-Options", "nosniff")
+ if c.Config.RefNoRef || !c.Site.EnableSsl {
+ h.Set("Referrer-Policy","no-referrer")
+ } else {
+ h.Set("Referrer-Policy","strict-origin")
+ }
}
if c.Dev.SuperDebug {
@@ -836,8 +865,8 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// Increment the request counter
counters.GlobalViewCounter.Bump()
- if prefix == "/static" {
- counters.RouteViewCounter.Bump(143)
+ if prefix == "/s" { //old prefix: /static
+ counters.RouteViewCounter.Bump(151)
req.URL.Path += extraData
routes.StaticFile(w, req)
return
@@ -988,14 +1017,16 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
counters.LangViewCounter.Bump("none")
}
- referrer := req.Header.Get("Referer") // Check the 'referrer' header too? :P
- if referrer != "" {
- // ? Optimise this a little?
- referrer = strings.TrimPrefix(strings.TrimPrefix(referrer,"http://"),"https://")
- referrer = strings.Split(referrer,"/")[0]
- portless := strings.Split(referrer,":")[0]
- if portless != "localhost" && portless != "127.0.0.1" && portless != c.Site.Host {
- counters.ReferrerTracker.Bump(referrer)
+ if !c.Config.RefNoTrack {
+ referrer := req.Header.Get("Referer") // Check the 'referrer' header too? :P
+ if referrer != "" {
+ // ? Optimise this a little?
+ referrer = strings.TrimPrefix(strings.TrimPrefix(referrer,"http://"),"https://")
+ referrer = strings.Split(referrer,"/")[0]
+ portless := strings.Split(referrer,":")[0]
+ if portless != "localhost" && portless != "127.0.0.1" && portless != c.Site.Host {
+ counters.ReferrerTracker.Bump(referrer)
+ }
}
}
@@ -1813,9 +1844,110 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
err = routes.LevelList(w,req,user,head)
+ case "/user/convos/":
+ err = c.MemberOnly(w,req,user)
+ if err != nil {
+ return err
+ }
+
+ counters.RouteViewCounter.Bump(102)
+ head, err := c.UserCheck(w,req,&user)
+ if err != nil {
+ return err
+ }
+ err = routes.Convos(w,req,user,head)
+ case "/user/convos/create/":
+ err = c.MemberOnly(w,req,user)
+ if err != nil {
+ return err
+ }
+
+ counters.RouteViewCounter.Bump(103)
+ head, err := c.UserCheck(w,req,&user)
+ if err != nil {
+ return err
+ }
+ err = routes.ConvosCreate(w,req,user,head)
+ case "/user/convo/":
+ err = c.MemberOnly(w,req,user)
+ if err != nil {
+ return err
+ }
+
+ counters.RouteViewCounter.Bump(104)
+ head, err := c.UserCheck(w,req,&user)
+ if err != nil {
+ return err
+ }
+ err = routes.Convo(w,req,user,head,extraData)
+ case "/user/convos/create/submit/":
+ err = c.NoSessionMismatch(w,req,user)
+ if err != nil {
+ return err
+ }
+
+ err = c.MemberOnly(w,req,user)
+ if err != nil {
+ return err
+ }
+
+ counters.RouteViewCounter.Bump(105)
+ err = routes.ConvosCreateSubmit(w,req,user)
+ case "/user/convos/delete/submit/":
+ err = c.NoSessionMismatch(w,req,user)
+ if err != nil {
+ return err
+ }
+
+ err = c.MemberOnly(w,req,user)
+ if err != nil {
+ return err
+ }
+
+ counters.RouteViewCounter.Bump(106)
+ err = routes.ConvosDeleteSubmit(w,req,user,extraData)
+ case "/user/convo/create/submit/":
+ err = c.NoSessionMismatch(w,req,user)
+ if err != nil {
+ return err
+ }
+
+ err = c.MemberOnly(w,req,user)
+ if err != nil {
+ return err
+ }
+
+ counters.RouteViewCounter.Bump(107)
+ err = routes.ConvosCreateReplySubmit(w,req,user)
+ case "/user/convo/delete/submit/":
+ err = c.NoSessionMismatch(w,req,user)
+ if err != nil {
+ return err
+ }
+
+ err = c.MemberOnly(w,req,user)
+ if err != nil {
+ return err
+ }
+
+ counters.RouteViewCounter.Bump(108)
+ err = routes.ConvosDeleteReplySubmit(w,req,user,extraData)
+ case "/user/convo/edit/submit/":
+ err = c.NoSessionMismatch(w,req,user)
+ if err != nil {
+ return err
+ }
+
+ err = c.MemberOnly(w,req,user)
+ if err != nil {
+ return err
+ }
+
+ counters.RouteViewCounter.Bump(109)
+ err = routes.ConvosEditReplySubmit(w,req,user,extraData)
default:
req.URL.Path += extraData
- counters.RouteViewCounter.Bump(102)
+ counters.RouteViewCounter.Bump(110)
head, err := c.UserCheck(w,req,&user)
if err != nil {
return err
@@ -1835,7 +1967,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(103)
+ counters.RouteViewCounter.Bump(111)
err = routes.BanUserSubmit(w,req,user,extraData)
case "/users/unban/":
err = c.NoSessionMismatch(w,req,user)
@@ -1848,7 +1980,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(104)
+ counters.RouteViewCounter.Bump(112)
err = routes.UnbanUser(w,req,user,extraData)
case "/users/activate/":
err = c.NoSessionMismatch(w,req,user)
@@ -1861,7 +1993,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(105)
+ counters.RouteViewCounter.Bump(113)
err = routes.ActivateUser(w,req,user,extraData)
case "/users/ips/":
err = c.MemberOnly(w,req,user)
@@ -1869,7 +2001,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(106)
+ counters.RouteViewCounter.Bump(114)
head, err := c.UserCheck(w,req,&user)
if err != nil {
return err
@@ -1893,7 +2025,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(107)
+ counters.RouteViewCounter.Bump(115)
err = routes.CreateTopicSubmit(w,req,user)
case "/topic/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -1906,7 +2038,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(108)
+ counters.RouteViewCounter.Bump(116)
err = routes.EditTopicSubmit(w,req,user,extraData)
case "/topic/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -1920,7 +2052,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
}
req.URL.Path += extraData
- counters.RouteViewCounter.Bump(109)
+ counters.RouteViewCounter.Bump(117)
err = routes.DeleteTopicSubmit(w,req,user)
case "/topic/stick/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -1933,7 +2065,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(110)
+ counters.RouteViewCounter.Bump(118)
err = routes.StickTopicSubmit(w,req,user,extraData)
case "/topic/unstick/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -1946,7 +2078,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(111)
+ counters.RouteViewCounter.Bump(119)
err = routes.UnstickTopicSubmit(w,req,user,extraData)
case "/topic/lock/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -1960,7 +2092,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
}
req.URL.Path += extraData
- counters.RouteViewCounter.Bump(112)
+ counters.RouteViewCounter.Bump(120)
err = routes.LockTopicSubmit(w,req,user)
case "/topic/unlock/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -1973,7 +2105,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(113)
+ counters.RouteViewCounter.Bump(121)
err = routes.UnlockTopicSubmit(w,req,user,extraData)
case "/topic/move/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -1986,7 +2118,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(114)
+ counters.RouteViewCounter.Bump(122)
err = routes.MoveTopicSubmit(w,req,user,extraData)
case "/topic/like/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -1999,7 +2131,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(115)
+ counters.RouteViewCounter.Bump(123)
err = routes.LikeTopicSubmit(w,req,user,extraData)
case "/topic/attach/add/submit/":
err = c.MemberOnly(w,req,user)
@@ -2016,7 +2148,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(116)
+ counters.RouteViewCounter.Bump(124)
err = routes.AddAttachToTopicSubmit(w,req,user,extraData)
case "/topic/attach/remove/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -2029,10 +2161,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(117)
+ counters.RouteViewCounter.Bump(125)
err = routes.RemoveAttachFromTopicSubmit(w,req,user,extraData)
default:
- counters.RouteViewCounter.Bump(118)
+ counters.RouteViewCounter.Bump(126)
head, err := c.UserCheck(w,req,&user)
if err != nil {
return err
@@ -2056,7 +2188,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(119)
+ counters.RouteViewCounter.Bump(127)
err = routes.CreateReplySubmit(w,req,user)
case "/reply/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -2069,7 +2201,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(120)
+ counters.RouteViewCounter.Bump(128)
err = routes.ReplyEditSubmit(w,req,user,extraData)
case "/reply/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -2082,7 +2214,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(121)
+ counters.RouteViewCounter.Bump(129)
err = routes.ReplyDeleteSubmit(w,req,user,extraData)
case "/reply/like/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -2095,7 +2227,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(122)
+ counters.RouteViewCounter.Bump(130)
err = routes.ReplyLikeSubmit(w,req,user,extraData)
case "/reply/attach/add/submit/":
err = c.MemberOnly(w,req,user)
@@ -2112,7 +2244,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(123)
+ counters.RouteViewCounter.Bump(131)
err = routes.AddAttachToReplySubmit(w,req,user,extraData)
case "/reply/attach/remove/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -2125,7 +2257,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(124)
+ counters.RouteViewCounter.Bump(132)
err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData)
}
case "/profile":
@@ -2141,7 +2273,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(125)
+ counters.RouteViewCounter.Bump(133)
err = routes.ProfileReplyCreateSubmit(w,req,user)
case "/profile/reply/edit/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -2154,7 +2286,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(126)
+ counters.RouteViewCounter.Bump(134)
err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
case "/profile/reply/delete/submit/":
err = c.NoSessionMismatch(w,req,user)
@@ -2167,7 +2299,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(127)
+ counters.RouteViewCounter.Bump(135)
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
}
case "/poll":
@@ -2183,23 +2315,23 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(128)
+ counters.RouteViewCounter.Bump(136)
err = routes.PollVote(w,req,user,extraData)
case "/poll/results/":
- counters.RouteViewCounter.Bump(129)
+ counters.RouteViewCounter.Bump(137)
err = routes.PollResults(w,req,user,extraData)
}
case "/accounts":
switch(req.URL.Path) {
case "/accounts/login/":
- counters.RouteViewCounter.Bump(130)
+ counters.RouteViewCounter.Bump(138)
head, err := c.UserCheck(w,req,&user)
if err != nil {
return err
}
err = routes.AccountLogin(w,req,user,head)
case "/accounts/create/":
- counters.RouteViewCounter.Bump(131)
+ counters.RouteViewCounter.Bump(139)
head, err := c.UserCheck(w,req,&user)
if err != nil {
return err
@@ -2216,7 +2348,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(132)
+ counters.RouteViewCounter.Bump(140)
err = routes.AccountLogout(w,req,user)
case "/accounts/login/submit/":
err = c.ParseForm(w,req,user)
@@ -2224,10 +2356,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(133)
+ counters.RouteViewCounter.Bump(141)
err = routes.AccountLoginSubmit(w,req,user)
case "/accounts/mfa_verify/":
- counters.RouteViewCounter.Bump(134)
+ counters.RouteViewCounter.Bump(142)
head, err := c.UserCheck(w,req,&user)
if err != nil {
return err
@@ -2239,7 +2371,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(135)
+ counters.RouteViewCounter.Bump(143)
err = routes.AccountLoginMFAVerifySubmit(w,req,user)
case "/accounts/create/submit/":
err = c.ParseForm(w,req,user)
@@ -2247,10 +2379,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(136)
+ counters.RouteViewCounter.Bump(144)
err = routes.AccountRegisterSubmit(w,req,user)
case "/accounts/password-reset/":
- counters.RouteViewCounter.Bump(137)
+ counters.RouteViewCounter.Bump(145)
head, err := c.UserCheck(w,req,&user)
if err != nil {
return err
@@ -2262,10 +2394,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(138)
+ counters.RouteViewCounter.Bump(146)
err = routes.AccountPasswordResetSubmit(w,req,user)
case "/accounts/password-reset/token/":
- counters.RouteViewCounter.Bump(139)
+ counters.RouteViewCounter.Bump(147)
head, err := c.UserCheck(w,req,&user)
if err != nil {
return err
@@ -2277,7 +2409,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err
}
- counters.RouteViewCounter.Bump(140)
+ counters.RouteViewCounter.Bump(148)
err = routes.AccountPasswordResetTokenSubmit(w,req,user)
}
/*case "/sitemaps": // TODO: Count these views
@@ -2294,7 +2426,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
h.Del("Content-Type")
h.Del("Content-Encoding")
}
- counters.RouteViewCounter.Bump(142)
+ counters.RouteViewCounter.Bump(150)
req.URL.Path += extraData
// TODO: Find a way to propagate errors up from this?
r.UploadHandler(w,req) // TODO: Count these views
@@ -2304,7 +2436,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
// TODO: Add support for favicons and robots.txt files
switch(extraData) {
case "robots.txt":
- counters.RouteViewCounter.Bump(144)
+ counters.RouteViewCounter.Bump(152)
return routes.RobotsTxt(w,req)
case "favicon.ico":
gzw, ok := w.(c.GzipResponseWriter)
@@ -2314,14 +2446,14 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
h.Del("Content-Type")
h.Del("Content-Encoding")
}
- req.URL.Path = "/static/favicon.ico"
+ req.URL.Path = "/s/favicon.ico"
routes.StaticFile(w,req)
return nil
case "opensearch.xml":
- counters.RouteViewCounter.Bump(146)
+ counters.RouteViewCounter.Bump(154)
return routes.OpenSearchXml(w,req)
/*case "sitemap.xml":
- counters.RouteViewCounter.Bump(145)
+ counters.RouteViewCounter.Bump(153)
return routes.SitemapXml(w,req)*/
}
return c.NotFound(w,req,nil)
@@ -2332,7 +2464,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
r.RUnlock()
if ok {
- counters.RouteViewCounter.Bump(141) // TODO: Be more specific about *which* dynamic route it is
+ counters.RouteViewCounter.Bump(149) // TODO: Be more specific about *which* dynamic route it is
req.URL.Path += extraData
return handle(w,req,user)
}
@@ -2343,7 +2475,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
} else {
r.DumpRequest(req,"Bad Route")
}
- counters.RouteViewCounter.Bump(147)
+ counters.RouteViewCounter.Bump(155)
return c.NotFound(w,req,nil)
}
return err
diff --git a/general_test.go b/general_test.go
index 7682e87f..e9fc6419 100644
--- a/general_test.go
+++ b/general_test.go
@@ -567,7 +567,7 @@ func BenchmarkRoutesSerial(b *testing.B) {
b.Log("Plugins have already been initialised, they can't be deinitialised so these tests will run with plugins on")
}
static_w := httptest.NewRecorder()
- static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil))
+ static_req := httptest.NewRequest("get","/s/global.js",bytes.NewReader(nil))
static_handler := http.HandlerFunc(route_static)
topic_w := httptest.NewRecorder()
@@ -1134,7 +1134,7 @@ func TestStaticRoute(t *testing.T) {
}
static_w := httptest.NewRecorder()
- static_req := httptest.NewRequest("get","/static/global.js",bytes.NewReader(nil))
+ static_req := httptest.NewRequest("get","/s/global.js",bytes.NewReader(nil))
static_handler := http.HandlerFunc(route_static)
static_handler.ServeHTTP(static_w,static_req)
diff --git a/langs/english.json b/langs/english.json
index 65a279e4..23d9dc2e 100644
--- a/langs/english.json
+++ b/langs/english.json
@@ -318,6 +318,8 @@
"password_reset_email_sent":"An email was sent to you. Please follow the steps within.",
"password_reset_token_token_verified":"Your password was successfully updated.",
+ "convo_dev":"Messages are currently under development. Some features may not work yet and your messages may be purged every now and then.",
+
"panel_forum_created":"The forum was successfully created.",
"panel_forum_deleted":"The forum was successfully deleted.",
"panel_forum_updated":"The forum was successfully updated.",
diff --git a/main.go b/main.go
index 25d2c376..121a3aa6 100644
--- a/main.go
+++ b/main.go
@@ -134,10 +134,10 @@ func storeInit() (err error) {
if err != nil {
return errors.WithStack(err)
}
- /*c.Convos, err = c.NewDefaultConversationStore(acc)
+ c.Convos, err = c.NewDefaultConversationStore(acc)
if err != nil {
return errors.WithStack(err)
- }*/
+ }
err = phrases.InitPhrases(c.Site.Language)
if err != nil {
diff --git a/patcher/patches.go b/patcher/patches.go
index 187a1e9f..1c81b4df 100644
--- a/patcher/patches.go
+++ b/patcher/patches.go
@@ -9,6 +9,7 @@ import (
)
type tblColumn = qgen.DBTableColumn
+type tC = tblColumn
type tblKey = qgen.DBTableKey
func init() {
@@ -35,6 +36,7 @@ func init() {
addPatch(20, patch20)
addPatch(21, patch21)
addPatch(22, patch22)
+ addPatch(23, patch23)
}
func patch0(scanner *bufio.Scanner) (err error) {
@@ -48,8 +50,8 @@ func patch0(scanner *bufio.Scanner) (err error) {
}
err = execStmt(qgen.Builder.CreateTable("menus", "", "",
- []tblColumn{
- tblColumn{"mid", "int", 0, false, true, ""},
+ []tC{
+ tC{"mid", "int", 0, false, true, ""},
},
[]tblKey{
tblKey{"mid", "primary","",false},
@@ -60,23 +62,23 @@ func patch0(scanner *bufio.Scanner) (err error) {
}
err = execStmt(qgen.Builder.CreateTable("menu_items", "", "",
- []tblColumn{
- tblColumn{"miid", "int", 0, false, true, ""},
- tblColumn{"mid", "int", 0, false, false, ""},
- tblColumn{"name", "varchar", 200, false, false, ""},
- tblColumn{"htmlID", "varchar", 200, false, false, "''"},
- tblColumn{"cssClass", "varchar", 200, false, false, "''"},
- tblColumn{"position", "varchar", 100, false, false, ""},
- tblColumn{"path", "varchar", 200, false, false, "''"},
- tblColumn{"aria", "varchar", 200, false, false, "''"},
- tblColumn{"tooltip", "varchar", 200, false, false, "''"},
- tblColumn{"tmplName", "varchar", 200, false, false, "''"},
- tblColumn{"order", "int", 0, false, false, "0"},
+ []tC{
+ tC{"miid", "int", 0, false, true, ""},
+ tC{"mid", "int", 0, false, false, ""},
+ tC{"name", "varchar", 200, false, false, ""},
+ tC{"htmlID", "varchar", 200, false, false, "''"},
+ tC{"cssClass", "varchar", 200, false, false, "''"},
+ tC{"position", "varchar", 100, false, false, ""},
+ tC{"path", "varchar", 200, false, false, "''"},
+ tC{"aria", "varchar", 200, false, false, "''"},
+ tC{"tooltip", "varchar", 200, false, false, "''"},
+ tC{"tmplName", "varchar", 200, false, false, "''"},
+ tC{"order", "int", 0, false, false, "0"},
- tblColumn{"guestOnly", "boolean", 0, false, false, "0"},
- tblColumn{"memberOnly", "boolean", 0, false, false, "0"},
- tblColumn{"staffOnly", "boolean", 0, false, false, "0"},
- tblColumn{"adminOnly", "boolean", 0, false, false, "0"},
+ tC{"guestOnly", "boolean", 0, false, false, "0"},
+ tC{"memberOnly", "boolean", 0, false, false, "0"},
+ tC{"staffOnly", "boolean", 0, false, false, "0"},
+ tC{"adminOnly", "boolean", 0, false, false, "0"},
},
[]tblKey{
tblKey{"miid", "primary","",false},
@@ -176,14 +178,14 @@ func patch2(scanner *bufio.Scanner) error {
func patch3(scanner *bufio.Scanner) error {
return execStmt(qgen.Builder.CreateTable("registration_logs", "", "",
- []tblColumn{
- tblColumn{"rlid", "int", 0, false, true, ""},
- tblColumn{"username", "varchar", 100, false, false, ""},
- tblColumn{"email", "varchar", 100, false, false, ""},
- tblColumn{"failureReason", "varchar", 100, false, false, ""},
- tblColumn{"success", "bool", 0, false, false, "0"}, // Did this attempt succeed?
- tblColumn{"ipaddress", "varchar", 200, false, false, ""},
- tblColumn{"doneAt", "createdAt", 0, false, false, ""},
+ []tC{
+ tC{"rlid", "int", 0, false, true, ""},
+ tC{"username", "varchar", 100, false, false, ""},
+ tC{"email", "varchar", 100, false, false, ""},
+ tC{"failureReason", "varchar", 100, false, false, ""},
+ tC{"success", "bool", 0, false, false, "0"}, // Did this attempt succeed?
+ tC{"ipaddress", "varchar", 200, false, false, ""},
+ tC{"doneAt", "createdAt", 0, false, false, ""},
},
[]tblKey{
tblKey{"rlid", "primary","",false},
@@ -240,13 +242,13 @@ func patch4(scanner *bufio.Scanner) error {
}
err = execStmt(qgen.Builder.CreateTable("pages", "utf8mb4", "utf8mb4_general_ci",
- []tblColumn{
- tblColumn{"pid", "int", 0, false, true, ""},
- tblColumn{"name", "varchar", 200, false, false, ""},
- tblColumn{"title", "varchar", 200, false, false, ""},
- tblColumn{"body", "text", 0, false, false, ""},
- tblColumn{"allowedGroups", "text", 0, false, false, ""},
- tblColumn{"menuID", "int", 0, false, false, "-1"},
+ []tC{
+ tC{"pid", "int", 0, false, true, ""},
+ tC{"name", "varchar", 200, false, false, ""},
+ tC{"title", "varchar", 200, false, false, ""},
+ tC{"body", "text", 0, false, false, ""},
+ tC{"allowedGroups", "text", 0, false, false, ""},
+ tC{"menuID", "int", 0, false, false, "-1"},
},
[]tblKey{
tblKey{"pid", "primary","",false},
@@ -278,18 +280,18 @@ func patch5(scanner *bufio.Scanner) error {
}
err = execStmt(qgen.Builder.CreateTable("users_2fa_keys", "utf8mb4", "utf8mb4_general_ci",
- []tblColumn{
- tblColumn{"uid", "int", 0, false, false, ""},
- tblColumn{"secret", "varchar", 100, false, false, ""},
- tblColumn{"scratch1", "varchar", 50, false, false, ""},
- tblColumn{"scratch2", "varchar", 50, false, false, ""},
- tblColumn{"scratch3", "varchar", 50, false, false, ""},
- tblColumn{"scratch4", "varchar", 50, false, false, ""},
- tblColumn{"scratch5", "varchar", 50, false, false, ""},
- tblColumn{"scratch6", "varchar", 50, false, false, ""},
- tblColumn{"scratch7", "varchar", 50, false, false, ""},
- tblColumn{"scratch8", "varchar", 50, false, false, ""},
- tblColumn{"createdAt", "createdAt", 0, false, false, ""},
+ []tC{
+ tC{"uid", "int", 0, false, false, ""},
+ tC{"secret", "varchar", 100, false, false, ""},
+ tC{"scratch1", "varchar", 50, false, false, ""},
+ tC{"scratch2", "varchar", 50, false, false, ""},
+ tC{"scratch3", "varchar", 50, false, false, ""},
+ tC{"scratch4", "varchar", 50, false, false, ""},
+ tC{"scratch5", "varchar", 50, false, false, ""},
+ tC{"scratch6", "varchar", 50, false, false, ""},
+ tC{"scratch7", "varchar", 50, false, false, ""},
+ tC{"scratch8", "varchar", 50, false, false, ""},
+ tC{"createdAt", "createdAt", 0, false, false, ""},
},
[]tblKey{
tblKey{"uid", "primary","",false},
@@ -308,8 +310,8 @@ func patch6(scanner *bufio.Scanner) error {
func patch7(scanner *bufio.Scanner) error {
return execStmt(qgen.Builder.CreateTable("users_avatar_queue", "", "",
- []tblColumn{
- tblColumn{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
+ []tC{
+ tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
},
[]tblKey{
tblKey{"uid", "primary","",false},
@@ -371,8 +373,8 @@ func patch8(scanner *bufio.Scanner) error {
return err
}
return execStmt(qgen.Builder.CreateTable("updates", "", "",
- []tblColumn{
- tblColumn{"dbVersion", "int", 0, false, false, "0"},
+ []tC{
+ tC{"dbVersion", "int", 0, false, false, "0"},
},
[]tblKey{},
))
@@ -386,12 +388,12 @@ func patch9(scanner *bufio.Scanner) error {
}
return execStmt(qgen.Builder.CreateTable("login_logs", "", "",
- []tblColumn{
- tblColumn{"lid", "int", 0, false, true, ""},
- tblColumn{"uid", "int", 0, false, false, ""},
- tblColumn{"success", "bool", 0, false, false, "0"}, // Did this attempt succeed?
- tblColumn{"ipaddress", "varchar", 200, false, false, ""},
- tblColumn{"doneAt", "createdAt", 0, false, false, ""},
+ []tC{
+ tC{"lid", "int", 0, false, true, ""},
+ tC{"uid", "int", 0, false, false, ""},
+ tC{"success", "bool", 0, false, false, "0"}, // Did this attempt succeed?
+ tC{"ipaddress", "varchar", 200, false, false, ""},
+ tC{"doneAt", "createdAt", 0, false, false, ""},
},
[]tblKey{
tblKey{"lid", "primary","",false},
@@ -403,11 +405,11 @@ var acc = qgen.NewAcc
var itoa = strconv.Itoa
func patch10(scanner *bufio.Scanner) error {
- err := execStmt(qgen.Builder.AddColumn("topics", tblColumn{"attachCount", "int", 0, false, false, "0"}, nil))
+ err := execStmt(qgen.Builder.AddColumn("topics", tC{"attachCount", "int", 0, false, false, "0"}, nil))
if err != nil {
return err
}
- err = execStmt(qgen.Builder.AddColumn("topics", tblColumn{"lastReplyID", "int", 0, false, false, "0"}, nil))
+ err = execStmt(qgen.Builder.AddColumn("topics", tC{"lastReplyID", "int", 0, false, false, "0"}, nil))
if err != nil {
return err
}
@@ -443,7 +445,7 @@ func patch10(scanner *bufio.Scanner) error {
}
func patch11(scanner *bufio.Scanner) error {
- err := execStmt(qgen.Builder.AddColumn("replies", tblColumn{"attachCount", "int", 0, false, false, "0"}, nil))
+ err := execStmt(qgen.Builder.AddColumn("replies", tC{"attachCount", "int", 0, false, false, "0"}, nil))
if err != nil {
return err
}
@@ -517,7 +519,7 @@ func patch12(scanner *bufio.Scanner) error {
}
func patch13(scanner *bufio.Scanner) error {
- err := execStmt(qgen.Builder.AddColumn("widgets", tblColumn{"wid", "int", 0, false, true, ""}, &tblKey{"wid", "primary","",false}))
+ err := execStmt(qgen.Builder.AddColumn("widgets", tC{"wid", "int", 0, false, true, ""}, &tblKey{"wid", "primary","",false}))
if err != nil {
return err
}
@@ -548,18 +550,18 @@ func patch15(scanner *bufio.Scanner) error {
func patch16(scanner *bufio.Scanner) error {
return execStmt(qgen.Builder.CreateTable("password_resets", "", "",
- []tblColumn{
- tblColumn{"email", "varchar", 200, false, false, ""},
- tblColumn{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
- tblColumn{"validated", "varchar", 200, false, false, ""}, // Token given once the one-use token is consumed, used to prevent multiple people consuming the same one-use token
- tblColumn{"token", "varchar", 200, false, false, ""},
- tblColumn{"createdAt", "createdAt", 0, false, false, ""},
+ []tC{
+ tC{"email", "varchar", 200, false, false, ""},
+ tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key
+ tC{"validated", "varchar", 200, false, false, ""}, // Token given once the one-use token is consumed, used to prevent multiple people consuming the same one-use token
+ tC{"token", "varchar", 200, false, false, ""},
+ tC{"createdAt", "createdAt", 0, false, false, ""},
}, nil,
))
}
func patch17(scanner *bufio.Scanner) error {
- err := execStmt(qgen.Builder.AddColumn("attachments", tblColumn{"extra", "varchar", 200, false, false, ""}, nil))
+ err := execStmt(qgen.Builder.AddColumn("attachments", tC{"extra", "varchar", 200, false, false, ""}, nil))
if err != nil {
return err
}
@@ -595,14 +597,14 @@ func patch17(scanner *bufio.Scanner) error {
}
func patch18(scanner *bufio.Scanner) error {
- return execStmt(qgen.Builder.AddColumn("forums", tblColumn{"order", "int", 0, false, false, "0"}, nil))
+ return execStmt(qgen.Builder.AddColumn("forums", tC{"order", "int", 0, false, false, "0"}, nil))
}
func patch19(scanner *bufio.Scanner) error {
return execStmt(qgen.Builder.CreateTable("memchunks", "", "",
- []tblColumn{
- tblColumn{"count", "int", 0, false, false, "0"},
- tblColumn{"createdAt", "datetime", 0, false, false, ""},
+ []tC{
+ tC{"count", "int", 0, false, false, "0"},
+ tC{"createdAt", "datetime", 0, false, false, ""},
}, nil,
))
}
@@ -631,29 +633,82 @@ func patch20(scanner *bufio.Scanner) error {
}
func patch21(scanner *bufio.Scanner) error {
- err := execStmt(qgen.Builder.AddColumn("memchunks", tblColumn{"stack", "int", 0, false, false, "0"}, nil))
+ err := execStmt(qgen.Builder.AddColumn("memchunks", tC{"stack", "int", 0, false, false, "0"}, nil))
if err != nil {
return err
}
- err = execStmt(qgen.Builder.AddColumn("memchunks", tblColumn{"heap", "int", 0, false, false, "0"}, nil))
+ err = execStmt(qgen.Builder.AddColumn("memchunks", tC{"heap", "int", 0, false, false, "0"}, nil))
if err != nil {
return err
}
err = execStmt(qgen.Builder.CreateTable("meta", "", "",
- []tblColumn{
- tblColumn{"name", "varchar", 200, false, false, ""},
- tblColumn{"value", "varchar", 200, false, false, ""},
+ []tC{
+ tC{"name", "varchar", 200, false, false, ""},
+ tC{"value", "varchar", 200, false, false, ""},
}, nil,
))
if err != nil {
return err
}
- return execStmt(qgen.Builder.AddColumn("activity_stream", tblColumn{"createdAt", "createdAt", 0, false, false, ""}, nil))
+ return execStmt(qgen.Builder.AddColumn("activity_stream", tC{"createdAt", "createdAt", 0, false, false, ""}, nil))
}
func patch22(scanner *bufio.Scanner) error {
- return execStmt(qgen.Builder.AddColumn("forums", tblColumn{"tmpl", "varchar", 200, false, false, "''"}, nil))
+ return execStmt(qgen.Builder.AddColumn("forums", tC{"tmpl", "varchar", 200, false, false, "''"}, nil))
+}
+
+func patch23(scanner *bufio.Scanner) error {
+ err := execStmt(qgen.Builder.DropTable("conversations"))
+ if err != nil {
+ return err
+ }
+ err = execStmt(qgen.Builder.CreateTable("conversations", "", "",
+ []tC{
+ tC{"cid", "int", 0, false, true, ""},
+ tC{"createdBy", "int", 0, false, false, ""}, // TODO: Make this a foreign key
+ tC{"createdAt", "createdAt", 0, false, false, ""},
+ tC{"lastReplyAt", "datetime", 0, false, false, ""},
+ tC{"lastReplyBy", "int", 0, false, false, ""},
+ },
+ []tblKey{
+ tblKey{"cid", "primary","",false},
+ },
+ ))
+ if err != nil {
+ return err
+ }
+
+ err = execStmt(qgen.Builder.DropTable("conversations_posts"))
+ if err != nil {
+ return err
+ }
+ err = execStmt(qgen.Builder.CreateTable("conversations_posts", "", "",
+ []tC{
+ tC{"pid", "int", 0, false, true, ""},
+ tC{"cid", "int", 0, false, false, ""},
+ tC{"createdBy", "int", 0, false, false, ""},
+ tC{"body", "varchar", 50, false, false, ""},
+ tC{"post", "varchar", 50, false, false, "''"},
+ },
+ []tblKey{
+ tblKey{"pid", "primary","",false},
+ },
+ ))
+ if err != nil {
+ return err
+ }
+
+ err = execStmt(qgen.Builder.DropTable("conversations_participants"))
+ if err != nil {
+ return err
+ }
+ return execStmt(qgen.Builder.CreateTable("conversations_participants", "", "",
+ []tC{
+ tC{"uid", "int", 0, false, false, ""},
+ tC{"cid", "int", 0, false, false, ""},
+ }, nil,
+ ))
}
\ No newline at end of file
diff --git a/public/init.js b/public/init.js
index c5517920..44777ced 100644
--- a/public/init.js
+++ b/public/init.js
@@ -83,9 +83,9 @@ function asyncGetScript(source) {
}
function notifyOnScript(source) {
- source = "/static/"+source;
+ source = "/s/"+source;
return new Promise((resolve, reject) => {
- let ss = source.replace("/static/","");
+ let ss = source.replace("/s/","");
try {
let ssp = ss.charAt(0).toUpperCase() + ss.slice(1)
console.log("ssp:",ssp)
@@ -138,8 +138,8 @@ function loadScript(name, callback,fail) {
let parts = value.split("; current_theme=");
if (parts.length == 2) fname += "_"+ parts.pop().split(";").shift();
- let url = "/static/"+fname+".js"
- let iurl = "/static/"+name+".js"
+ let url = "/s/"+fname+".js"
+ let iurl = "/s/"+name+".js"
asyncGetScript(url)
.then(callback)
.catch((e) => {
@@ -161,7 +161,7 @@ function loadScript(name, callback,fail) {
/*
function loadTmpl(name,callback) {
- let url = "/static/"+name
+ let url = "/s/"+name
let worker = new Worker(url);
}
*/
diff --git a/public/jquery-emojiarea/emojis.js b/public/jquery-emojiarea/emojis.js
index ff684dd4..c94a7c58 100644
--- a/public/jquery-emojiarea/emojis.js
+++ b/public/jquery-emojiarea/emojis.js
@@ -1,4 +1,4 @@
-$.emojiarea.path = '/static/smilies/emojiarea';
+$.emojiarea.path = '/s/smilies/emojiarea';
$.emojiarea.icons = [{"name" : "
", "icons" : {':bowtie:' : 'bowtie.png',
':smile:' : 'smile.png',
':laughing:' : 'laughing.png',
diff --git a/query_gen/mysql.go b/query_gen/mysql.go
index 17dd84ce..8d99e7cc 100644
--- a/query_gen/mysql.go
+++ b/query_gen/mysql.go
@@ -654,7 +654,7 @@ func (a *MysqlAdapter) complexSelect(preBuilder *selectPrebuilder, sb *strings.B
return nil
}
-func (adapter *MysqlAdapter) SimpleLeftJoin(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string, limit string) (string, error) {
+func (a *MysqlAdapter) SimpleLeftJoin(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string, limit string) (string, error) {
if table1 == "" {
return "", errors.New("You need a name for the left table")
}
@@ -668,7 +668,7 @@ func (adapter *MysqlAdapter) SimpleLeftJoin(name string, table1 string, table2 s
return "", errors.New("No joiners found for SimpleLeftJoin")
}
- whereStr, err := adapter.buildJoinWhere(where)
+ whereStr, err := a.buildJoinWhere(where)
if err != nil {
return "", err
}
@@ -684,14 +684,14 @@ func (adapter *MysqlAdapter) SimpleLeftJoin(name string, table1 string, table2 s
as2 = " AS `"+ thalf2[1]+"`"
}
- var querystr = "SELECT" + adapter.buildJoinColumns(columns) + " FROM `" + thalf1[0] + "`"+as1+" LEFT JOIN `" + thalf2[0] + "`"+as2+" ON " + adapter.buildJoiners(joiners) + whereStr + adapter.buildOrderby(orderby) + adapter.buildLimit(limit)
+ q := "SELECT" + a.buildJoinColumns(columns) + " FROM `" + thalf1[0] + "`"+as1+" LEFT JOIN `" + thalf2[0] + "`"+as2+" ON " + a.buildJoiners(joiners) + whereStr + a.buildOrderby(orderby) + a.buildLimit(limit)
- querystr = strings.TrimSpace(querystr)
- adapter.pushStatement(name, "select", querystr)
- return querystr, nil
+ q = strings.TrimSpace(q)
+ a.pushStatement(name, "select", q)
+ return q, nil
}
-func (adapter *MysqlAdapter) SimpleInnerJoin(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string, limit string) (string, error) {
+func (a *MysqlAdapter) SimpleInnerJoin(name string, table1 string, table2 string, columns string, joiners string, where string, orderby string, limit string) (string, error) {
if table1 == "" {
return "", errors.New("You need a name for the left table")
}
@@ -705,16 +705,27 @@ func (adapter *MysqlAdapter) SimpleInnerJoin(name string, table1 string, table2
return "", errors.New("No joiners found for SimpleInnerJoin")
}
- whereStr, err := adapter.buildJoinWhere(where)
+ whereStr, err := a.buildJoinWhere(where)
if err != nil {
return "", err
}
- var querystr = "SELECT " + adapter.buildJoinColumns(columns) + " FROM `" + table1 + "` INNER JOIN `" + table2 + "` ON " + adapter.buildJoiners(joiners) + whereStr + adapter.buildOrderby(orderby) + adapter.buildLimit(limit)
+ thalf1 := strings.Split(strings.Replace(table1," as ", " AS ",-1)," AS ")
+ var as1 string
+ if len(thalf1) == 2 {
+ as1 = " AS `"+ thalf1[1]+"`"
+ }
+ thalf2 := strings.Split(strings.Replace(table2," as ", " AS ",-1)," AS ")
+ var as2 string
+ if len(thalf2) == 2 {
+ as2 = " AS `"+ thalf2[1]+"`"
+ }
- querystr = strings.TrimSpace(querystr)
- adapter.pushStatement(name, "select", querystr)
- return querystr, nil
+ q := "SELECT " + a.buildJoinColumns(columns) + " FROM `" + thalf1[0] + "`"+as1+" INNER JOIN `" + thalf2[0] + "`"+as2+" ON " + a.buildJoiners(joiners) + whereStr + a.buildOrderby(orderby) + a.buildLimit(limit)
+
+ q = strings.TrimSpace(q)
+ a.pushStatement(name, "select", q)
+ return q, nil
}
func (adapter *MysqlAdapter) SimpleUpdateSelect(up *updatePrebuilder) (string, error) {
@@ -767,7 +778,7 @@ func (adapter *MysqlAdapter) SimpleInsertLeftJoin(name string, ins DBInsert, sel
return "", err
}
- var q = "INSERT INTO `" + ins.Table + "`(" + adapter.buildColumns(ins.Columns) + ") SELECT" + adapter.buildJoinColumns(sel.Columns) + " FROM `" + sel.Table1 + "` LEFT JOIN `" + sel.Table2 + "` ON " + adapter.buildJoiners(sel.Joiners) + whereStr + adapter.buildOrderby(sel.Orderby) + adapter.buildLimit(sel.Limit)
+ q := "INSERT INTO `" + ins.Table + "`(" + adapter.buildColumns(ins.Columns) + ") SELECT" + adapter.buildJoinColumns(sel.Columns) + " FROM `" + sel.Table1 + "` LEFT JOIN `" + sel.Table2 + "` ON " + adapter.buildJoiners(sel.Joiners) + whereStr + adapter.buildOrderby(sel.Orderby) + adapter.buildLimit(sel.Limit)
q = strings.TrimSpace(q)
adapter.pushStatement(name, "insert", q)
@@ -856,7 +867,7 @@ func (adapter *MysqlAdapter) SimpleInsertInnerJoin(name string, ins DBInsert, se
return "", err
}
- var q = "INSERT INTO `" + ins.Table + "`(" + adapter.buildColumns(ins.Columns) + ") SELECT" + adapter.buildJoinColumns(sel.Columns) + " FROM `" + sel.Table1 + "` INNER JOIN `" + sel.Table2 + "` ON " + adapter.buildJoiners(sel.Joiners) + whereStr + adapter.buildOrderby(sel.Orderby) + adapter.buildLimit(sel.Limit)
+ q := "INSERT INTO `" + ins.Table + "`(" + adapter.buildColumns(ins.Columns) + ") SELECT" + adapter.buildJoinColumns(sel.Columns) + " FROM `" + sel.Table1 + "` INNER JOIN `" + sel.Table2 + "` ON " + adapter.buildJoiners(sel.Joiners) + whereStr + adapter.buildOrderby(sel.Orderby) + adapter.buildLimit(sel.Limit)
q = strings.TrimSpace(q)
adapter.pushStatement(name, "insert", q)
@@ -882,13 +893,13 @@ func (adapter *MysqlAdapter) Builder() *prebuilder {
return &prebuilder{adapter}
}
-func (adapter *MysqlAdapter) Write() error {
+func (a *MysqlAdapter) Write() error {
var stmts, body string
- for _, name := range adapter.BufferOrder {
+ for _, name := range a.BufferOrder {
if name[0] == '_' {
continue
}
- stmt := adapter.Buffer[name]
+ stmt := a.Buffer[name]
// ? - Table creation might be a little complex for Go to do outside a SQL file :(
if stmt.Type == "upsert" {
stmts += "\t" + name + " *qgen.MySQLUpsertCallback\n"
@@ -945,12 +956,12 @@ func _gen_mysql() (err error) {
}
// Internal methods, not exposed in the interface
-func (adapter *MysqlAdapter) pushStatement(name string, stype string, querystr string) {
+func (a *MysqlAdapter) pushStatement(name string, stype string, querystr string) {
if name == "" {
return
}
- adapter.Buffer[name] = DBStmt{querystr, stype}
- adapter.BufferOrder = append(adapter.BufferOrder, name)
+ a.Buffer[name] = DBStmt{querystr, stype}
+ a.BufferOrder = append(a.BufferOrder, name)
}
func (adapter *MysqlAdapter) stringyType(ctype string) bool {
diff --git a/router_gen/main.go b/router_gen/main.go
index f012a495..13f0be1f 100644
--- a/router_gen/main.go
+++ b/router_gen/main.go
@@ -593,6 +593,11 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
h.Set("X-Frame-Options", "deny")
h.Set("X-XSS-Protection", "1; mode=block") // TODO: Remove when we add a CSP? CSP's are horrendously glitchy things, tread with caution before removing
h.Set("X-Content-Type-Options", "nosniff")
+ if c.Config.RefNoRef || !c.Site.EnableSsl {
+ h.Set("Referrer-Policy","no-referrer")
+ } else {
+ h.Set("Referrer-Policy","strict-origin")
+ }
}
if c.Dev.SuperDebug {
@@ -601,7 +606,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// Increment the request counter
counters.GlobalViewCounter.Bump()
- if prefix == "/static" {
+ if prefix == "/s" { //old prefix: /static
counters.RouteViewCounter.Bump({{ index .AllRouteMap "routes.StaticFile" }})
req.URL.Path += extraData
routes.StaticFile(w, req)
@@ -753,14 +758,16 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
counters.LangViewCounter.Bump("none")
}
- referrer := req.Header.Get("Referer") // Check the 'referrer' header too? :P
- if referrer != "" {
- // ? Optimise this a little?
- referrer = strings.TrimPrefix(strings.TrimPrefix(referrer,"http://"),"https://")
- referrer = strings.Split(referrer,"/")[0]
- portless := strings.Split(referrer,":")[0]
- if portless != "localhost" && portless != "127.0.0.1" && portless != c.Site.Host {
- counters.ReferrerTracker.Bump(referrer)
+ if !c.Config.RefNoTrack {
+ referrer := req.Header.Get("Referer") // Check the 'referrer' header too? :P
+ if referrer != "" {
+ // ? Optimise this a little?
+ referrer = strings.TrimPrefix(strings.TrimPrefix(referrer,"http://"),"https://")
+ referrer = strings.Split(referrer,"/")[0]
+ portless := strings.Split(referrer,":")[0]
+ if portless != "localhost" && portless != "127.0.0.1" && portless != c.Site.Host {
+ counters.ReferrerTracker.Bump(referrer)
+ }
}
}
@@ -840,7 +847,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
h.Del("Content-Type")
h.Del("Content-Encoding")
}
- req.URL.Path = "/static/favicon.ico"
+ req.URL.Path = "/s/favicon.ico"
routes.StaticFile(w,req)
return nil
case "opensearch.xml":
diff --git a/router_gen/routes.go b/router_gen/routes.go
index c15e0c0e..419b435f 100644
--- a/router_gen/routes.go
+++ b/router_gen/routes.go
@@ -49,7 +49,7 @@ func userRoutes() *RouteGroup {
return newRouteGroup("/user/").Routes(
View("routes.ViewProfile", "/user/").LitBefore("req.URL.Path += extraData"),
- Set("routes.AccountEdit","/user/edit",
+ Set("routes.AccountEdit", "/user/edit/",
MView("", "/"),
MView("Password", "/password/"),
Action("PasswordSubmit", "/password/submit/"), // TODO: Full test this
@@ -82,14 +82,15 @@ func userRoutes() *RouteGroup {
MView("routes.LevelList", "/user/levels/"),
//MView("routes.LevelRankings", "/user/rankings/"),
//MView("routes.Alerts", "/user/alerts/"),
-
- /*MView("routes.Convos", "/user/convos/"),
+
+ MView("routes.Convos", "/user/convos/"),
MView("routes.ConvosCreate", "/user/convos/create/"),
- MView("routes.Convo", "/user/convo/","extraData"),
+ MView("routes.Convo", "/user/convo/", "extraData"),
Action("routes.ConvosCreateSubmit", "/user/convos/create/submit/"),
- Action("routes.ConvosDeleteSubmit", "/user/convos/delete/submit/","extraData"),
+ Action("routes.ConvosDeleteSubmit", "/user/convos/delete/submit/", "extraData"),
Action("routes.ConvosCreateReplySubmit", "/user/convo/create/submit/"),
- Action("routes.ConvosDeleteReplySubmit", "/user/convo/delete/submit/"),*/
+ Action("routes.ConvosDeleteReplySubmit", "/user/convo/delete/submit/","extraData"),
+ Action("routes.ConvosEditReplySubmit", "/user/convo/edit/submit/", "extraData"),
)
}
@@ -171,6 +172,8 @@ func accountRoutes() *RouteGroup {
func panelRoutes() *RouteGroup {
return newRouteGroup("/panel/").Before("SuperModOnly").NoHeader().Routes(
View("panel.Dashboard", "/panel/"),
+ //View("panel.StatsDisk", "/panel/stats/disk/"),
+
View("panel.Forums", "/panel/forums/"),
Action("panel.ForumsCreateSubmit", "/panel/forums/create/"),
Action("panel.ForumsDelete", "/panel/forums/delete/", "extraData"),
diff --git a/routes/common.go b/routes/common.go
index 07caa2ea..062c4faf 100644
--- a/routes/common.go
+++ b/routes/common.go
@@ -21,8 +21,8 @@ func ParseSEOURL(urlBit string) (slug string, id int, err error) {
return halves[0], tid, err
}
-var slen1 = len("; rel=preload; as=script,")
-var slen2 = len("; rel=preload; as=style,")
+var slen1 = len("; rel=preload; as=script,")
+var slen2 = len("; rel=preload; as=style,")
func doPush(w http.ResponseWriter, header *c.Header) {
//fmt.Println("in doPush")
@@ -32,7 +32,7 @@ func doPush(w http.ResponseWriter, header *c.Header) {
var push = func(in []string) {
sb.Grow((slen1 + 5) * len(in))
for _, path := range in {
- sb.WriteString("; rel=preload; as=script,")
}
@@ -44,7 +44,7 @@ func doPush(w http.ResponseWriter, header *c.Header) {
if len(header.Stylesheets) > 0 {
sb.Grow((slen2 + 6) * len(header.Stylesheets))
for _, path := range header.Stylesheets {
- sb.WriteString("; rel=preload; as=style,")
}
@@ -69,9 +69,9 @@ func doPush(w http.ResponseWriter, header *c.Header) {
var push = func(in []string) {
for _, path := range in {
- //fmt.Println("pushing /static/" + path)
+ //fmt.Println("pushing /s/" + path)
// TODO: Avoid concatenating here
- err := pusher.Push("/static/"+path, nil)
+ err := pusher.Push("/s/"+path, nil)
if err != nil {
break
}
@@ -116,7 +116,7 @@ func renderTemplate3(tmplName string, hookName string, w http.ResponseWriter, r
h.Stylesheets = nil
c.PrepResources(&h.CurrentUser, h, h.Theme)
for _, ss := range s {
- h.Stylesheets = append(h.Stylesheets,ss)
+ h.Stylesheets = append(h.Stylesheets, ss)
}
if h.CurrentUser.Loggedin {
@@ -141,4 +141,4 @@ func renderTemplate3(tmplName string, hookName string, w http.ResponseWriter, r
}
// TODO: Rename renderTemplate to RenderTemplate instead of using this hack to avoid breaking things
-var RenderTemplate = renderTemplate3
\ No newline at end of file
+var RenderTemplate = renderTemplate3
diff --git a/routes/convos.go b/routes/convos.go
index a1781c76..698049ee 100644
--- a/routes/convos.go
+++ b/routes/convos.go
@@ -7,11 +7,12 @@ import (
"strings"
c "github.com/Azareal/Gosora/common"
- "github.com/Azareal/Gosora/common/phrases"
+ p "github.com/Azareal/Gosora/common/phrases"
)
func Convos(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
accountEditHead("convos", w, r, &user, header)
+ header.AddNotice("convo_dev")
ccount := c.Convos.GetUserCount(user.ID)
page, _ := strconv.Atoi(r.FormValue("page"))
offset, page, lastPage := c.PageOffset(ccount, page, c.Config.ItemsPerPage)
@@ -30,9 +31,11 @@ func Convos(w http.ResponseWriter, r *http.Request, user c.User, header *c.Heade
func Convo(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header, scid string) c.RouteError {
accountEditHead("convo", w, r, &user, header)
+ header.AddSheet(header.Theme.Name + "/convo.css")
+ header.AddNotice("convo_dev")
cid, err := strconv.Atoi(scid)
if err != nil {
- return c.LocalError(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user)
+ return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)
}
convo, err := c.Convos.Get(cid)
@@ -50,7 +53,7 @@ func Convo(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header
offset, page, lastPage := c.PageOffset(pcount, page, c.Config.ItemsPerPage)
pageList := c.Paginate(page, lastPage, 5)
- posts, err := convo.Posts(offset)
+ posts, err := convo.Posts(offset, c.Config.ItemsPerPage)
// TODO: Report a better error for no posts
if err == sql.ErrNoRows {
return c.NotFound(w, r, header)
@@ -58,12 +61,23 @@ func Convo(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header
return c.InternalError(err, w, r)
}
- pi := c.Account{header, "dashboard", "convo", c.ConvoViewPage{header, posts, c.Paginator{pageList, page, lastPage}}}
+ pitems := make([]c.ConvoViewRow, len(posts))
+ for i, post := range posts {
+ user, err := c.Users.Get(post.CreatedBy)
+ if err != nil {
+ return c.InternalError(err, w, r)
+ }
+ pitems[i] = c.ConvoViewRow{post, user, "", "4"}
+ }
+ canModify := user.ID == convo.CreatedBy || user.IsSuperMod
+
+ pi := c.Account{header, "dashboard", "convo", c.ConvoViewPage{header, convo, pitems, canModify, c.Paginator{pageList, page, lastPage}}}
return renderTemplate("account", w, r, header, pi)
}
func ConvosCreate(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
accountEditHead("create_convo", w, r, &user, header)
+ header.AddNotice("convo_dev")
recpName := ""
pi := c.Account{header, "dashboard", "create_convo", c.ConvoCreatePage{header, recpName}}
return renderTemplate("account", w, r, header, pi)
@@ -103,13 +117,6 @@ func ConvosCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
return nil
}
-/*type ConversationPost struct {
- ID int
- CID int
- Body string
- Post string // aes, ''
-}*/
-
func ConvosDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, scid string) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user)
if ferr != nil {
@@ -117,7 +124,7 @@ func ConvosDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, sci
}
cid, err := strconv.Atoi(scid)
if err != nil {
- return c.LocalError(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user)
+ return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)
}
err = c.Convos.Delete(cid)
@@ -138,11 +145,61 @@ func ConvosCreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User
return nil
}
-func ConvosDeleteReplySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
+func ConvosDeleteReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, scpid string) c.RouteError {
+ _, ferr := c.SimpleUserCheck(w, r, &user)
+ if ferr != nil {
+ return ferr
+ }
+ cpid, err := strconv.Atoi(scpid)
+ if err != nil {
+ return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)
+ }
+
+ post := &c.ConversationPost{ID: cpid}
+ err = post.Fetch()
+ if err == sql.ErrNoRows {
+ return c.NotFound(w, r, nil)
+ } else if err != nil {
+ return c.InternalError(err, w, r)
+ }
+
+ convo, err := c.Convos.Get(post.CID)
+ if err == sql.ErrNoRows {
+ return c.NotFound(w, r, nil)
+ } else if err != nil {
+ return c.InternalError(err, w, r)
+ }
+ pcount := convo.PostsCount()
+ if pcount == 0 {
+ return c.NotFound(w, r, nil)
+ }
+
+ posts, err := convo.Posts(0, c.Config.ItemsPerPage)
+ // TODO: Report a better error for no posts
+ if err == sql.ErrNoRows {
+ return c.NotFound(w, r, nil)
+ } else if err != nil {
+ return c.InternalError(err, w, r)
+ }
+
+ if post.ID == posts[0].ID {
+ err = c.Convos.Delete(convo.ID)
+ } else {
+ err = post.Delete()
+ }
+ if err != nil {
+ return c.InternalError(err, w, r)
+ }
+
+ http.Redirect(w, r, "/user/convo/"+strconv.Itoa(post.CID), http.StatusSeeOther)
+ return nil
+}
+
+func ConvosEditReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, scpid string) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user)
if ferr != nil {
return ferr
}
http.Redirect(w, r, "/user/convo/id", http.StatusSeeOther)
return nil
-}
\ No newline at end of file
+}
diff --git a/routes/reports.go b/routes/reports.go
index f2a87793..167d4ee2 100644
--- a/routes/reports.go
+++ b/routes/reports.go
@@ -24,7 +24,8 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID s
// TODO: Localise these titles and bodies
var title, content string
- if itemType == "reply" {
+ switch itemType {
+ case "reply":
reply, err := c.Rstore.Get(itemID)
if err == sql.ErrNoRows {
return c.LocalError("We were unable to find the reported post", w, r, user)
@@ -41,7 +42,7 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID s
title = "Reply: " + topic.Title
content = reply.Content + "\n\nOriginal Post: #rid-" + strconv.Itoa(itemID)
- } else if itemType == "user-reply" {
+ case "user-reply":
userReply, err := c.Prstore.Get(itemID)
if err == sql.ErrNoRows {
return c.LocalError("We weren't able to find the reported post", w, r, user)
@@ -57,7 +58,7 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID s
}
title = "Profile: " + profileOwner.Name
content = userReply.Content + "\n\nOriginal Post: @" + strconv.Itoa(userReply.ParentID)
- } else if itemType == "topic" {
+ case "topic":
topic, err := c.Topics.Get(itemID)
if err == sql.ErrNoRows {
return c.NotFound(w, r, nil)
@@ -66,7 +67,27 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID s
}
title = "Topic: " + topic.Title
content = topic.Content + "\n\nOriginal Post: #tid-" + strconv.Itoa(itemID)
- } else {
+ case "convo-reply":
+ post := &c.ConversationPost{ID: itemID}
+ err := post.Fetch()
+ if err == sql.ErrNoRows {
+ return c.NotFound(w, r, nil)
+ } else if err != nil {
+ return c.InternalError(err, w, r)
+ }
+
+ post, err = c.ConvoPostProcess.OnLoad(post)
+ if err != nil {
+ return c.InternalError(err, w, r)
+ }
+ user, err := c.Users.Get(post.CreatedBy)
+ if err != nil {
+ return c.InternalError(err, w, r)
+ }
+
+ title = "Convo Post: " + user.Name
+ content = post.Body + "\n\nOriginal Post: #cpid-" + strconv.Itoa(itemID)
+ default:
_, hasHook := headerLite.Hooks.VhookNeedHook("report_preassign", &itemID, &itemType)
if hasHook {
return nil
diff --git a/schema/mssql/query_conversations.sql b/schema/mssql/query_conversations.sql
new file mode 100644
index 00000000..591de621
--- /dev/null
+++ b/schema/mssql/query_conversations.sql
@@ -0,0 +1,8 @@
+CREATE TABLE [conversations] (
+ [cid] int not null IDENTITY,
+ [createdBy] int not null,
+ [createdAt] datetime not null,
+ [lastReplyAt] datetime not null,
+ [lastReplyBy] int not null,
+ primary key([cid])
+);
\ No newline at end of file
diff --git a/schema/mssql/query_conversations_participants.sql b/schema/mssql/query_conversations_participants.sql
new file mode 100644
index 00000000..027e302e
--- /dev/null
+++ b/schema/mssql/query_conversations_participants.sql
@@ -0,0 +1,4 @@
+CREATE TABLE [conversations_participants] (
+ [uid] int not null,
+ [cid] int not null
+);
\ No newline at end of file
diff --git a/schema/mssql/query_conversations_posts.sql b/schema/mssql/query_conversations_posts.sql
new file mode 100644
index 00000000..dc691be1
--- /dev/null
+++ b/schema/mssql/query_conversations_posts.sql
@@ -0,0 +1,8 @@
+CREATE TABLE [conversations_posts] (
+ [pid] int not null IDENTITY,
+ [cid] int not null,
+ [createdBy] int not null,
+ [body] nvarchar (50) not null,
+ [post] nvarchar (50) DEFAULT '' not null,
+ primary key([pid])
+);
\ No newline at end of file
diff --git a/schema/mysql/query_conversations.sql b/schema/mysql/query_conversations.sql
new file mode 100644
index 00000000..6dbdeb68
--- /dev/null
+++ b/schema/mysql/query_conversations.sql
@@ -0,0 +1,8 @@
+CREATE TABLE `conversations` (
+ `cid` int not null AUTO_INCREMENT,
+ `createdBy` int not null,
+ `createdAt` datetime not null,
+ `lastReplyAt` datetime not null,
+ `lastReplyBy` int not null,
+ primary key(`cid`)
+);
\ No newline at end of file
diff --git a/schema/mysql/query_conversations_participants.sql b/schema/mysql/query_conversations_participants.sql
new file mode 100644
index 00000000..405273a9
--- /dev/null
+++ b/schema/mysql/query_conversations_participants.sql
@@ -0,0 +1,4 @@
+CREATE TABLE `conversations_participants` (
+ `uid` int not null,
+ `cid` int not null
+);
\ No newline at end of file
diff --git a/schema/mysql/query_conversations_posts.sql b/schema/mysql/query_conversations_posts.sql
new file mode 100644
index 00000000..6921dd5f
--- /dev/null
+++ b/schema/mysql/query_conversations_posts.sql
@@ -0,0 +1,8 @@
+CREATE TABLE `conversations_posts` (
+ `pid` int not null AUTO_INCREMENT,
+ `cid` int not null,
+ `createdBy` int not null,
+ `body` varchar(50) not null,
+ `post` varchar(50) DEFAULT '' not null,
+ primary key(`pid`)
+);
\ No newline at end of file
diff --git a/schema/pgsql/query_conversations.sql b/schema/pgsql/query_conversations.sql
new file mode 100644
index 00000000..1c5f9345
--- /dev/null
+++ b/schema/pgsql/query_conversations.sql
@@ -0,0 +1,8 @@
+CREATE TABLE "conversations" (
+ `cid` serial not null,
+ `createdBy` int not null,
+ `createdAt` timestamp not null,
+ `lastReplyAt` timestamp not null,
+ `lastReplyBy` int not null,
+ primary key(`cid`)
+);
\ No newline at end of file
diff --git a/schema/pgsql/query_conversations_participants.sql b/schema/pgsql/query_conversations_participants.sql
new file mode 100644
index 00000000..c7b5f860
--- /dev/null
+++ b/schema/pgsql/query_conversations_participants.sql
@@ -0,0 +1,4 @@
+CREATE TABLE "conversations_participants" (
+ `uid` int not null,
+ `cid` int not null
+);
\ No newline at end of file
diff --git a/schema/pgsql/query_conversations_posts.sql b/schema/pgsql/query_conversations_posts.sql
new file mode 100644
index 00000000..3d206e3c
--- /dev/null
+++ b/schema/pgsql/query_conversations_posts.sql
@@ -0,0 +1,8 @@
+CREATE TABLE "conversations_posts" (
+ `pid` serial not null,
+ `cid` int not null,
+ `createdBy` int not null,
+ `body` varchar (50) not null,
+ `post` varchar (50) DEFAULT '' not null,
+ primary key(`pid`)
+);
\ No newline at end of file
diff --git a/templates/account_menu.html b/templates/account_menu.html
index d4dbb4d6..7355ed3f 100644
--- a/templates/account_menu.html
+++ b/templates/account_menu.html
@@ -9,6 +9,8 @@
+
+
{{/** TODO: Add an alerts page with pagination to go through alerts which either don't fit in the alerts drop-down or which have already been dismissed. Bear in mind though that dismissed alerts older than two weeks might be purged to save space and to speed up the database **/}}
diff --git a/templates/convo.html b/templates/convo.html
index a6b39ef8..c3617af9 100644
--- a/templates/convo.html
+++ b/templates/convo.html
@@ -3,8 +3,4 @@