gosora/routes/common.go

227 lines
7.7 KiB
Go
Raw Normal View History

UNSTABLE: Began work on the Nox Theme. Removed the Tempra Cursive Theme. You can now do bulk moderation actions with Shadow. Added: Argon2 as a dependency. The EmailStore. The ReportStore. The Copy method to *Setting. The AddColumn method to the query builder and adapters. The textarea setting type. More logging to better debug issues. The GetOffset method to the UserStore. Removed: Sortable from Code Climate's Analysis. MemberCheck and memberCheck as they're obsolete now. The obsolete url_tags setting. The BcryptGeneratePasswordNoSalt function. Some redundant fields from some of the page structs. Revamped: The Control Panel Setting List and Editor. Refactored: The password hashing logic to make it more amenable to multiple hashing algorithms. The email portion of the Account Manager. The Control Panel User List. The report system. simplePanelUserCheck and simpleUserCheck to remove the duplicated logic as the two do the exact same thing. Fixed: Missing slugs in the profile links in the User Manager. A few template initialisers potentially reducing the number of odd template edge cases. Some problems with the footer. Custom selection colour not applying to images on Shadow. The avatars of the bottom row of the topic list on Conflux leaking out. Other: Moved the startTime variable into package common and exported it. Moved the password hashing logic from user.go to auth.go Split common/themes.go into common/theme.go and common/theme_list.go Replaced the SettingLabels phrase category with the more generic SettingPhrases category. Moved a load of routes, including panel ones into the routes and panel packages. Hid the notifications link from the Account Menu. Moved more inline CSS into the CSS files and made things a little more flexible here and there. Continued work on PgSQL, still a ways away. Guests now have a default avatar like everyone else. Tweaked some of the font sizes on Cosora to make the text look a little nicer. Partially implemented the theme dock override logic. Partially implemented a "symlink" like feature for theme directories. ... And a bunch of other things I might have missed. You will need to run this update script / patcher for this commit. Warning: This is an "unstable commit", therefore some things may be a little less stable than I'd like. For instance, the Shadow Theme is a little broken in this commit.
2018-05-27 09:36:35 +00:00
package routes
import (
2022-02-21 03:32:53 +00:00
//"fmt"
"net/http"
"strconv"
"strings"
"sync"
"time"
c "github.com/Azareal/Gosora/common"
co "github.com/Azareal/Gosora/common/counters"
"github.com/Azareal/Gosora/uutils"
)
var successJSONBytes = []byte(`{"success":1}`)
func ParseSEOURL(urlBit string) (slug string, id int, err error) {
2022-02-21 03:32:53 +00:00
halves := strings.Split(urlBit, ".")
if len(halves) < 2 {
halves = append(halves, halves[0])
}
tid, err := strconv.Atoi(halves[1])
return halves[0], tid, err
}
const slen1 = len("</s/>;rel=preload;as=script,") + 6
const slen2 = len("</s/>;rel=preload;as=style,") + 7
2020-04-21 00:08:54 +00:00
var pushStrPool = sync.Pool{}
func doPush(w http.ResponseWriter, h *c.Header) {
2022-02-21 03:32:53 +00:00
//fmt.Println("in doPush")
if len(h.Scripts) == 0 && len(h.ScriptsAsync) == 0 && len(h.Stylesheets) == 0 {
return
}
if c.Config.EnableCDNPush {
var sb *strings.Builder = &strings.Builder{}
/*ii := pushStrPool.Get()
if ii == nil {
sb = &strings.Builder{}
} else {
sb = ii.(*strings.Builder)
sb.Reset()
}*/
sb.Grow((slen1 * (len(h.Scripts) + len(h.ScriptsAsync))) + ((slen2 + 7) * len(h.Stylesheets)))
push := func(in []c.HScript) {
for i, s := range in {
if i != 0 {
sb.WriteString(",</s/")
} else {
sb.WriteString("</s/")
}
sb.WriteString(s.Name)
sb.WriteString(">;rel=preload;as=script")
}
}
push(h.Scripts)
//push(h.PreScriptsAsync)
push(h.ScriptsAsync)
if len(h.Stylesheets) > 0 {
for i, s := range h.Stylesheets {
if i != 0 {
sb.WriteString(",</s/")
} else {
sb.WriteString("</s/")
}
sb.WriteString(s.Name)
sb.WriteString(">;rel=preload;as=style")
}
}
// TODO: Push avatars?
if sb.Len() > 0 {
sbuf := sb.String()
w.Header().Set("Link", sbuf)
//pushStrPool.Put(sb)
}
} else if !c.Config.DisableServerPush {
//fmt.Println("push enabled")
/*if bzw, ok := w.(c.BrResponseWriter); ok {
w = bzw.ResponseWriter
} else */if gzw, ok := w.(c.GzipResponseWriter); ok {
w = gzw.ResponseWriter
}
pusher, ok := w.(http.Pusher)
if !ok {
return
}
//panic("has pusher")
//fmt.Println("has pusher")
var sb *strings.Builder = &strings.Builder{}
/*ii := pushStrPool.Get()
if ii == nil {
sb = &strings.Builder{}
} else {
sb = ii.(*strings.Builder)
sb.Reset()
}*/
sb.Grow(6 * (len(h.Scripts) + len(h.ScriptsAsync) + len(h.Stylesheets)))
push := func(in []c.HScript) {
for _, s := range in {
//fmt.Println("pushing /s/" + path)
sb.WriteString("/s/")
sb.WriteString(s.Name)
err := pusher.Push(sb.String(), nil)
if err != nil {
break
}
sb.Reset()
}
}
push(h.Scripts)
//push(h.PreScriptsAsync)
push(h.ScriptsAsync)
push(h.Stylesheets)
// TODO: Push avatars?
//pushStrPool.Put(sb)
}
}
func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, header *c.Header, pi interface{}) c.RouteError {
2022-02-21 03:32:53 +00:00
return renderTemplate2(tmplName, tmplName, w, r, header, pi)
}
initial perf anaytics add tasks to debug page ignore .git on debug page for speed add perfchunks table Renamed phrases (changed statistics to stats): panel_menu_stats panel_menu_stats_posts panel_menu_stats_topics panel_menu_stats_forums panel_menu_stats_routes panel_menu_stats_agents panel_menu_stats_systems panel_menu_stats_languages panel_menu_stats_referrers panel_menu_stats_memory panel_menu_stats_active_memory panel_menu_stats_perf panel_stats_views_head_suffix panel_stats_user_agents_head panel_stats_forums_head panel_stats_languages_head panel_stats_post_counts_head panel_stats_referrers_head panel_stats_routes_head panel_stats_operating_systems_head panel_stats_topic_counts_head panel_stats_requests_head panel_stats_memory_head panel_stats_active_memory_head panel_stats_spam_hide panel_stats_spam_show panel_stats_memory_type_total panel_stats_memory_type_stack panel_stats_memory_type_heap panel_stats_time_range_one_year panel_stats_time_range_three_months panel_stats_time_range_one_month panel_stats_time_range_one_week panel_stats_time_range_two_days panel_stats_time_range_one_day panel_stats_time_range_twelve_hours panel_stats_time_range_six_hours panel_stats_post_counts_chart_aria panel_stats_topic_counts_chart_aria panel_stats_requests_chart_aria panel_stats_memory_chart_aria panel_stats_details_head panel_stats_post_counts_table_aria panel_stats_topic_counts_table_aria panel_stats_route_views_table_aria panel_stats_requests_table_aria panel_stats_memory_table_aria panel_stats_views_suffix panel_stats_posts_suffix panel_stats_topics_suffix panel_stats_user_agents_no_user_agents panel_stats_forums_no_forums panel_stats_languages_no_languages panel_stats_post_counts_no_post_counts panel_stats_referrers_no_referrers panel_stats_routes_no_routes panel_stats_operating_systems_no_operating_systems panel_stats_memory_no_memory Added phrases: panel_debug_tasks panel_debug_tasks_half_second panel_debug_tasks_second panel_debug_tasks_fifteen_minute panel_debug_tasks_hour panel_debug_tasks_shutdown panel_stats_perf_head panel_stats_perf_low panel_stats_perf_high panel_stats_perf_avg You will need to run the updater / patcher for this commit.
2020-02-23 09:08:47 +00:00
func renderTemplate2(tmplName, hookName string, w http.ResponseWriter, r *http.Request, header *c.Header, pi interface{}) c.RouteError {
2022-02-21 03:32:53 +00:00
err := renderTemplate3(tmplName, tmplName, w, r, header, pi)
if err != nil {
return c.InternalError(err, w, r)
}
return nil
}
2020-03-18 09:45:36 +00:00
func FootHeaders(w http.ResponseWriter, h *c.Header) {
2022-02-21 03:32:53 +00:00
// TODO: Only set video domain when there is a video on the page
if !h.LooseCSP {
he := w.Header()
if c.Config.SslSchema {
if h.ExternalMedia {
he.Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'"+c.Config.ExtraCSPOrigins+"; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self' www.youtube-nocookie.com embed.nicovideo.jp;upgrade-insecure-requests")
} else {
he.Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'"+c.Config.ExtraCSPOrigins+"; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self';upgrade-insecure-requests")
}
} else {
if h.ExternalMedia {
he.Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'"+c.Config.ExtraCSPOrigins+"; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self' www.youtube-nocookie.com embed.nicovideo.jp")
} else {
he.Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'"+c.Config.ExtraCSPOrigins+"; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self'")
}
}
}
// Server pushes can backfire on certain browsers, so we want to make sure it's only triggered for ones where it'll help
lastAgent := h.CurrentUser.LastAgent
//fmt.Println("lastAgent:", lastAgent)
if lastAgent == c.Chrome || lastAgent == c.Firefox {
doPush(w, h)
}
}
initial perf anaytics add tasks to debug page ignore .git on debug page for speed add perfchunks table Renamed phrases (changed statistics to stats): panel_menu_stats panel_menu_stats_posts panel_menu_stats_topics panel_menu_stats_forums panel_menu_stats_routes panel_menu_stats_agents panel_menu_stats_systems panel_menu_stats_languages panel_menu_stats_referrers panel_menu_stats_memory panel_menu_stats_active_memory panel_menu_stats_perf panel_stats_views_head_suffix panel_stats_user_agents_head panel_stats_forums_head panel_stats_languages_head panel_stats_post_counts_head panel_stats_referrers_head panel_stats_routes_head panel_stats_operating_systems_head panel_stats_topic_counts_head panel_stats_requests_head panel_stats_memory_head panel_stats_active_memory_head panel_stats_spam_hide panel_stats_spam_show panel_stats_memory_type_total panel_stats_memory_type_stack panel_stats_memory_type_heap panel_stats_time_range_one_year panel_stats_time_range_three_months panel_stats_time_range_one_month panel_stats_time_range_one_week panel_stats_time_range_two_days panel_stats_time_range_one_day panel_stats_time_range_twelve_hours panel_stats_time_range_six_hours panel_stats_post_counts_chart_aria panel_stats_topic_counts_chart_aria panel_stats_requests_chart_aria panel_stats_memory_chart_aria panel_stats_details_head panel_stats_post_counts_table_aria panel_stats_topic_counts_table_aria panel_stats_route_views_table_aria panel_stats_requests_table_aria panel_stats_memory_table_aria panel_stats_views_suffix panel_stats_posts_suffix panel_stats_topics_suffix panel_stats_user_agents_no_user_agents panel_stats_forums_no_forums panel_stats_languages_no_languages panel_stats_post_counts_no_post_counts panel_stats_referrers_no_referrers panel_stats_routes_no_routes panel_stats_operating_systems_no_operating_systems panel_stats_memory_no_memory Added phrases: panel_debug_tasks panel_debug_tasks_half_second panel_debug_tasks_second panel_debug_tasks_fifteen_minute panel_debug_tasks_hour panel_debug_tasks_shutdown panel_stats_perf_head panel_stats_perf_low panel_stats_perf_high panel_stats_perf_avg You will need to run the updater / patcher for this commit.
2020-02-23 09:08:47 +00:00
func renderTemplate3(tmplName, hookName string, w http.ResponseWriter, r *http.Request, h *c.Header, pi interface{}) error {
2022-02-21 03:32:53 +00:00
s := h.Stylesheets
h.Stylesheets = nil
noDescSimpleBot := h.CurrentUser.LastAgent == c.SimpleBots[0] || h.CurrentUser.LastAgent == c.SimpleBots[1]
var simpleBot bool
for _, agent := range c.SimpleBots {
if h.CurrentUser.LastAgent == agent {
simpleBot = true
}
}
inner := r.FormValue("i") == "1"
if !inner && !simpleBot {
c.PrepResources(h.CurrentUser, h, h.Theme)
for _, ss := range s {
h.Stylesheets = append(h.Stylesheets, ss)
}
h.AddScript("global.js")
if h.CurrentUser.Loggedin {
h.AddScriptAsync("member.js")
}
} else {
h.CurrentUser.LastAgent = 0
}
if h.CurrentUser.Loggedin || inner || noDescSimpleBot {
h.MetaDesc = ""
h.OGDesc = ""
} else if h.MetaDesc != "" && h.OGDesc == "" {
h.OGDesc = h.MetaDesc
}
if !simpleBot {
FootHeaders(w, h)
} else {
h.GoogSiteVerify = ""
}
if h.Zone != "error" {
since := time.Duration(uutils.Nanotime() - h.StartedAt)
if h.CurrentUser.IsAdmin {
h.Elapsed1 = since.String()
}
co.PerfCounter.Push(since /*, false*/)
}
if c.RunPreRenderHook("pre_render_"+hookName, w, r, h.CurrentUser, pi) {
return nil
}
/*defer func() {
c.StrSlicePool.Put(h.Scripts)
c.StrSlicePool.Put(h.PreScriptsAsync)
}()*/
return h.Theme.RunTmpl(tmplName, pi, w)
}
// TODO: Rename renderTemplate to RenderTemplate instead of using this hack to avoid breaking things
var RenderTemplate = renderTemplate3
func actionSuccess(w http.ResponseWriter, r *http.Request, dest string, js bool) c.RouteError {
2022-02-21 03:32:53 +00:00
if !js {
http.Redirect(w, r, dest, http.StatusSeeOther)
} else {
_, _ = w.Write(successJSONBytes)
}
return nil
}