From ea57d657fe6dabecde18b9c3908aa7cec4454b71 Mon Sep 17 00:00:00 2001 From: Harvey Tindall Date: Fri, 11 Oct 2024 16:38:19 +0100 Subject: [PATCH] form: fix contact details/profile application when using email confirmation my rewrite of account-creation stuff had a massive oversight of email confirmation, the steps done after account creation (email and contact method storage, referral stuff) were not done on the email confirmation path. This has been factored out to PostNewUserFromIvnite, and the ConfirmationKeys store now includes the newUserDTO and the list of completeContactMethods. --- api-users.go | 66 ++++++++++++++++++++++++++++------------------------ main.go | 2 +- models.go | 11 +++++++++ views.go | 8 +++++-- 4 files changed, 53 insertions(+), 34 deletions(-) diff --git a/api-users.go b/api-users.go index b529266..3c29f2d 100644 --- a/api-users.go +++ b/api-users.go @@ -110,11 +110,7 @@ func (app *appContext) NewUserFromInvite(gc *gin.Context) { gc.JSON(200, validation) return } - completeContactMethods := make([]struct { - Verified bool - PIN string - User ContactMethodUser - }, len(app.contactMethods)) + completeContactMethods := make([]ContactMethodKey, len(app.contactMethods)) for i, cm := range app.contactMethods { completeContactMethods[i].PIN = cm.PIN(req) if completeContactMethods[i].PIN == "" { @@ -168,13 +164,16 @@ func (app *appContext) NewUserFromInvite(gc *gin.Context) { return } if app.ConfirmationKeys == nil { - app.ConfirmationKeys = map[string]map[string]newUserDTO{} + app.ConfirmationKeys = map[string]map[string]ConfirmationKey{} } cKeys, ok := app.ConfirmationKeys[req.Code] if !ok { - cKeys = map[string]newUserDTO{} + cKeys = map[string]ConfirmationKey{} + } + cKeys[key] = ConfirmationKey{ + newUserDTO: req, + completeContactMethods: completeContactMethods, } - cKeys[key] = req app.confirmationKeysLock.Lock() app.ConfirmationKeys[req.Code] = cKeys app.confirmationKeysLock.Unlock() @@ -223,10 +222,32 @@ func (app *appContext) NewUserFromInvite(gc *gin.Context) { } app.checkInvite(req.Code, true, req.Username) + app.PostNewUserFromInvite(nu, ConfirmationKey{newUserDTO: req, completeContactMethods: completeContactMethods}, profile, invite) + + /*responseFunc, logFunc, success := app.NewUser(req, false, gc) + if !success { + logFunc() + responseFunc(gc) + return + }*/ + code := 200 + for _, val := range validation { + if !val { + code = 400 + } + } + + gc.JSON(code, validation) + // These don't need to complete anytime soon + // wg.Wait() +} + +// PostNewUserFromInvite attaches user details (e.g. contact method details) to a new user once they've been created from an invite. +func (app *appContext) PostNewUserFromInvite(nu NewUserData, req ConfirmationKey, profile *Profile, invite Invite) { nonEmailContactMethodEnabled := false - for i, c := range completeContactMethods { + for i, c := range req.completeContactMethods { if c.Verified { - c.User.SetAllowContactFromDTO(req) + c.User.SetAllowContactFromDTO(req.newUserDTO) if c.User.AllowContact() { nonEmailContactMethodEnabled = true } @@ -308,12 +329,12 @@ func (app *appContext) NewUserFromInvite(gc *gin.Context) { // FIXME: figure these out in a nicer way? this relies on the current ordering, // which may not be fixed. if discordEnabled { - discordUser = completeContactMethods[0].User.(*DiscordUser) + discordUser = req.completeContactMethods[0].User.(*DiscordUser) if telegramEnabled { - telegramUser = completeContactMethods[1].User.(*TelegramUser) + telegramUser = req.completeContactMethods[1].User.(*TelegramUser) } } else if telegramEnabled { - telegramUser = completeContactMethods[0].User.(*TelegramUser) + telegramUser = req.completeContactMethods[0].User.(*TelegramUser) } } @@ -322,30 +343,13 @@ func (app *appContext) NewUserFromInvite(gc *gin.Context) { continue } // User already created, now we can link contact methods - err := tps.AddContactMethods(nu.User.ID, req, discordUser, telegramUser) + err := tps.AddContactMethods(nu.User.ID, req.newUserDTO, discordUser, telegramUser) if err != nil { app.err.Printf(lm.FailedSyncContactMethods, tps.Name(), err) } } app.WelcomeNewUser(nu.User, expiry) - - /*responseFunc, logFunc, success := app.NewUser(req, false, gc) - if !success { - logFunc() - responseFunc(gc) - return - }*/ - code := 200 - for _, val := range validation { - if !val { - code = 400 - } - } - - gc.JSON(code, validation) - // These don't need to complete anytime soon - // wg.Wait() } // @Summary Enable/Disable a list of users, optionally notifying them why. diff --git a/main.go b/main.go index d9c2596..04d408f 100644 --- a/main.go +++ b/main.go @@ -132,7 +132,7 @@ type appContext struct { proxyConfig easyproxy.ProxyConfig internalPWRs map[string]InternalPWR pwrCaptchas map[string]Captcha - ConfirmationKeys map[string]map[string]newUserDTO // Map of invite code to jwt to request + ConfirmationKeys map[string]map[string]ConfirmationKey // Map of invite code to jwt to request confirmationKeysLock sync.Mutex } diff --git a/models.go b/models.go index 2b81672..fd24e2a 100644 --- a/models.go +++ b/models.go @@ -455,3 +455,14 @@ type CreateBackupDTO struct { type GetBackupsDTO struct { Backups []CreateBackupDTO `json:"backups"` } + +type ConfirmationKey struct { + newUserDTO + completeContactMethods []ContactMethodKey +} + +type ContactMethodKey struct { + Verified bool + PIN string + User ContactMethodUser +} diff --git a/views.go b/views.go index 6928bba..7542606 100644 --- a/views.go +++ b/views.go @@ -624,7 +624,7 @@ func (app *appContext) NewUserFromConfirmationKey(invite Invite, key string, lan "contactMessage": app.config.Section("ui").Key("contact_message").String(), }) } - var req newUserDTO + var req ConfirmationKey if app.ConfirmationKeys == nil { fail() return @@ -666,8 +666,10 @@ func (app *appContext) NewUserFromConfirmationKey(invite Invite, key string, lan profile = &p } + // FIXME: Email and contract method linking????? + nu /*wg*/, _ := app.NewUserPostVerification(NewUserParams{ - Req: req, + Req: req.newUserDTO, SourceType: sourceType, Source: source, ContextForIPLogging: gc, @@ -683,6 +685,8 @@ func (app *appContext) NewUserFromConfirmationKey(invite Invite, key string, lan } app.checkInvite(req.Code, true, req.Username) + app.PostNewUserFromInvite(nu, req, profile, invite) + jfLink := app.config.Section("ui").Key("redirect_url").String() if app.config.Section("ui").Key("auto_redirect").MustBool(false) { gc.Redirect(301, jfLink)