diff --git a/src/App.tsx b/src/App.tsx
index a1c0a18..27b7448 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,7 +1,9 @@
+
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import { Suspense, lazy } from 'react';
import { Toaster } from "@/components/ui/sonner";
import Auth from './pages/Auth';
+import EmailConfirmation from './pages/EmailConfirmation';
import ProtectedRoute from './components/auth/ProtectedRoute';
import { authStore } from './stores/authStore';
@@ -31,6 +33,12 @@ function App() {
element={isLoggedIn ? : }
/>
+ {/* Email confirmation route - should be accessible without authentication */}
+ }
+ />
+
{/* Protected routes */}
diff --git a/src/components/auth/AuthSecurityFeatures.tsx b/src/components/auth/AuthSecurityFeatures.tsx
new file mode 100644
index 0000000..863293c
--- /dev/null
+++ b/src/components/auth/AuthSecurityFeatures.tsx
@@ -0,0 +1,32 @@
+
+import { Alert, AlertDescription } from "@/components/ui/alert";
+import { Shield, Mail, Lock } from 'lucide-react';
+
+const AuthSecurityFeatures = () => {
+ return (
+
+
+
+
+ Segurança reforçada: Sua conta está protegida contra tentativas de acesso não autorizado.
+
+
+
+
+
+
+ Confirmação por email: Você receberá um link de confirmação para ativar sua conta.
+
+
+
+
+
+
+ Proteção contra força bruta: Sistema automaticamente bloqueia tentativas suspeitas.
+
+
+
+ );
+};
+
+export default AuthSecurityFeatures;
diff --git a/src/components/auth/RegisterForm.tsx b/src/components/auth/RegisterForm.tsx
index d346220..1312625 100644
--- a/src/components/auth/RegisterForm.tsx
+++ b/src/components/auth/RegisterForm.tsx
@@ -49,7 +49,7 @@ const RegisterForm = ({ isLoading, setIsLoading }: RegisterFormProps) => {
email,
password: senha,
options: {
- emailRedirectTo: `${window.location.origin}/`,
+ emailRedirectTo: `${window.location.origin}/email-confirmation`,
data: {
nome,
empresa: empresa || null,
@@ -69,7 +69,7 @@ const RegisterForm = ({ isLoading, setIsLoading }: RegisterFormProps) => {
if (data.user.identities && data.user.identities.length === 0) {
console.log('👤 Usuário já existe, reenviando confirmação');
toast.info("E-mail já cadastrado. Verifique sua caixa de entrada!", {
- description: "Enviamos um novo link para você definir sua senha e acessar sua conta. Não se esqueça de checar a pasta de spam.",
+ description: "Enviamos um novo link de confirmação para você ativar sua conta. Não se esqueça de checar a pasta de spam.",
duration: 10000,
});
} else {
@@ -94,11 +94,17 @@ const RegisterForm = ({ isLoading, setIsLoading }: RegisterFormProps) => {
console.error('❌ Erro crítico no webhook para n8n:', error);
});
+ // Show success message and redirect to login
+ toast.success("Cadastro realizado com sucesso!", {
+ description: "📧 Enviamos um link de confirmação para seu email. Clique no link para ativar sua conta e fazer login.",
+ duration: 10000,
+ });
+
// Redirect to login page with success message
navigate('/auth', {
state: {
showSuccessMessage: true,
- message: "✅ Cadastro realizado com sucesso! Agora, faça o login com o e-mail e a senha que você acabou de criar."
+ message: "✅ Cadastro realizado! Verifique seu email e clique no link de confirmação para ativar sua conta."
}
});
}
diff --git a/src/components/auth/SocialLoginButtons.tsx b/src/components/auth/SocialLoginButtons.tsx
new file mode 100644
index 0000000..09fe488
--- /dev/null
+++ b/src/components/auth/SocialLoginButtons.tsx
@@ -0,0 +1,96 @@
+
+import { useState } from 'react';
+import { Button } from "@/components/ui/button";
+import { toast } from "sonner";
+import { supabase } from '@/integrations/supabase/client';
+
+const SocialLoginButtons = () => {
+ const [loadingGoogle, setLoadingGoogle] = useState(false);
+
+ const handleGoogleLogin = async () => {
+ setLoadingGoogle(true);
+
+ try {
+ console.log('🔐 Iniciando login com Google...');
+
+ const { error } = await supabase.auth.signInWithOAuth({
+ provider: 'google',
+ options: {
+ redirectTo: `${window.location.origin}/`,
+ queryParams: {
+ access_type: 'offline',
+ prompt: 'consent',
+ }
+ }
+ });
+
+ if (error) {
+ console.error('❌ Erro no login com Google:', error);
+ toast.error("Erro no login com Google", {
+ description: error.message || "Não foi possível conectar com o Google. Tente novamente.",
+ });
+ }
+ // Note: Se não houver erro, o usuário será redirecionado automaticamente
+ } catch (error) {
+ console.error('❌ Erro geral no login com Google:', error);
+ toast.error("Erro no login", {
+ description: "Ocorreu um erro inesperado. Tente novamente.",
+ });
+ } finally {
+ setLoadingGoogle(false);
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+ Ou continue com
+
+
+
+
+
+
+ );
+};
+
+export default SocialLoginButtons;
diff --git a/src/pages/Auth.tsx b/src/pages/Auth.tsx
index eb29d96..3f192ca 100644
--- a/src/pages/Auth.tsx
+++ b/src/pages/Auth.tsx
@@ -5,6 +5,8 @@ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle }
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import LoginForm from '@/components/auth/LoginForm';
import RegisterForm from '@/components/auth/RegisterForm';
+import SocialLoginButtons from '@/components/auth/SocialLoginButtons';
+import AuthSecurityFeatures from '@/components/auth/AuthSecurityFeatures';
import { toast } from "sonner";
const Auth = () => {
@@ -12,10 +14,10 @@ const Auth = () => {
const [activeTab, setActiveTab] = useState("login");
const location = useLocation();
- // Show success message when redirected from registration
+ // Show success message when redirected from registration or email confirmation
useEffect(() => {
if (location.state?.showSuccessMessage && location.state?.message) {
- toast.success("Cadastro realizado!", {
+ toast.success("Sucesso!", {
description: location.state.message,
duration: 8000,
});
@@ -40,12 +42,15 @@ const Auth = () => {
Cadastro
-
+
+
-
+
+
+
diff --git a/src/pages/EmailConfirmation.tsx b/src/pages/EmailConfirmation.tsx
new file mode 100644
index 0000000..e463099
--- /dev/null
+++ b/src/pages/EmailConfirmation.tsx
@@ -0,0 +1,126 @@
+
+import { useEffect, useState } from 'react';
+import { useNavigate, useSearchParams } from 'react-router-dom';
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
+import { Button } from "@/components/ui/button";
+import { CheckCircle, XCircle, Loader2 } from 'lucide-react';
+import { supabase } from '@/integrations/supabase/client';
+import { toast } from "sonner";
+
+const EmailConfirmation = () => {
+ const [searchParams] = useSearchParams();
+ const navigate = useNavigate();
+ const [status, setStatus] = useState<'loading' | 'success' | 'error'>('loading');
+ const [message, setMessage] = useState('');
+
+ useEffect(() => {
+ const handleEmailConfirmation = async () => {
+ try {
+ // Pegar os tokens da URL
+ const token_hash = searchParams.get('token_hash');
+ const type = searchParams.get('type');
+
+ if (token_hash && type) {
+ console.log('🔐 Processando confirmação de email...');
+
+ const { data, error } = await supabase.auth.verifyOtp({
+ token_hash,
+ type: type as any,
+ });
+
+ if (error) {
+ console.error('❌ Erro na confirmação:', error);
+ setStatus('error');
+ setMessage('Erro ao confirmar email. O link pode ter expirado.');
+ toast.error("Erro na confirmação", {
+ description: "O link de confirmação pode ter expirado. Tente fazer login novamente.",
+ });
+ } else {
+ console.log('✅ Email confirmado com sucesso:', data);
+ setStatus('success');
+ setMessage('Email confirmado com sucesso! Você já pode fazer login.');
+ toast.success("Email confirmado!", {
+ description: "Sua conta foi ativada com sucesso. Redirecionando...",
+ });
+
+ // Redirecionar para login após 3 segundos
+ setTimeout(() => {
+ navigate('/auth', {
+ state: {
+ showSuccessMessage: true,
+ message: "✅ Email confirmado! Agora você pode fazer login com suas credenciais."
+ }
+ });
+ }, 3000);
+ }
+ } else {
+ setStatus('error');
+ setMessage('Link de confirmação inválido.');
+ }
+ } catch (error) {
+ console.error('❌ Erro geral na confirmação:', error);
+ setStatus('error');
+ setMessage('Ocorreu um erro inesperado.');
+ }
+ };
+
+ handleEmailConfirmation();
+ }, [searchParams, navigate]);
+
+ const handleBackToLogin = () => {
+ navigate('/auth');
+ };
+
+ return (
+
+
+
+ Confirmação de Email
+
+ {status === 'loading' && "Processando confirmação do seu email..."}
+ {status === 'success' && "Email confirmado com sucesso!"}
+ {status === 'error' && "Problema na confirmação"}
+
+
+
+
+ {status === 'loading' && (
+ <>
+
+
+ Aguarde enquanto confirmamos seu email...
+
+ >
+ )}
+
+ {status === 'success' && (
+ <>
+
+
+ {message}
+
+
+ Você será redirecionado automaticamente em alguns segundos...
+