diff --git a/README.md b/README.md
index 4f0b6bb..68da89b 100644
--- a/README.md
+++ b/README.md
@@ -47,15 +47,15 @@ It's designed to be flexible and share your writing widely, so it's built around
## Hosting
-We offer two kinds of hosting services that make WriteFreely deployment painless: [Write.as](https://write.as) for individuals, and [WriteFreely.host](https://writefreely.host) for communities. Besides saving you time, as a customer you directly help fund WriteFreely development.
+We offer two kinds of hosting services that make WriteFreely deployment painless: [Write.as Pro](https://write.as/pro) for individuals, and [Write.as for Teams](https://write.as/for/teams) for businesses. Besides saving you time and effort, both services directly fund WriteFreely development and ensure the long-term sustainability of our open source work.
-### [![Write.as](https://write.as/img/writeas-wf-readme.png)](https://write.as/)
+### [![Write.as Pro](https://writefreely.org/img/writeas-pro-readme.png)](https://write.as/pro)
-Start a personal blog on [Write.as](https://write.as), our flagship instance. Built to eliminate setup friction and preserve your privacy, Write.as helps you start a blog in seconds. It supports custom domains (with SSL) and multiple blogs / pen names per account. [Read more here](https://write.as/pricing).
+Start a personal blog on [Write.as](https://write.as), our flagship instance. Built to eliminate setup friction and preserve your privacy, Write.as helps you start a blog in seconds. It supports custom domains (with SSL) and multiple blogs / pen names per account. [Read more here](https://write.as/pro).
-### [![WriteFreely.host](https://writefreely.host/img/wfhost-wf-readme.png)](https://writefreely.host)
+### [![Write.as for Teams](https://writefreely.org/img/writeas-for-teams-readme.png)](https://write.as/for/teams)
-[WriteFreely.host](https://writefreely.host) makes it easy to start a close-knit community — to share knowledge, complement your Mastodon instance, or publish updates in your organization. We take care of the hosting, upgrades, backups, and maintenance so you can focus on writing.
+[Write.as for Teams](https://write.as/for/teams) gives your organization, business, or [open source project](https://write.as/for/open-source) a clutter-free space to share updates or proposals and build your collective knowledge. We take care of hosting, upgrades, backups, and maintenance so your team can focus on writing.
## Quick start
diff --git a/account.go b/account.go
index 5fb87f0..c41f24d 100644
--- a/account.go
+++ b/account.go
@@ -85,7 +85,7 @@ func apiSignup(app *App, w http.ResponseWriter, r *http.Request) error {
}
func signup(app *App, w http.ResponseWriter, r *http.Request) (*AuthUser, error) {
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
// Get params
var ur userRegistration
@@ -120,7 +120,7 @@ func signup(app *App, w http.ResponseWriter, r *http.Request) (*AuthUser, error)
}
func signupWithRegistration(app *App, signup userRegistration, w http.ResponseWriter, r *http.Request) (*AuthUser, error) {
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
// Validate required params (alias)
if signup.Alias == "" {
@@ -377,7 +377,7 @@ func webLogin(app *App, w http.ResponseWriter, r *http.Request) error {
var loginAttemptUsers = sync.Map{}
func login(app *App, w http.ResponseWriter, r *http.Request) error {
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
oneTimeToken := r.FormValue("with")
verbose := r.FormValue("all") == "true" || r.FormValue("verbose") == "1" || r.FormValue("verbose") == "true" || (reqJSON && oneTimeToken != "")
@@ -580,7 +580,7 @@ func viewExportOptions(app *App, u *User, w http.ResponseWriter, r *http.Request
func viewExportPosts(app *App, w http.ResponseWriter, r *http.Request) ([]byte, string, error) {
var filename string
var u = &User{}
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
if reqJSON {
// Use given Authorization header
accessToken := r.Header.Get("Authorization")
@@ -625,7 +625,7 @@ func viewExportPosts(app *App, w http.ResponseWriter, r *http.Request) ([]byte,
// Export as CSV
if strings.HasSuffix(r.URL.Path, ".csv") {
- data = exportPostsCSV(u, posts)
+ data = exportPostsCSV(app.cfg.App.Host, u, posts)
return data, filename, err
}
if strings.HasSuffix(r.URL.Path, ".zip") {
@@ -662,7 +662,7 @@ func viewExportFull(app *App, w http.ResponseWriter, r *http.Request) ([]byte, s
}
func viewMeAPI(app *App, w http.ResponseWriter, r *http.Request) error {
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
uObj := struct {
ID int64 `json:"id,omitempty"`
Username string `json:"username,omitempty"`
@@ -686,7 +686,7 @@ func viewMeAPI(app *App, w http.ResponseWriter, r *http.Request) error {
}
func viewMyPostsAPI(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
if !reqJSON {
return ErrBadRequestedType
}
@@ -717,7 +717,7 @@ func viewMyPostsAPI(app *App, u *User, w http.ResponseWriter, r *http.Request) e
}
func viewMyCollectionsAPI(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
if !reqJSON {
return ErrBadRequestedType
}
@@ -842,7 +842,7 @@ func viewEditCollection(app *App, u *User, w http.ResponseWriter, r *http.Reques
}
func updateSettings(app *App, w http.ResponseWriter, r *http.Request) error {
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
var s userSettings
var u *User
diff --git a/activitypub.go b/activitypub.go
index eeaa1fa..a18a636 100644
--- a/activitypub.go
+++ b/activitypub.go
@@ -415,11 +415,11 @@ func handleFetchCollectionInbox(app *App, w http.ResponseWriter, r *http.Request
// Add follower locally, since it wasn't found before
res, err := t.Exec("INSERT INTO remoteusers (actor_id, inbox, shared_inbox) VALUES (?, ?, ?)", fullActor.ID, fullActor.Inbox, fullActor.Endpoints.SharedInbox)
if err != nil {
- if !app.db.isDuplicateKeyErr(err) {
- t.Rollback()
- log.Error("Couldn't add new remoteuser in DB: %v\n", err)
- return
- }
+ // if duplicate key, res will be nil and panic on
+ // res.LastInsertId below
+ t.Rollback()
+ log.Error("Couldn't add new remoteuser in DB: %v\n", err)
+ return
}
followerID, err = res.LastInsertId()
diff --git a/admin.go b/admin.go
index e624bfb..ebb4225 100644
--- a/admin.go
+++ b/admin.go
@@ -16,12 +16,14 @@ import (
"net/http"
"runtime"
"strconv"
+ "strings"
"time"
"github.com/gorilla/mux"
"github.com/writeas/impart"
"github.com/writeas/web-core/auth"
"github.com/writeas/web-core/log"
+ "github.com/writeas/web-core/passgen"
"github.com/writeas/writefreely/appstats"
"github.com/writeas/writefreely/config"
)
@@ -170,11 +172,12 @@ func handleViewAdminUser(app *App, u *User, w http.ResponseWriter, r *http.Reque
Config config.AppCfg
Message string
- User *User
- Colls []inspectedCollection
- LastPost string
-
- TotalPosts int64
+ User *User
+ Colls []inspectedCollection
+ LastPost string
+ NewPassword string
+ TotalPosts int64
+ ClearEmail string
}{
Config: app.cfg.App,
Message: r.FormValue("m"),
@@ -186,6 +189,14 @@ func handleViewAdminUser(app *App, u *User, w http.ResponseWriter, r *http.Reque
if err != nil {
return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not get user: %v", err)}
}
+
+ flashes, _ := getSessionFlashes(app, w, r, nil)
+ for _, flash := range flashes {
+ if strings.HasPrefix(flash, "SUCCESS: ") {
+ p.NewPassword = strings.TrimPrefix(flash, "SUCCESS: ")
+ p.ClearEmail = p.User.EmailClear(app.keys)
+ }
+ }
p.UserPage = NewUserPage(app, r, u, p.User.Username, nil)
p.TotalPosts = app.db.GetUserPostsCount(p.User.ID)
lp, err := app.db.GetUserLastPostTime(p.User.ID)
@@ -254,6 +265,38 @@ func handleAdminToggleUserStatus(app *App, u *User, w http.ResponseWriter, r *ht
return impart.HTTPError{http.StatusFound, fmt.Sprintf("/admin/user/%s#status", username)}
}
+func handleAdminResetUserPass(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
+ vars := mux.Vars(r)
+ username := vars["username"]
+ if username == "" {
+ return impart.HTTPError{http.StatusFound, "/admin/users"}
+ }
+
+ // Generate new random password since none supplied
+ pass := passgen.NewWordish()
+ hashedPass, err := auth.HashPass([]byte(pass))
+ if err != nil {
+ return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not create password hash: %v", err)}
+ }
+
+ userIDVal := r.FormValue("user")
+ log.Info("ADMIN: Changing user %s password", userIDVal)
+ id, err := strconv.Atoi(userIDVal)
+ if err != nil {
+ return impart.HTTPError{http.StatusBadRequest, fmt.Sprintf("Invalid user ID: %v", err)}
+ }
+
+ err = app.db.ChangePassphrase(int64(id), true, "", hashedPass)
+ if err != nil {
+ return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not update passphrase: %v", err)}
+ }
+ log.Info("ADMIN: Successfully changed.")
+
+ addSessionFlash(app, w, r, fmt.Sprintf("SUCCESS: %s", pass), nil)
+
+ return impart.HTTPError{http.StatusFound, fmt.Sprintf("/admin/user/%s", username)}
+}
+
func handleViewAdminPages(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
p := struct {
*UserPage
diff --git a/app.go b/app.go
index 514c7c8..9b01bc6 100644
--- a/app.go
+++ b/app.go
@@ -56,7 +56,7 @@ var (
debugging bool
// Software version can be set from git env using -ldflags
- softwareVer = "0.10.0"
+ softwareVer = "0.11.0"
// DEPRECATED VARS
isSingleUser bool
diff --git a/collections.go b/collections.go
index 3e86f30..54ddc8a 100644
--- a/collections.go
+++ b/collections.go
@@ -339,7 +339,7 @@ func (c *Collection) RenderMathJax() bool {
}
func newCollection(app *App, w http.ResponseWriter, r *http.Request) error {
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
alias := r.FormValue("alias")
title := r.FormValue("title")
@@ -464,7 +464,7 @@ func fetchCollection(app *App, w http.ResponseWriter, r *http.Request) error {
c.hostName = app.cfg.App.Host
// Redirect users who aren't requesting JSON
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
if !reqJSON {
return impart.HTTPError{http.StatusFound, c.CanonicalURL()}
}
@@ -943,7 +943,7 @@ func handleCollectionPostRedirect(app *App, w http.ResponseWriter, r *http.Reque
}
func existingCollection(app *App, w http.ResponseWriter, r *http.Request) error {
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
vars := mux.Vars(r)
collAlias := vars["alias"]
isWeb := r.FormValue("web") == "1"
diff --git a/export.go b/export.go
index 3b5ac49..592bc0c 100644
--- a/export.go
+++ b/export.go
@@ -20,7 +20,7 @@ import (
"github.com/writeas/web-core/log"
)
-func exportPostsCSV(u *User, posts *[]PublicPost) []byte {
+func exportPostsCSV(hostName string, u *User, posts *[]PublicPost) []byte {
var b bytes.Buffer
r := [][]string{
@@ -30,8 +30,9 @@ func exportPostsCSV(u *User, posts *[]PublicPost) []byte {
var blog string
if p.Collection != nil {
blog = p.Collection.Alias
+ p.Collection.hostName = hostName
}
- f := []string{p.ID, p.Slug.String, blog, p.CanonicalURL(), p.Created8601(), p.Title.String, strings.Replace(p.Content, "\n", "\\n", -1)}
+ f := []string{p.ID, p.Slug.String, blog, p.CanonicalURL(hostName), p.Created8601(), p.Title.String, strings.Replace(p.Content, "\n", "\\n", -1)}
r = append(r, f)
}
diff --git a/go.mod b/go.mod
index 9c67aeb..88af8c9 100644
--- a/go.mod
+++ b/go.mod
@@ -45,7 +45,7 @@ require (
github.com/writeas/openssl-go v1.0.0 // indirect
github.com/writeas/saturday v1.7.1
github.com/writeas/slug v1.2.0
- github.com/writeas/web-core v1.0.0
+ github.com/writeas/web-core v1.2.0
github.com/writefreely/go-nodeinfo v1.2.0
golang.org/x/crypto v0.0.0-20190208162236-193df9c0f06f
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1 // indirect
diff --git a/go.sum b/go.sum
index ec1e19d..b256223 100644
--- a/go.sum
+++ b/go.sum
@@ -135,6 +135,8 @@ github.com/writeas/slug v1.2.0 h1:EMQ+cwLiOcA6EtFwUgyw3Ge18x9uflUnOnR6bp/J+/g=
github.com/writeas/slug v1.2.0/go.mod h1:RE8shOqQP3YhsfsQe0L3RnuejfQ4Mk+JjY5YJQFubfQ=
github.com/writeas/web-core v1.0.0 h1:5VKkCakQgdKZcbfVKJXtRpc5VHrkflusCl/KRCPzpQ0=
github.com/writeas/web-core v1.0.0/go.mod h1:Si3chV7VWgY8CsV+3gRolMXSO2Vx1ZFAQ/mkrpvmyEE=
+github.com/writeas/web-core v1.2.0 h1:CYqvBd+byi1cK4mCr1NZ6CjILuMOFmiFecv+OACcmG0=
+github.com/writeas/web-core v1.2.0/go.mod h1:vTYajviuNBAxjctPp2NUYdgjofywVkxUGpeaERF3SfI=
github.com/writefreely/go-nodeinfo v1.2.0 h1:La+YbTCvmpTwFhBSlebWDDL81N88Qf/SCAvRLR7F8ss=
github.com/writefreely/go-nodeinfo v1.2.0/go.mod h1:UTvE78KpcjYOlRHupZIiSEFcXHioTXuacCbHU+CAcPg=
golang.org/x/crypto v0.0.0-20180527072434-ab813273cd59 h1:hk3yo72LXLapY9EXVttc3Z1rLOxT9IuAPPX3GpY2+jo=
diff --git a/handle.go b/handle.go
index 99c23ae..7e410f5 100644
--- a/handle.go
+++ b/handle.go
@@ -772,7 +772,7 @@ func (h *Handler) handleError(w http.ResponseWriter, r *http.Request, err error)
return
}
- if IsJSON(r.Header.Get("Content-Type")) {
+ if IsJSON(r) {
impart.WriteError(w, impart.HTTPError{http.StatusInternalServerError, "This is an unhelpful error message for a miscellaneous internal error."})
return
}
diff --git a/posts.go b/posts.go
index 6974a4f..2a6fe74 100644
--- a/posts.go
+++ b/posts.go
@@ -483,7 +483,7 @@ func handleViewPost(app *App, w http.ResponseWriter, r *http.Request) error {
// /posts?collection={alias}
// ? /collections/{alias}/posts
func newPost(app *App, w http.ResponseWriter, r *http.Request) error {
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
vars := mux.Vars(r)
collAlias := vars["alias"]
if collAlias == "" {
@@ -617,7 +617,7 @@ func newPost(app *App, w http.ResponseWriter, r *http.Request) error {
}
func existingPost(app *App, w http.ResponseWriter, r *http.Request) error {
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
vars := mux.Vars(r)
postID := vars["post"]
@@ -1118,9 +1118,9 @@ func (p *Post) processPost() PublicPost {
return *res
}
-func (p *PublicPost) CanonicalURL() string {
+func (p *PublicPost) CanonicalURL(hostName string) string {
if p.Collection == nil || p.Collection.Alias == "" {
- return p.Collection.hostName + "/" + p.ID
+ return hostName + "/" + p.ID
}
return p.Collection.CanonicalURL() + p.Slug.String
}
@@ -1129,7 +1129,7 @@ func (p *PublicPost) ActivityObject(cfg *config.Config) *activitystreams.Object
o := activitystreams.NewArticleObject()
o.ID = p.Collection.FederatedAPIBase() + "api/posts/" + p.ID
o.Published = p.Created
- o.URL = p.CanonicalURL()
+ o.URL = p.CanonicalURL(cfg.App.Host)
o.AttributedTo = p.Collection.FederatedAccount()
o.CC = []string{
p.Collection.FederatedAccount() + "/followers",
diff --git a/read.go b/read.go
index 6d0c8a7..d708121 100644
--- a/read.go
+++ b/read.go
@@ -295,7 +295,7 @@ func viewLocalTimelineFeed(app *App, w http.ResponseWriter, req *http.Request) e
}
title = p.PlainDisplayTitle()
- permalink = p.CanonicalURL()
+ permalink = p.CanonicalURL(app.cfg.App.Host)
if p.Collection != nil {
author = p.Collection.Title
} else {
diff --git a/request.go b/request.go
index 4939f9c..2eb29f5 100644
--- a/request.go
+++ b/request.go
@@ -10,9 +10,13 @@
package writefreely
-import "mime"
+import (
+ "mime"
+ "net/http"
+)
-func IsJSON(h string) bool {
- ct, _, _ := mime.ParseMediaType(h)
- return ct == "application/json"
+func IsJSON(r *http.Request) bool {
+ ct, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
+ accept := r.Header.Get("Accept")
+ return ct == "application/json" || accept == "application/json"
}
diff --git a/routes.go b/routes.go
index 1ff250f..64c6c0f 100644
--- a/routes.go
+++ b/routes.go
@@ -145,6 +145,7 @@ func InitRoutes(apper Apper, r *mux.Router) *mux.Router {
write.HandleFunc("/admin/users", handler.Admin(handleViewAdminUsers)).Methods("GET")
write.HandleFunc("/admin/user/{username}", handler.Admin(handleViewAdminUser)).Methods("GET")
write.HandleFunc("/admin/user/{username}/status", handler.Admin(handleAdminToggleUserStatus)).Methods("POST")
+ write.HandleFunc("/admin/user/{username}/passphrase", handler.Admin(handleAdminResetUserPass)).Methods("POST")
write.HandleFunc("/admin/pages", handler.Admin(handleViewAdminPages)).Methods("GET")
write.HandleFunc("/admin/page/{slug}", handler.Admin(handleViewAdminPage)).Methods("GET")
write.HandleFunc("/admin/update/config", handler.AdminApper(handleAdminUpdateConfig)).Methods("POST")
diff --git a/templates/chorus-collection-post.tmpl b/templates/chorus-collection-post.tmpl
index 58e514f..a6b6102 100644
--- a/templates/chorus-collection-post.tmpl
+++ b/templates/chorus-collection-post.tmpl
@@ -8,7 +8,7 @@
-
+
@@ -25,7 +25,7 @@
-
+
{{range .Images}} {{else}} {{end}}
@@ -80,7 +80,7 @@ article time.dt-published {
{{if .PinnedPosts}}
- {{range .PinnedPosts}}{{.PlainDisplayTitle}} {{end}}
+ {{range .PinnedPosts}}{{.PlainDisplayTitle}} {{end}}
{{end}}
diff --git a/templates/chorus-collection.tmpl b/templates/chorus-collection.tmpl
index 5f4d418..504e54f 100644
--- a/templates/chorus-collection.tmpl
+++ b/templates/chorus-collection.tmpl
@@ -71,7 +71,7 @@ body#collection header nav.tabs a:first-child {
{{/*end*/}}
{{if .PinnedPosts}}
- {{range .PinnedPosts}}{{.PlainDisplayTitle}} {{end}}
+ {{range .PinnedPosts}}{{.PlainDisplayTitle}} {{end}}
{{end}}
diff --git a/templates/collection-post.tmpl b/templates/collection-post.tmpl
index 4398804..e24c6dd 100644
--- a/templates/collection-post.tmpl
+++ b/templates/collection-post.tmpl
@@ -9,7 +9,7 @@
{{ if .IsFound }}
-
+
@@ -26,7 +26,7 @@
-
+
{{range .Images}} {{else}} {{end}}
@@ -50,7 +50,7 @@
{{if .PinnedPosts}}
- {{range .PinnedPosts}}{{.PlainDisplayTitle}} {{end}}
+ {{range .PinnedPosts}}{{.PlainDisplayTitle}} {{end}}
{{end}}
{{ if and .IsOwner .IsFound }}{{largeNumFmt .Views}} {{pluralize "view" "views" .Views}}
Edit
diff --git a/templates/collection-tags.tmpl b/templates/collection-tags.tmpl
index 5e2e2d3..2618f3d 100644
--- a/templates/collection-tags.tmpl
+++ b/templates/collection-tags.tmpl
@@ -48,7 +48,7 @@
{{if .PinnedPosts}}
- {{range .PinnedPosts}}{{.DisplayTitle}} {{end}}
+ {{range .PinnedPosts}}{{.DisplayTitle}} {{end}}
{{end}}
diff --git a/templates/collection.tmpl b/templates/collection.tmpl
index 5a33bba..47dc24d 100644
--- a/templates/collection.tmpl
+++ b/templates/collection.tmpl
@@ -71,7 +71,7 @@
{{/*end*/}}
{{if .PinnedPosts}}
- {{range .PinnedPosts}}{{.PlainDisplayTitle}} {{end}}
+ {{range .PinnedPosts}}{{.PlainDisplayTitle}} {{end}}
{{end}}
diff --git a/templates/pad.tmpl b/templates/pad.tmpl
index 0b73b94..a8fca98 100644
--- a/templates/pad.tmpl
+++ b/templates/pad.tmpl
@@ -25,10 +25,10 @@
{{else}}Draft
- description Draft
- {{if .Blogs}}{{range .Blogs}}
- public {{if .Title}}{{.Title}}{{else}}{{.Alias}}{{end}}
+ {{if .Blogs}}{{range $idx, $el := .Blogs}}
+ public {{if $el.Title}}{{$el.Title}}{{else}}{{$el.Alias}}{{end}}
{{end}}{{end}}
+ description Draft
{{ if .SingleUser }}
launch View Blog
@@ -282,7 +282,7 @@
document.getElementById('target-name').innerText = newText.join(' ');
});
}
- var postTarget = H.get('postTarget', 'anonymous');
+ var postTarget = H.get('postTarget', '{{if .Blogs}}{{$blog := index .Blogs 0}}{{$blog.Alias}}{{else}}anonymous{{end}}');
if (location.hash != '') {
postTarget = location.hash.substring(1);
// TODO: pushState to /pad (or whatever the URL is) so we live on a clean URL
diff --git a/templates/read.tmpl b/templates/read.tmpl
index 9541ab5..f1cbf29 100644
--- a/templates/read.tmpl
+++ b/templates/read.tmpl
@@ -87,17 +87,17 @@
{{ if gt (len .Posts) 0 }}
{{ else }}
diff --git a/templates/user/admin/view-user.tmpl b/templates/user/admin/view-user.tmpl
index be50b12..7a7446c 100644
--- a/templates/user/admin/view-user.tmpl
+++ b/templates/user/admin/view-user.tmpl
@@ -25,12 +25,25 @@ td.active-suspend > input[type="submit"] {
margin: auto;
}
}
+input.copy-text {
+ text-align: center;
+ font-size: 1.2em;
+ color: #555;
+ width: 100%;
+ box-sizing: border-box;
+}
{{template "admin-header" .}}
-
+ {{if .NewPassword}}
+
This user's password has been reset to:
+
+
They can use this new password to log in to their account. This will only be shown once , so be sure to copy it and send it to them now.
+ {{if .ClearEmail}}
Their email address is: {{.ClearEmail}}
{{end}}
+
+ {{end}}
No.
@@ -71,6 +84,19 @@ td.active-suspend > input[type="submit"] {
+
+ Password
+
+ {{if ne .Username .User.Username}}
+
+ {{else}}
+ Change your password
+ {{end}}
+
+
Blogs
@@ -120,7 +146,15 @@ td.active-suspend > input[type="submit"] {
function confirmSilence() {
return confirm("Silence this user? They'll still be able to log in and access their posts, but no one else will be able to see them anymore. You can reverse this decision at any time.");
}
-
+ form = document.getElementById("reset-form");
+ form.addEventListener('submit', function(e) {
+ e.preventDefault();
+ agreed = confirm("Reset this user's password? This will generate a new temporary password that you'll need to share with them, and invalidate their old one.");
+ if (agreed === true) {
+ form.submit();
+ }
+ });
+
{{template "footer" .}}
{{end}}
diff --git a/unregisteredusers.go b/unregisteredusers.go
index 550c83b..b6f6ce6 100644
--- a/unregisteredusers.go
+++ b/unregisteredusers.go
@@ -13,13 +13,14 @@ package writefreely
import (
"database/sql"
"encoding/json"
+ "net/http"
+
"github.com/writeas/impart"
"github.com/writeas/web-core/log"
- "net/http"
)
func handleWebSignup(app *App, w http.ResponseWriter, r *http.Request) error {
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
// Get params
var ur userRegistration
@@ -71,7 +72,7 @@ func handleWebSignup(app *App, w http.ResponseWriter, r *http.Request) error {
// { "username": "asdf" }
// result: { code: 204 }
func handleUsernameCheck(app *App, w http.ResponseWriter, r *http.Request) error {
- reqJSON := IsJSON(r.Header.Get("Content-Type"))
+ reqJSON := IsJSON(r)
// Get params
var d struct {