'use strict'; const { getManifest, getDocument } = require('../services/vhlVerify'); /** * POST /vhl/manifest/:manifestId * * Returns the VHL manifest for a given manifest ID. * Corresponds to Fase 4 step 6 in validar_qr_vhl.mmd: * NodoDominio → BusNación: POST [Manifest_URL] (envía PIN si el ciudadano lo configuró) * BusNación → NodoDominio: 200 OK (retorna Manifest con link al NodoDominio_B) * * Path parameter: * :manifestId — ID portion of the manifest URL embedded in the CWT. * * Body (optional, application/json): * { "pin": "1234" } ← required only if the VHL was issued with a PIN. * * Response 200: * { * "files": [ * { "contentType": "application/fhir+json", "location": "https://..." } * ] * } */ async function getManifestController(req, res, next) { try { const { manifestId } = req.params; const pin = req.body && typeof req.body.pin === 'string' ? req.body.pin.trim() || undefined : undefined; const manifest = getManifest(manifestId, pin); res.status(200).json(manifest); } catch (err) { next(err); } } /** * GET /vhl/document/:documentId * * Returns the AES-256-GCM encrypted IPS document. * Corresponds to Fase 4 step 8 in validar_qr_vhl.mmd: * NodoDominio → NodoDominio_B: GET [Document_URL] (descarga P2P directa del archivo) * NodoDominio_B → NodoDominio: 200 OK (retorna IPS encriptado) * * The caller decrypts with the symmetric key extracted from the CWT: * Wire format: [ 12 bytes IV ][ N bytes ciphertext ][ 16 bytes GCM tag ] * Algorithm: AES-256-GCM * * Response 200: application/octet-stream (binary encrypted payload) */ async function getDocumentController(req, res, next) { try { const { documentId } = req.params; const payload = getDocument(documentId); res .status(200) .set('Content-Type', 'application/octet-stream') .send(payload); } catch (err) { next(err); } } module.exports = { getManifestController, getDocumentController };