fix(ui): poll for out-of-band email confirmation
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 1m8s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m39s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Has been skipped
CI / integration (pull_request) Has been skipped
CI / ui (pull_request) Successful in 1m8s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m39s
An email link/code can be confirmed out of band: the recipient taps the one-tap link in the email, which confirms in another browser/session. The backend already publishes a `notify` `profile` re-fetch signal for this (handlers_auth.go handleEmailConfirmLink), and the client re-fetches on it. But the live stream is single-shot with no replay: a Mini App backgrounded while the user is in their mail app tapping the link drops the stream and misses the event (the gateway hub has no subscriber to deliver to), and the reconnect on foreground does not re-sync — so the open code form stayed until a manual reload. On Telegram Desktop the app is never backgrounded, so the push works and there was no bug. Add a client-side fallback: while an add-email confirmation is pending (a code was sent, no email yet), poll `profile.get` on a 4s interval and on foreground regain until the address lands; the effect stops as soon as the email appears. The live push still updates instantly when foregrounded — this only covers the backgrounded-miss gap. Tests: a mock e2e attaches the email WITHOUT emitting a live event (new window.__mock.clearEmail / confirmEmailOutOfBand seams), so it exercises the poll, not the push, and asserts the code form collapses into the email row. Docs: ARCHITECTURE.md §10 notes the single-shot gap + the poll fallback.
This commit is contained in:
@@ -659,6 +659,17 @@ export class MockGateway implements GatewayClient {
|
||||
this.profile.email = email;
|
||||
return emptyLinked();
|
||||
}
|
||||
// e2e hooks (window.__mock, see lib/gateway.ts): mockClearEmail drops the seeded email so the
|
||||
// sign-in section offers the add-email flow; mockConfirmEmailOutOfBand attaches the address
|
||||
// WITHOUT a live event — standing in for the one-tap confirm link opened in another browser,
|
||||
// so the open code form must reflect it by polling the profile, not by a push.
|
||||
mockClearEmail(): void {
|
||||
this.profile.email = '';
|
||||
this.emit({ kind: 'notify', sub: 'profile' });
|
||||
}
|
||||
mockConfirmEmailOutOfBand(email: string): void {
|
||||
this.profile.email = email;
|
||||
}
|
||||
async linkEmailMerge(email: string, _code: string): Promise<LinkResult> {
|
||||
this.profile.isGuest = false;
|
||||
this.profile.email = email;
|
||||
|
||||
Reference in New Issue
Block a user