fix(account): clear the guest flag on a deeplink email link
ConfirmByToken attached the confirmed email to the account but, on the link path, skipped ClearGuest — so a guest who bound an email via the one-tap deeplink stayed a guest (the code-based flow clears it in the link service). Clear the flag on a free link too, promoting the guest to a durable account; the profile live event then refreshes the open session. Integration test added.
This commit is contained in:
@@ -319,6 +319,11 @@ func (s *EmailService) ConfirmByToken(ctx context.Context, token string) (LinkCo
|
|||||||
if err := s.store.confirmEmailIdentity(ctx, pend.id, pend.accountID, pend.email, s.now()); err != nil {
|
if err := s.store.confirmEmailIdentity(ctx, pend.id, pend.accountID, pend.email, s.now()); err != nil {
|
||||||
return LinkConfirmation{}, err
|
return LinkConfirmation{}, err
|
||||||
}
|
}
|
||||||
|
// Binding the first email promotes a guest to a durable account, matching the
|
||||||
|
// code-based link flow (which clears the guest flag in the link service).
|
||||||
|
if err := s.store.ClearGuest(ctx, pend.accountID); err != nil {
|
||||||
|
return LinkConfirmation{}, err
|
||||||
|
}
|
||||||
return LinkConfirmation{Purpose: purposeLink, Account: pend.accountID}, nil
|
return LinkConfirmation{Purpose: purposeLink, Account: pend.accountID}, nil
|
||||||
default:
|
default:
|
||||||
return LinkConfirmation{}, fmt.Errorf("account: unsupported confirmation purpose %q", pend.purpose)
|
return LinkConfirmation{}, fmt.Errorf("account: unsupported confirmation purpose %q", pend.purpose)
|
||||||
|
|||||||
@@ -394,3 +394,32 @@ func TestEmailAccountSeedsDisplayName(t *testing.T) {
|
|||||||
t.Errorf("display name = %q, want the email local part %q", acc.DisplayName, local)
|
t.Errorf("display name = %q, want the email local part %q", acc.DisplayName, local)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestConfirmByTokenLinkClearsGuest: binding an email to a guest via the deeplink
|
||||||
|
// promotes the guest to a durable account (the deeplink path must match the
|
||||||
|
// code-based link flow, which clears the guest flag).
|
||||||
|
func TestConfirmByTokenLinkClearsGuest(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
store := account.NewStore(testDB)
|
||||||
|
mailer := &capturingMailer{}
|
||||||
|
svc := account.NewEmailService(store, mailer, "https://erudit-game.ru")
|
||||||
|
guest, err := store.ProvisionGuest(ctx, "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("provision guest: %v", err)
|
||||||
|
}
|
||||||
|
email := "guest-link-" + uuid.NewString() + "@example.com"
|
||||||
|
|
||||||
|
if err := svc.RequestLinkCode(ctx, guest.ID, email); err != nil {
|
||||||
|
t.Fatalf("request link: %v", err)
|
||||||
|
}
|
||||||
|
if _, err := svc.ConfirmByToken(ctx, tokenFromMail(t, mailer.lastBody)); err != nil {
|
||||||
|
t.Fatalf("confirm by token: %v", err)
|
||||||
|
}
|
||||||
|
acc, err := store.GetByID(ctx, guest.ID)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("get: %v", err)
|
||||||
|
}
|
||||||
|
if acc.IsGuest {
|
||||||
|
t.Error("linking an email via the deeplink must promote the guest to durable")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user