mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 23:51:13 -05:00
feat: Add persistent sign-in toast for orphaned passwords
This commit is contained in:
@@ -196,7 +196,7 @@ export function SecurityTab() {
|
||||
const handleSendConfirmationEmail = async () => {
|
||||
setAddingPassword(true);
|
||||
|
||||
const result = await triggerOrphanedPasswordConfirmation();
|
||||
const result = await triggerOrphanedPasswordConfirmation('security_settings');
|
||||
|
||||
if (result.success) {
|
||||
sonnerToast.success("Confirmation Email Sent!", {
|
||||
|
||||
@@ -111,6 +111,58 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
|
||||
} else {
|
||||
setAal(null);
|
||||
}
|
||||
|
||||
// Check for orphaned password on SIGNED_IN events
|
||||
if (event === 'SIGNED_IN' && session?.user) {
|
||||
try {
|
||||
// Import identityService functions
|
||||
const { getUserIdentities, hasOrphanedPassword, triggerOrphanedPasswordConfirmation } =
|
||||
await import('@/lib/identityService');
|
||||
|
||||
// Check if user has email identity
|
||||
const identities = await getUserIdentities();
|
||||
const hasEmailIdentity = identities.some(i => i.provider === 'email');
|
||||
|
||||
// If no email identity but has other identities, check for orphaned password
|
||||
if (!hasEmailIdentity && identities.length > 0) {
|
||||
const isOrphaned = await hasOrphanedPassword();
|
||||
|
||||
if (isOrphaned) {
|
||||
// Show persistent toast with Resend button
|
||||
const { toast: sonnerToast } = await import('sonner');
|
||||
|
||||
sonnerToast.warning("Password Activation Pending", {
|
||||
description: "Your password needs email confirmation to be fully activated.",
|
||||
duration: Infinity, // Persistent until dismissed
|
||||
action: {
|
||||
label: "Resend Email",
|
||||
onClick: async () => {
|
||||
const result = await triggerOrphanedPasswordConfirmation('signin_toast');
|
||||
|
||||
if (result.success) {
|
||||
sonnerToast.success("Confirmation Email Sent!", {
|
||||
description: `Check ${result.email} for the confirmation link.`,
|
||||
duration: 10000,
|
||||
});
|
||||
} else {
|
||||
sonnerToast.error("Failed to Send Email", {
|
||||
description: result.error,
|
||||
duration: 8000,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
cancel: {
|
||||
label: "Dismiss",
|
||||
onClick: () => {} // Allow dismissal
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
authError('[Auth] Failed to check for orphaned password:', error);
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
|
||||
// Detect confirmed email change: email changed AND no longer pending
|
||||
|
||||
@@ -293,7 +293,9 @@ export async function hasOrphanedPassword(): Promise<boolean> {
|
||||
* Trigger email confirmation for orphaned password
|
||||
* Direct trigger without requiring password re-entry
|
||||
*/
|
||||
export async function triggerOrphanedPasswordConfirmation(): Promise<IdentityOperationResult> {
|
||||
export async function triggerOrphanedPasswordConfirmation(
|
||||
source?: string
|
||||
): Promise<IdentityOperationResult> {
|
||||
try {
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
|
||||
@@ -313,7 +315,8 @@ export async function triggerOrphanedPasswordConfirmation(): Promise<IdentityOpe
|
||||
if (error) throw error;
|
||||
|
||||
await logIdentityChange(user.id, 'orphaned_password_confirmation_triggered', {
|
||||
method: 'manual_button_click'
|
||||
method: source || 'manual_button_click',
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user