UNPKG

@openade/fe

Version:

Fatturazione Elettronica - Electronic Invoicing for Sistema di Interscambio (SDI)

119 lines 5.14 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SignatureManager = void 0; exports.createSignatureManager = createSignatureManager; exports.signInvoiceXml = signInvoiceXml; exports.verifySignedInvoiceXml = verifySignedInvoiceXml; const signature_service_1 = require("./signature.service"); class SignatureManager { constructor(config) { this.config = { algorithm: 'RSA-SHA256', includeTimestamp: false, ...config, }; this.signatureService = new signature_service_1.SignatureService(); } async signInvoice(xmlContent) { const privateKey = await this.getPrivateKey(); const algorithm = this.config.algorithm; const signatureResult = await this.signatureService.sign(Buffer.from(xmlContent, 'utf8'), privateKey, algorithm); const timestamp = this.config.includeTimestamp ? new Date().toISOString() : undefined; const signedXml = this.createSignedXml(xmlContent, signatureResult.signature, signatureResult.digest, timestamp); return { signedXml, digest: signatureResult.digest, algorithm: signatureResult.algorithm, timestamp, }; } async verifySignature(signedXml) { try { const certificate = await this.getCertificate(); const { xmlContent, signature, algorithm } = this.extractSignatureData(signedXml); return await this.signatureService.verify(Buffer.from(xmlContent, 'utf8'), signature, certificate, algorithm); } catch { return false; } } async getPrivateKey() { if (this.config.privateKey) { return this.config.privateKey; } if (this.config.privateKeyPath) { const keyContent = await this.config.fileStorage.retrieve(this.config.privateKeyPath); if (!keyContent) { throw new Error(`Private key file not found: ${this.config.privateKeyPath}`); } return Buffer.from(keyContent).toString('utf8'); } throw new Error('Private key not provided. Set privateKey or privateKeyPath in config.'); } async getCertificate() { if (this.config.certificate) { return this.config.certificate; } if (this.config.certificatePath) { const certContent = await this.config.fileStorage.retrieve(this.config.certificatePath); if (!certContent) { throw new Error(`Certificate file not found: ${this.config.certificatePath}`); } return Buffer.from(certContent).toString('utf8'); } throw new Error('Certificate not provided. Set certificate or certificatePath in config.'); } createSignedXml(xmlContent, signature, digest, timestamp) { const signatureElement = ` <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> <ds:Reference URI=""> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> <ds:DigestValue>${digest}</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>${signature}</ds:SignatureValue> <ds:KeyInfo> <ds:X509Data> <ds:X509Certificate>${this.getCertificateContent()}</ds:X509Certificate> </ds:X509Data> </ds:KeyInfo> ${timestamp ? `<ds:Object><Timestamp>${timestamp}</Timestamp></ds:Object>` : ''} </ds:Signature>`; return xmlContent.replace('</p:FatturaElettronica>', `${signatureElement}\n</p:FatturaElettronica>`); } extractSignatureData(signedXml) { const signatureMatch = signedXml.match(/<ds:SignatureValue>(.*?)<\/ds:SignatureValue>/); const digestMatch = signedXml.match(/<ds:DigestValue>(.*?)<\/ds:DigestValue>/); if (!signatureMatch || !digestMatch) { throw new Error('Invalid signed XML format'); } const xmlContent = signedXml.replace(/<ds:Signature[\s\S]*?<\/ds:Signature>/, ''); return { xmlContent, signature: signatureMatch[1], algorithm: 'RSA-SHA256', }; } getCertificateContent() { return 'CERTIFICATE_CONTENT_PLACEHOLDER'; } } exports.SignatureManager = SignatureManager; function createSignatureManager(config) { return new SignatureManager(config); } async function signInvoiceXml(xmlContent, config) { const manager = createSignatureManager(config); return await manager.signInvoice(xmlContent); } async function verifySignedInvoiceXml(signedXml, config) { const manager = createSignatureManager(config); return await manager.verifySignature(signedXml); } //# sourceMappingURL=signature.manager.js.map