import { BookProject, Chapter, Entity, Idea, WorkflowData, UserProfile } from '../types'; // Configuration NoCodeBackend const AUTH_API_ROOT = 'https://app.nocodebackend.com/api/user-auth'; const DATA_API_ROOT = 'https://openapi.nocodebackend.com'; const INSTANCE_ID = '54770_plumeia_db'; // WARNING: SECRET_KEY restored for debugging purposes (createItem failed without it). // Ideally, RLS should allow user creation. If not, this key is needed. const SECRET_KEY = 'c11b7be982d6f369b71a74a7735caf8c2d25d6b09bb5a6ac52d12d49bff3acf1'; const mcp_server = "ncb_67f8e246c8e4e18598918212035ba6b309d6cac9a6aec919"; /** * Récupère les headers avec gestion du token de session * @param forceUserToken Si true, on n'utilise pas la SECRET_KEY en fallback (pour l'auth) */ const getHeaders = (isAuthAction = false) => { const token = localStorage.getItem('ncb_session_token'); const headers: any = { 'Content-Type': 'application/json', 'X-Database-Instance': INSTANCE_ID }; // RLS requires the User Token in the Authorization header if (token && !isAuthAction) { headers['Authorization'] = `Bearer ${token}`; } else { // FALLBACK: Use Secret Key if no token is available (e.g., initial profile creation) headers['Authorization'] = `Bearer ${SECRET_KEY}`; } return headers; }; /** * Service d'authentification NoCodeBackend */ export const authService = { async getSession() { console.log("[Auth] getSession"); const token = localStorage.getItem('ncb_session_token'); if (!token) return null; console.log("[Auth] getSession token:", token); try { const res = await fetch(`${AUTH_API_ROOT}/get-session`, { method: 'GET', headers: getHeaders(), credentials: 'include' }); const data = await res.json(); console.log("[Auth] getSession data:", data); if (!res.ok || !data) { // Vérifie que data existe if (res.status === 401) localStorage.removeItem('ncb_session_token'); return null; } // Utilise le chaînage optionnel ?. return data?.user || (data?.id ? data : null); } catch (err) { console.error("[Auth] Erreur critique getSession:", err); return null; } }, async signIn(email: string, password: string) { console.log("[Auth] Tentative de connexion pour:", email); try { const res = await fetch(`${AUTH_API_ROOT}/sign-in/email`, { method: 'POST', headers: getHeaders(true), body: JSON.stringify({ email, password }), credentials: 'include' }); const data = await res.json(); console.log("[Auth] signIn: Payload reçu:", data); if (!res.ok) { return { error: data.message || 'Identifiants incorrects' }; } // DEBUG: Trace exact token extraction console.log("[Auth] Token extraction attempt:", { 'user.token': data.user?.token, 'token': data.token, 'session.token': data.session?.token, 'auth_token': data.auth_token, 'accessToken': data.accessToken, '_token': data._token }); const token = data.user?.token || data.token || data.session?.token || data.auth_token || data.accessToken || data._token; console.log("[Auth] Final extracted token:", token); if (token) { localStorage.setItem('ncb_session_token', token); } else { console.error("[Auth] WARNING: No token found in response!"); } return data; } catch (err) { console.error("[Auth] Erreur réseau sign-in:", err); return { error: 'Erreur réseau lors de la connexion' }; } }, async signUp(email: string, password: string, name: string) { try { const res = await fetch(`${AUTH_API_ROOT}/sign-up/email`, { method: 'POST', headers: getHeaders(true), body: JSON.stringify({ email, password, name }), credentials: 'include' }); const data = await res.json(); if (!res.ok) { return { error: data.message || "Erreur lors de la création du compte" }; } const token = data.user?.token || data.token || data.session?.token || data.auth_token || data.accessToken; if (token) { localStorage.setItem('ncb_session_token', token); } return data; } catch (err) { return { error: "Erreur réseau lors de l'inscription" }; } }, async signOut() { try { await fetch(`${AUTH_API_ROOT}/sign-out`, { method: 'POST', headers: getHeaders(true), body: JSON.stringify({}), credentials: 'include' }); } catch (err) { console.error("[Auth] Erreur sign-out:", err); } finally { localStorage.removeItem('ncb_session_token'); } } }; export const dataService = { async getProfile(userId: string) { try { const encodedId = encodeURIComponent(userId); const url = `${DATA_API_ROOT}/read/profiles?Instance=${INSTANCE_ID}&user_id=${encodedId}`; const res = await fetch(url, { headers: getHeaders(), credentials: 'include' }); const json = await res.json(); if (!res.ok) { console.error("[Data] Erreur lecture profil API:", json); return null; } return json.data?.[0] || null; } catch (err) { console.error("[Data] Erreur lecture profil:", err); return null; } }, async getProjects(userId: string) { try { const encodedId = encodeURIComponent(userId); const url = `${DATA_API_ROOT}/read/projects?Instance=${INSTANCE_ID}&user_id=${encodedId}`; const res = await fetch(url, { headers: getHeaders(), credentials: 'include' }); const json = await res.json(); return json.data || []; } catch (err) { console.error("[Data] Erreur lecture projets:", err); return []; } }, async createProject(projectData: any) { try { const url = `${DATA_API_ROOT}/create/projects?Instance=${INSTANCE_ID}`; const res = await fetch(url, { method: 'POST', headers: getHeaders(), body: JSON.stringify(projectData), credentials: 'include' }); const data = await res.json(); return data; } catch (err) { console.error("[Data] Erreur création projet:", err); return { status: 'error' }; } }, async getRelatedData(table: string, projectId: number) { try { const url = `${DATA_API_ROOT}/read/${table}?Instance=${INSTANCE_ID}&project_id=${projectId}`; const res = await fetch(url, { headers: getHeaders(), credentials: 'include' }); const json = await res.json(); return json.data || []; } catch (err) { console.error(`[Data] Erreur lecture ${table}:`, err); return []; } }, async createItem(table: string, data: any) { try { console.log(`[Data] Création item dans ${table}...`, data); const url = `${DATA_API_ROOT}/create/${table}?Instance=${INSTANCE_ID}`; const res = await fetch(url, { method: 'POST', headers: getHeaders(), body: JSON.stringify(data), credentials: 'include' }); const result = await res.json(); if (!res.ok) { console.error(`[Data] Erreur API création ${table}:`, result); } return result; } catch (err) { console.error(`[Data] Erreur réseau création item ${table}:`, err); return { status: 'error', message: err }; } }, async updateItem(table: string, id: number, data: any) { try { const url = `${DATA_API_ROOT}/update/${table}/${id}?Instance=${INSTANCE_ID}`; await fetch(url, { method: 'PUT', headers: getHeaders(), body: JSON.stringify(data), credentials: 'include' }); } catch (err) { console.error(`[Data] Erreur mise à jour item ${table}:`, err); } }, async deleteItem(table: string, id: number) { try { const url = `${DATA_API_ROOT}/delete/${table}/${id}?Instance=${INSTANCE_ID}`; await fetch(url, { method: 'DELETE', headers: getHeaders(), credentials: 'include' }); } catch (err) { console.error(`[Data] Erreur suppression item ${table}:`, err); } } };