/**
* validation_rest.js
* version 1.0.0 (2026-06-17T01:31Z)
* author: David Ireland <https://di-mgt.com.au/contact>
* copyright (c) 2026 DI Management Services Pty Ltd
* SPDX-License-Identifier: Apache-2.0
*
* Node.js REST client for the FirmaSAT validation service.
* Reads XML input and optional PAC certificate data, posts them to the
* FirmaSAT validation API, and prints the parsed JSON response.
*
* Usage:
* node validation_rest.js
*/
import fs from "fs";
import path from "path";
const DEBUG = false;
const DPRINT = DEBUG ? console.log : () => {};
/**
* Validate XML data with the FirmaSAT validation REST API.
*
* @param {string} xmlFile - Path to the XML input file.
* @param {string} [certFileOrString=""] - Optional PAC certificate file path,
* PEM/base64 certificate text file, or base64 string.
* @returns {Promise<void>} Resolves when the validation response is printed.
* @throws {Error} If a certificate path is missing or invalid.
*/
async function validate(xmlFile, certFileOrString = "") {
const url = "https://di-mgt.com.au/cryptosys/api/fsa_validation";
const apiToken = "YOUR_API_TOKEN_HERE"; // replace with your api-token
console.log(`FILE: ${xmlFile}`);
const encodeFileToBase64 = (filePath) => fs.readFileSync(filePath).toString('base64');
const readTextFile = (filePath) => fs.readFileSync(filePath, 'utf8');
const xmlContent = readTextFile(xmlFile);
DPRINT(xmlContent);
let certContent = "";
if (certFileOrString) {
if (certFileOrString.length > 250 && !fs.existsSync(certFileOrString)) {
certContent = certFileOrString;
} else {
if (!fs.existsSync(certFileOrString)) {
throw new Error(`File '${certFileOrString}' not found`);
}
const buf = fs.readFileSync(certFileOrString);
const firstByte = buf[0];
if (firstByte === 0x30) { // binary DER (starts 0x30)
certContent = encodeFileToBase64(certFileOrString);
} else if (firstByte === 0x4D || firstByte === 0x2D) { // 'M' or '-'
certContent = readTextFile(certFileOrString);
} else {
throw new Error(`${certFileOrString} is not a valid certificate`);
}
}
}
DPRINT(certContent);
const payload = { "api-token": apiToken, "xmldata": xmlContent, "pac-cert": certContent };
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
const data = await response.json();
if (typeof data["validation-result"] === "string") {
data["validation-result"] = JSON.parse(data["validation-result"]);
}
console.log(JSON.stringify(data, null, 2));
}
async function main() {
// These two files must exist in the CWD
await validate("cfdv40-ejemplo-signed-tfd.xml", "pac.cer");
}
main();