mirror of https://github.com/writeas/writefreely
This adds a self-serve password reset page. Users can enter their username and receive an email with a link that will let them create a new password. If they've never set a password, it will send them a one-time login link (building on #776) that will then take them to their Account Settings page. If they don't have an email associated with their account, they'll be instructed to contact the admin, so they can manually reset the password. Includes changes to the stylesheet and database, so run: make ui writefreely db migrate Closes T508pull/778/head
parent
7dda53146d
commit
f404f7b928
@ -0,0 +1,37 @@ |
||||
/* |
||||
* Copyright © 2023 Musing Studio 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 migrations |
||||
|
||||
func supportPassReset(db *datastore) error { |
||||
t, err := db.Begin() |
||||
if err != nil { |
||||
t.Rollback() |
||||
return err |
||||
} |
||||
|
||||
_, err = t.Exec(`CREATE TABLE password_resets ( |
||||
user_id ` + db.typeInt() + ` not null, |
||||
token ` + db.typeChar(32) + ` not null primary key, |
||||
used ` + db.typeBool() + ` default 0 not null, |
||||
created ` + db.typeDateTime() + ` not null |
||||
)`) |
||||
if err != nil { |
||||
t.Rollback() |
||||
return err |
||||
} |
||||
|
||||
err = t.Commit() |
||||
if err != nil { |
||||
t.Rollback() |
||||
return err |
||||
} |
||||
return nil |
||||
} |
@ -0,0 +1,48 @@ |
||||
{{define "head"}}<title>Reset password — {{.SiteName}}</title> |
||||
<style> |
||||
input { |
||||
margin-bottom: 0.5em; |
||||
width: 100%; |
||||
box-sizing: border-box; |
||||
} |
||||
label { |
||||
display: block; |
||||
} |
||||
</style> |
||||
{{end}} |
||||
{{define "content"}} |
||||
<div class="toosmall content-container clean"> |
||||
<h1>Reset your password</h1> |
||||
|
||||
{{if .Flashes}}<ul class="errors"> |
||||
{{range .Flashes}}<li class="urgent">{{.}}</li>{{end}} |
||||
</ul>{{end}} |
||||
|
||||
{{if .IsResetting}} |
||||
<form method="post" action="/reset" onsubmit="disableSubmit()"> |
||||
<label> |
||||
<p>New Password</p> |
||||
<input type="password" name="new-pass" autocomplete="new-password" placeholder="New password" tabindex="1" /> |
||||
</label> |
||||
<input type="hidden" name="t" value="{{.Token}}" /> |
||||
<input type="submit" id="btn-login" value="Reset Password" /> |
||||
{{ .CSRFField }} |
||||
</form> |
||||
{{else if not .IsSent}} |
||||
<form action="/reset" method="post" onsubmit="disableSubmit()"> |
||||
<label> |
||||
<p>Username</p> |
||||
<input type="text" name="alias" placeholder="Username" autofocus /> |
||||
</label> |
||||
{{ .CSRFField }} |
||||
<input type="submit" id="btn-login" value="Reset Password" /> |
||||
</form> |
||||
{{end}} |
||||
|
||||
<script type="text/javascript"> |
||||
var $btn = document.getElementById("btn-login"); |
||||
function disableSubmit() { |
||||
$btn.disabled = true; |
||||
} |
||||
</script> |
||||
{{end}} |
@ -0,0 +1,25 @@ |
||||
/* |
||||
* Copyright © 2023 Musing Studio 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 spam |
||||
|
||||
import ( |
||||
"net/http" |
||||
"strings" |
||||
) |
||||
|
||||
func GetIP(r *http.Request) string { |
||||
h := r.Header.Get("X-Forwarded-For") |
||||
if h == "" { |
||||
return "" |
||||
} |
||||
ips := strings.Split(h, ",") |
||||
return strings.TrimSpace(ips[0]) |
||||
} |
Loading…
Reference in new issue