Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions internal/useraccount/register_flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ func (c *Context) GetOrRegister(ctx context.Context, req UserRegisterRequest) (*
// check if user already exists
user, err := c.entClient.User.Query().Where(user.EmailEQ(req.Email)).Only(ctx)
if err == nil {
// update name and avatar to match the OAuth user info
user, err = user.Update().SetName(req.Name).SetAvatar(req.Avatar).Save(ctx)
if err != nil {
return nil, fmt.Errorf("update user: %w", err)
}

return user, nil
}
if !ent.IsNotFound(err) {
Expand Down
134 changes: 132 additions & 2 deletions internal/useraccount/register_flow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,140 @@ func TestGetOrRegister_ExistingUser(t *testing.T) {

// Should return existing user, not create new one
assert.Equal(t, existingUser.ID, user.ID)
assert.Equal(t, existingUser.Name, user.Name) // Should keep original name
assert.Equal(t, req.Name, user.Name) // Should update to new name from OAuth
assert.Equal(t, existingUser.Email, user.Email)
}

func TestGetOrRegister_UpdateNameAndAvatar(t *testing.T) {
client := setupTestDatabase(t)
authStorage := newMockAuthStorage()
eventService := events.NewEventService(client, nil)
ctx := useraccount.NewContext(client, authStorage, eventService)
context := context.Background()

// Create an existing user with original name and avatar
unverifiedGroup, err := client.Group.Query().Where(group.NameEQ(useraccount.UnverifiedGroupSlug)).Only(context)
require.NoError(t, err)

originalName := "Original Name"
originalAvatar := "https://example.com/old-avatar.jpg"
existingUser, err := client.User.Create().
SetName(originalName).
SetEmail("[email protected]").
SetAvatar(originalAvatar).
SetGroup(unverifiedGroup).
Save(context)
require.NoError(t, err)

// Register again with updated OAuth info
updatedName := "Updated OAuth Name"
updatedAvatar := "https://oauth-provider.com/new-avatar.jpg"
req := useraccount.UserRegisterRequest{
Name: updatedName,
Email: "[email protected]", // Same email
Avatar: updatedAvatar,
}

user, err := ctx.GetOrRegister(context, req)
require.NoError(t, err)
require.NotNil(t, user)

// Verify it's the same user (ID unchanged)
assert.Equal(t, existingUser.ID, user.ID)

// Verify name and avatar were updated to match OAuth info
assert.Equal(t, updatedName, user.Name, "name should be updated to match OAuth info")
assert.Equal(t, updatedAvatar, user.Avatar, "avatar should be updated to match OAuth info")
assert.Equal(t, existingUser.Email, user.Email, "email should remain unchanged")

// Verify the updates persisted in the database
refreshedUser, err := client.User.Get(context, user.ID)
require.NoError(t, err)
assert.Equal(t, updatedName, refreshedUser.Name)
assert.Equal(t, updatedAvatar, refreshedUser.Avatar)
}

func TestGetOrRegister_UpdateNameAndAvatar_VerifiedUser(t *testing.T) {
client := setupTestDatabase(t)
authStorage := newMockAuthStorage()
eventService := events.NewEventService(client, nil)
ctx := useraccount.NewContext(client, authStorage, eventService)
context := context.Background()

// Create an existing verified user (in new-user group)
newUserGroup, err := client.Group.Query().Where(group.NameEQ(useraccount.NewUserGroupSlug)).Only(context)
require.NoError(t, err)

originalName := "Verified User Original"
originalAvatar := "https://example.com/verified-old.jpg"
existingUser, err := client.User.Create().
SetName(originalName).
SetEmail("[email protected]").
SetAvatar(originalAvatar).
SetGroup(newUserGroup).
Save(context)
require.NoError(t, err)

// Login/register again with updated OAuth info
updatedName := "Verified User Updated"
updatedAvatar := "https://oauth-provider.com/verified-new.jpg"
req := useraccount.UserRegisterRequest{
Name: updatedName,
Email: "[email protected]",
Avatar: updatedAvatar,
}

user, err := ctx.GetOrRegister(context, req)
require.NoError(t, err)
require.NotNil(t, user)

// Verify the existing verified user was updated
assert.Equal(t, existingUser.ID, user.ID)
assert.Equal(t, updatedName, user.Name, "name should be updated even for verified users")
assert.Equal(t, updatedAvatar, user.Avatar, "avatar should be updated even for verified users")

// Verify user is still in the verified group
group, err := user.QueryGroup().Only(context)
require.NoError(t, err)
assert.Equal(t, useraccount.NewUserGroupSlug, group.Name, "group should not change")
}

func TestGetOrRegister_UpdateWithEmptyAvatar(t *testing.T) {
client := setupTestDatabase(t)
authStorage := newMockAuthStorage()
eventService := events.NewEventService(client, nil)
ctx := useraccount.NewContext(client, authStorage, eventService)
context := context.Background()

// Create user with avatar
unverifiedGroup, err := client.Group.Query().Where(group.NameEQ(useraccount.UnverifiedGroupSlug)).Only(context)
require.NoError(t, err)

existingUser, err := client.User.Create().
SetName("User With Avatar").
SetEmail("[email protected]").
SetAvatar("https://example.com/has-avatar.jpg").
SetGroup(unverifiedGroup).
Save(context)
require.NoError(t, err)

// Register again with empty avatar (OAuth provider might not provide avatar)
req := useraccount.UserRegisterRequest{
Name: "User Name Updated",
Email: "[email protected]",
Avatar: "", // Empty avatar
}

user, err := ctx.GetOrRegister(context, req)
require.NoError(t, err)
require.NotNil(t, user)

// Verify avatar was cleared
assert.Equal(t, existingUser.ID, user.ID)
assert.Equal(t, req.Name, user.Name)
assert.Equal(t, "", user.Avatar, "empty avatar should be set")
}

func TestGetOrRegister_MissingUnverifiedGroup(t *testing.T) {
// Create a fresh database without setup
client := testhelper.NewEntSqliteClient(t)
Expand Down Expand Up @@ -275,7 +405,7 @@ func TestRegistrationFlow_ExistingUser(t *testing.T) {

// Should return existing user
assert.Equal(t, existingUser.ID, user.ID)
assert.Equal(t, existingUser.Name, user.Name) // Keep original name
assert.Equal(t, req.Name, user.Name) // Name updated to match OAuth info

// Grant token - should have new-user scopes
token, err := ctx.GrantToken(context, user, "web", useraccount.WithFlow("login"))
Expand Down