form: rework email confirmation

realized half the info from the signup form wasnt being stored in the JWT
used to create the account after email confirmation, and instead of
adding them, the -whole request- from the browser is stored temporarily
by the server, indexed by a smaller JWT that only includes the invite
code. Someone complained on reddit about me storing the password in the
JWT a while back, and although security-wise that isn't an issue (only
the server can decrypt the token), it doesn't happen anymore. Happy?
user-page
Harvey Tindall 1 year ago
parent f779f0345e
commit 14c18bd668
No known key found for this signature in database
GPG Key ID: BBC65952848FB1A2

@ -242,12 +242,17 @@ func (app *appContext) newUser(req newUserDTO, confirmed bool) (f errorFunc, suc
success = false
return
}
inv, _ := app.storage.GetInvitesKey(req.Code)
if inv.ConfirmationKeys == nil {
inv.ConfirmationKeys = map[string]newUserDTO{}
if app.ConfirmationKeys == nil {
app.ConfirmationKeys = map[string]map[string]newUserDTO{}
}
inv.ConfirmationKeys[key] = req
app.storage.SetInvitesKey(req.Code, inv)
cKeys, ok := app.ConfirmationKeys[req.Code]
if !ok {
cKeys = map[string]newUserDTO{}
}
cKeys[key] = req
app.confirmationKeysLock.Lock()
app.ConfirmationKeys[req.Code] = cKeys
app.confirmationKeysLock.Unlock()
f = func(gc *gin.Context) {
app.debug.Printf("%s: Email confirmation required", req.Code)
respond(401, "confirmEmail", gc)

@ -17,6 +17,7 @@ import (
"path/filepath"
"runtime"
"strings"
"sync"
"syscall"
"time"
@ -111,6 +112,8 @@ type appContext struct {
tag Tag
update Update
internalPWRs map[string]InternalPWR
ConfirmationKeys map[string]map[string]newUserDTO // Map of invite code to jwt to request
confirmationKeysLock sync.Mutex
}
func generateSecret(length int) (string, error) {

@ -278,7 +278,6 @@ type Invite struct {
Notify map[string]map[string]bool `json:"notify"`
Profile string `json:"profile"`
Label string `json:"label,omitempty"`
ConfirmationKeys map[string]newUserDTO `json:"-"` // map of JWT confirmation keys to their original requests
Captchas map[string]*captcha.Data // Map of Captcha IDs to answers
}

@ -512,7 +512,6 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
return
}
if key := gc.Query("key"); key != "" && app.config.Section("email_confirmation").Key("enabled").MustBool(false) {
req, ok := inv.ConfirmationKeys[key]
fail := func() {
gcHTML(gc, 404, "404.html", gin.H{
"cssClass": app.cssClass,
@ -520,6 +519,18 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
"contactMessage": app.config.Section("ui").Key("contact_message").String(),
})
}
var req newUserDTO
if app.ConfirmationKeys == nil {
fail()
return
}
invKeys, ok := app.ConfirmationKeys[code]
if !ok {
fail()
return
}
req, ok = invKeys[key]
if !ok {
fail()
return
@ -537,8 +548,11 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
app.debug.Printf("Invalid key")
return
}
_, success := app.newUser(req, true)
f, success := app.newUser(req, true)
if !success {
app.err.Printf("Failed to create new user")
// Not meant for us. Calling this will be a mess, but at least it might give us some information.
f(gc)
fail()
return
}
@ -554,11 +568,10 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
"jfLink": jfLink,
})
}
inv, ok := app.storage.GetInvitesKey(code)
if ok {
delete(inv.ConfirmationKeys, key)
app.storage.SetInvitesKey(code, inv)
}
delete(invKeys, key)
app.confirmationKeysLock.Lock()
app.ConfirmationKeys[code] = invKeys
app.confirmationKeysLock.Unlock()
return
}
email := ""

Loading…
Cancel
Save