UNPKG

@smartdcc/duis-sign-wrap

Version:
166 lines 5.27 kB
"use strict"; /* * Created on Fri Feb 06 2026 * * Copyright (c) 2026 Smart DCC Limited * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.port = void 0; exports.setLogger = setLogger; exports.startBackend = startBackend; exports.checkPort = checkPort; exports.stopBackend = stopBackend; exports.buildUrl = buildUrl; exports.makeRequest = makeRequest; exports.makeSignDuisRequest = makeSignDuisRequest; exports.makeVerifyDuisRequest = makeVerifyDuisRequest; const path_1 = require("path"); const node_child_process_1 = require("node:child_process"); const node_net_1 = require("node:net"); const jarFile = (0, path_1.resolve)(__dirname, 'tool.jar'); exports.port = Math.round(Math.random() * 16384) + 32768; let child; let logger; function setLogger(f) { logger = f; } async function startBackend() { if (child !== undefined && child.exitCode === null) { /* already running */ return; } child = (0, node_child_process_1.spawn)('java', [ '-cp', jarFile, 'uk.co.smartdcc.boxed.xmldsig.Server', '-p', exports.port.toString(10), ], { stdio: ['ignore', 'inherit', 'pipe'], }); child.stderr?.on('data', (data) => { if (logger) { logger(data.toString()); } else { console.error(data); } }); let ctr = 0; do { if (ctr > 10) { child?.kill(); throw new Error('timeout waiting for server to start'); } await new Promise((resolve) => { setTimeout(resolve, 50); }); if (child.exitCode !== null) { throw new Error('server failed to start'); } ctr++; } while ((await checkPort(exports.port)) === false); } function checkPort(port) { return new Promise((resolve) => { const socket = new node_net_1.Socket(); socket.setTimeout(100); socket.connect(port, '127.0.0.1', () => { socket.end(); resolve(true); }); socket.on('error', () => { resolve(false); }); }); } function stopBackend() { if (child === undefined || child.exitCode !== null) { return; } child.kill(); child = undefined; } process.on('exit', stopBackend); process.on('SIGINT', stopBackend); process.on('SIGTERM', stopBackend); function buildUrl(backend, mode) { if (backend === true) { return new URL(`http://localhost:${exports.port}/${mode}`); } return new URL(mode, backend); } async function makeRequest(url, options) { const body = { message: Buffer.from(options.xml).toString('base64'), }; if (typeof options.preserveCounter === 'boolean') { body.preserveCounter = options.preserveCounter; } const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', ...(options.headers ?? {}), }, body: JSON.stringify(body), }); if (response.status !== 200) { const error = (await response.json()); throw new Error(error.errorCode ?? `HTTP ${response.status}`, { cause: error.error, }); } const data = (await response.json()); if (typeof data?.message !== 'string') { throw new Error('invalid response'); } return Buffer.from(data.message, 'base64').toString('utf8'); } /** * Signs a DUIS message using the HTTP backend. * * @param options - Configuration options including XML content and backend URL * @returns Promise resolving to the signed DUIS XML string * @throws Error if the backend returns a non-200 status or invalid response */ async function makeSignDuisRequest(options) { if (options.backend === true) { await startBackend(); } return makeRequest(buildUrl(options.backend, 'sign'), { xml: options.xml, preserveCounter: options.preserveCounter, headers: options.headers, }); } /** * Validates and verifies a signed DUIS message using the HTTP backend. * * @param options - Configuration options including XML content and backend URL * @returns Promise resolving to the validated DUIS XML string without signature * @throws Error if the backend returns a non-200 status or invalid response */ async function makeVerifyDuisRequest(options) { if (options.backend === true) { await startBackend(); } return makeRequest(buildUrl(options.backend, 'verify'), { xml: options.xml, headers: options.headers, }); } //# sourceMappingURL=server.js.map