94 lines
3.4 KiB
JavaScript
94 lines
3.4 KiB
JavaScript
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);
|
|
} |