From 314ce43e67acaf57f1a8481a4e15095911839cf2 Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Fri, 8 Aug 2025 09:20:50 -0700 Subject: [PATCH 01/23] Add new endpoint to process json clob data --- icmJsonClobHandler.js | 75 +++++++++++++++++++++++++++++++++++++++++++ routes.js | 49 +++++++++++++++++++++++++--- 2 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 icmJsonClobHandler.js diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js new file mode 100644 index 0000000..1cc6424 --- /dev/null +++ b/icmJsonClobHandler.js @@ -0,0 +1,75 @@ +const axios = require("axios"); +const { keycloakForSiebel } = require("./keycloak.js"); + +function processICMJsonItem(item, index) { + console.log(">>> ICMJsonClob (raw):\n\n", item.ICMJsonClob); + console.log("--------------------------------------------------"); + + const trimmedClob = item.ICMJsonClob.trim(); + if (!trimmedClob.startsWith('{') && !trimmedClob.startsWith('[')) { + console.log(`Item ${index + 1}: ICMJsonClob is not a valid JSON`); + return; + } + + try { + const parsedClob = JSON.parse(item.ICMJsonClob); + console.log("ICMJsonClob (parsed):\n\n", JSON.stringify(parsedClob, null, 2)); + } catch (parseError) { + console.log(`Item ${index + 1}: Failed to parse JSON: ${parseError.message}`); + } +} + +async function getData() { + try { + const grant = await keycloakForSiebel.grantManager.obtainFromClientCredentials(); + + const headers = { + Authorization: `Bearer ${grant.id_token.token}`, + "X-ICM-TrustedUsername": "DMEIRELE", + "Content-Type": "application/json" + }; + + const url = "https://sieblabm.apps.gov.bc.ca/ffdy/v1.0/data/ICMJSONClobBO/ICMJSONClobBC" + + const queryParams = { + ViewMode: "Catalog", + workspace: "dev_sadmin_bz_1", + searchspec: `("SR Id" = "1-54SIG7F")` + }; + + const response = await axios.get(url, { + headers, + params: queryParams + }); + + console.log("Status:", response.status + " " + response.statusText); + + if (response.data && response.data.items && Array.isArray(response.data.items)) { + response.data.items.forEach((item, index) => { + processICMJsonItem(item, index); + }); + } else { + console.log("No items found in response"); + } + + return { + success: true, + totalItems: response.data?.items?.length || 0, + statusCode: response.status, + statusText: response.statusText + }; + + } catch (error) { + console.error("API call failed:", error.message); + return { + success: false, + error: error.message, + totalItems: 0, + errors: [error.message] + }; + } +} + +module.exports = { + getData +}; \ No newline at end of file diff --git a/routes.js b/routes.js index 252d79d..624616a 100644 --- a/routes.js +++ b/routes.js @@ -12,13 +12,33 @@ const generatePortalIntegratedTemplate = require("./portal/generatePortalIntegra const submitForPortalAction = require("./portal/savePortalFormDataHandler.js"); const loadPortalIntegratedForm = require("./portal/loadPortalIntegratedHandler.js"); - const getFormsFromFormTemplate = require("./formRepoHandler"); +const {getData} = require("./icmJsonClobHandler"); const router = express.Router(); const FORM_SERVER_URL = process.env.FORMSERVERURL; const ENDPOINT_URL = process.env.ENDPOINTURL; +const localhostOnlyMiddleware = (req, res, next) => { + const clientIP = req.ip || + req.connection.remoteAddress || + req.socket.remoteAddress || + (req.connection.socket ? req.connection.socket.remoteAddress : null); + + const actualIP = clientIP?.replace('::ffff:', '') || clientIP; + + const isLocalhost = clientIP === '127.0.0.1' || + clientIP === '::1' || + clientIP === 'localhost' || + actualIP?.startsWith('172.') || // Docker default bridge network + actualIP?.startsWith('192.168.') || // Docker custom networks + actualIP?.startsWith('10.'); // Docker swarm networks + + if (!isLocalhost) { + return res.status(403).json({ error: 'Localhost access only' }); + } + next(); +}; // Form Map const formMap = new Map(); @@ -115,8 +135,7 @@ router.post("/generate", generateTemplate); router.get("/getAllForms", async (request, response) => { try { - const grant = - await keycloakForFormRepo.grantManager.obtainFromClientCredentials(); + const grant = await keycloakForFormRepo.grantManager.obtainFromClientCredentials(); let endpointUrl = `http://localhost:3030/api/forms-list`; const forms = await axios.get(endpointUrl, { @@ -134,10 +153,31 @@ router.get("/getAllForms", async (request, response) => { }); +router.get("/processIcmJsonClob", localhostOnlyMiddleware, async (req, res) => { + try { + const result = await getData(); + + if (result.success) { + res.status(200).json({ + message: "Success." + }); + } else { + res.status(500).json({ + error: "Error." + }); + } + } catch (error) { + console.error("Error:", error.message); + res.status(500).json({ + error: "Internal server error", + message: error.message + }); + } +}); + // clear the locked by flags in ICM for the form, used when form is closed router.post("/clearICMLockedFlag", clearICMLockedFlag); - router.post("/generatePDFFromJson", generatePDFFromJSON); // Generate route @@ -149,4 +189,5 @@ router.post("/generateNewTemplate", generateNewTemplate); router.use('/pdfRender', renderRouter); router.use('/submitForPortalAction', submitForPortalAction); router.post("/loadPortalForm", loadPortalIntegratedForm); + module.exports = router; \ No newline at end of file From 03963e0fdacd220f6c8fd26254e07668a270c6bd Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Fri, 8 Aug 2025 17:11:30 -0700 Subject: [PATCH 02/23] Process clob data data. --- icmJsonClobHandler.js | 87 ++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js index 1cc6424..4c2b64d 100644 --- a/icmJsonClobHandler.js +++ b/icmJsonClobHandler.js @@ -1,75 +1,92 @@ const axios = require("axios"); const { keycloakForSiebel } = require("./keycloak.js"); -function processICMJsonItem(item, index) { - console.log(">>> ICMJsonClob (raw):\n\n", item.ICMJsonClob); - console.log("--------------------------------------------------"); - - const trimmedClob = item.ICMJsonClob.trim(); - if (!trimmedClob.startsWith('{') && !trimmedClob.startsWith('[')) { - console.log(`Item ${index + 1}: ICMJsonClob is not a valid JSON`); - return; +function processIcmJsonClobData(jsonData) { + // Create a copy to avoid mutating the original instance + const processedData = JSON.parse(JSON.stringify(jsonData)); + + if (processedData.items && Array.isArray(processedData.items)) { + processedData.items = processedData.items.map(item => { + if (item.ICMJsonClob && typeof item.ICMJsonClob === 'string') { + try { + item.ICMJsonClobParsed = JSON.parse(item.ICMJsonClob); + delete item.ICMJsonClob; + } catch (error) { + console.warn(`Failed to parse ICMJsonClob for item ${item.Id}: ${error.message}`); + item.ICMJsonClobParsed = null; + } + } + + return item; + }); } + else { + if (processedData.ICMJsonClob && typeof processedData.ICMJsonClob === 'string') { + try { + processedData.ICMJsonClobParsed = JSON.parse(processedData.ICMJsonClob); + delete processedData.ICMJsonClob; + } catch (error) { + console.warn(`Failed to parse ICMJsonClob for item ${processedData.Id}: ${error.message}`); + processedData.ICMJsonClobParsed = null; + } + } - try { - const parsedClob = JSON.parse(item.ICMJsonClob); - console.log("ICMJsonClob (parsed):\n\n", JSON.stringify(parsedClob, null, 2)); - } catch (parseError) { - console.log(`Item ${index + 1}: Failed to parse JSON: ${parseError.message}`); + return processedData; } + + return processedData; } -async function getData() { +async function fetchIcmJsonClobData(attachmentId) { try { const grant = await keycloakForSiebel.grantManager.obtainFromClientCredentials(); + const username = process.env.SIEBEL_ICM_TRUSTED_USERNAME; + const headers = { Authorization: `Bearer ${grant.id_token.token}`, - "X-ICM-TrustedUsername": "DMEIRELE", + "X-ICM-TrustedUsername": username, "Content-Type": "application/json" }; - const url = "https://sieblabm.apps.gov.bc.ca/ffdy/v1.0/data/ICMJSONClobBO/ICMJSONClobBC" + const url = process.env.SIEBEL_ICM_BASE_URL; const queryParams = { ViewMode: "Catalog", - workspace: "dev_sadmin_bz_1", - searchspec: `("SR Id" = "1-54SIG7F")` + searchspec: attachmentId // "UserFieldCLOB"="1-123ABC" }; - const response = await axios.get(url, { + return await axios.get(url, { headers, - params: queryParams + params: queryParams, + timeout: 30000 }); - console.log("Status:", response.status + " " + response.statusText); + } catch (error) { + throw new Error(`Failed to fetch ICM data for SR ID ${attachmentId}: ${error.message}`); + } +} - if (response.data && response.data.items && Array.isArray(response.data.items)) { - response.data.items.forEach((item, index) => { - processICMJsonItem(item, index); - }); - } else { - console.log("No items found in response"); - } +async function getProcessedData(attachmentId) { + try { + const response = await fetchIcmJsonClobData(attachmentId); + const processedResult = processIcmJsonClobData(response.data); return { success: true, - totalItems: response.data?.items?.length || 0, - statusCode: response.status, - statusText: response.statusText + data: processedResult }; } catch (error) { console.error("API call failed:", error.message); + return { success: false, - error: error.message, - totalItems: 0, - errors: [error.message] + error: error.message }; } } module.exports = { - getData + getProcessedData }; \ No newline at end of file From d96e3d69a1500a25d7123c6dfc6e64c43feeefc1 Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Sat, 9 Aug 2025 18:48:11 -0700 Subject: [PATCH 03/23] Update router.js --- routes.js | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/routes.js b/routes.js index 624616a..00a8d82 100644 --- a/routes.js +++ b/routes.js @@ -13,7 +13,7 @@ const submitForPortalAction = require("./portal/savePortalFormDataHandler.js"); const loadPortalIntegratedForm = require("./portal/loadPortalIntegratedHandler.js"); const getFormsFromFormTemplate = require("./formRepoHandler"); -const {getData} = require("./icmJsonClobHandler"); +const {getProcessedData} = require("./icmJsonClobHandler"); const router = express.Router(); const FORM_SERVER_URL = process.env.FORMSERVERURL; @@ -154,24 +154,18 @@ router.get("/getAllForms", async (request, response) => { }); router.get("/processIcmJsonClob", localhostOnlyMiddleware, async (req, res) => { + try { - const result = await getData(); + const result = await getProcessedData(req.query.attachmentId); if (result.success) { - res.status(200).json({ - message: "Success." - }); + res.status(200).json(result.data); } else { - res.status(500).json({ - error: "Error." - }); + res.status(500).json({ error: "Error." }); } } catch (error) { console.error("Error:", error.message); - res.status(500).json({ - error: "Internal server error", - message: error.message - }); + res.status(500).json({ error: "Internal server error", message: error.message }); } }); From 5afb6594de177ea26674751e28ca4e3a089b88f4 Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Sat, 9 Aug 2025 18:48:55 -0700 Subject: [PATCH 04/23] Refactor processIcmJsonClobData --- icmJsonClobHandler.js | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js index 4c2b64d..83906d8 100644 --- a/icmJsonClobHandler.js +++ b/icmJsonClobHandler.js @@ -1,40 +1,30 @@ const axios = require("axios"); const { keycloakForSiebel } = require("./keycloak.js"); +function parseIcmJsonClob(item) { + if (item.ICMJsonClob && typeof item.ICMJsonClob === 'string') { + try { + item.ICMJsonClobParsed = JSON.parse(item.ICMJsonClob); + delete item.ICMJsonClob; + } catch (error) { + console.warn(`Failed to parse ICMJsonClob for item ${item.Id || 'unknown'}: ${error.message}`); + item.ICMJsonClobParsed = null; + } + } + return item; +} + function processIcmJsonClobData(jsonData) { + // Create a copy to avoid mutating the original instance const processedData = JSON.parse(JSON.stringify(jsonData)); if (processedData.items && Array.isArray(processedData.items)) { - processedData.items = processedData.items.map(item => { - if (item.ICMJsonClob && typeof item.ICMJsonClob === 'string') { - try { - item.ICMJsonClobParsed = JSON.parse(item.ICMJsonClob); - delete item.ICMJsonClob; - } catch (error) { - console.warn(`Failed to parse ICMJsonClob for item ${item.Id}: ${error.message}`); - item.ICMJsonClobParsed = null; - } - } - - return item; - }); - } - else { - if (processedData.ICMJsonClob && typeof processedData.ICMJsonClob === 'string') { - try { - processedData.ICMJsonClobParsed = JSON.parse(processedData.ICMJsonClob); - delete processedData.ICMJsonClob; - } catch (error) { - console.warn(`Failed to parse ICMJsonClob for item ${processedData.Id}: ${error.message}`); - processedData.ICMJsonClobParsed = null; - } - } - + processedData.items = processedData.items.map(parseIcmJsonClob); return processedData; } - return processedData; + return parseIcmJsonClob(processedData); } async function fetchIcmJsonClobData(attachmentId) { From 21bf42a4070f2592cdbf97b75c86a729fe65f3d8 Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Sat, 9 Aug 2025 23:04:50 -0700 Subject: [PATCH 05/23] Code cleanup. --- routes.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/routes.js b/routes.js index 00a8d82..1b2e0d1 100644 --- a/routes.js +++ b/routes.js @@ -11,8 +11,7 @@ const {generatePDFFromHTML,generatePDFFromURL,generatePDFFromJSON,loadSavedJson const generatePortalIntegratedTemplate = require("./portal/generatePortalIntegratedHandler.js"); const submitForPortalAction = require("./portal/savePortalFormDataHandler.js"); const loadPortalIntegratedForm = require("./portal/loadPortalIntegratedHandler.js"); - -const getFormsFromFormTemplate = require("./formRepoHandler"); +require("./formRepoHandler"); const {getProcessedData} = require("./icmJsonClobHandler"); const router = express.Router(); @@ -154,7 +153,6 @@ router.get("/getAllForms", async (request, response) => { }); router.get("/processIcmJsonClob", localhostOnlyMiddleware, async (req, res) => { - try { const result = await getProcessedData(req.query.attachmentId); From ccd46ea1a2440b4aaeb9fd048411cbba9a726f16 Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Mon, 11 Aug 2025 09:22:27 -0700 Subject: [PATCH 06/23] Use existing settings for siebel url and username --- icmJsonClobHandler.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js index 83906d8..4fcd622 100644 --- a/icmJsonClobHandler.js +++ b/icmJsonClobHandler.js @@ -31,7 +31,7 @@ async function fetchIcmJsonClobData(attachmentId) { try { const grant = await keycloakForSiebel.grantManager.obtainFromClientCredentials(); - const username = process.env.SIEBEL_ICM_TRUSTED_USERNAME; + const username = process.env.TRUSTED_USERNAME; const headers = { Authorization: `Bearer ${grant.id_token.token}`, @@ -39,7 +39,7 @@ async function fetchIcmJsonClobData(attachmentId) { "Content-Type": "application/json" }; - const url = process.env.SIEBEL_ICM_BASE_URL; + const url = process.env.SIEBEL_ICM_API_HOST; const queryParams = { ViewMode: "Catalog", From accf5f8996258622ad4d6377ea54837b78281128 Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Tue, 12 Aug 2025 11:16:53 -0700 Subject: [PATCH 07/23] Fix URL path --- icmJsonClobHandler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js index 4fcd622..b5ee5c0 100644 --- a/icmJsonClobHandler.js +++ b/icmJsonClobHandler.js @@ -39,7 +39,7 @@ async function fetchIcmJsonClobData(attachmentId) { "Content-Type": "application/json" }; - const url = process.env.SIEBEL_ICM_API_HOST; + const url = `${process.env.SIEBEL_ICM_API_HOST}${process.env.ICM_JSON_CLOB_ENDPONT}`; const queryParams = { ViewMode: "Catalog", From b91ad5384d136b918aa1018e884e091eaecddb24 Mon Sep 17 00:00:00 2001 From: NicolaSDPR1 Date: Tue, 12 Aug 2025 15:42:38 -0700 Subject: [PATCH 08/23] (ADO-3158) truncate json UUID before XML creation, remove index/offest and parent values from children keys --- saveICMdataHandler.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/saveICMdataHandler.js b/saveICMdataHandler.js index 5c508ac..f6e719c 100644 --- a/saveICMdataHandler.js +++ b/saveICMdataHandler.js @@ -133,8 +133,30 @@ async function saveICMdata(req, res) { saveJson["DocFileExt"] = "json"; saveJson["Doc Attachment Id"] = Buffer.from(savedFormParam).toString('base64');//savedForm is saved as attachment let saveData = JSON.parse(savedFormParam)["data"];// This is the data part of the savedJson + const truncatedKeysSaveData = {}; + for(let oldKey in saveData) { //This begins trunicating the JSON keys for XML (UUID should be first 8 characters) + const stringLength = oldKey.length; + const newKey = oldKey.substring(0, stringLength-28); + if (Array.isArray(saveData[oldKey]) > 0 && Object.keys(saveData[oldKey]).length > 0) { //This trunicates child/dependant objects + const childrenArray = []; + for(let i = 0; i < saveData[oldKey].length; i++) { + const truncatedChildrenKeys = {}; + for (let oldChildKey in saveData[oldKey][i]) { + const childStringLength = oldChildKey.length; + const newChildKey = oldChildKey.substring(stringLength+3, childStringLength-28); + truncatedChildrenKeys[newChildKey] = saveData[oldKey][i][oldChildKey]; + } + childrenArray.push(truncatedChildrenKeys); + } + const wrapperKey = {} + wrapperKey[newKey] = childrenArray; + truncatedKeysSaveData[`${newKey}-List`] = wrapperKey // Add a wrapper around the children/dependecies + } else { + truncatedKeysSaveData[newKey] = saveData[oldKey]; //Data is added to new JSON with the truncated key + } + } let builder = new xml2js.Builder(); - saveJson["XML Hierarchy"] = builder.buildObject(saveData); + saveJson["XML Hierarchy"] = builder.buildObject(truncatedKeysSaveData); //let url = buildUrlWithParams('SIEBEL_ICM_API_HOST', 'fwd/v1.0/data/DT Form Instance Thin/DT Form Instance Thin/' + attachment_id + '/', ''); let url = buildUrlWithParams(params["apiHost"], params["saveEndpoint"] + attachment_id + '/', params); try { From 41355cd86852c8ee8396a9ee1d93a8dd82d0b842 Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Fri, 8 Aug 2025 09:20:50 -0700 Subject: [PATCH 09/23] Add new endpoint to process json clob data --- icmJsonClobHandler.js | 75 +++++++++++++++++++++++++++++++++++++++++++ routes.js | 49 +++++++++++++++++++++++++--- 2 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 icmJsonClobHandler.js diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js new file mode 100644 index 0000000..1cc6424 --- /dev/null +++ b/icmJsonClobHandler.js @@ -0,0 +1,75 @@ +const axios = require("axios"); +const { keycloakForSiebel } = require("./keycloak.js"); + +function processICMJsonItem(item, index) { + console.log(">>> ICMJsonClob (raw):\n\n", item.ICMJsonClob); + console.log("--------------------------------------------------"); + + const trimmedClob = item.ICMJsonClob.trim(); + if (!trimmedClob.startsWith('{') && !trimmedClob.startsWith('[')) { + console.log(`Item ${index + 1}: ICMJsonClob is not a valid JSON`); + return; + } + + try { + const parsedClob = JSON.parse(item.ICMJsonClob); + console.log("ICMJsonClob (parsed):\n\n", JSON.stringify(parsedClob, null, 2)); + } catch (parseError) { + console.log(`Item ${index + 1}: Failed to parse JSON: ${parseError.message}`); + } +} + +async function getData() { + try { + const grant = await keycloakForSiebel.grantManager.obtainFromClientCredentials(); + + const headers = { + Authorization: `Bearer ${grant.id_token.token}`, + "X-ICM-TrustedUsername": "DMEIRELE", + "Content-Type": "application/json" + }; + + const url = "https://sieblabm.apps.gov.bc.ca/ffdy/v1.0/data/ICMJSONClobBO/ICMJSONClobBC" + + const queryParams = { + ViewMode: "Catalog", + workspace: "dev_sadmin_bz_1", + searchspec: `("SR Id" = "1-54SIG7F")` + }; + + const response = await axios.get(url, { + headers, + params: queryParams + }); + + console.log("Status:", response.status + " " + response.statusText); + + if (response.data && response.data.items && Array.isArray(response.data.items)) { + response.data.items.forEach((item, index) => { + processICMJsonItem(item, index); + }); + } else { + console.log("No items found in response"); + } + + return { + success: true, + totalItems: response.data?.items?.length || 0, + statusCode: response.status, + statusText: response.statusText + }; + + } catch (error) { + console.error("API call failed:", error.message); + return { + success: false, + error: error.message, + totalItems: 0, + errors: [error.message] + }; + } +} + +module.exports = { + getData +}; \ No newline at end of file diff --git a/routes.js b/routes.js index 252d79d..624616a 100644 --- a/routes.js +++ b/routes.js @@ -12,13 +12,33 @@ const generatePortalIntegratedTemplate = require("./portal/generatePortalIntegra const submitForPortalAction = require("./portal/savePortalFormDataHandler.js"); const loadPortalIntegratedForm = require("./portal/loadPortalIntegratedHandler.js"); - const getFormsFromFormTemplate = require("./formRepoHandler"); +const {getData} = require("./icmJsonClobHandler"); const router = express.Router(); const FORM_SERVER_URL = process.env.FORMSERVERURL; const ENDPOINT_URL = process.env.ENDPOINTURL; +const localhostOnlyMiddleware = (req, res, next) => { + const clientIP = req.ip || + req.connection.remoteAddress || + req.socket.remoteAddress || + (req.connection.socket ? req.connection.socket.remoteAddress : null); + + const actualIP = clientIP?.replace('::ffff:', '') || clientIP; + + const isLocalhost = clientIP === '127.0.0.1' || + clientIP === '::1' || + clientIP === 'localhost' || + actualIP?.startsWith('172.') || // Docker default bridge network + actualIP?.startsWith('192.168.') || // Docker custom networks + actualIP?.startsWith('10.'); // Docker swarm networks + + if (!isLocalhost) { + return res.status(403).json({ error: 'Localhost access only' }); + } + next(); +}; // Form Map const formMap = new Map(); @@ -115,8 +135,7 @@ router.post("/generate", generateTemplate); router.get("/getAllForms", async (request, response) => { try { - const grant = - await keycloakForFormRepo.grantManager.obtainFromClientCredentials(); + const grant = await keycloakForFormRepo.grantManager.obtainFromClientCredentials(); let endpointUrl = `http://localhost:3030/api/forms-list`; const forms = await axios.get(endpointUrl, { @@ -134,10 +153,31 @@ router.get("/getAllForms", async (request, response) => { }); +router.get("/processIcmJsonClob", localhostOnlyMiddleware, async (req, res) => { + try { + const result = await getData(); + + if (result.success) { + res.status(200).json({ + message: "Success." + }); + } else { + res.status(500).json({ + error: "Error." + }); + } + } catch (error) { + console.error("Error:", error.message); + res.status(500).json({ + error: "Internal server error", + message: error.message + }); + } +}); + // clear the locked by flags in ICM for the form, used when form is closed router.post("/clearICMLockedFlag", clearICMLockedFlag); - router.post("/generatePDFFromJson", generatePDFFromJSON); // Generate route @@ -149,4 +189,5 @@ router.post("/generateNewTemplate", generateNewTemplate); router.use('/pdfRender', renderRouter); router.use('/submitForPortalAction', submitForPortalAction); router.post("/loadPortalForm", loadPortalIntegratedForm); + module.exports = router; \ No newline at end of file From c7859fd9ec8ed3abfb728318598d37711ecaf5b5 Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Fri, 8 Aug 2025 17:11:30 -0700 Subject: [PATCH 10/23] Process clob data data. --- icmJsonClobHandler.js | 87 ++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js index 1cc6424..4c2b64d 100644 --- a/icmJsonClobHandler.js +++ b/icmJsonClobHandler.js @@ -1,75 +1,92 @@ const axios = require("axios"); const { keycloakForSiebel } = require("./keycloak.js"); -function processICMJsonItem(item, index) { - console.log(">>> ICMJsonClob (raw):\n\n", item.ICMJsonClob); - console.log("--------------------------------------------------"); - - const trimmedClob = item.ICMJsonClob.trim(); - if (!trimmedClob.startsWith('{') && !trimmedClob.startsWith('[')) { - console.log(`Item ${index + 1}: ICMJsonClob is not a valid JSON`); - return; +function processIcmJsonClobData(jsonData) { + // Create a copy to avoid mutating the original instance + const processedData = JSON.parse(JSON.stringify(jsonData)); + + if (processedData.items && Array.isArray(processedData.items)) { + processedData.items = processedData.items.map(item => { + if (item.ICMJsonClob && typeof item.ICMJsonClob === 'string') { + try { + item.ICMJsonClobParsed = JSON.parse(item.ICMJsonClob); + delete item.ICMJsonClob; + } catch (error) { + console.warn(`Failed to parse ICMJsonClob for item ${item.Id}: ${error.message}`); + item.ICMJsonClobParsed = null; + } + } + + return item; + }); } + else { + if (processedData.ICMJsonClob && typeof processedData.ICMJsonClob === 'string') { + try { + processedData.ICMJsonClobParsed = JSON.parse(processedData.ICMJsonClob); + delete processedData.ICMJsonClob; + } catch (error) { + console.warn(`Failed to parse ICMJsonClob for item ${processedData.Id}: ${error.message}`); + processedData.ICMJsonClobParsed = null; + } + } - try { - const parsedClob = JSON.parse(item.ICMJsonClob); - console.log("ICMJsonClob (parsed):\n\n", JSON.stringify(parsedClob, null, 2)); - } catch (parseError) { - console.log(`Item ${index + 1}: Failed to parse JSON: ${parseError.message}`); + return processedData; } + + return processedData; } -async function getData() { +async function fetchIcmJsonClobData(attachmentId) { try { const grant = await keycloakForSiebel.grantManager.obtainFromClientCredentials(); + const username = process.env.SIEBEL_ICM_TRUSTED_USERNAME; + const headers = { Authorization: `Bearer ${grant.id_token.token}`, - "X-ICM-TrustedUsername": "DMEIRELE", + "X-ICM-TrustedUsername": username, "Content-Type": "application/json" }; - const url = "https://sieblabm.apps.gov.bc.ca/ffdy/v1.0/data/ICMJSONClobBO/ICMJSONClobBC" + const url = process.env.SIEBEL_ICM_BASE_URL; const queryParams = { ViewMode: "Catalog", - workspace: "dev_sadmin_bz_1", - searchspec: `("SR Id" = "1-54SIG7F")` + searchspec: attachmentId // "UserFieldCLOB"="1-123ABC" }; - const response = await axios.get(url, { + return await axios.get(url, { headers, - params: queryParams + params: queryParams, + timeout: 30000 }); - console.log("Status:", response.status + " " + response.statusText); + } catch (error) { + throw new Error(`Failed to fetch ICM data for SR ID ${attachmentId}: ${error.message}`); + } +} - if (response.data && response.data.items && Array.isArray(response.data.items)) { - response.data.items.forEach((item, index) => { - processICMJsonItem(item, index); - }); - } else { - console.log("No items found in response"); - } +async function getProcessedData(attachmentId) { + try { + const response = await fetchIcmJsonClobData(attachmentId); + const processedResult = processIcmJsonClobData(response.data); return { success: true, - totalItems: response.data?.items?.length || 0, - statusCode: response.status, - statusText: response.statusText + data: processedResult }; } catch (error) { console.error("API call failed:", error.message); + return { success: false, - error: error.message, - totalItems: 0, - errors: [error.message] + error: error.message }; } } module.exports = { - getData + getProcessedData }; \ No newline at end of file From 7007a8240072a1ec8e2af676f58a7876b093638f Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Sat, 9 Aug 2025 18:48:11 -0700 Subject: [PATCH 11/23] Update router.js --- routes.js | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/routes.js b/routes.js index 624616a..00a8d82 100644 --- a/routes.js +++ b/routes.js @@ -13,7 +13,7 @@ const submitForPortalAction = require("./portal/savePortalFormDataHandler.js"); const loadPortalIntegratedForm = require("./portal/loadPortalIntegratedHandler.js"); const getFormsFromFormTemplate = require("./formRepoHandler"); -const {getData} = require("./icmJsonClobHandler"); +const {getProcessedData} = require("./icmJsonClobHandler"); const router = express.Router(); const FORM_SERVER_URL = process.env.FORMSERVERURL; @@ -154,24 +154,18 @@ router.get("/getAllForms", async (request, response) => { }); router.get("/processIcmJsonClob", localhostOnlyMiddleware, async (req, res) => { + try { - const result = await getData(); + const result = await getProcessedData(req.query.attachmentId); if (result.success) { - res.status(200).json({ - message: "Success." - }); + res.status(200).json(result.data); } else { - res.status(500).json({ - error: "Error." - }); + res.status(500).json({ error: "Error." }); } } catch (error) { console.error("Error:", error.message); - res.status(500).json({ - error: "Internal server error", - message: error.message - }); + res.status(500).json({ error: "Internal server error", message: error.message }); } }); From 5c9e4493e292ad63e6d9e933bdaf8bd0248e830b Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Sat, 9 Aug 2025 18:48:55 -0700 Subject: [PATCH 12/23] Refactor processIcmJsonClobData --- icmJsonClobHandler.js | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js index 4c2b64d..83906d8 100644 --- a/icmJsonClobHandler.js +++ b/icmJsonClobHandler.js @@ -1,40 +1,30 @@ const axios = require("axios"); const { keycloakForSiebel } = require("./keycloak.js"); +function parseIcmJsonClob(item) { + if (item.ICMJsonClob && typeof item.ICMJsonClob === 'string') { + try { + item.ICMJsonClobParsed = JSON.parse(item.ICMJsonClob); + delete item.ICMJsonClob; + } catch (error) { + console.warn(`Failed to parse ICMJsonClob for item ${item.Id || 'unknown'}: ${error.message}`); + item.ICMJsonClobParsed = null; + } + } + return item; +} + function processIcmJsonClobData(jsonData) { + // Create a copy to avoid mutating the original instance const processedData = JSON.parse(JSON.stringify(jsonData)); if (processedData.items && Array.isArray(processedData.items)) { - processedData.items = processedData.items.map(item => { - if (item.ICMJsonClob && typeof item.ICMJsonClob === 'string') { - try { - item.ICMJsonClobParsed = JSON.parse(item.ICMJsonClob); - delete item.ICMJsonClob; - } catch (error) { - console.warn(`Failed to parse ICMJsonClob for item ${item.Id}: ${error.message}`); - item.ICMJsonClobParsed = null; - } - } - - return item; - }); - } - else { - if (processedData.ICMJsonClob && typeof processedData.ICMJsonClob === 'string') { - try { - processedData.ICMJsonClobParsed = JSON.parse(processedData.ICMJsonClob); - delete processedData.ICMJsonClob; - } catch (error) { - console.warn(`Failed to parse ICMJsonClob for item ${processedData.Id}: ${error.message}`); - processedData.ICMJsonClobParsed = null; - } - } - + processedData.items = processedData.items.map(parseIcmJsonClob); return processedData; } - return processedData; + return parseIcmJsonClob(processedData); } async function fetchIcmJsonClobData(attachmentId) { From d5d83452ca9c69ef5ccc833fc4ac8ac174aa4a54 Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Sat, 9 Aug 2025 23:04:50 -0700 Subject: [PATCH 13/23] Code cleanup. --- routes.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/routes.js b/routes.js index 00a8d82..1b2e0d1 100644 --- a/routes.js +++ b/routes.js @@ -11,8 +11,7 @@ const {generatePDFFromHTML,generatePDFFromURL,generatePDFFromJSON,loadSavedJson const generatePortalIntegratedTemplate = require("./portal/generatePortalIntegratedHandler.js"); const submitForPortalAction = require("./portal/savePortalFormDataHandler.js"); const loadPortalIntegratedForm = require("./portal/loadPortalIntegratedHandler.js"); - -const getFormsFromFormTemplate = require("./formRepoHandler"); +require("./formRepoHandler"); const {getProcessedData} = require("./icmJsonClobHandler"); const router = express.Router(); @@ -154,7 +153,6 @@ router.get("/getAllForms", async (request, response) => { }); router.get("/processIcmJsonClob", localhostOnlyMiddleware, async (req, res) => { - try { const result = await getProcessedData(req.query.attachmentId); From c7cd6eac41f80a288bd263039f878b7fcce0263a Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Mon, 11 Aug 2025 09:22:27 -0700 Subject: [PATCH 14/23] Use existing settings for siebel url and username --- icmJsonClobHandler.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js index 83906d8..4fcd622 100644 --- a/icmJsonClobHandler.js +++ b/icmJsonClobHandler.js @@ -31,7 +31,7 @@ async function fetchIcmJsonClobData(attachmentId) { try { const grant = await keycloakForSiebel.grantManager.obtainFromClientCredentials(); - const username = process.env.SIEBEL_ICM_TRUSTED_USERNAME; + const username = process.env.TRUSTED_USERNAME; const headers = { Authorization: `Bearer ${grant.id_token.token}`, @@ -39,7 +39,7 @@ async function fetchIcmJsonClobData(attachmentId) { "Content-Type": "application/json" }; - const url = process.env.SIEBEL_ICM_BASE_URL; + const url = process.env.SIEBEL_ICM_API_HOST; const queryParams = { ViewMode: "Catalog", From 82dfe4081be4c2de3b7d75bfbb6e90cc0556d805 Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Tue, 12 Aug 2025 11:16:53 -0700 Subject: [PATCH 15/23] Fix URL path --- icmJsonClobHandler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js index 4fcd622..b5ee5c0 100644 --- a/icmJsonClobHandler.js +++ b/icmJsonClobHandler.js @@ -39,7 +39,7 @@ async function fetchIcmJsonClobData(attachmentId) { "Content-Type": "application/json" }; - const url = process.env.SIEBEL_ICM_API_HOST; + const url = `${process.env.SIEBEL_ICM_API_HOST}${process.env.ICM_JSON_CLOB_ENDPONT}`; const queryParams = { ViewMode: "Catalog", From c6ccad03f5c7e0dceda97e708f8218dc508042da Mon Sep 17 00:00:00 2001 From: David Okulski <32730627+DavidOkulski@users.noreply.github.com> Date: Fri, 15 Aug 2025 13:35:22 -0700 Subject: [PATCH 16/23] Update databindings host/endpoint processing --- databindingsHandler.js | 43 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/databindingsHandler.js b/databindingsHandler.js index 8861a7a..b5d27e6 100644 --- a/databindingsHandler.js +++ b/databindingsHandler.js @@ -40,6 +40,7 @@ async function fetchDataFromSources(dataSources, params) { let updatedParams = updateParams(source.params || {}, params, data); const response = await readJsonFormApi(source, { ...params, ...updatedParams }); + console.log("Response:",response); data[source.name] = response; } catch (error) { @@ -199,6 +200,7 @@ async function readJsonFormApi(datasource, pathParams) { } // Store response data + console.log("Response:",response); return ensureObjectOrArray(response.data); } catch (error) { @@ -210,6 +212,10 @@ async function readJsonFormApi(datasource, pathParams) { function buildUrlWithParams(host, endpoint, pathVariables) { const hostFromEnv = getHost(pathVariables,host); const endpointFromEnv = getEndpoint(endpoint); + + if (!hostFromEnv) throw new Error("API host not resolved"); + if (!endpointFromEnv) throw new Error("API endpoint not resolved"); + let url = `${hostFromEnv}${endpointFromEnv}`; // Replace any placeholder variables like @@attachmentId Object.keys(pathVariables).forEach(key => { @@ -222,18 +228,23 @@ function buildUrlWithParams(host, endpoint, pathVariables) { function getHost(params, host) { - // Use host from environment variable if available, otherwise fall back to JSON - try { - return params["apiHost"]; - } catch { - return process.env[host]; + // Use process.env if present + const fromEnv = resolveMaybeEnv(host); + if (fromEnv) return fromEnv; + + //Fall back to path params + if (params && typeof params.apiHost === "string" && params.apiHost.trim()) { + return params.apiHost.trim(); } + + return host ? (process.env[host] ?? host) : null; } function getEndpoint(endpoint) { // Use endpoint from environment variable if available, otherwise fall back to JSON - return process.env[endpoint] || endpoint; + return resolveMaybeEnv(endpoint) ?? endpoint; } + function buildBodyWithParams(bodyFromJson, pathVariables) { let bodyString = JSON.stringify(bodyFromJson); @@ -316,5 +327,25 @@ function updateParams(params, pathParams = {}, allFetchedData = {}) { return updated; } +function resolveMaybeEnv(str) { + if (typeof str !== "string" || !str) { + return null; + } + + // Check if value is in the form "process.env.VAR_NAME" + const envPattern = /^process\.env\.(.+)$/; + const match = str.match(envPattern); + + if (!match) { + return str; + } + + const envVarName = match[1]; + const envValue = process.env[envVarName]; + + return envValue != null ? envValue : str; +} + + module.exports.populateDatabindings = populateDatabindings; module.exports.buildUrlWithParams = buildUrlWithParams; From 6fac249d27daa2d2524c69f77ab7e851855e0bf0 Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Fri, 15 Aug 2025 14:46:26 -0700 Subject: [PATCH 17/23] Update the attachement id value. --- icmJsonClobHandler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js index b5ee5c0..0d47e7f 100644 --- a/icmJsonClobHandler.js +++ b/icmJsonClobHandler.js @@ -43,7 +43,7 @@ async function fetchIcmJsonClobData(attachmentId) { const queryParams = { ViewMode: "Catalog", - searchspec: attachmentId // "UserFieldCLOB"="1-123ABC" + SearchSpec: `UserFieldCLOB=\"${attachmentId}\"` }; return await axios.get(url, { From f09d46aa4342decd517e8fec5f4f8185200145fd Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Mon, 18 Aug 2025 09:09:44 -0700 Subject: [PATCH 18/23] Create a second endpoint with only the answers in the response --- icmJsonClobHandler.js | 23 ++++++++++++++++++++--- routes.js | 17 ++++++++++++++++- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js index 0d47e7f..2a9aace 100644 --- a/icmJsonClobHandler.js +++ b/icmJsonClobHandler.js @@ -57,16 +57,33 @@ async function fetchIcmJsonClobData(attachmentId) { } } -async function getProcessedData(attachmentId) { +function extractICMJsonClobParsed(data) { + if (data.items && Array.isArray(data.items)) { + return data.items + .map(item => item.ICMJsonClobParsed) + .filter(parsed => parsed !== null && parsed !== undefined); + } + + if (data.ICMJsonClobParsed !== null && data.ICMJsonClobParsed !== undefined) { + return data.ICMJsonClobParsed; + } + + return []; +} + +async function getProcessedData(attachmentId, returnAnswersOnly = true) { try { const response = await fetchIcmJsonClobData(attachmentId); - const processedResult = processIcmJsonClobData(response.data); + let processedResult = processIcmJsonClobData(response.data); + + if (returnAnswersOnly) { + processedResult = extractICMJsonClobParsed(processedResult); + } return { success: true, data: processedResult }; - } catch (error) { console.error("API call failed:", error.message); diff --git a/routes.js b/routes.js index 1b2e0d1..01c3fc5 100644 --- a/routes.js +++ b/routes.js @@ -154,7 +154,7 @@ router.get("/getAllForms", async (request, response) => { router.get("/processIcmJsonClob", localhostOnlyMiddleware, async (req, res) => { try { - const result = await getProcessedData(req.query.attachmentId); + const result = await getProcessedData(req.query.attachmentId, false); if (result.success) { res.status(200).json(result.data); @@ -167,6 +167,21 @@ router.get("/processIcmJsonClob", localhostOnlyMiddleware, async (req, res) => { } }); +router.get("/processIcmJsonClob2", localhostOnlyMiddleware, async (req, res) => { + try { + const result = await getProcessedData(req.query.attachmentId, true); + + if (result.success) { + res.status(200).json(result.data); + } else { + res.status(500).json({ error: "Error." }); + } + } catch (error) { + console.error("Error:", error.message); + res.status(500).json({ error: "Internal server error", message: error.message }); + } +}); + // clear the locked by flags in ICM for the form, used when form is closed router.post("/clearICMLockedFlag", clearICMLockedFlag); From 37fdee5e5c10202fb5c328f2748161518b586bf4 Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Mon, 18 Aug 2025 09:12:48 -0700 Subject: [PATCH 19/23] Rename answers endpoint --- routes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes.js b/routes.js index 01c3fc5..656b4ea 100644 --- a/routes.js +++ b/routes.js @@ -167,7 +167,7 @@ router.get("/processIcmJsonClob", localhostOnlyMiddleware, async (req, res) => { } }); -router.get("/processIcmJsonClob2", localhostOnlyMiddleware, async (req, res) => { +router.get("/processIcmJsonClobAnswers", localhostOnlyMiddleware, async (req, res) => { try { const result = await getProcessedData(req.query.attachmentId, true); From 308dd8149f1b66c92f25b0a24eb251e7aabb88da Mon Sep 17 00:00:00 2001 From: Danilo Meireles Date: Mon, 18 Aug 2025 10:37:00 -0700 Subject: [PATCH 20/23] Update response object. --- icmJsonClobHandler.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js index 2a9aace..0b291f4 100644 --- a/icmJsonClobHandler.js +++ b/icmJsonClobHandler.js @@ -60,12 +60,12 @@ async function fetchIcmJsonClobData(attachmentId) { function extractICMJsonClobParsed(data) { if (data.items && Array.isArray(data.items)) { return data.items - .map(item => item.ICMJsonClobParsed) + .map(item => item.ICMJsonClobParsed.Answers) .filter(parsed => parsed !== null && parsed !== undefined); } if (data.ICMJsonClobParsed !== null && data.ICMJsonClobParsed !== undefined) { - return data.ICMJsonClobParsed; + return data.ICMJsonClobParsed.Answers; } return []; From c373f4640262ed6e97f72874ba95b4b7d46328a3 Mon Sep 17 00:00:00 2001 From: NicolaSDPR1 Date: Tue, 19 Aug 2025 09:55:02 -0700 Subject: [PATCH 21/23] Quick fix using XMLDEC to ensure the beginning xml tag does not include standalone and encoding --- saveICMdataHandler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saveICMdataHandler.js b/saveICMdataHandler.js index f6e719c..9834e0e 100644 --- a/saveICMdataHandler.js +++ b/saveICMdataHandler.js @@ -155,7 +155,7 @@ async function saveICMdata(req, res) { truncatedKeysSaveData[newKey] = saveData[oldKey]; //Data is added to new JSON with the truncated key } } - let builder = new xml2js.Builder(); + let builder = new xml2js.Builder({xmldec: { version: '1.0' }}); saveJson["XML Hierarchy"] = builder.buildObject(truncatedKeysSaveData); //let url = buildUrlWithParams('SIEBEL_ICM_API_HOST', 'fwd/v1.0/data/DT Form Instance Thin/DT Form Instance Thin/' + attachment_id + '/', ''); let url = buildUrlWithParams(params["apiHost"], params["saveEndpoint"] + attachment_id + '/', params); From dfa66b7138e27f70b8958972e34af29ef3feaac1 Mon Sep 17 00:00:00 2001 From: David Okulski <32730627+DavidOkulski@users.noreply.github.com> Date: Wed, 20 Aug 2025 09:01:55 -0700 Subject: [PATCH 22/23] Remove answer drilldown --- icmJsonClobHandler.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js index 0b291f4..2a9aace 100644 --- a/icmJsonClobHandler.js +++ b/icmJsonClobHandler.js @@ -60,12 +60,12 @@ async function fetchIcmJsonClobData(attachmentId) { function extractICMJsonClobParsed(data) { if (data.items && Array.isArray(data.items)) { return data.items - .map(item => item.ICMJsonClobParsed.Answers) + .map(item => item.ICMJsonClobParsed) .filter(parsed => parsed !== null && parsed !== undefined); } if (data.ICMJsonClobParsed !== null && data.ICMJsonClobParsed !== undefined) { - return data.ICMJsonClobParsed.Answers; + return data.ICMJsonClobParsed; } return []; From c1568092cb21561a8d19192bbac97e6e55fd2a53 Mon Sep 17 00:00:00 2001 From: David Okulski <32730627+DavidOkulski@users.noreply.github.com> Date: Wed, 20 Aug 2025 14:11:23 -0700 Subject: [PATCH 23/23] Use apiHost for portal endpoints --- databindingsHandler.js | 1 + icmJsonClobHandler.js | 8 ++++---- routes.js | 7 +++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/databindingsHandler.js b/databindingsHandler.js index b5d27e6..c14b2cc 100644 --- a/databindingsHandler.js +++ b/databindingsHandler.js @@ -188,6 +188,7 @@ async function readJsonFormApi(datasource, pathParams) { const headers = { Authorization: `Bearer ${grant.id_token.token}`, "X-ICM-TrustedUsername": username, + "X-API-Host": apiHost, } if (type.toUpperCase() === 'GET') { // For GET requests, add params directly in axios config diff --git a/icmJsonClobHandler.js b/icmJsonClobHandler.js index 2a9aace..a17dcd3 100644 --- a/icmJsonClobHandler.js +++ b/icmJsonClobHandler.js @@ -27,7 +27,7 @@ function processIcmJsonClobData(jsonData) { return parseIcmJsonClob(processedData); } -async function fetchIcmJsonClobData(attachmentId) { +async function fetchIcmJsonClobData(attachmentId, apiHost) { try { const grant = await keycloakForSiebel.grantManager.obtainFromClientCredentials(); @@ -39,7 +39,7 @@ async function fetchIcmJsonClobData(attachmentId) { "Content-Type": "application/json" }; - const url = `${process.env.SIEBEL_ICM_API_HOST}${process.env.ICM_JSON_CLOB_ENDPONT}`; + const url = `${apiHost}${process.env.ICM_JSON_CLOB_ENDPONT}`; const queryParams = { ViewMode: "Catalog", @@ -71,9 +71,9 @@ function extractICMJsonClobParsed(data) { return []; } -async function getProcessedData(attachmentId, returnAnswersOnly = true) { +async function getProcessedData(attachmentId, apiHost, returnAnswersOnly = true) { try { - const response = await fetchIcmJsonClobData(attachmentId); + const response = await fetchIcmJsonClobData(attachmentId, apiHost); let processedResult = processIcmJsonClobData(response.data); if (returnAnswersOnly) { diff --git a/routes.js b/routes.js index 656b4ea..0cbd7f2 100644 --- a/routes.js +++ b/routes.js @@ -6,6 +6,7 @@ const { generateTemplate,generateNewTemplate } = require("./generateHandler"); const { saveICMdata, loadICMdata, clearICMLockedFlag } = require("./saveICMdataHandler"); const { getUsername } = require("./usernameHandler.js"); const renderRouter = require("./renderHandler"); +const appCfg = require('./appConfig.js'); const {generatePDFFromHTML,generatePDFFromURL,generatePDFFromJSON,loadSavedJson } = require("./generatePDFHandler"); const generatePortalIntegratedTemplate = require("./portal/generatePortalIntegratedHandler.js"); @@ -154,7 +155,8 @@ router.get("/getAllForms", async (request, response) => { router.get("/processIcmJsonClob", localhostOnlyMiddleware, async (req, res) => { try { - const result = await getProcessedData(req.query.attachmentId, false); + const apiHost = req.get("X-API-Host"); + const result = await getProcessedData(req.query.attachmentId, apiHost, false); if (result.success) { res.status(200).json(result.data); @@ -169,7 +171,8 @@ router.get("/processIcmJsonClob", localhostOnlyMiddleware, async (req, res) => { router.get("/processIcmJsonClobAnswers", localhostOnlyMiddleware, async (req, res) => { try { - const result = await getProcessedData(req.query.attachmentId, true); + const apiHost = req.get("X-API-Host"); + const result = await getProcessedData(req.query.attachmentId, apiHost, true); if (result.success) { res.status(200).json(result.data);