add-new-login-endpoint
This commit is contained in:
parent
c07705a2fc
commit
be789948ee
46
susconecta/app/api/signin-user/route.ts
Normal file
46
susconecta/app/api/signin-user/route.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { ENV_CONFIG } from '@/lib/env-config';
|
||||
|
||||
/**
|
||||
* Proxy server-side route (App Router) to call Supabase OpenAPI /auth/v1/signin
|
||||
* This keeps the Supabase anon key on the server and avoids CORS from browsers.
|
||||
*/
|
||||
export async function POST(req: Request) {
|
||||
try {
|
||||
const payload = await req.json();
|
||||
|
||||
// Lightweight, non-sensitive debug logging to verify the proxy is hit at runtime.
|
||||
try {
|
||||
console.log('[api/signin-user] POST received', {
|
||||
url: typeof (req as any).url === 'string' ? (req as any).url : undefined,
|
||||
email: payload?.email ?? null,
|
||||
});
|
||||
} catch (e) {
|
||||
// never throw from logging
|
||||
}
|
||||
|
||||
const url = `${ENV_CONFIG.SUPABASE_URL}/auth/v1/signin`;
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
apikey: ENV_CONFIG.SUPABASE_ANON_KEY,
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
const text = await response.text();
|
||||
let data: any = null;
|
||||
try {
|
||||
data = text ? JSON.parse(text) : null;
|
||||
} catch (e) {
|
||||
data = text;
|
||||
}
|
||||
|
||||
return NextResponse.json(data, { status: response.status });
|
||||
} catch (error) {
|
||||
console.error('[api/signin-user] Unexpected error', error);
|
||||
return NextResponse.json({ error: 'Internal proxy error' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@ -89,7 +89,10 @@ export async function loginUser(
|
||||
password: string,
|
||||
userType: 'profissional' | 'paciente' | 'administrador'
|
||||
): Promise<LoginResponse> {
|
||||
let url = AUTH_ENDPOINTS.LOGIN;
|
||||
// Use server-side AUTH_ENDPOINTS.LOGIN by default. When running in the browser
|
||||
// prefer the local proxy that forwards to the OpenAPI signin: `/api/signin-user`.
|
||||
const isBrowser = typeof window !== 'undefined';
|
||||
const url = isBrowser ? '/api/signin-user' : AUTH_ENDPOINTS.LOGIN;
|
||||
|
||||
const payload = {
|
||||
email,
|
||||
@ -104,9 +107,9 @@ export async function loginUser(
|
||||
timestamp: new Date().toLocaleTimeString()
|
||||
});
|
||||
|
||||
console.log('🔑 [AUTH-API] Credenciais sendo usadas no login:');
|
||||
// Log only non-sensitive info; never log passwords
|
||||
console.log('🔑 [AUTH-API] Credenciais sendo usadas no login (redacted):');
|
||||
console.log('📧 Email:', email);
|
||||
console.log('🔐 Senha:', password);
|
||||
console.log('👤 UserType:', userType);
|
||||
|
||||
// Delay para visualizar na aba Network
|
||||
@ -118,11 +121,48 @@ export async function loginUser(
|
||||
// Debug: Log request sem credenciais sensíveis
|
||||
debugRequest('POST', url, getLoginHeaders(), payload);
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: getLoginHeaders(),
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
// Helper to perform a login fetch and return response (no processing here)
|
||||
async function doLoginFetch(targetUrl: string) {
|
||||
try {
|
||||
return await fetch(targetUrl, {
|
||||
method: 'POST',
|
||||
headers: getLoginHeaders(),
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
} catch (err) {
|
||||
// bubble up the error to the caller
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
let response: Response;
|
||||
try {
|
||||
response = await doLoginFetch(url);
|
||||
} catch (networkError) {
|
||||
console.warn('[AUTH-API] Network error when calling', url, networkError);
|
||||
// Try fallback to server endpoints if available
|
||||
const fallback1 = AUTH_ENDPOINTS.LOGIN;
|
||||
const fallback2 = `${ENV_CONFIG.SUPABASE_URL}/auth/v1/signin`;
|
||||
let tried = [] as string[];
|
||||
|
||||
try {
|
||||
tried.push(fallback1);
|
||||
response = await doLoginFetch(fallback1);
|
||||
} catch (e1) {
|
||||
console.warn('[AUTH-API] Fallback1 failed', fallback1, e1);
|
||||
try {
|
||||
tried.push(fallback2);
|
||||
response = await doLoginFetch(fallback2);
|
||||
} catch (e2) {
|
||||
console.error('[AUTH-API] All fallbacks failed', { tried, e1, e2 });
|
||||
throw new AuthenticationError(
|
||||
'Não foi possível contatar o serviço de autenticação (todos os caminhos falharam)',
|
||||
'AUTH_NETWORK_ERROR',
|
||||
{ tried }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[AUTH-API] Login response: ${response.status} ${response.statusText}`, {
|
||||
url: response.url,
|
||||
@ -130,6 +170,34 @@ export async function loginUser(
|
||||
timestamp: new Date().toLocaleTimeString()
|
||||
});
|
||||
|
||||
// If proxy returned 404, try direct fallbacks (in case the proxy route is missing)
|
||||
if (response.status === 404) {
|
||||
console.warn('[AUTH-API] Proxy returned 404, attempting direct login fallbacks');
|
||||
const fallback1 = AUTH_ENDPOINTS.LOGIN;
|
||||
const fallback2 = `${ENV_CONFIG.SUPABASE_URL}/auth/v1/signin`;
|
||||
let fallbackResponse: Response | null = null;
|
||||
try {
|
||||
fallbackResponse = await doLoginFetch(fallback1);
|
||||
} catch (e) {
|
||||
console.warn('[AUTH-API] fallback1 failed', fallback1, e);
|
||||
}
|
||||
|
||||
if (!fallbackResponse || fallbackResponse.status === 404) {
|
||||
try {
|
||||
fallbackResponse = await doLoginFetch(fallback2);
|
||||
} catch (e) {
|
||||
console.warn('[AUTH-API] fallback2 failed', fallback2, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (fallbackResponse) {
|
||||
response = fallbackResponse;
|
||||
console.log('[AUTH-API] Used fallback response', { url: response.url, status: response.status });
|
||||
} else {
|
||||
console.error('[AUTH-API] No fallback produced a valid response');
|
||||
}
|
||||
}
|
||||
|
||||
// Se falhar, mostrar detalhes do erro
|
||||
if (!response.ok) {
|
||||
try {
|
||||
@ -148,6 +216,16 @@ export async function loginUser(
|
||||
// Delay adicional para ver status code
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
|
||||
// If after trying fallbacks we still have a 404, make the error explicit and actionable
|
||||
if (response.status === 404) {
|
||||
console.error('[AUTH-API] Final response was 404 (Not Found). Likely the local proxy route is missing or Next dev server is not running.', { url: response.url });
|
||||
throw new AuthenticationError(
|
||||
'Signin endpoint not found (404). Ensure Next.js dev server is running and the route `/api/signin-user` exists.',
|
||||
'SIGNIN_NOT_FOUND',
|
||||
{ url: response.url }
|
||||
);
|
||||
}
|
||||
|
||||
const data = await processResponse<any>(response);
|
||||
|
||||
console.log('[AUTH] Dados recebidos da API:', data);
|
||||
|
||||
@ -9,7 +9,6 @@ export function debugRequest(
|
||||
body?: any
|
||||
) {
|
||||
if (process.env.NODE_ENV !== 'development') return;
|
||||
|
||||
const headersWithoutSensitive = Object.keys(headers).reduce((acc, key) => {
|
||||
// Não logar valores sensíveis, apenas nomes
|
||||
if (key.toLowerCase().includes('apikey') || key.toLowerCase().includes('authorization')) {
|
||||
@ -20,15 +19,35 @@ export function debugRequest(
|
||||
return acc;
|
||||
}, {} as Record<string, string>);
|
||||
|
||||
const bodyShape = body ? Object.keys(typeof body === 'string' ? JSON.parse(body) : body) : [];
|
||||
const bodyShape = body ? Object.keys(typeof body === 'string' ? (() => {
|
||||
try { return JSON.parse(body); } catch { return {}; }
|
||||
})() : body) : [];
|
||||
|
||||
console.log('[DEBUG] Request Preview:', {
|
||||
method,
|
||||
path: new URL(url).pathname,
|
||||
query: new URL(url).search,
|
||||
headerNames: Object.keys(headers),
|
||||
headers: headersWithoutSensitive,
|
||||
bodyShape,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
// Support relative URLs (e.g. '/api/signin-user') by providing a base when needed.
|
||||
try {
|
||||
let urlObj: URL;
|
||||
try {
|
||||
urlObj = new URL(url);
|
||||
} catch (e) {
|
||||
// Fallbacks: browser origin or localhost for server-side dev
|
||||
const base = (typeof window !== 'undefined' && window.location && window.location.origin)
|
||||
? window.location.origin
|
||||
: 'http://localhost';
|
||||
urlObj = new URL(url, base);
|
||||
}
|
||||
|
||||
console.log('[DEBUG] Request Preview:', {
|
||||
method,
|
||||
path: urlObj.pathname,
|
||||
query: urlObj.search,
|
||||
headerNames: Object.keys(headers),
|
||||
headers: headersWithoutSensitive,
|
||||
bodyShape,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
} catch (err) {
|
||||
// Never throw from debug tooling; keep best-effort logging
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('[DEBUG] debugRequest failed to parse URL or body', { url, error: err });
|
||||
}
|
||||
}
|
||||
39
susconecta/pages/api/signin-user.ts
Normal file
39
susconecta/pages/api/signin-user.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { ENV_CONFIG } from '@/lib/env-config';
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method !== 'POST') {
|
||||
res.setHeader('Allow', 'POST');
|
||||
return res.status(405).json({ error: 'Method not allowed' });
|
||||
}
|
||||
|
||||
try {
|
||||
const payload = req.body;
|
||||
|
||||
// Lightweight debug log to confirm the pages API route is invoked.
|
||||
try {
|
||||
console.log('[pages/api/signin-user] POST received', { url: req.url, email: payload?.email ?? null });
|
||||
} catch (e) {
|
||||
// ignore logging errors
|
||||
}
|
||||
const url = `${ENV_CONFIG.SUPABASE_URL}/auth/v1/signin`;
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
apikey: ENV_CONFIG.SUPABASE_ANON_KEY,
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
const text = await response.text();
|
||||
let data: any = null;
|
||||
try { data = text ? JSON.parse(text) : null; } catch { data = text; }
|
||||
|
||||
return res.status(response.status).json(data);
|
||||
} catch (error) {
|
||||
console.error('[pages/api/signin-user] Unexpected error', error);
|
||||
return res.status(500).json({ error: 'Internal proxy error' });
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user