Fix Supabase linter warnings and backend validation

This commit is contained in:
gpt-engineer-app[bot]
2025-10-14 18:00:59 +00:00
parent 7a6273111d
commit 85c79ad511
6 changed files with 576 additions and 5 deletions

View File

@@ -14,6 +14,7 @@ import { useCaptchaBypass } from '@/hooks/useCaptchaBypass';
import { MFAChallenge } from './MFAChallenge';
import { verifyMfaUpgrade } from '@/lib/authService';
import { setAuthMethod } from '@/lib/sessionFlags';
import { validateEmailNotDisposable } from '@/lib/emailValidation';
interface AuthModalProps {
open: boolean;
@@ -178,6 +179,20 @@ export function AuthModal({ open, onOpenChange, defaultTab = 'signin' }: AuthMod
setCaptchaToken(null);
try {
// Validate email is not disposable
const emailValidation = await validateEmailNotDisposable(formData.email);
if (!emailValidation.valid) {
toast({
variant: "destructive",
title: "Invalid Email",
description: emailValidation.reason || "Please use a permanent email address"
});
setCaptchaKey(prev => prev + 1);
setLoading(false);
return;
}
const signUpOptions: any = {
email: formData.email,
password: formData.password,

View File

@@ -27,6 +27,7 @@ import { TurnstileCaptcha } from '@/components/auth/TurnstileCaptcha';
import { useTheme } from '@/components/theme/ThemeProvider';
import { notificationService } from '@/lib/notificationService';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { validateEmailNotDisposable } from '@/lib/emailValidation';
const emailSchema = z.object({
currentPassword: z.string().min(1, 'Current password is required'),
@@ -93,7 +94,18 @@ export function EmailChangeDialog({ open, onOpenChange, currentEmail, userId }:
setLoading(true);
try {
// Step 1: Reauthenticate with current password
// Step 1: Validate email is not disposable
const emailValidation = await validateEmailNotDisposable(data.newEmail);
if (!emailValidation.valid) {
toast.error("Invalid Email", {
description: emailValidation.reason || "Please use a permanent email address"
});
setLoading(false);
return;
}
// Step 2: Reauthenticate with current password
const { error: signInError } = await supabase.auth.signInWithPassword({
email: currentEmail,
password: data.currentPassword,
@@ -109,7 +121,7 @@ export function EmailChangeDialog({ open, onOpenChange, currentEmail, userId }:
throw signInError;
}
// Step 2: Update email address
// Step 3: Update email address
// Supabase will send verification emails to both old and new addresses
const { error: updateError } = await supabase.auth.updateUser({
email: data.newEmail
@@ -117,10 +129,10 @@ export function EmailChangeDialog({ open, onOpenChange, currentEmail, userId }:
if (updateError) throw updateError;
// Step 3: Novu subscriber will be updated automatically after both emails are confirmed
// Step 4: Novu subscriber will be updated automatically after both emails are confirmed
// This happens in the useAuth hook when the email change is fully verified
// Step 4: Log the email change attempt
// Step 5: Log the email change attempt
supabase.from('admin_audit_log').insert({
admin_user_id: userId,
target_user_id: userId,
@@ -134,7 +146,7 @@ export function EmailChangeDialog({ open, onOpenChange, currentEmail, userId }:
if (error) console.error('Failed to log email change:', error);
});
// Step 5: Send security notifications (non-blocking)
// Step 6: Send security notifications (non-blocking)
if (notificationService.isEnabled()) {
notificationService.trigger({
workflowId: 'security-alert',

View File

@@ -0,0 +1,35 @@
import { supabase } from '@/integrations/supabase/client';
interface EmailValidationResult {
valid: boolean;
reason?: string;
suggestions?: string[];
}
/**
* Validates an email address against disposable email domains
* Uses the validate-email edge function to check the backend blocklist
*/
export async function validateEmailNotDisposable(email: string): Promise<EmailValidationResult> {
try {
const { data, error } = await supabase.functions.invoke('validate-email', {
body: { email }
});
if (error) {
console.error('Email validation error:', error);
return {
valid: false,
reason: 'Unable to validate email address. Please try again.'
};
}
return data as EmailValidationResult;
} catch (error) {
console.error('Email validation exception:', error);
return {
valid: false,
reason: 'Unable to validate email address. Please try again.'
};
}
}