mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 22:51:12 -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 () => {
|
const handleSendConfirmationEmail = async () => {
|
||||||
setAddingPassword(true);
|
setAddingPassword(true);
|
||||||
|
|
||||||
const result = await triggerOrphanedPasswordConfirmation();
|
const result = await triggerOrphanedPasswordConfirmation('security_settings');
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
sonnerToast.success("Confirmation Email Sent!", {
|
sonnerToast.success("Confirmation Email Sent!", {
|
||||||
|
|||||||
@@ -111,6 +111,58 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
|
|||||||
} else {
|
} else {
|
||||||
setAal(null);
|
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);
|
}, 0);
|
||||||
|
|
||||||
// Detect confirmed email change: email changed AND no longer pending
|
// 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
|
* Trigger email confirmation for orphaned password
|
||||||
* Direct trigger without requiring password re-entry
|
* Direct trigger without requiring password re-entry
|
||||||
*/
|
*/
|
||||||
export async function triggerOrphanedPasswordConfirmation(): Promise<IdentityOperationResult> {
|
export async function triggerOrphanedPasswordConfirmation(
|
||||||
|
source?: string
|
||||||
|
): Promise<IdentityOperationResult> {
|
||||||
try {
|
try {
|
||||||
const { data: { user } } = await supabase.auth.getUser();
|
const { data: { user } } = await supabase.auth.getUser();
|
||||||
|
|
||||||
@@ -313,7 +315,8 @@ export async function triggerOrphanedPasswordConfirmation(): Promise<IdentityOpe
|
|||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
|
|
||||||
await logIdentityChange(user.id, 'orphaned_password_confirmation_triggered', {
|
await logIdentityChange(user.id, 'orphaned_password_confirmation_triggered', {
|
||||||
method: 'manual_button_click'
|
method: source || 'manual_button_click',
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user