From 38b19ad97af3380bc9a3e188dbd20e8f310bf0f8 Mon Sep 17 00:00:00 2001 From: S Rishiraj <74849474+rishiraj-58@users.noreply.github.com> Date: Thu, 24 Jul 2025 22:35:44 +0530 Subject: [PATCH] fix: preserve user metadata when email_confirm=true in Confirm function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem When creating a user with `email_confirm: true`, the `Confirm` function in `internal/models/user.go` overwrites the user's existing metadata instead of merging the `email_verified: true` flag with it. ## Root Cause The current implementation calls `UpdateUserMetaData` with only `{"email_verified": true}`, which replaces the entire metadata object instead of merging with existing data. ## Solution 1. Reload the user's latest state from the database to get the most recent metadata 2. Merge the `email_verified: true` flag with existing metadata 3. Use the existing `UpdateUserMetaData` function to properly update without data loss ## Testing - ✅ Created user with `email_confirm: true` and custom metadata - ✅ Verified metadata is preserved and `email_verified: true` is merged - ✅ Confirmed fix works through Kong API gateway - ✅ Tested user creation, updates, and deletion operations ## Impact Fixes data loss issue where user metadata was being overwritten during email confirmation, ensuring all custom user data is preserved. Closes #2088 --- internal/models/user.go | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/internal/models/user.go b/internal/models/user.go index 69e76b336..1841b67ad 100644 --- a/internal/models/user.go +++ b/internal/models/user.go @@ -449,9 +449,24 @@ func (u *User) Confirm(tx *storage.Connection) error { return err } - if err := u.UpdateUserMetaData(tx, map[string]interface{}{ - "email_verified": true, - }); err != nil { + // 1. Reload the user state from the database to get the most recent + // metadata, including any changes made by database triggers. + latestUser, err := FindUserByID(tx, u.ID) + if err != nil { + return err + } + + // 2. Prepare the metadata for update. Start with the fresh data from the database. + metaDataToUpdate := latestUser.UserMetaData + if metaDataToUpdate == nil { + metaDataToUpdate = make(map[string]interface{}) + } + metaDataToUpdate["email_verified"] = true + + // 3. Now, call the existing UpdateUserMetaData function. + // This will correctly update the user's metadata without data loss, + // and it also updates the in-memory user object 'u' for consistency. + if err := u.UpdateUserMetaData(tx, metaDataToUpdate); err != nil { return err }