/** User-facing messages for Supabase Auth API errors. */ type AuthLikeError = { message?: string; status?: number; code?: string; }; export function isAuthRateLimitError(error: AuthLikeError | null | undefined): boolean { if (!error) return false; if (error.status === 429) return true; const msg = (error.message ?? "").toLowerCase(); return ( msg.includes("rate limit") || msg.includes("too many requests") || msg.includes("email rate limit") ); } export function formatSignupError(message: string): string { const lower = message.toLowerCase(); if ( lower.includes("database error saving new user") || lower.includes("unexpected_failure") ) { return [ "Account could not be saved in the database (profile setup failed).", "", "Fix:", "1. Run: npm run db:push", "2. Or run supabase/migrations/20250524000008_fix_signup_trigger.sql in the SQL Editor", "3. Try signup again", ].join("\n"); } if (lower.includes("user already registered")) { return "This email is already registered. Try signing in or use Forgot password."; } return message; } export function formatAuthError(error: AuthLikeError | null | undefined): string { if (!error) return "Something went wrong. Please try again."; if (isAuthRateLimitError(error)) { return [ "Too many password-reset emails were sent recently.", "", "Supabase limits auth emails (especially on the free plan — often about 2 per hour per project).", "", "What to do:", "• Wait 60 minutes, then try once (do not spam the button).", "• Check inbox and spam for an email you already received — the link may still work.", "• Or reset from the dashboard: Authentication → Users → your user → Send password recovery.", "• For local dev: npm run auth:reset-password -- email@example.com NewPassword", ].join("\n"); } return formatSignupError(error.message ?? "Something went wrong. Please try again."); }