Added an experimental content security policy.

Added support for Open Graph Descriptions.
Nox now officially supports notices.
Tweaked the language detection algorithm to cover more cases.
Tweaked the user agent parser to accomodate DotBot better.
Added a non-JS fallback for the theme selector.
Tweaked the padding on widget simple.
Scripts should now execute properly for individual language charts in the analytics panel.
This commit is contained in:
Azareal 2019-02-24 18:02:00 +10:00
parent 1fb497adf8
commit fe33112827
14 changed files with 63 additions and 8 deletions

View File

@ -33,7 +33,8 @@ type Header struct {
Path string
MetaDesc string
//OGImage string
//OGDesc string
OGDesc string
LooseCSP bool
StartedAt time.Time
Elapsed1 string
Writer http.ResponseWriter

View File

@ -85,6 +85,7 @@ type config struct {
DisableLiveTopicList bool
DisableJSAntispam bool
//LooseCSP bool
Noavatar string // ? - Move this into the settings table?
ItemsPerPage int // ? - Move this into the settings table?

View File

@ -768,7 +768,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
for _, item := range StringToBytes(ua) {
if (item > 64 && item < 91) || (item > 96 && item < 123) {
buffer = append(buffer, item)
} else if item == ' ' || item == '(' || item == ')' || item == '-' || (item > 47 && item < 58) || item == '_' || item == ';' || item == ':' || item == '.' || item == '+' || item == '~' || (item == ':' && bytes.Equal(buffer,[]byte("http"))) || item == ',' || item == '/' {
} else if item == ' ' || item == '(' || item == ')' || item == '-' || (item > 47 && item < 58) || item == '_' || item == ';' || item == ':' || item == '.' || item == '+' || item == '~' || item == '@' || (item == ':' && bytes.Equal(buffer,[]byte("http"))) || item == ',' || item == '/' {
if len(buffer) != 0 {
if len(buffer) > 2 {
// Use an unsafe zero copy conversion here just to use the switch, it's not safe for this string to escape from here, as it will get mutated, so do a regular string conversion in append
@ -862,8 +862,9 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if lang != "" {
lang = strings.TrimSpace(lang)
lLang := strings.Split(lang,"-")
common.DebugDetail("lLang:", lLang)
validCode := counters.LangViewCounter.Bump(lLang[0])
llLang := strings.Split(strings.Split(lLang[0],";")[0],",")
common.DebugDetail("llLang:", llLang)
validCode := counters.LangViewCounter.Bump(llLang[0])
if !validCode {
r.DumpRequest(req,"Invalid ISO Code")
}

View File

@ -560,7 +560,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
for _, item := range StringToBytes(ua) {
if (item > 64 && item < 91) || (item > 96 && item < 123) {
buffer = append(buffer, item)
} else if item == ' ' || item == '(' || item == ')' || item == '-' || (item > 47 && item < 58) || item == '_' || item == ';' || item == ':' || item == '.' || item == '+' || item == '~' || (item == ':' && bytes.Equal(buffer,[]byte("http"))) || item == ',' || item == '/' {
} else if item == ' ' || item == '(' || item == ')' || item == '-' || (item > 47 && item < 58) || item == '_' || item == ';' || item == ':' || item == '.' || item == '+' || item == '~' || item == '@' || (item == ':' && bytes.Equal(buffer,[]byte("http"))) || item == ',' || item == '/' {
if len(buffer) != 0 {
if len(buffer) > 2 {
// Use an unsafe zero copy conversion here just to use the switch, it's not safe for this string to escape from here, as it will get mutated, so do a regular string conversion in append
@ -654,8 +654,9 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if lang != "" {
lang = strings.TrimSpace(lang)
lLang := strings.Split(lang,"-")
common.DebugDetail("lLang:", lLang)
validCode := counters.LangViewCounter.Bump(lLang[0])
llLang := strings.Split(strings.Split(lLang[0],";")[0],",")
common.DebugDetail("llLang:", llLang)
validCode := counters.LangViewCounter.Bump(llLang[0])
if !validCode {
r.DumpRequest(req,"Invalid ISO Code")
}

View File

@ -200,6 +200,7 @@ func AccountRegister(w http.ResponseWriter, r *http.Request, user common.User, h
return common.LocalError("You're already logged in.", w, r, user)
}
header.Title = phrases.GetTitlePhrase("register")
header.LooseCSP = true
pi := common.Page{header, tList, nil}
return renderTemplate("register", w, r, header, pi)
}

View File

@ -21,6 +21,13 @@ func ParseSEOURL(urlBit string) (slug string, id int, err error) {
}
func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, header *common.Header, pi interface{}) common.RouteError {
if header.MetaDesc != "" && header.OGDesc == "" {
header.OGDesc = header.MetaDesc
}
// TODO: Expand this to non-HTTPS requests too
if !header.LooseCSP && common.Site.EnableSsl {
w.Header().Set("Content-Security-Policy", "default-src https: 'unsafe-eval'; style-src https: 'unsafe-eval' 'unsafe-inline'; img-src https: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; upgrade-insecure-requests")
}
if header.CurrentUser.IsAdmin {
header.Elapsed1 = time.Since(header.StartedAt).String()
}

View File

@ -52,6 +52,7 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user common.User, header
return common.InternalError(err, w, r)
}
header.Title = forum.Name
header.OGDesc = forum.Desc
// TODO: Does forum.TopicCount take the deleted items into consideration for guests? We don't have soft-delete yet, only hard-delete
offset, page, lastPage := common.PageOffset(forum.TopicCount, page, common.Config.ItemsPerPage)

View File

@ -31,6 +31,7 @@ func init() {
func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
// TODO: Preload this?
header.AddSheet(header.Theme.Name + "/profile.css")
header.LooseCSP = true
var err error
var replyCreatedAt time.Time

View File

@ -70,6 +70,11 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, header
topic.ContentHTML = common.ParseMessage(topic.Content, topic.ParentID, "forums")
topic.ContentLines = strings.Count(topic.Content, "\n")
header.OGDesc = topic.Content
if len(header.OGDesc) > 200 {
header.OGDesc = header.OGDesc[:197] + "..."
}
postGroup, err := common.Groups.Get(topic.Group)
if err != nil {
return common.InternalError(err, w, r)
@ -123,6 +128,10 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, header
// Get the replies if we have any...
if topic.PostCount > 0 {
var pFrag int
if strings.HasPrefix(r.URL.Fragment, "post-") {
pFrag, _ = strconv.Atoi(strings.TrimPrefix(r.URL.Fragment, "post-"))
}
var likedMap map[int]int
if user.Liked > 0 {
likedMap = make(map[int]int)
@ -156,6 +165,13 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, header
replyItem.ContentHtml = common.ParseMessage(replyItem.Content, topic.ParentID, "forums")
replyItem.ContentLines = strings.Count(replyItem.Content, "\n")
if replyItem.ID == pFrag {
header.OGDesc = replyItem.Content
if len(header.OGDesc) > 200 {
header.OGDesc = header.OGDesc[:197] + "..."
}
}
postGroup, err = common.Groups.Get(replyItem.Group)
if err != nil {
return common.InternalError(err, w, r)

View File

@ -17,6 +17,7 @@
{{if not .HideFromThemes}}<option val="{{.Name}}"{{if eq $.Header.Theme.Name .Name}} selected{{end}}>{{.FriendlyName}}</option>{{end}}
{{end}}
</select>
<noscript><input type="submit" /></noscript>
</div>
</form>
</div>

View File

@ -18,6 +18,8 @@
<meta property="og:site_name" content="{{.Header.Site.Name}}">
<meta property="og:title" content="{{.Title}} | {{.Header.Site.Name}}">
<meta name="twitter:title" content="{{.Title}} | {{.Header.Site.Name}}" />
{{if .OGDesc}}<meta property="og:description" content="{{.OGDesc}}" />
<meta property="twitter:description" content="{{.OGDesc}}" />{{end}}
</head>
<body>
{{if not .CurrentUser.IsSuperMod}}<style>.supermod_only { display: none !important; }</style>{{end}}

View File

@ -15,6 +15,5 @@
</div>
</main>
</div>
<script>
{{template "panel_analytics_script.html" . }}
{{template "footer.html" . }}

View File

@ -153,6 +153,12 @@ li a {
width: 100%;
}
.alert {
border-radius: 3px;
background-color: #444444;
padding: 12px;
}
.sidebar {
width: 320px;
}
@ -161,6 +167,9 @@ li a {
padding-top: 14px !important;
padding-bottom: 14px !important;
}
.widget_simple.rowhead .rowitem {
padding-bottom: 4px !important;
}
.the_form {
border-radius: 3px;
background-color: #444444;

View File

@ -26,4 +26,18 @@ $(document).ready(() => {
alerts.className += " selectedAlert";
document.getElementById("back").className += " alertActive"
});
// Move the alerts above the first header
let colSel = $(".colstack_right .colstack_head:first");
let colSelAlt = $(".colstack_right .colstack_item:first");
let colSelAltAlt = $(".colstack_right .coldyn_block:first");
if(colSel.length > 0) {
$('.alert').insertBefore(colSel);
} else if (colSelAlt.length > 0) {
$('.alert').insertBefore(colSelAlt);
} else if (colSelAltAlt.length > 0) {
$('.alert').insertBefore(colSelAltAlt);
} else {
$('.alert').insertAfter(".rowhead:first");
}
});