import forge from 'node-forge'; import { apiGet, apiPost } from './apiClient.js'; let cachedPublicKeyPem = null; const VERIFACTU_ERROR_MESSAGES = { missing_fields: 'Faltan campos obligatorios para registrar el certificado.', invalid_json: 'La peticion enviada a VeriFactu no tiene un JSON valido.', invalid_password_encrypted: 'La contraseña cifrada no tiene un formato valido.', decrypt_failed: 'No se pudo descifrar la contraseña del certificado.', file_not_found: 'No se encontro el archivo del certificado.', invalid_password_or_format: 'La contraseña del .p12 es incorrecta o el archivo no es valido.', certificate_not_yet_valid: 'El certificado aun no es valido por fecha.', certificate_expired: 'El certificado ha caducado.', temp_storage_failed: 'No se pudo guardar el certificado temporalmente.', storage_failed: 'No se pudo guardar el certificado de forma permanente.', token_generation_failed: 'No se pudo generar el token de sesion del certificado.', hash_storage_error: 'Error leyendo el hash previo de facturacion.', hash_save_error: 'Error guardando el hash de la factura.', internal_server_error: 'VeriFactu devolvio un error interno del servidor.' }; export async function getVeriFactuHealth() { return apiGet('/api/VeriFactu/health', { auth: false }); } export async function getVeriFactuPublicKey() { return apiGet('/api/VeriFactu/public-key', { auth: false }); } async function getVeriFactuPublicKeyPem() { if (cachedPublicKeyPem) { return cachedPublicKeyPem; } const response = await getVeriFactuPublicKey(); if (!response?.public_key) { throw new Error('La API no devolvio la clave publica de VeriFactu'); } cachedPublicKeyPem = atob(response.public_key); return cachedPublicKeyPem; } export async function encryptVeriFactuPassword(password) { if (!password) { throw new Error('La contraseña del certificado no puede estar vacia'); } console.log('[ENCRYPT] Input password:', password); const publicKeyPem = await getVeriFactuPublicKeyPem(); console.log('[ENCRYPT] Got public key'); const publicKey = forge.pki.publicKeyFromPem(publicKeyPem); console.log('[ENCRYPT] Parsed public key'); const encryptedBytes = publicKey.encrypt(forge.util.encodeUtf8(password), 'RSAES-PKCS1-V1_5'); console.log('[ENCRYPT] RSA encrypted, bytes length:', encryptedBytes.length); const result = forge.util.encode64(encryptedBytes); console.log('[ENCRYPT] Base64 encoded, result length:', result.length); return result; } export async function getVeriFactuFormats() { return apiGet('/api/VeriFactu/formats', { auth: false }); } export async function registerVeriFactuCertificate(payload) { return apiPost('/api/VeriFactu/certificates/register', payload); } export function formatVeriFactuError(errorLike) { const raw = String(errorLike?.message || errorLike || '').trim(); if (!raw) { return 'Error desconocido en VeriFactu.'; } // Preserve backend text format for these errors to avoid changing JSON/detail structure. if (raw === 'invalid_json' || raw.startsWith('validation_failed') || raw.startsWith('aeat_error:') || raw.startsWith('aeat_fault:')) { return raw; } if (VERIFACTU_ERROR_MESSAGES[raw]) { return VERIFACTU_ERROR_MESSAGES[raw]; } return raw; } export async function sendVeriFactuInvoice(payload) { return apiPost('/api/VeriFactu/facturas', payload); } export async function cancelVeriFactuInvoice(payload) { return apiPost('/api/VeriFactu/facturas/anular', payload); }