almeira-web/src/lib/appwrite.server.ts

122 lines
3.5 KiB
TypeScript

import { Client, Account, Databases } from 'node-appwrite';
import { cookies } from 'next/headers';
// Robust instance-level patch for Appwrite Next.js Server Components
export function patchClientInstance(client: any) {
if (client._isPatched) return client;
const originalCall = client.call.bind(client);
client.call = async function (...args: any[]) {
// Suppress Appwrite version mismatch warnings during this call
const oldWarn = console.warn;
console.warn = (...warnArgs: any[]) => {
if (warnArgs[0] && typeof warnArgs[0] === 'string' && warnArgs[0].includes('built for Appwrite')) return;
oldWarn(...warnArgs);
};
try {
const res = await originalCall(...args);
// Ensure all objects are fully plain JSON (strips getters/prototypes that break Server -> Client transitions)
if (res && typeof res === 'object') {
return JSON.parse(JSON.stringify(res));
}
return res;
} finally {
console.warn = oldWarn;
}
};
client._isPatched = true;
return client;
}
const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1';
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c';
const COOKIE_NAME = `a_session_${PROJECT_ID.toLowerCase()}`;
export async function createSessionClient() {
const cookieStore = await cookies();
const sessionCookie = cookieStore.get(COOKIE_NAME);
if (!sessionCookie || !sessionCookie.value) {
return null;
}
const client = new Client()
.setEndpoint(ENDPOINT)
.setProject(PROJECT_ID);
// Soporte para bypass de administrador (Emergencia/Dev)
if (sessionCookie.value === "admin-bypass-session") {
// Escalamos a privilegios de API Key para el bypass
client.setKey((process.env.APPWRITE_API_KEY || '').trim());
} else {
client.setSession(sessionCookie.value);
}
patchClientInstance(client);
return {
get account() {
return new Account(client);
},
get databases() {
return new Databases(client);
}
};
}
export async function createAdminClient() {
const client = new Client()
.setEndpoint(ENDPOINT)
.setProject(PROJECT_ID)
.setKey((process.env.APPWRITE_API_KEY || '').trim());
patchClientInstance(client);
return {
get account() {
return new Account(client);
},
get databases() {
return new Databases(client);
}
};
}
export async function getLoggedInUser() {
try {
const cookieStore = await cookies();
const sessionCookie = cookieStore.get(COOKIE_NAME);
// Verificación de bypass (Evitamos imprimir log repetitivo a menos que sea un error)
if (sessionCookie?.value === "admin-bypass-session") {
return {
$id: "admin-emergency",
name: "Administrador (Emergencia)",
email: "admin@almeira.com.co",
prefs: { role: 'admin' }
};
}
if (!sessionCookie || !sessionCookie.value) {
return null;
}
const sessionClient = await createSessionClient();
if (!sessionClient) {
return null;
}
return await sessionClient.account.get();
} catch (error: any) {
// Next.js uses a specific error to bailout of static generation. We MUST re-throw it.
if (error?.digest === 'DYNAMIC_SERVER_USAGE' || error?.message?.includes('Dynamic server usage')) {
throw error;
}
if (error?.code !== 401) {
console.error("getLoggedInUser: Error al validar sesión:", error.message || error);
}
return null;
}
}