feat(identity): store verified email on profile + show in account modal
Email verification wrote to the `email` column but account status read from `profile_email` — now setUserEmail writes both. Account modal email section displays the verified address when collapsed. Tour finale step triggers identity setup on completion. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4c1cd21b8c
commit
29c4f48634
|
|
@ -711,7 +711,7 @@ export class RStackIdentity extends HTMLElement {
|
|||
let openSection: string | null = null;
|
||||
|
||||
// Account completion status
|
||||
let acctStatus: { email: boolean; multiDevice: boolean; socialRecovery: boolean; guardianCount: number; credentialCount: number } | null = null;
|
||||
let acctStatus: { email: boolean; emailAddress?: string | null; multiDevice: boolean; socialRecovery: boolean; guardianCount: number; credentialCount: number } | null = null;
|
||||
|
||||
// Lazy-loaded data
|
||||
let guardians: { id: string; name: string; email?: string; status: string }[] = [];
|
||||
|
|
@ -819,10 +819,13 @@ export class RStackIdentity extends HTMLElement {
|
|||
</div>`;
|
||||
}
|
||||
}
|
||||
const emailDisplay = !isOpen && done && acctStatus?.emailAddress
|
||||
? `<span style="color:var(--rs-text-secondary);font-size:0.85rem;margin-left:8px">${acctStatus.emailAddress}</span>`
|
||||
: "";
|
||||
return `
|
||||
<div class="account-section${isOpen ? " open" : ""}${done === false ? " section--warning" : ""}">
|
||||
<div class="account-section-header" data-section="email">
|
||||
<span>${statusDot(done)} ✉️ Email</span>
|
||||
<span>${statusDot(done)} ✉️ Email${emailDisplay}</span>
|
||||
<span class="section-arrow">${isOpen ? "▾" : "▸"}</span>
|
||||
</div>
|
||||
${body}
|
||||
|
|
@ -1087,7 +1090,7 @@ export class RStackIdentity extends HTMLElement {
|
|||
body: JSON.stringify({ email: emailAddr, code }),
|
||||
});
|
||||
if (!res.ok) throw new Error((await res.json().catch(() => ({}))).error || "Verification failed");
|
||||
if (acctStatus) acctStatus.email = true;
|
||||
if (acctStatus) { acctStatus.email = true; acctStatus.emailAddress = emailAddr; }
|
||||
openSection = null; render();
|
||||
this.dispatchEvent(new CustomEvent("identity-action", { bubbles: true, composed: true, detail: { action: "email-added", email: emailAddr } }));
|
||||
} catch (e: any) {
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ export async function cleanExpiredChallenges(): Promise<number> {
|
|||
// ============================================================================
|
||||
|
||||
export async function setUserEmail(userId: string, email: string): Promise<void> {
|
||||
await sql`UPDATE users SET email = ${email} WHERE id = ${userId}`;
|
||||
await sql`UPDATE users SET email = ${email}, profile_email = ${email}, updated_at = NOW() WHERE id = ${userId}`;
|
||||
}
|
||||
|
||||
export async function getUserByEmail(email: string) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue