diff --git a/src/hooks/useAuth.tsx b/src/hooks/useAuth.tsx
index fc41b3a..ec90b65 100644
--- a/src/hooks/useAuth.tsx
+++ b/src/hooks/useAuth.tsx
@@ -7,7 +7,7 @@ interface AuthContextType {
user: User | null;
session: Session | null;
loading: boolean;
- signIn: (email: string, password: string) => Promise<{ error: unknown }>;
+ signIn: () => Promise<{ error: unknown }>;
signUp: (email: string, password: string) => Promise<{ error: unknown }>;
signOut: () => Promise;
updatePassword: (password: string) => Promise<{ error: unknown }>;
@@ -334,15 +334,17 @@ export function AuthProvider({ children }: { children: ReactNode }) {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [user?.id, authInitialized]);
- const signIn = async (email: string, password: string) => {
+ const signIn = async () => {
try {
- const { error } = await supabase.auth.signInWithPassword({
- email,
- password,
+ const { error } = await supabase.auth.signInWithOAuth({
+ provider: 'keycloak',
+ options: {
+ scopes: 'openid email profile',
+ }
});
return { error };
} catch (error) {
- logger.error('Erro crítico no login:', error);
+ logger.error('Erro crítico no login SSO:', error);
return { error };
}
};
diff --git a/src/main.tsx b/src/main.tsx
index e548786..ff28edb 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -9,6 +9,7 @@ import { AuthProvider } from './hooks/useAuth'
import { IconStyleProvider } from './hooks/useIconStyle'
import { ErrorBoundary } from './components/ErrorBoundary'
import { AppRoutes } from './components/AppRoutes'
+import { LogtoProvider, LogtoConfig } from '@logto/react'
import './index.css'
@@ -28,6 +29,11 @@ const queryClient = new QueryClient({
},
})
+const config: LogtoConfig = {
+ endpoint: 'https://logto-bzlued1boxl3t8ewsyn99an9.187.77.227.172.sslip.io',
+ appId: '4qun0u1tfce1fdn3pxrgq',
+};
+
// ============================================================================
// Render da aplicação
// ============================================================================
@@ -36,16 +42,18 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
,
diff --git a/src/pages/Auth.tsx b/src/pages/Auth.tsx
index dc0b9fc..7591ab2 100644
--- a/src/pages/Auth.tsx
+++ b/src/pages/Auth.tsx
@@ -16,57 +16,35 @@ import { Eye, EyeOff, Mail, Lock } from 'lucide-react';
const Auth = () => {
const [isLoading, setIsLoading] = useState(false);
- const [showPassword, setShowPassword] = useState(false);
- const [showForgotPassword, setShowForgotPassword] = useState(false);
- const [loginData, setLoginData] = useState({ email: '', password: '' });
- const [signupData, setSignupData] = useState({ email: '', password: '', confirmPassword: '' });
- const { signIn, signUp, user, loading, isRecoveryFlow, session } = useAuth();
+ const { signIn, user, loading, isRecoveryFlow, session } = useAuth();
const { brandSettings } = useBrandSettings();
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const location = useLocation();
+ const recoveryType = searchParams.get('type');
+ const hashParams = new URLSearchParams(location.hash.substring(1));
+ const hashType = hashParams.get('type');
+ const accessToken = hashParams.get('access_token');
+ const refreshToken = hashParams.get('refresh_token');
+
+ const shouldShowReset = Boolean(
+ recoveryType === 'recovery' ||
+ hashType === 'recovery' ||
+ isRecoveryFlow ||
+ (accessToken && refreshToken)
+ );
+
// Estado para controlar se está em modo de recuperação
- const [showPasswordReset, setShowPasswordReset] = useState(false);
+ const [showPasswordReset, setShowPasswordReset] = useState(shouldShowReset);
useEffect(() => {
- console.log('🔍 Auth.tsx - Verificando fluxo de recuperação...');
- console.log('Location:', {
- pathname: location.pathname,
- search: location.search,
- hash: location.hash
- });
- console.log('Auth states:', {
- user: !!user,
- session: !!session,
- isRecoveryFlow,
- loading
- });
-
- // Verificar se é fluxo de recuperação
- const recoveryType = searchParams.get('type');
- const hashParams = new URLSearchParams(location.hash.substring(1));
- const hashType = hashParams.get('type');
- const accessToken = hashParams.get('access_token');
- const refreshToken = hashParams.get('refresh_token');
-
- console.log('🔍 Parâmetros de recuperação:', {
- recoveryType,
- hashType,
- accessToken: !!accessToken,
- refreshToken: !!refreshToken,
- isRecoveryFlow
- });
-
- // Se há type=recovery OU isRecoveryFlow OU tokens, mostrar tela de reset
- const shouldShowReset = recoveryType === 'recovery' ||
- hashType === 'recovery' ||
- isRecoveryFlow ||
- (accessToken && refreshToken);
-
- console.log('🔑 Deve mostrar reset de senha:', shouldShowReset);
- setShowPasswordReset(Boolean(shouldShowReset));
- }, [searchParams, location.hash, location.search, isRecoveryFlow, user, session]);
+ if (shouldShowReset !== showPasswordReset) {
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ setShowPasswordReset(shouldShowReset);
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [shouldShowReset, showPasswordReset, loading, location.pathname]);
// Redirecionar usuários autenticados para página principal (exceto em fluxo de recuperação)
useEffect(() => {
@@ -139,112 +117,18 @@ const Auth = () => {
);
}
- const validatePassword = (password: string) => {
- const minLength = password.length >= 8;
- const hasUpperCase = /[A-Z]/.test(password);
- const hasLowerCase = /[a-z]/.test(password);
- const hasNumbers = /\d/.test(password);
- const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(password);
-
- const score = [minLength, hasUpperCase, hasLowerCase, hasNumbers, hasSpecialChar].filter(Boolean).length;
-
- return {
- score,
- minLength,
- hasUpperCase,
- hasLowerCase,
- hasNumbers,
- hasSpecialChar,
- isValid: score >= 4 && minLength
- };
- };
-
- const passwordStrength = validatePassword(signupData.password);
-
- // Email validation
- const isValidEmail = (email: string) => {
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
- return emailRegex.test(email);
- };
-
- const handleLogin = async (e: React.FormEvent) => {
- e.preventDefault();
-
- if (!loginData.email || !loginData.password) {
- toast.error('Por favor, preencha todos os campos');
- return;
- }
-
- if (!isValidEmail(loginData.email)) {
- toast.error('Por favor, insira um email válido');
- return;
- }
-
+ const handleLogin = async () => {
setIsLoading(true);
- const { error } = await signIn(loginData.email, loginData.password);
+ const { error } = await signIn();
if (error) {
- if (error.message.includes('Invalid login credentials')) {
- toast.error('Email ou senha incorretos');
- } else {
- toast.error('Erro ao fazer login: ' + error.message);
- }
- } else {
- toast.success('Login realizado com sucesso!');
- navigate('/');
+ toast.error('Erro ao redirecionar para o login: ' + (error as Error).message);
+ setIsLoading(false);
}
- setIsLoading(false);
+ // No else block needed as it redirects to external OIDC provider
};
- const handleSignup = async (e: React.FormEvent) => {
- e.preventDefault();
-
- if (!signupData.email || !signupData.password || !signupData.confirmPassword) {
- toast.error('Por favor, preencha todos os campos');
- return;
- }
- if (!isValidEmail(signupData.email)) {
- toast.error('Por favor, insira um email válido');
- return;
- }
-
- if (!passwordStrength.isValid) {
- toast.error('A senha deve ter pelo menos 8 caracteres e incluir maiúsculas, minúsculas, números e símbolos');
- return;
- }
-
- if (signupData.password !== signupData.confirmPassword) {
- toast.error('As senhas não coincidem');
- return;
- }
-
- setIsLoading(true);
- const { error } = await signUp(signupData.email, signupData.password);
-
- if (error) {
- if (error.message.includes('User already registered')) {
- toast.error('Este email já está cadastrado');
- } else {
- toast.error('Erro ao criar conta: ' + error.message);
- }
- } else {
- toast.success('Conta criada com sucesso! Verifique seu email.');
- }
- setIsLoading(false);
- };
-
- const getPasswordStrengthColor = (score: number) => {
- if (score <= 2) return 'bg-red-500';
- if (score <= 3) return 'bg-yellow-500';
- return 'bg-green-500';
- };
-
- const getPasswordStrengthText = (score: number) => {
- if (score <= 2) return 'Fraca';
- if (score <= 3) return 'Média';
- return 'Forte';
- };
console.log('📱 Renderizando página de login/cadastro');
return (
@@ -281,188 +165,14 @@ const Auth = () => {
-
-
-
- Entrar
- Cadastrar
-
-
-
-
-
-
-
-
-
-
+
+
@@ -471,12 +181,6 @@ const Auth = () => {
-
- {/* Modal Esqueci a Senha */}
- setShowForgotPassword(false)}
- />
);
};