Merge remote-tracking branch 'upstream/master' into localhost_custom

This commit is contained in:
localhost_frssoft 2023-11-06 12:07:24 +03:00
commit ab58d8a900
9 changed files with 46 additions and 44 deletions

View file

@ -38,5 +38,4 @@ post_formats=PlainText:text/plain,HTML:text/html,Markdown:text/markdown,BBCode:t
# single_instance=pl.mydomain.com
# Path to custom CSS. Value can be a file path relative to the static directory.
# or a URL starting with either "http://" or "https://".
# custom_css=custom.css

View file

@ -8,7 +8,6 @@ import (
"net/http"
"os"
"path/filepath"
"strings"
"bloat/config"
"bloat/renderer"
@ -47,14 +46,8 @@ func main() {
errExit(err)
}
customCSS := config.CustomCSS
if len(customCSS) > 0 && !strings.HasPrefix(customCSS, "http://") &&
!strings.HasPrefix(customCSS, "https://") {
customCSS = "/static/" + customCSS
}
s := service.NewService(config.ClientName, config.ClientScope,
config.ClientWebsite, customCSS, config.SingleInstance,
config.ClientWebsite, config.CustomCSS, config.SingleInstance,
config.PostFormats, renderer)
handler := service.NewHandler(s, *verbose, config.StaticDirectory)

View file

@ -1,7 +1,6 @@
package model
type Session struct {
ID string `json:"id,omitempty"`
UserID string `json:"uid,omitempty"`
Instance string `json:"ins,omitempty"`
ClientID string `json:"cid,omitempty"`
@ -30,6 +29,7 @@ type Settings struct {
InstanceEmojiFilter string `json:"iemojfilter,omitempty"`
AddReactionsFilter string `json:"reactionfilter,omitempty"`
CSS string `json:"css,omitempty"`
CSSHash string `json:"cssh,omitempty"`
}
func NewSettings() *Settings {
@ -48,5 +48,6 @@ func NewSettings() *Settings {
InstanceEmojiFilter: "",
AddReactionsFilter: "",
CSS: "",
CSSHash: "",
}
}

View file

@ -34,6 +34,8 @@ func (c *client) setSession(sess *model.Session) error {
}
http.SetCookie(c.w, &http.Cookie{
Name: "session",
Path: "/",
HttpOnly: true,
Value: sb.String(),
Expires: time.Now().Add(365 * 24 * time.Hour),
})
@ -53,6 +55,7 @@ func (c *client) getSession() (sess *model.Session, err error) {
func (c *client) unsetSession() {
http.SetCookie(c.w, &http.Cookie{
Name: "session",
Path: "/",
Value: "",
Expires: time.Now(),
})

View file

@ -1,6 +1,8 @@
package service
import (
"crypto/sha256"
"encoding/base64"
"errors"
"fmt"
"mime/multipart"
@ -936,10 +938,6 @@ func (s *service) NewSession(c *client, instance string) (rurl string, sess *mod
instanceURL = "https://" + instance
}
sid, err := util.NewSessionID()
if err != nil {
return
}
csrf, err := util.NewCSRFToken()
if err != nil {
return
@ -955,28 +953,14 @@ func (s *service) NewSession(c *client, instance string) (rurl string, sess *mod
if err != nil {
return
}
rurl = app.AuthURI
sess = &model.Session{
ID: sid,
Instance: instance,
ClientID: app.ClientID,
ClientSecret: app.ClientSecret,
CSRFToken: csrf,
Settings: *model.NewSettings(),
}
u, err := url.Parse("/oauth/authorize")
if err != nil {
return
}
q := make(url.Values)
q.Set("scope", "read write follow")
q.Set("client_id", app.ClientID)
q.Set("response_type", "code")
q.Set("redirect_uri", s.cwebsite+"/oauth_callback")
u.RawQuery = q.Encode()
rurl = instanceURL + u.String()
return
}
@ -1213,9 +1197,19 @@ func (s *service) SaveSettings(c *client, settings *model.Settings) (err error)
default:
return errInvalidArgument
}
if len(settings.CSS) > 0 {
if len(settings.CSS) > 1<<20 {
return errInvalidArgument
}
// For some reason, browsers convert CRLF to LF before calculating
// the hash of the inline resources.
settings.CSS = strings.Replace(settings.CSS, "\x0d\x0a", "\x0a", -1)
h := sha256.Sum256([]byte(settings.CSS))
settings.CSSHash = base64.StdEncoding.EncodeToString(h[:])
} else {
settings.CSSHash = ""
}
c.s.Settings = *settings
return c.setSession(c.s)
}

View file

@ -26,6 +26,15 @@ const (
CSRF
)
const csp = "default-src 'none';" +
" img-src *;" +
" media-src *;" +
" font-src *;" +
" child-src *;" +
" connect-src 'self';" +
" script-src 'self';" +
" style-src 'self'"
func NewHandler(s *service, verbose bool, staticDir string) http.Handler {
r := mux.NewRouter()
@ -58,14 +67,14 @@ func NewHandler(s *service, verbose bool, staticDir string) http.Handler {
}(time.Now())
}
var ct string
h := c.w.Header()
switch rt {
case HTML:
ct = "text/html; charset=utf-8"
h.Set("Content-Type", "text/html; charset=utf-8")
h.Set("Content-Security-Policy", csp)
case JSON:
ct = "application/json"
h.Set("Content-Type", "application/json")
}
c.w.Header().Add("Content-Type", ct)
err = c.authenticate(at, s.instance)
if err != nil {
@ -73,6 +82,13 @@ func NewHandler(s *service, verbose bool, staticDir string) http.Handler {
return
}
// Override the CSP header to allow custom CSS
if rt == HTML && len(c.s.Settings.CSS) > 0 &&
len(c.s.Settings.CSSHash) > 0 {
v := fmt.Sprintf("%s 'sha256-%s'", csp, c.s.Settings.CSSHash)
h.Set("Content-Security-Policy", v)
}
err = f(c)
if err != nil {
writeError(c, err, rt, req.Method == http.MethodGet)

View file

@ -326,7 +326,7 @@ document.addEventListener("DOMContentLoaded", function() {
links[j].target = "_blank";
}
var links = document.querySelectorAll(".status-media-container .img-link");
var links = document.querySelectorAll(".status-media-container .img-link, .user-profile-img-container .img-link");
for (var j = 0; j < links.length; j++) {
handleImgPreview(links[j]);
}

View file

@ -20,7 +20,7 @@
<title> {{if gt .Count 0}}({{.Count}}){{end}} {{.Title}} </title>
<link rel="stylesheet" href="/static/style.css">
{{if .CustomCSS}}
<link rel="stylesheet" href="{{.CustomCSS}}">
<link rel="stylesheet" href="/static/{{.CustomCSS}}">
{{end}}
{{if $.Ctx.FluorideMode}}
<script src="/static/fluoride.js"></script>

View file

@ -16,10 +16,6 @@ func NewRandID(n int) (string, error) {
return enc.EncodeToString(data), nil
}
func NewSessionID() (string, error) {
return NewRandID(24)
}
func NewCSRFToken() (string, error) {
return NewRandID(24)
}