From 7ca1e23acf4bdafce346afda587269d92714173e Mon Sep 17 00:00:00 2001 From: Ryan Stafford Date: Mon, 10 Jul 2023 11:53:15 -0400 Subject: [PATCH] csp and http only cookies --- public/style.css | 33 +++++++++------- public/utils.js | 85 +++++++++++++++++++++++++++------------- routes.go | 15 ++++--- templates/comment.html | 14 +++---- templates/frontpage.html | 6 +-- templates/main.html | 6 +-- templates/nav.html | 8 ++-- templates/post.html | 6 +-- templates/settings.html | 4 +- 9 files changed, 109 insertions(+), 68 deletions(-) diff --git a/public/style.css b/public/style.css index 32d6649..48bde5a 100644 --- a/public/style.css +++ b/public/style.css @@ -167,10 +167,10 @@ summary { .comment { font-size: 14px; - margin: 0px 0px 5px 15px; + margin: 0px 0px 5px 0px; border: 1px solid #e6e6e6; border-radius: 3px; - padding: 5px 10px 5px 7px; + padding: 10px 10px 0px 7px; } .dark .comment { border-color: #333; @@ -182,7 +182,6 @@ summary { max-height: 300px; } .comment .comment { - margin-left: 15px; } .comment .comment, .comment .comment .comment .comment, @@ -243,18 +242,21 @@ summary { } .commentmenu { font-size: 16px; - margin: 0px 0px 10px 10px; + margin: 0px 0px 10px 0px; } .commentmenu div { border-top: 1px dotted gray; font-size: 12px; } form.savecomment { - margin: 0px 0px 10px 10px; + margin: 0px 0px 10px 0px; } .comment > .children > form.savecomment { margin: 0px 0px 10px 20px; } +.comment .children { + margin: 5px 0px 10px 15px; +} .savecomment textarea { width: 500px; height: 100px; @@ -275,11 +277,13 @@ form.savecomment { font-style: italic; font-weight: 700; } -.comment.hidden .content, .comment.hidden .children { +.comment.hidden .content, .comment.hidden .children, .comment.hidden .morecomments { display: none; } +.children .morecomments { +} .morecomments { - margin: 10px 0px; + margin: 0px 0px 10px 0px; font-size: 10px; } .morecomments a { @@ -406,7 +410,7 @@ form.nsfw div { width: 100%; } .comment .buttons { - margin: 3px 0px 10px 0px; + margin: 3px 0px 0px 0px; } .comment.hidden .buttons { display: none; @@ -481,7 +485,7 @@ form.nsfw div { position: relative; color: #000; } -#settings { +#settingspopup { background-color: white; border: 1px solid #888; display: none; @@ -489,13 +493,13 @@ form.nsfw div { right: 10px; top: 45px; } -#settings form { +#settingspopup form { margin: 0px; } -.dark #settings { +.dark #settingspopup { background-color: #262626; } -#settings.open { +#settingspopup.open { display: inline-block; } .expando.open{ @@ -585,6 +589,7 @@ form.nsfw div { } main { position: relative; + margin: 0px 10px; } @media (min-width: 900px) { .side { @@ -594,8 +599,8 @@ main { right: 0; } main { - padding-right: 310px; - margin-left: 10px; + padding-right: 316px; + margin-right: 0px; } } .side form { diff --git a/public/utils.js b/public/utils.js index fa7b05f..cd42e34 100644 --- a/public/utils.js +++ b/public/utils.js @@ -29,8 +29,8 @@ function postClick(e) { bdy.className = 'expando open'; btn.className = "expando-button open" var url = targ.getElementsByClassName("url")[0].href - if (id = parse_youtube(url)) { - targ.getElementsByClassName("embed")[0].innerHTML = youtube_iframe(id) + if (id = parseYoutube(url)) { + targ.getElementsByClassName("embed")[0].innerHTML = youtubeIframe(id) } } } @@ -114,23 +114,26 @@ function loadMore(e) { request(window.location.origin+window.location.pathname+"?"+urlParams.toString(), "", function(res){ if (res.trim()) { - e.target.outerHTML = res + '' + e.target.outerHTML = res + '' if (showimages = document.getElementById("showimages")) { if (showimages.className == "selected") { - toggle_images(true) + toggleImages(true) } } var loadmore = document.getElementById("loadmore") - if (loadmore) loadmore.className = "show" - insert_youtube() + loadmore.className = "show" + loadmore.addEventListener("click", loadMore) + setup() } else { e.target.outerHTML = '' } }, function(res) { - e.target.outerHTML = '' - document.getElementById("loadmore").className = "show" + e.target.outerHTML = '' + var loadmore = document.getElementById("loadmore") + loadmore.className = "show" + loadmore.addEventListener("click", loadMore) } ) return false; @@ -177,9 +180,9 @@ function formSubmit(e) { return false } -function open_settings(e) { +function openSettings(e) { e.preventDefault() - var settings = document.getElementById("settings") + var settings = document.getElementById("settingspopup") settings.className = "open" request(e.target.href + "?xhr=1", "", function(res) { settings.innerHTML = res @@ -191,22 +194,23 @@ function open_settings(e) { input[0].checked = "checked" } } + document.getElementById("settings").addEventListener("submit", saveSettings) + document.getElementById("closesettings").addEventListener("click", closeSettings) }) return false } -function close_settings(e) { +function closeSettings(e) { e.preventDefault() - var settings = document.getElementById("settings") + var settings = document.getElementById("settingspopup") settings.className = "" return false } -function save_settings(e) { +function saveSettings(e) { e = e || window.event; var targ = e.currentTarget || e.srcElement || e; var data = new FormData(targ) - console.log(data) e.preventDefault() var params = new URLSearchParams(data).toString() request(targ.target, params, function(res) { @@ -218,7 +222,7 @@ function save_settings(e) { return false; } -function parse_youtube(url){ +function parseYoutube(url){ if (url.indexOf("youtu") == -1) return false var regExp = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/|shorts\/)|(?:(?:watch)?\?v(?:i)?=|\&v(?:i)?=))([^#\&\?]*).*/; var match = url.match(regExp); @@ -227,27 +231,26 @@ function parse_youtube(url){ } return false } -function youtube_iframe(id) { +function youtubeIframe(id) { return '' } -function show_images(e) { +function showImages(e) { e = e || window.event; e.preventDefault() var targ = e.currentTarget || e.srcElement || e; - console.log(targ) var parent = targ.parentNode if (parent.className == "") { parent.className = "selected" - toggle_images(true) + toggleImages(true) } else { parent.className = "" - toggle_images(false) + toggleImages(false) } return false } -function toggle_images(open) { +function toggleImages(open) { var posts = document.getElementsByClassName("post") for (var i = 0; i < posts.length; i++) { var btn = posts[i].getElementsByClassName("expando-button")[0] @@ -265,27 +268,48 @@ function toggle_images(open) { } } -function insert_youtube() { +function setup() { + if (showimages = document.getElementById("se")) { + showimages.addEventListener("click", showImages) + } + if (settings = document.getElementById("opensettings")) { + settings.addEventListener("click", openSettings) + } + if (hidechildren = document.getElementById("hidechildren")){ + hidechildren.addEventListener("click", hideAllChildComments) + } var posts = document.getElementsByClassName("post") for (var i = 0; i < posts.length; i++) { + posts[i].addEventListener("click", postClick) + var voteForm = posts[i].getElementsByClassName("link-btn") + if (voteForm.length) { + voteForm[0].addEventListener("submit", formSubmit) + } var url = posts[i].getElementsByClassName("url")[0].href - if (id = parse_youtube(url)) { + if (id = parseYoutube(url)) { var btn = posts[i].getElementsByClassName("expando-button")[0] if (btn.className.indexOf("open") > -1) { - posts[i].getElementsByClassName("embed")[0].innerHTML = youtube_iframe(id) + posts[i].getElementsByClassName("embed")[0].innerHTML = youtubeIframe(id) } else { btn.className = "expando-button" } } } + var comments = document.getElementsByClassName("comment") + for (var i = 0; i < comments.length; i++) { + comments[i].addEventListener("click", commentClick) + } } -insert_youtube() +setup() if (localStorage.getItem("endlessScrolling") == "true") { var pager = document.getElementsByClassName("pager") if (pager.length) pager[0].className = "pager hidden" var loadmore = document.getElementById("loadmore") - if (loadmore) loadmore.className = "show" + if (loadmore) { + loadmore.className = "show" + loadmore.addEventListener("click", loadMore) + } if (localStorage.getItem("autoLoad") == "true") { window.onscroll = function(e) { @@ -299,4 +323,11 @@ if (localStorage.getItem("endlessScrolling") == "true") { } } - +// delete cookies without HTTPOnly +var cookies = document.cookie.split(";"); +for (var i = 0; i < cookies.length; i++) { + var cookie = cookies[i]; + var eqPos = cookie.indexOf("="); + var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie; + document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT;SameSite=None;Secure"; +} diff --git a/routes.go b/routes.go index c32c9a4..7fe49eb 100644 --- a/routes.go +++ b/routes.go @@ -194,7 +194,7 @@ func Initialize(Host string, r *http.Request) (State, error) { token := getCookie(r, "jwt") user := getCookie(r, "user") parts := strings.Split(user, ":") - if len(parts) == 2 { + if len(parts) == 2 && token != "" { if id, err := strconv.Atoi(parts[1]); err == nil { state.Client.Token = token sess := Session{ @@ -248,6 +248,8 @@ func Render(w http.ResponseWriter, templateName string, state State) { if state.Status != http.StatusOK { w.WriteHeader(state.Status) } + header := w.Header() + header.Set("Content-Security-Policy", "script-src 'self'") err = tmpl.Execute(w, state) if err != nil { fmt.Println("execute fail", err) @@ -504,10 +506,13 @@ func setCookie(w http.ResponseWriter, host string, name string, value string) { host = "" } cookie := http.Cookie{ - Name: name, - Value: value, - MaxAge: 86400 * 30, - Path: "/" + host, + Name: name, + Value: value, + MaxAge: 86400 * 30, + HttpOnly: true, + SameSite: http.SameSiteNoneMode, + Secure: true, + Path: "/" + host, } http.SetCookie(w, &cookie) } diff --git a/templates/comment.html b/templates/comment.html index 3533ac2..956445f 100644 --- a/templates/comment.html +++ b/templates/comment.html @@ -1,5 +1,4 @@ -
-
+
{{ if .State.Session }}
{{ end }} + {{ if ne .P.Counts.ChildCount .ChildCount}} -
- load more comments - ({{ sub .P.Counts.ChildCount .ChildCount}} replies) -
+
+ load more comments + ({{ sub .P.Counts.ChildCount .ChildCount}} replies) +
{{end}} +
diff --git a/templates/frontpage.html b/templates/frontpage.html index f2c504e..deecf9f 100644 --- a/templates/frontpage.html +++ b/templates/frontpage.html @@ -2,7 +2,7 @@ {{ if and .Community (ne .Community.CommunityView.Community.Title "")}}{{.Community.CommunityView.Community.Title}}{{else if ne .CommunityName ""}}/c/{{.CommunityName}}{{ else if .User}}overview for {{.User.PersonView.Person.Name}}{{else}}{{ host .Host }}{{end}} - + @@ -50,12 +50,12 @@
view more: {{if gt .Page 1 }}‹ prev{{ end }} next ›
- + {{ end }} {{ template "sidebar.html" . }} {{ end }} - + diff --git a/templates/main.html b/templates/main.html index acdaae4..4d71963 100644 --- a/templates/main.html +++ b/templates/main.html @@ -3,7 +3,7 @@ {{if and .Posts .PostID }}{{ (index .Posts 0).Post.Name}} : {{.CommunityName}}{{else if and .Community (ne .Community.CommunityView.Community.Title "")}}{{.Community.CommunityView.Community.Title}}{{else if ne .CommunityName ""}}/c/{{.CommunityName}}{{ else if .User}}overview for {{.User.PersonView.Person.Name}}{{else}}{{ host .Host }}{{end}} - +
-
+
@@ -66,7 +66,7 @@ new comments top {{ if .Posts }} -
  • show images
  • +
  • show images
  • {{ end }} {{ end }} diff --git a/templates/post.html b/templates/post.html index c0763ec..e0d9fcf 100644 --- a/templates/post.html +++ b/templates/post.html @@ -1,12 +1,12 @@ {{ if ne .State.Op "vote_post" }} -
    +
    {{ if gt .Rank 0 }}
    {{ .Rank }}
    {{ end }}
    {{ end }} {{ if .State.Session }} - {{end}} {{ if .State.PostID }} - hide all child comments + hide all child comments {{ end }}
    diff --git a/templates/settings.html b/templates/settings.html index a0406a2..6793ee9 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -61,7 +61,7 @@
    {{.Error}}
    {{ end }} {{ end }} -
    +