diff --git a/account.go b/account.go index 0a6c4ae..5f10fe4 100644 --- a/account.go +++ b/account.go @@ -1028,9 +1028,10 @@ func viewStats(app *App, u *User, w http.ResponseWriter, r *http.Request) error if c.OwnerID != u.ID { return ErrCollectionNotFound } + c.hostName = app.cfg.App.Host } - topPosts, err := app.db.GetTopPosts(u, alias) + topPosts, err := app.db.GetTopPosts(u, alias, c.hostName) if err != nil { log.Error("Unable to get top posts: %v", err) return err diff --git a/app.go b/app.go index 9a72dc9..149eb4b 100644 --- a/app.go +++ b/app.go @@ -30,7 +30,7 @@ import ( "github.com/gorilla/schema" "github.com/gorilla/sessions" "github.com/manifoldco/promptui" - stripmd "github.com/writeas/go-strip-markdown" + stripmd "github.com/writeas/go-strip-markdown/v2" "github.com/writeas/impart" "github.com/writeas/web-core/auth" "github.com/writeas/web-core/converter" @@ -56,7 +56,7 @@ var ( debugging bool // Software version can be set from git env using -ldflags - softwareVer = "0.13.0" + softwareVer = "0.13.1" // DEPRECATED VARS isSingleUser bool @@ -808,7 +808,7 @@ func connectToDatabase(app *App) { os.Exit(1) } db, err = sql.Open("sqlite3_with_regex", app.cfg.Database.FileName+"?parseTime=true&cached=shared") - db.SetMaxOpenConns(1) + db.SetMaxOpenConns(2) } else { log.Error("Invalid database type '%s'. Only 'mysql' and 'sqlite3' are supported right now.", app.cfg.Database.Type) os.Exit(1) diff --git a/collections.go b/collections.go index 4f1cfad..0840743 100644 --- a/collections.go +++ b/collections.go @@ -247,6 +247,8 @@ func (c *Collection) DisplayCanonicalURL() string { return d + p } +// RedirectingCanonicalURL returns the fully-qualified canonical URL for the Collection, with a trailing slash. The +// hostName field needs to be populated for this to work correctly. func (c *Collection) RedirectingCanonicalURL(isRedir bool) string { if c.hostName == "" { // If this is true, the human programmers screwed up. So ask for a bug report and fail, fail, fail diff --git a/database.go b/database.go index 2232652..07bc109 100644 --- a/database.go +++ b/database.go @@ -77,7 +77,7 @@ type writestore interface { GetMeStats(u *User) userMeStats GetTotalCollections() (int64, error) GetTotalPosts() (int64, error) - GetTopPosts(u *User, alias string) (*[]PublicPost, error) + GetTopPosts(u *User, alias string, hostName string) (*[]PublicPost, error) GetAnonymousPosts(u *User, page int) (*[]PublicPost, error) GetUserPosts(u *User) (*[]PublicPost, error) @@ -1803,7 +1803,7 @@ func (db *datastore) GetTotalPosts() (postCount int64, err error) { return } -func (db *datastore) GetTopPosts(u *User, alias string) (*[]PublicPost, error) { +func (db *datastore) GetTopPosts(u *User, alias string, hostName string) (*[]PublicPost, error) { params := []interface{}{u.ID} where := "" if alias != "" { @@ -1838,6 +1838,7 @@ func (db *datastore) GetTopPosts(u *User, alias string) (*[]PublicPost, error) { c.Title = title.String c.Description = description.String c.Views = views.Int64 + c.hostName = hostName pubPost.Collection = &CollectionObj{Collection: c} } diff --git a/feed.go b/feed.go index 32c6591..d85baf8 100644 --- a/feed.go +++ b/feed.go @@ -17,7 +17,7 @@ import ( . "github.com/gorilla/feeds" "github.com/gorilla/mux" - stripmd "github.com/writeas/go-strip-markdown" + stripmd "github.com/writeas/go-strip-markdown/v2" "github.com/writeas/web-core/log" ) diff --git a/go.mod b/go.mod index 9a6616b..72c74da 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,7 @@ module github.com/writefreely/writefreely require ( + git.mills.io/prologic/go-gopher v0.0.0-20210712135410-b7ebb55feece github.com/PuerkitoBio/goquery v1.7.0 // indirect github.com/aymerick/douceur v0.2.0 github.com/clbanning/mxj v1.8.4 // indirect @@ -32,7 +33,6 @@ require ( github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d github.com/onsi/ginkgo v1.16.4 // indirect github.com/onsi/gomega v1.13.0 // indirect - github.com/prologic/go-gopher v0.0.0-20200721020712-3e11dcff0469 github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be // indirect github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 // indirect github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c // indirect @@ -40,7 +40,6 @@ require ( github.com/urfave/cli/v2 v2.3.0 github.com/writeas/activity v0.1.2 github.com/writeas/activityserve v0.0.0-20200409150223-d7ab3eaa4481 - github.com/writeas/go-strip-markdown v2.0.1+incompatible github.com/writeas/go-strip-markdown/v2 v2.1.1 github.com/writeas/go-webfinger v1.1.0 github.com/writeas/httpsig v1.0.0 diff --git a/go.sum b/go.sum index 007047b..106e978 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ code.as/core/socks v1.0.0 h1:SPQXNp4SbEwjOAP9VzUahLHak8SDqy5n+9cm9tpjZOs= code.as/core/socks v1.0.0/go.mod h1:BAXBy5O9s2gmw6UxLqNJcVbWY7C/UPs+801CcSsfWOY= +git.mills.io/prologic/go-gopher v0.0.0-20210712135410-b7ebb55feece h1:0esmnntqeuM1iBgHH0HOeSynsLA1l28p2K3h/WZuIfQ= +git.mills.io/prologic/go-gopher v0.0.0-20210712135410-b7ebb55feece/go.mod h1:EMXlYOIbYJQhPTtIltgaaHtCYDawV/HL0dYf8ShzAck= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/PuerkitoBio/goquery v1.7.0 h1:O5SP3b9JWqMSVMG69zMfj577zwkSNpxrFf7ybS74eiw= github.com/PuerkitoBio/goquery v1.7.0/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= @@ -151,8 +153,6 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prologic/go-gopher v0.0.0-20200721020712-3e11dcff0469 h1:rAbv2gekFbUcjhUkruwo0vMJ0JqhUgg9tz7t+bxHbN4= -github.com/prologic/go-gopher v0.0.0-20200721020712-3e11dcff0469/go.mod h1:c61IFFAJw8ADWu54tti30Tj5VrBstVoTprmET35UEkY= github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be h1:ta7tUOvsPHVHGom5hKW5VXNc2xZIkfCKP8iaqOyYtUQ= github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be/go.mod h1:MIDFMn7db1kT65GmV94GzpX9Qdi7N/pQlwb+AN8wh+Q= github.com/rogpeppe/go-internal v1.3.2 h1:XU784Pr0wdahMY2bYcyK6N1KuaRAdLtqD4qd8D18Bfs= @@ -168,7 +168,6 @@ github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:X github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= @@ -177,8 +176,6 @@ github.com/writeas/activity v0.1.2 h1:Y12B5lIrabfqKE7e7HFCWiXrlfXljr9tlkFm2mp7Dg github.com/writeas/activity v0.1.2/go.mod h1:mYYgiewmEM+8tlifirK/vl6tmB2EbjYaxwb+ndUw5T0= github.com/writeas/activityserve v0.0.0-20200409150223-d7ab3eaa4481 h1:BiSivIxLQFcKoUorpNN3rNwwFG5bITPnqUSyIccfdh0= github.com/writeas/activityserve v0.0.0-20200409150223-d7ab3eaa4481/go.mod h1:4akDJSl+sSp+QhrQKMqzAqdV1gJ1pPx6XPI77zgMM8o= -github.com/writeas/go-strip-markdown v2.0.1+incompatible h1:IIqxTM5Jr7RzhigcL6FkrCNfXkvbR+Nbu1ls48pXYcw= -github.com/writeas/go-strip-markdown v2.0.1+incompatible/go.mod h1:Rsyu10ZhbEK9pXdk8V6MVnZmTzRG0alMNLMwa0J01fE= github.com/writeas/go-strip-markdown/v2 v2.1.1 h1:hAxUM21Uhznf/FnbVGiJciqzska6iLei22Ijc3q2e28= github.com/writeas/go-strip-markdown/v2 v2.1.1/go.mod h1:UvvgPJgn1vvN8nWuE5e7v/+qmDu3BSVnKAB6Gl7hFzA= github.com/writeas/go-webfinger v1.1.0 h1:MzNyt0ry/GMsRmJGftn2o9mPwqK1Q5MLdh4VuJCfb1Q= diff --git a/gopher.go b/gopher.go index f87d85c..7d86632 100644 --- a/gopher.go +++ b/gopher.go @@ -18,7 +18,7 @@ import ( "regexp" "strings" - "github.com/prologic/go-gopher" + "git.mills.io/prologic/go-gopher" "github.com/writeas/web-core/log" ) diff --git a/handle.go b/handle.go index 1cbf114..d746feb 100644 --- a/handle.go +++ b/handle.go @@ -20,8 +20,8 @@ import ( "strings" "time" + "git.mills.io/prologic/go-gopher" "github.com/gorilla/sessions" - "github.com/prologic/go-gopher" "github.com/writeas/impart" "github.com/writeas/web-core/log" "github.com/writefreely/writefreely/config" diff --git a/oauth_generic.go b/oauth_generic.go index ba8b97e..ccf6a0f 100644 --- a/oauth_generic.go +++ b/oauth_generic.go @@ -1,8 +1,20 @@ +/* + * Copyright © 2020-2021 A Bunch Tell LLC and respective authors. + * + * This file is part of WriteFreely. + * + * WriteFreely is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, included + * in the LICENSE file in this source code package. + */ + package writefreely import ( "context" "errors" + "fmt" + "github.com/writeas/web-core/log" "net/http" "net/url" "strings" @@ -118,6 +130,10 @@ func (c genericOauthClient) inspectOauthAccessToken(ctx context.Context, accessT // map each relevant field in inspectResponse to the mapped field from the config var inspectResponse InspectResponse inspectResponse.UserID, _ = genericInterface[c.MapUserID].(string) + if inspectResponse.UserID == "" { + log.Error("[CONFIGURATION ERROR] Generic OAuth provider returned empty UserID value (`%s`).\n Do you need to configure a different `map_user_id` value for this provider?", c.MapUserID) + return nil, fmt.Errorf("no UserID (`%s`) value returned", c.MapUserID) + } inspectResponse.Username, _ = genericInterface[c.MapUsername].(string) inspectResponse.DisplayName, _ = genericInterface[c.MapDisplayName].(string) inspectResponse.Email, _ = genericInterface[c.MapEmail].(string) diff --git a/postrender.go b/postrender.go index 8e71109..13bf02e 100644 --- a/postrender.go +++ b/postrender.go @@ -11,6 +11,7 @@ package writefreely import ( + "bytes" "encoding/json" "fmt" "html" @@ -23,7 +24,7 @@ import ( "unicode/utf8" "github.com/microcosm-cc/bluemonday" - stripmd "github.com/writeas/go-strip-markdown" + stripmd "github.com/writeas/go-strip-markdown/v2" "github.com/writeas/impart" blackfriday "github.com/writeas/saturday" "github.com/writeas/web-core/log" @@ -181,6 +182,10 @@ func applyMarkdownSpecial(data []byte, skipNoFollow bool, baseURL string, cfg *c } func applyBasicMarkdown(data []byte) string { + if len(bytes.TrimSpace(data)) == 0 { + return "" + } + mdExtensions := 0 | blackfriday.EXTENSION_STRIKETHROUGH | blackfriday.EXTENSION_SPACE_HEADERS | @@ -191,7 +196,12 @@ func applyBasicMarkdown(data []byte) string { blackfriday.HTML_SMARTYPANTS_DASHES // Generate Markdown - md := blackfriday.Markdown([]byte(data), blackfriday.HtmlRenderer(htmlFlags, "", ""), mdExtensions) + // This passes the supplied title into blackfriday.Markdown() as an H1 header, so we only render HTML that + // belongs in an H1. + md := blackfriday.Markdown(append([]byte("# "), data...), blackfriday.HtmlRenderer(htmlFlags, "", ""), mdExtensions) + // Remove H1 markup + md = bytes.TrimSpace(md) // blackfriday.Markdown adds a newline at the end of the

+ md = md[len("

") : len(md)-len("

")] // Strip out bad HTML policy := bluemonday.UGCPolicy() policy.AllowAttrs("class", "id").Globally() diff --git a/postrender_test.go b/postrender_test.go new file mode 100644 index 0000000..531c0f1 --- /dev/null +++ b/postrender_test.go @@ -0,0 +1,43 @@ +/* + * Copyright © 2021 A Bunch Tell LLC. + * + * This file is part of WriteFreely. + * + * WriteFreely is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, included + * in the LICENSE file in this source code package. + */ + +package writefreely + +import "testing" + +func TestApplyBasicMarkdown(t *testing.T) { + tests := []struct { + name string + in string + result string + }{ + {"empty", "", ""}, + {"empty spaces", " ", ""}, + {"empty tabs", "\t", ""}, + {"empty newline", "\n", ""}, + {"nums", "123", "123"}, + {"dot", ".", "."}, + {"dash", "-", "-"}, + {"plain", "Hello, World!", "Hello, World!"}, + {"multibyte", "こんにちは", `こんにちは`}, + {"bold", "**안녕하세요**", `안녕하세요`}, + {"link", "[WriteFreely](https://writefreely.org)", `WriteFreely`}, + {"date", "12. April", `12. April`}, + {"table", "| Hi | There |", `| Hi | There |`}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + res := applyBasicMarkdown([]byte(test.in)) + if res != test.result { + t.Errorf("%s: wanted %s, got %s", test.name, test.result, res) + } + }) + } +} diff --git a/posts.go b/posts.go index 9da0975..ef460ef 100644 --- a/posts.go +++ b/posts.go @@ -27,7 +27,7 @@ import ( "github.com/guregu/null/zero" "github.com/kylemcc/twitter-text-go/extract" "github.com/microcosm-cc/bluemonday" - stripmd "github.com/writeas/go-strip-markdown" + stripmd "github.com/writeas/go-strip-markdown/v2" "github.com/writeas/impart" "github.com/writeas/monday" "github.com/writeas/slug" @@ -235,7 +235,7 @@ func (p Post) Summary() string { } p.Content = stripHTMLWithoutEscaping(p.Content) // and Markdown - p.Content = stripmd.Strip(p.Content) + p.Content = stripmd.StripOptions(p.Content, stripmd.Options{SkipImages: true}) title := p.Title.String var desc string @@ -1487,7 +1487,7 @@ func viewCollectionPost(app *App, w http.ResponseWriter, r *http.Request) error if slug == "feed" { // User tried to access blog feed without a trailing slash, and // there's no post with a slug "feed" - return impart.HTTPError{http.StatusFound, c.CanonicalURL() + "/feed/"} + return impart.HTTPError{http.StatusFound, c.CanonicalURL() + "feed/"} } po := &Post{ diff --git a/prose/prose.js b/prose/prose.js index 3096c9e..ae8b3ce 100644 --- a/prose/prose.js +++ b/prose/prose.js @@ -40,13 +40,7 @@ class ProseMirrorView { $title.value = title; } - const doc = writeFreelyMarkdownParser.parse( - // Replace all "solo" \n's with \\\n for correct markdown parsing - // Can't use lookahead or lookbehind because it's not supported on Safari - content.replace(/([^]{0,1})(\n)([^]{0,1})/g, (match, p1, p2, p3) => { - return p1 !== "\n" && p3 !== "\n" ? p1 + "\\\n" + p3 : match; - }) - ); + const doc = writeFreelyMarkdownParser.parse(content) this.view = new EditorView(target, { state: EditorState.create({ diff --git a/read.go b/read.go index 35a671f..f2706a9 100644 --- a/read.go +++ b/read.go @@ -21,7 +21,7 @@ import ( . "github.com/gorilla/feeds" "github.com/gorilla/mux" - stripmd "github.com/writeas/go-strip-markdown" + stripmd "github.com/writeas/go-strip-markdown/v2" "github.com/writeas/impart" "github.com/writeas/web-core/log" "github.com/writeas/web-core/memo"