mirror of https://github.com/jlelse/GoBlog
Private mode
This commit is contained in:
parent
98e81875d4
commit
e25199b2a3
|
@ -15,7 +15,7 @@ var asContext = []string{"https://www.w3.org/ns/activitystreams"}
|
|||
|
||||
const asRequestKey requestContextKey = "asRequest"
|
||||
|
||||
func manipulateAsPath(next http.Handler) http.Handler {
|
||||
func checkActivityStreamsRequest(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
if ap := appConfig.ActivityPub; ap != nil && ap.Enabled {
|
||||
if lowerAccept := strings.ToLower(r.Header.Get("Accept")); (strings.Contains(lowerAccept, contentTypeAS) || strings.Contains(lowerAccept, "application/ld+json")) && !strings.Contains(lowerAccept, contentTypeHTML) {
|
||||
|
|
|
@ -20,6 +20,7 @@ type config struct {
|
|||
PathRedirects []*configRegexRedirect `mapstructure:"pathRedirects"`
|
||||
ActivityPub *configActivityPub `mapstructure:"activityPub"`
|
||||
Notifications *configNotifications `mapstructure:"notifications"`
|
||||
PrivateMode *configPrivateMode `mapstructure:"privateMode"`
|
||||
}
|
||||
|
||||
type configServer struct {
|
||||
|
@ -190,6 +191,10 @@ type configTelegram struct {
|
|||
InstantViewHash string `mapstructure:"instantViewHash"`
|
||||
}
|
||||
|
||||
type configPrivateMode struct {
|
||||
Enabled bool `mapstructure:"enabled"`
|
||||
}
|
||||
|
||||
var appConfig = &config{}
|
||||
|
||||
func initConfig() error {
|
||||
|
@ -255,6 +260,9 @@ func initConfig() error {
|
|||
}
|
||||
appConfig.Micropub.MediaStorage.MediaURL = strings.TrimSuffix(appConfig.Micropub.MediaStorage.MediaURL, "/")
|
||||
}
|
||||
if pm := appConfig.PrivateMode; pm != nil && pm.Enabled {
|
||||
appConfig.ActivityPub = &configActivityPub{Enabled: false}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
5
go.mod
5
go.mod
|
@ -44,6 +44,7 @@ require (
|
|||
github.com/spf13/viper v1.7.1
|
||||
github.com/tdewolff/minify/v2 v2.9.13
|
||||
github.com/tdewolff/parse/v2 v2.5.11 // indirect
|
||||
github.com/thoas/go-funk v0.7.1-0.20201128100912-5035611e402b
|
||||
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80
|
||||
github.com/vcraescu/go-paginator v1.0.1-0.20201114172518-2cfc59fe05c2
|
||||
github.com/yuin/goldmark v1.3.2
|
||||
|
@ -53,9 +54,9 @@ require (
|
|||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 // indirect
|
||||
golang.org/x/mod v0.4.1 // indirect
|
||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 // indirect
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 // indirect
|
||||
golang.org/x/sys v0.0.0-20210227040730-b0d1d43c014d // indirect
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
|
||||
golang.org/x/text v0.3.5 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
|
|
10
go.sum
10
go.sum
|
@ -288,6 +288,8 @@ github.com/tdewolff/parse/v2 v2.5.11 h1:Wq0x026IKZh9GPUB5Fp+v5bki/SNmpIkdltcnm6H
|
|||
github.com/tdewolff/parse/v2 v2.5.11/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
|
||||
github.com/tdewolff/test v1.0.6 h1:76mzYJQ83Op284kMT+63iCNCI7NEERsIN8dLM+RiKr4=
|
||||
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
github.com/thoas/go-funk v0.7.1-0.20201128100912-5035611e402b h1:EBnJBNE7sw2Z7dg2inKlTQNO2se7PvDejZQjNaPAjg8=
|
||||
github.com/thoas/go-funk v0.7.1-0.20201128100912-5035611e402b/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 h1:nrZ3ySNYwJbSpD6ce9duiP+QkD3JuLCcWkdaehUS/3Y=
|
||||
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFyPdL66DjUD96XmzVL3ZntbzcflLnznH0fr99w5VqE=
|
||||
|
@ -370,8 +372,8 @@ golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 h1:OgUuv8lsRpBibGNbSizVwKWlysjaNzmC9gYMhPVfqFM=
|
||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -404,8 +406,8 @@ golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073 h1:8qxJSnu+7dRq6upnbntrmriWByIakBuct5OM/MdQC1M=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210227040730-b0d1d43c014d h1:9fH9JvLNoSpsDWcXJ4dSE3lZW99Z3OCUZLr07g60U6o=
|
||||
golang.org/x/sys v0.0.0-20210227040730-b0d1d43c014d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
|
||||
|
|
124
http.go
124
http.go
|
@ -77,13 +77,21 @@ func reloadRouter() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
const paginationPath = "/page/{page:[0-9-]+}"
|
||||
const feedPath = ".{feed:rss|json|atom}"
|
||||
|
||||
func buildHandler() (http.Handler, error) {
|
||||
|
||||
paginationPath := "/page/{page:[0-9-]+}"
|
||||
feedPath := ".{feed:rss|json|atom}"
|
||||
|
||||
r := chi.NewRouter()
|
||||
|
||||
// Private mode
|
||||
privateMode := false
|
||||
privateModeHandler := []func(http.Handler) http.Handler{}
|
||||
if pm := appConfig.PrivateMode; pm != nil && pm.Enabled {
|
||||
privateMode = true
|
||||
privateModeHandler = append(privateModeHandler, authMiddleware)
|
||||
}
|
||||
|
||||
// Basic middleware
|
||||
if appConfig.Server.Logging {
|
||||
r.Use(logMiddleware)
|
||||
}
|
||||
|
@ -96,29 +104,37 @@ func buildHandler() (http.Handler, error) {
|
|||
if !appConfig.Cache.Enable {
|
||||
r.Use(middleware.NoCache)
|
||||
}
|
||||
|
||||
// No Index Header
|
||||
if privateMode {
|
||||
r.Use(noIndexHeader)
|
||||
}
|
||||
|
||||
// Login middleware etc.
|
||||
r.Use(checkIsLogin)
|
||||
r.Use(checkIsCaptcha)
|
||||
r.Use(checkLoggedIn)
|
||||
r.Use(checkActivityStreamsRequest)
|
||||
|
||||
// Logout
|
||||
r.With(authMiddleware).Get("/login", serveLogin)
|
||||
r.With(authMiddleware).Get("/logout", serveLogout)
|
||||
|
||||
// Micropub
|
||||
r.Route(micropubPath, func(mpRouter chi.Router) {
|
||||
mpRouter.Use(checkIndieAuth)
|
||||
mpRouter.Get("/", serveMicropubQuery)
|
||||
mpRouter.Post("/", serveMicropubPost)
|
||||
mpRouter.Post(micropubMediaSubPath, serveMicropubMedia)
|
||||
r.Route(micropubPath, func(r chi.Router) {
|
||||
r.Use(checkIndieAuth)
|
||||
r.Get("/", serveMicropubQuery)
|
||||
r.Post("/", serveMicropubPost)
|
||||
r.Post(micropubMediaSubPath, serveMicropubMedia)
|
||||
})
|
||||
|
||||
// IndieAuth
|
||||
r.Route("/indieauth", func(indieauthRouter chi.Router) {
|
||||
indieauthRouter.Get("/", indieAuthRequest)
|
||||
indieauthRouter.With(authMiddleware).Post("/accept", indieAuthAccept)
|
||||
indieauthRouter.Post("/", indieAuthVerification)
|
||||
indieauthRouter.Get("/token", indieAuthToken)
|
||||
indieauthRouter.Post("/token", indieAuthToken)
|
||||
r.Route("/indieauth", func(r chi.Router) {
|
||||
r.Get("/", indieAuthRequest)
|
||||
r.With(authMiddleware).Post("/accept", indieAuthAccept)
|
||||
r.Post("/", indieAuthVerification)
|
||||
r.Get("/token", indieAuthToken)
|
||||
r.Post("/token", indieAuthToken)
|
||||
})
|
||||
|
||||
// ActivityPub and stuff
|
||||
|
@ -132,9 +148,9 @@ func buildHandler() (http.Handler, error) {
|
|||
}
|
||||
|
||||
// Webmentions
|
||||
r.Route(webmentionPath, func(webmentionRouter chi.Router) {
|
||||
webmentionRouter.Post("/", handleWebmention)
|
||||
webmentionRouter.Group(func(r chi.Router) {
|
||||
r.Route(webmentionPath, func(r chi.Router) {
|
||||
r.Post("/", handleWebmention)
|
||||
r.Group(func(r chi.Router) {
|
||||
// Authenticated routes
|
||||
r.Use(authMiddleware)
|
||||
r.Get("/", webmentionAdmin)
|
||||
|
@ -159,7 +175,8 @@ func buildHandler() (http.Handler, error) {
|
|||
return nil, err
|
||||
}
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(manipulateAsPath, cacheMiddleware)
|
||||
r.Use(privateModeHandler...)
|
||||
r.Use(cacheMiddleware)
|
||||
for _, path := range pp {
|
||||
r.Get(path, servePost)
|
||||
}
|
||||
|
@ -171,7 +188,7 @@ func buildHandler() (http.Handler, error) {
|
|||
return nil, err
|
||||
}
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(authMiddleware, cacheMiddleware)
|
||||
r.Use(authMiddleware)
|
||||
for _, path := range dp {
|
||||
r.Get(path, servePost)
|
||||
}
|
||||
|
@ -183,6 +200,7 @@ func buildHandler() (http.Handler, error) {
|
|||
return nil, err
|
||||
}
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(privateModeHandler...)
|
||||
r.Use(cacheMiddleware)
|
||||
for _, path := range allPostAliases {
|
||||
r.Get(path, servePostAlias)
|
||||
|
@ -200,13 +218,13 @@ func buildHandler() (http.Handler, error) {
|
|||
}
|
||||
|
||||
// Media files
|
||||
r.Get(`/m/{file:[0-9a-fA-F]+(\.[0-9a-zA-Z]+)?}`, serveMediaFile)
|
||||
r.With(privateModeHandler...).Get(`/m/{file:[0-9a-fA-F]+(\.[0-9a-zA-Z]+)?}`, serveMediaFile)
|
||||
|
||||
// Captcha
|
||||
r.Handle("/captcha/*", captcha.Server(500, 250))
|
||||
|
||||
// Short paths
|
||||
r.With(cacheMiddleware).Get("/s/{id:[0-9a-fA-F]+}", redirectToLongPath)
|
||||
r.With(privateModeHandler...).With(cacheMiddleware).Get("/s/{id:[0-9a-fA-F]+}", redirectToLongPath)
|
||||
|
||||
for blog, blogConfig := range appConfig.Blogs {
|
||||
|
||||
|
@ -216,12 +234,9 @@ func buildHandler() (http.Handler, error) {
|
|||
blogPath = ""
|
||||
}
|
||||
|
||||
r.Group(func(r chi.Router) {
|
||||
|
||||
})
|
||||
|
||||
// Sections
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(privateModeHandler...)
|
||||
r.Use(cacheMiddleware)
|
||||
for _, section := range blogConfig.Sections {
|
||||
if section.Name != "" {
|
||||
|
@ -243,6 +258,7 @@ func buildHandler() (http.Handler, error) {
|
|||
return nil, err
|
||||
}
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(privateModeHandler...)
|
||||
r.Use(cacheMiddleware)
|
||||
r.Get(taxPath, serveTaxonomy(blog, taxonomy))
|
||||
for _, tv := range taxValues {
|
||||
|
@ -253,13 +269,13 @@ func buildHandler() (http.Handler, error) {
|
|||
r.Get(vPath+paginationPath, handler)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Photos
|
||||
if blogConfig.Photos != nil && blogConfig.Photos.Enabled {
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(privateModeHandler...)
|
||||
r.Use(cacheMiddleware)
|
||||
photoPath := blogPath + blogConfig.Photos.Path
|
||||
handler := servePhotos(blog, photoPath)
|
||||
|
@ -272,6 +288,7 @@ func buildHandler() (http.Handler, error) {
|
|||
// Search
|
||||
if blogConfig.Search != nil && blogConfig.Search.Enabled {
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(privateModeHandler...)
|
||||
r.Use(cacheMiddleware)
|
||||
searchPath := blogPath + blogConfig.Search.Path
|
||||
handler := serveSearch(blog, searchPath)
|
||||
|
@ -288,7 +305,7 @@ func buildHandler() (http.Handler, error) {
|
|||
// Stats
|
||||
if blogConfig.BlogStats != nil && blogConfig.BlogStats.Enabled {
|
||||
statsPath := blogPath + blogConfig.BlogStats.Path
|
||||
r.With(cacheMiddleware).Get(statsPath, serveBlogStats(blog, statsPath))
|
||||
r.With(privateModeHandler...).With(cacheMiddleware).Get(statsPath, serveBlogStats(blog, statsPath))
|
||||
}
|
||||
|
||||
// Year / month archives
|
||||
|
@ -297,6 +314,7 @@ func buildHandler() (http.Handler, error) {
|
|||
return nil, err
|
||||
}
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(privateModeHandler...)
|
||||
r.Use(cacheMiddleware)
|
||||
for _, d := range dates {
|
||||
// Year
|
||||
|
@ -334,19 +352,23 @@ func buildHandler() (http.Handler, error) {
|
|||
|
||||
// Blog
|
||||
if !blogConfig.PostAsHome {
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(privateModeHandler...)
|
||||
r.Use(cacheMiddleware)
|
||||
handler := serveHome(blog, blogPath)
|
||||
r.With(manipulateAsPath, cacheMiddleware).Get(fullBlogPath, handler)
|
||||
r.With(cacheMiddleware).Get(fullBlogPath+feedPath, handler)
|
||||
r.With(cacheMiddleware).Get(blogPath+paginationPath, handler)
|
||||
r.Get(fullBlogPath, handler)
|
||||
r.Get(fullBlogPath+feedPath, handler)
|
||||
r.Get(blogPath+paginationPath, handler)
|
||||
})
|
||||
}
|
||||
|
||||
// Custom pages
|
||||
for _, cp := range blogConfig.CustomPages {
|
||||
handler := serveCustomPage(blogConfig, cp)
|
||||
if cp.Cache {
|
||||
r.With(cacheMiddleware).Get(cp.Path, handler)
|
||||
r.With(privateModeHandler...).With(cacheMiddleware).Get(cp.Path, handler)
|
||||
} else {
|
||||
r.Get(cp.Path, handler)
|
||||
r.With(privateModeHandler...).Get(cp.Path, handler)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,20 +378,21 @@ func buildHandler() (http.Handler, error) {
|
|||
if randomPath == "" {
|
||||
randomPath = "/random"
|
||||
}
|
||||
r.Get(blogPath+randomPath, redirectToRandomPost(blog))
|
||||
r.With(privateModeHandler...).Get(blogPath+randomPath, redirectToRandomPost(blog))
|
||||
}
|
||||
|
||||
// Editor
|
||||
r.Route(blogPath+"/editor", func(mpRouter chi.Router) {
|
||||
mpRouter.Use(authMiddleware)
|
||||
mpRouter.Get("/", serveEditor(blog))
|
||||
mpRouter.Post("/", serveEditorPost(blog))
|
||||
r.Route(blogPath+"/editor", func(r chi.Router) {
|
||||
r.Use(authMiddleware)
|
||||
r.Get("/", serveEditor(blog))
|
||||
r.Post("/", serveEditorPost(blog))
|
||||
})
|
||||
|
||||
// Comments
|
||||
if commentsConfig := blogConfig.Comments; commentsConfig != nil && commentsConfig.Enabled {
|
||||
commentsPath := blogPath + "/comment"
|
||||
r.Route(commentsPath, func(cr chi.Router) {
|
||||
cr.Use(privateModeHandler...)
|
||||
cr.With(cacheMiddleware).Get("/{id:[0-9]+}", serveComment(blog))
|
||||
cr.With(captchaMiddleware).Post("/", createComment(blog, commentsPath))
|
||||
// Admin
|
||||
|
@ -385,10 +408,14 @@ func buildHandler() (http.Handler, error) {
|
|||
}
|
||||
|
||||
// Sitemap
|
||||
r.With(cacheMiddleware).Get(sitemapPath, serveSitemap)
|
||||
r.With(privateModeHandler...).With(cacheMiddleware).Get(sitemapPath, serveSitemap)
|
||||
|
||||
// Robots.txt - doesn't need cache, because it's too simple
|
||||
if !privateMode {
|
||||
r.Get("/robots.txt", serveRobotsTXT)
|
||||
} else {
|
||||
r.Get("/robots.txt", servePrivateRobotsTXT)
|
||||
}
|
||||
|
||||
// Check redirects, then serve 404
|
||||
r.With(cacheMiddleware, checkRegexRedirects).NotFound(serve404)
|
||||
|
@ -411,12 +438,19 @@ func securityHeaders(next http.Handler) http.Handler {
|
|||
extraCSPDomains += " " + strings.Join(appConfig.Server.CSPDomains, " ")
|
||||
}
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("Strict-Transport-Security", "max-age=31536000;")
|
||||
w.Header().Add("Referrer-Policy", "no-referrer")
|
||||
w.Header().Add("X-Content-Type-Options", "nosniff")
|
||||
w.Header().Add("X-Frame-Options", "SAMEORIGIN")
|
||||
w.Header().Add("X-Xss-Protection", "1; mode=block")
|
||||
w.Header().Add("Content-Security-Policy", "default-src 'self'"+extraCSPDomains)
|
||||
w.Header().Set("Strict-Transport-Security", "max-age=31536000;")
|
||||
w.Header().Set("Referrer-Policy", "no-referrer")
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
w.Header().Set("X-Frame-Options", "SAMEORIGIN")
|
||||
w.Header().Set("X-Xss-Protection", "1; mode=block")
|
||||
w.Header().Set("Content-Security-Policy", "default-src 'self'"+extraCSPDomains)
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func noIndexHeader(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("X-Robots-Tag", "noindex")
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -8,3 +8,7 @@ import (
|
|||
func serveRobotsTXT(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = w.Write([]byte(fmt.Sprintf("User-agent: *\nSitemap: %v", appConfig.Server.PublicAddress+sitemapPath)))
|
||||
}
|
||||
|
||||
func servePrivateRobotsTXT(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = w.Write([]byte("User-agent: *\nDisallow: /"))
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
<input type="password" name="password" placeholder="{{ string .Blog.Lang "password" }}">
|
||||
<input class="fw" type="submit" value="{{ string .Blog.Lang "login" }}">
|
||||
</form>
|
||||
{{ include "author" . }}
|
||||
</main>
|
||||
{{ end }}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/thoas/go-funk"
|
||||
"github.com/tomnomnom/linkheader"
|
||||
)
|
||||
|
||||
|
@ -19,11 +20,12 @@ func (p *post) sendWebmentions() error {
|
|||
return err
|
||||
}
|
||||
links = append(links, contentLinks...)
|
||||
links = append(links, p.firstParameter(appConfig.Micropub.LikeParam), p.firstParameter(appConfig.Micropub.ReplyParam), p.firstParameter(appConfig.Micropub.BookmarkParam))
|
||||
for _, link := range links {
|
||||
links = append(links, p.firstParameter("link"), p.firstParameter(appConfig.Micropub.LikeParam), p.firstParameter(appConfig.Micropub.ReplyParam), p.firstParameter(appConfig.Micropub.BookmarkParam))
|
||||
for _, link := range funk.UniqString(links) {
|
||||
if link == "" {
|
||||
continue
|
||||
}
|
||||
// Internal mention
|
||||
if strings.HasPrefix(link, appConfig.Server.PublicAddress) {
|
||||
// Save mention directly
|
||||
if err := createWebmention(p.fullURL(), link); err != nil {
|
||||
|
@ -31,6 +33,11 @@ func (p *post) sendWebmentions() error {
|
|||
}
|
||||
continue
|
||||
}
|
||||
// External mention
|
||||
if pm := appConfig.PrivateMode; pm != nil && pm.Enabled {
|
||||
// Private mode, don't send external mentions
|
||||
continue
|
||||
}
|
||||
endpoint := discoverEndpoint(link)
|
||||
if endpoint == "" {
|
||||
continue
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"github.com/joncrlsn/dque"
|
||||
|
@ -73,6 +74,10 @@ func (m *mention) verifyMention() error {
|
|||
return err
|
||||
}
|
||||
req.Header.Set(userAgent, appUserAgent)
|
||||
if strings.HasPrefix(m.Source, appConfig.Server.PublicAddress) {
|
||||
// Set authentication
|
||||
req.SetBasicAuth(appConfig.User.Nick, appConfig.User.Password)
|
||||
}
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in New Issue