diff --git a/account.go b/account.go index 66a3fa0..357bae5 100644 --- a/account.go +++ b/account.go @@ -168,7 +168,7 @@ func signupWithRegistration(app *App, signup userRegistration, w http.ResponseWr } // Create actual user - if err := app.db.CreateUser(u, desiredUsername); err != nil { + if err := app.db.CreateUser(app.cfg, u, desiredUsername); err != nil { return nil, err } diff --git a/admin.go b/admin.go index 99e1672..fe19ad5 100644 --- a/admin.go +++ b/admin.go @@ -391,6 +391,7 @@ func handleAdminUpdateConfig(apper Apper, u *User, w http.ResponseWriter, r *htt if apper.App().cfg.App.UserInvites == "none" { apper.App().cfg.App.UserInvites = "" } + apper.App().cfg.App.DefaultVisibility = r.FormValue("default_visibility") m := "?cm=Configuration+saved." err = apper.SaveConfig(apper.App().cfg) diff --git a/app.go b/app.go index f8f7b11..d8ec70f 100644 --- a/app.go +++ b/app.go @@ -558,7 +558,7 @@ func DoConfig(app *App, configSections string) { // Create blog log.Info("Creating user %s...\n", u.Username) - err = app.db.CreateUser(u, app.cfg.App.SiteName) + err = app.db.CreateUser(app.cfg, u, app.cfg.App.SiteName) if err != nil { log.Error("Unable to create user: %s", err) os.Exit(1) @@ -753,7 +753,7 @@ func CreateUser(apper Apper, username, password string, isAdmin bool) error { userType = "admin" } log.Info("Creating %s %s...", userType, usernameDesc) - err = apper.App().db.CreateUser(u, desiredUsername) + err = apper.App().db.CreateUser(apper.App().Config(), u, desiredUsername) if err != nil { return fmt.Errorf("Unable to create user: %s", err) } diff --git a/collections.go b/collections.go index bccf2fb..4eb5606 100644 --- a/collections.go +++ b/collections.go @@ -31,6 +31,7 @@ import ( "github.com/writeas/web-core/log" waposts "github.com/writeas/web-core/posts" "github.com/writeas/writefreely/author" + "github.com/writeas/writefreely/config" "github.com/writeas/writefreely/page" ) @@ -126,6 +127,21 @@ const ( CollProtected ) +var collVisibilityStrings = map[string]collVisibility{ + "unlisted": CollUnlisted, + "public": CollPublic, + "private": CollPrivate, + "protected": CollProtected, +} + +func defaultVisibility(cfg *config.Config) collVisibility { + vis, ok := collVisibilityStrings[cfg.App.DefaultVisibility] + if !ok { + vis = CollUnlisted + } + return vis +} + func (cf *CollectionFormat) Ascending() bool { return cf.Format == "novel" } @@ -362,36 +378,32 @@ func newCollection(app *App, w http.ResponseWriter, r *http.Request) error { return impart.HTTPError{http.StatusBadRequest, fmt.Sprintf("Parameter(s) %srequired.", missingParams)} } + var userID int64 if reqJSON && !c.Web { accessToken = r.Header.Get("Authorization") if accessToken == "" { return ErrNoAccessToken } + userID = app.db.GetUserID(accessToken) + if userID == -1 { + return ErrBadAccessToken + } } else { u = getUserSession(app, r) if u == nil { return ErrNotLoggedIn } + userID = u.ID } if !author.IsValidUsername(app.cfg, c.Alias) { return impart.HTTPError{http.StatusPreconditionFailed, "Collection alias isn't valid."} } - var coll *Collection - var err error - if accessToken != "" { - coll, err = app.db.CreateCollectionFromToken(c.Alias, c.Title, accessToken) - if err != nil { - // TODO: handle this - return err - } - } else { - coll, err = app.db.CreateCollection(c.Alias, c.Title, u.ID) - if err != nil { - // TODO: handle this - return err - } + coll, err := app.db.CreateCollection(app.cfg, c.Alias, c.Title, userID) + if err != nil { + // TODO: handle this + return err } res := &CollectionObj{Collection: *coll} diff --git a/config/config.go b/config/config.go index 9a1db52..ae6af04 100644 --- a/config/config.go +++ b/config/config.go @@ -69,6 +69,7 @@ type ( WebFonts bool `ini:"webfonts"` Landing string `ini:"landing"` SimpleNav bool `ini:"simple_nav"` + WFModesty bool `ini:"wf_modesty"` Chorus bool `ini:"chorus"` // Users @@ -87,6 +88,9 @@ type ( // Additional functions LocalTimeline bool `ini:"local_timeline"` UserInvites string `ini:"user_invites"` + + // Defaults + DefaultVisibility string `ini:"default_visibility"` } // Config holds the complete configuration for running a writefreely instance diff --git a/database.go b/database.go index 05b38e8..77ae185 100644 --- a/database.go +++ b/database.go @@ -45,7 +45,7 @@ var ( ) type writestore interface { - CreateUser(*User, string) error + CreateUser(*config.Config, *User, string) error UpdateUserEmail(keys *key.Keychain, userID int64, email string) error UpdateEncryptedUserEmail(int64, []byte) error GetUserByID(int64) (*User, error) @@ -83,8 +83,8 @@ type writestore interface { GetOwnedPost(id string, ownerID int64) (*PublicPost, error) GetPostProperty(id string, collectionID int64, property string) (interface{}, error) - CreateCollectionFromToken(string, string, string) (*Collection, error) - CreateCollection(string, string, int64) (*Collection, error) + CreateCollectionFromToken(*config.Config, string, string, string) (*Collection, error) + CreateCollection(*config.Config, string, string, int64) (*Collection, error) GetCollectionBy(condition string, value interface{}) (*Collection, error) GetCollection(alias string) (*Collection, error) GetCollectionForPad(alias string) (*Collection, error) @@ -103,7 +103,7 @@ type writestore interface { CanCollect(cpr *ClaimPostRequest, userID int64) bool AttemptClaim(p *ClaimPostRequest, query string, params []interface{}, slugIdx int) (sql.Result, error) DispersePosts(userID int64, postIDs []string) (*[]ClaimPostResult, error) - ClaimPosts(userID int64, collAlias string, posts *[]ClaimPostRequest) (*[]ClaimPostResult, error) + ClaimPosts(cfg *config.Config, userID int64, collAlias string, posts *[]ClaimPostRequest) (*[]ClaimPostResult, error) GetPostsCount(c *CollectionObj, includeFuture bool) GetPosts(cfg *config.Config, c *Collection, page int, includeFuture, forceRecentFirst, includePinned bool) (*[]PublicPost, error) @@ -163,7 +163,7 @@ func (db *datastore) dateSub(l int, unit string) string { return fmt.Sprintf("DATE_SUB(NOW(), INTERVAL %d %s)", l, unit) } -func (db *datastore) CreateUser(u *User, collectionTitle string) error { +func (db *datastore) CreateUser(cfg *config.Config, u *User, collectionTitle string) error { if db.PostIDExists(u.Username) { return impart.HTTPError{http.StatusConflict, "Invalid collection name."} } @@ -197,7 +197,7 @@ func (db *datastore) CreateUser(u *User, collectionTitle string) error { if collectionTitle == "" { collectionTitle = u.Username } - res, err = t.Exec("INSERT INTO collections (alias, title, description, privacy, owner_id, view_count) VALUES (?, ?, ?, ?, ?, ?)", u.Username, collectionTitle, "", CollUnlisted, u.ID, 0) + res, err = t.Exec("INSERT INTO collections (alias, title, description, privacy, owner_id, view_count) VALUES (?, ?, ?, ?, ?, ?)", u.Username, collectionTitle, "", defaultVisibility(cfg), u.ID, 0) if err != nil { t.Rollback() if db.isDuplicateKeyErr(err) { @@ -239,13 +239,13 @@ func (db *datastore) UpdateEncryptedUserEmail(userID int64, encEmail []byte) err return nil } -func (db *datastore) CreateCollectionFromToken(alias, title, accessToken string) (*Collection, error) { +func (db *datastore) CreateCollectionFromToken(cfg *config.Config, alias, title, accessToken string) (*Collection, error) { userID := db.GetUserID(accessToken) if userID == -1 { return nil, ErrBadAccessToken } - return db.CreateCollection(alias, title, userID) + return db.CreateCollection(cfg, alias, title, userID) } func (db *datastore) GetUserCollectionCount(userID int64) (uint64, error) { @@ -262,13 +262,13 @@ func (db *datastore) GetUserCollectionCount(userID int64) (uint64, error) { return collCount, nil } -func (db *datastore) CreateCollection(alias, title string, userID int64) (*Collection, error) { +func (db *datastore) CreateCollection(cfg *config.Config, alias, title string, userID int64) (*Collection, error) { if db.PostIDExists(alias) { return nil, impart.HTTPError{http.StatusConflict, "Invalid collection name."} } // All good, so create new collection - res, err := db.Exec("INSERT INTO collections (alias, title, description, privacy, owner_id, view_count) VALUES (?, ?, ?, ?, ?, ?)", alias, title, "", CollUnlisted, userID, 0) + res, err := db.Exec("INSERT INTO collections (alias, title, description, privacy, owner_id, view_count) VALUES (?, ?, ?, ?, ?, ?)", alias, title, "", defaultVisibility(cfg), userID, 0) if err != nil { if db.isDuplicateKeyErr(err) { return nil, impart.HTTPError{http.StatusConflict, "Collection already exists."} @@ -282,6 +282,7 @@ func (db *datastore) CreateCollection(alias, title string, userID int64) (*Colle Title: title, OwnerID: userID, PublicOwner: false, + Public: defaultVisibility(cfg) == CollPublic, } c.ID, err = res.LastInsertId() @@ -1326,7 +1327,7 @@ func (db *datastore) DispersePosts(userID int64, postIDs []string) (*[]ClaimPost return &res, nil } -func (db *datastore) ClaimPosts(userID int64, collAlias string, posts *[]ClaimPostRequest) (*[]ClaimPostResult, error) { +func (db *datastore) ClaimPosts(cfg *config.Config, userID int64, collAlias string, posts *[]ClaimPostRequest) (*[]ClaimPostResult, error) { postClaimReqs := map[string]bool{} res := []ClaimPostResult{} postCollAlias := collAlias @@ -1383,7 +1384,7 @@ func (db *datastore) ClaimPosts(userID int64, collAlias string, posts *[]ClaimPo // This is a new collection // TODO: consider removing this. This seriously complicates this // method and adds another (unnecessary?) logic path. - coll, err = db.CreateCollection(postCollAlias, "", userID) + coll, err = db.CreateCollection(cfg, postCollAlias, "", userID) if err != nil { if err, ok := err.(impart.HTTPError); ok { r.Code = err.Status diff --git a/pad.go b/pad.go index 037a1f3..1545b4f 100644 --- a/pad.go +++ b/pad.go @@ -60,6 +60,10 @@ func handleViewPad(app *App, w http.ResponseWriter, r *http.Request) error { if action == "" && slug == "" { // Not editing any post; simply render the Pad + if templates[padTmpl] == nil { + log.Info("No template '%s' found. Falling back to default 'pad' template.", padTmpl) + padTmpl = "pad" + } if err = templates[padTmpl].ExecuteTemplate(w, "pad", appData); err != nil { log.Error("Unable to execute template: %v", err) } diff --git a/pages.go b/pages.go index e10227f..405b34f 100644 --- a/pages.go +++ b/pages.go @@ -65,9 +65,9 @@ func defaultPrivacyTitle() sql.NullString { func defaultAboutPage(cfg *config.Config) string { if cfg.App.Federation { - return `_` + cfg.App.SiteName + `_ is an interconnected place for you to write and publish, powered by WriteFreely and ActivityPub.` + return `_` + cfg.App.SiteName + `_ is an interconnected place for you to write and publish, powered by [WriteFreely](https://writefreely.org) and ActivityPub.` } - return `_` + cfg.App.SiteName + `_ is a place for you to write and publish, powered by WriteFreely.` + return `_` + cfg.App.SiteName + `_ is a place for you to write and publish, powered by [WriteFreely](https://writefreely.org).` } func defaultPrivacyPolicy(cfg *config.Config) string { diff --git a/pages/about.tmpl b/pages/about.tmpl index 0fae12b..7c502dc 100644 --- a/pages/about.tmpl +++ b/pages/about.tmpl @@ -12,6 +12,7 @@
{{.SiteName}} is home to {{largeNumFmt .AboutStats.NumPosts}} {{pluralize "article" "articles" .AboutStats.NumPosts}} across {{largeNumFmt .AboutStats.NumBlogs}} {{pluralize "blog" "blogs" .AboutStats.NumBlogs}}.
{{end}} + {{if not .WFModesty}}WriteFreely is a self-hosted, decentralized blogging platform for publishing beautiful, simple blogs.
It lets you publish a single blog, or host a community of writers who can create multiple blogs under one account. You can also enable federation, which allows people in the fediverse to follow your blog, bookmark your posts, and share them with others.
@@ -23,5 +24,6 @@ + {{end}} {{end}} diff --git a/posts.go b/posts.go index 9e5d42e..4a3688f 100644 --- a/posts.go +++ b/posts.go @@ -870,7 +870,7 @@ func addPost(app *App, w http.ResponseWriter, r *http.Request) error { collAlias := vars["alias"] // Update all given posts - res, err := app.db.ClaimPosts(ownerID, collAlias, claims) + res, err := app.db.ClaimPosts(app.cfg, ownerID, collAlias, claims) if err != nil { return err } diff --git a/templates/collection-tags.tmpl b/templates/collection-tags.tmpl index 6849fee..7cad3b7 100644 --- a/templates/collection-tags.tmpl +++ b/templates/collection-tags.tmpl @@ -141,7 +141,7 @@ function pinPost(e, postID, slug, title) { var $header = document.getElementsByTagName('header')[0]; var $pinnedNavs = $header.getElementsByTagName('nav'); // Add link to nav - var link = ''+title+''; + var link = ''+title+''; if ($pinnedNavs.length == 0) { $header.insertAdjacentHTML("beforeend", ''); } else { diff --git a/templates/collection.tmpl b/templates/collection.tmpl index 364ba15..36a266b 100644 --- a/templates/collection.tmpl +++ b/templates/collection.tmpl @@ -177,7 +177,7 @@ function pinPost(e, postID, slug, title) { var $header = document.getElementsByTagName('header')[0]; var $pinnedNavs = $header.getElementsByTagName('nav'); // Add link to nav - var link = ''+title+''; + var link = ''+title+''; if ($pinnedNavs.length == 0) { $header.insertAdjacentHTML("beforeend", ''); } else { diff --git a/templates/include/footer.tmpl b/templates/include/footer.tmpl index 32a7e68..16434b9 100644 --- a/templates/include/footer.tmpl +++ b/templates/include/footer.tmpl @@ -1,13 +1,21 @@ {{define "footer"}} -