From 50e2c4704cbe731c9ffd140fb29f88faaa1ac434 Mon Sep 17 00:00:00 2001 From: Trevor Dolby Date: Thu, 17 Jul 2025 14:38:12 -0500 Subject: [PATCH 1/4] Add X-INSTANCE-API-KEY support Signed-off-by: Trevor Dolby --- rest-fetch.js | 21 ++++++++++++++------- sync-rest-fetch.js | 16 +++++++++++++--- wmiocli.js | 30 +++++++++++++++++++----------- 3 files changed, 46 insertions(+), 21 deletions(-) diff --git a/rest-fetch.js b/rest-fetch.js index eb1fa94..a5d7250 100644 --- a/rest-fetch.js +++ b/rest-fetch.js @@ -156,10 +156,13 @@ async function uploadFileFormData(restEndPoint, user, pass, timeout, data, filen formData.append('field_separator', data.field_separator); formData.append('text_qualifier', data.text_qualifier); + const authHeaderName = (user === 'X-INSTANCE-API-KEY') ? 'X-INSTANCE-API-KEY' : 'Authorization'; + const authHeaderValue = (user === 'X-INSTANCE-API-KEY') ? pass : 'Basic ' + btoa(user + ':' + pass); + const options = { method: method, headers: { - 'Authorization': 'Basic ' + btoa(user + ':' + pass), + authHeaderName: authHeaderValue, 'Accept': 'application/json', ...formData.getHeaders() }, @@ -321,12 +324,16 @@ async function custom(restEndPoint,user,pass,timeout,jsonBody,formBody,type,call //Authentication if(user!==undefined) { - options.auth={}; - options.auth.username = user; - options.auth.password = pass; - const base64Credentials = Buffer.from(`${user}:${pass}`).toString('base64'); - options.headers['Authorization']= `Basic ${base64Credentials}`; - + if(user != "X-INSTANCE-API-KEY") + { + options.auth={}; + options.auth.username = user; + options.auth.password = pass; + const base64Credentials = Buffer.from(`${user}:${pass}`).toString('base64'); + options.headers['Authorization']= `Basic ${base64Credentials}`; + } else { + options.headers['X-INSTANCE-API-KEY'] = pass; + } } //Body Content diff --git a/sync-rest-fetch.js b/sync-rest-fetch.js index fea8188..7be912e 100644 --- a/sync-rest-fetch.js +++ b/sync-rest-fetch.js @@ -138,10 +138,13 @@ async function uploadFileFormData(restEndPoint, user, pass, timeout, data, filen formData.append('field_separator', data.field_separator); formData.append('text_qualifier', data.text_qualifier); + const authHeaderName = (user === 'X-INSTANCE-API-KEY') ? 'X-INSTANCE-API-KEY' : 'Authorization'; + const authHeaderValue = (user === 'X-INSTANCE-API-KEY') ? pass : 'Basic ' + Buffer.from(user + ':' + pass).toString('base64'); + const options = { method: method, headers: { - 'Authorization': 'Basic ' + Buffer.from(user + ':' + pass).toString('base64'), + authHeaderName: authHeaderValue, 'Accept': 'application/json', ...formData.getHeaders() }, @@ -171,7 +174,11 @@ async function custom(restEndPoint, user, pass, timeout, data, contentType, meth }; if(user!==undefined && user!==null && user.length>0){ - options.headers["Authorization"]='Basic ' + Buffer.from(user + ':' + pass).toString('base64'); + if ( user != "X-INSTANCE-API-KEY" ) { + options.headers["Authorization"]='Basic ' + Buffer.from(user + ':' + pass).toString('base64'); + } else { + options.headers["X-INSTANCE-API-KEY"]=pass; + } } if (data) { @@ -227,10 +234,13 @@ async function custom(restEndPoint, user, pass, timeout, data, contentType, meth async function downloadFile(restEndPoint, user, pass, timeout, destFile) { debug("GET File from: " + restEndPoint); + const authHeaderName = (user === 'X-INSTANCE-API-KEY') ? 'X-INSTANCE-API-KEY' : 'Authorization'; + const authHeaderValue = (user === 'X-INSTANCE-API-KEY') ? pass : 'Basic ' + Buffer.from(user + ':' + pass).toString('base64'); + const options = { method: 'GET', headers: { - 'Authorization': 'Basic ' + Buffer.from(user + ':' + pass).toString('base64'), + authHeaderName: authHeaderValue, 'Accept': 'application/octet-stream', }, timeout: timeout * 1000, diff --git a/wmiocli.js b/wmiocli.js index 30adaeb..20c58c8 100644 --- a/wmiocli.js +++ b/wmiocli.js @@ -130,20 +130,27 @@ function checkOptions() { } } - if (program.opts().user == undefined) { - tenantUser = readFromConsole('Please type your tenant User ID: '); - } - else { - tenantUser = program.opts().user - } - if (program.opts().password == undefined) { - tenantPw = readFromConsole('Please type your tenant User Password: ', true); + if (program.opts().apikey == undefined) { + if (program.opts().user == undefined) { + tenantUser = readFromConsole('Please type your tenant User ID: '); + } + else { + tenantUser = program.opts().user + } + + if (program.opts().password == undefined) { + tenantPw = readFromConsole('Please type your tenant User Password: ', true); + } + else { + tenantPw = program.opts().password + } } else { - tenantPw = program.opts().password + // Picked up in rest-fetch and used for the auth header + tenantUser = "X-INSTANCE-API-KEY" + tenantPw = program.opts().apikey } - } function debug(message) { @@ -158,10 +165,11 @@ program .version(versionNo) //required options - .option('-d, --domain ', 'Tenant Doamin Name, e.g. "tenant.int-aws-us.webmethods.io"') + .option('-d, --domain ', 'Tenant Domain Name, e.g. "tenant.int-aws-us.webmethods.io"') .option('-u, --user ', 'Tenant User ID') .option('-p, --password ', 'Tenant User Password') //.requiredOption('-p, --password ', 'Tenant User Password') + .option('-k, --apikey ', 'API key for X-INSTANCE-API-KEY header (replaces -u/-p)') //Positional optoins .option('-s, --start ', 'Index of where to start the return of data (default 0)') From aa0c5d31d81aafe34ae7c739e1597c3acc4278cb Mon Sep 17 00:00:00 2001 From: Trevor Dolby Date: Thu, 17 Jul 2025 14:43:49 -0500 Subject: [PATCH 2/4] IWHI update Signed-off-by: Trevor Dolby --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 98e5a8f..89fd9f0 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ The --help parameter provides further information on how to use this along with This CLI tool has been tested against * webMethods.io Integration v11.0.3 +This tool has also been used with IBM webMethods Hybrid Integration using the `--apikey` option to +allow authentication to succeed in that environment. + # License This project is licensed under the Apache 2.0 License - see the LICENSE file for details These tools are provided as-is and without warranty or support. They do not constitute part of the webMethods product suite. Users are free to use, fork and modify them, subject to the license agreement. While we welcome contributions, we cannot guarantee to include every contribution in the master project. @@ -38,6 +41,7 @@ Options: -d, --domain Tenant Doamin Name, e.g. "tenant.int-aws-us.webmethods.io" -u, --user Tenant User ID -p, --password Tenant User Password + -k, --apikey API key for X-INSTANCE-API-KEY header (replaces -u/-p) -s, --start Index of where to start the return of data (default 0) -l, --count Count of items to return (default 1000) -t, --timeout timeout in seconds (default: one minute) From 1f2287cc8b7a0b412de0ba3d0ee538d352bc89ba Mon Sep 17 00:00:00 2001 From: Trevor Dolby Date: Thu, 17 Jul 2025 14:49:37 -0500 Subject: [PATCH 3/4] Version bump Signed-off-by: Trevor Dolby --- package.json | 2 +- wmiocli.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 559fd76..a9f0995 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wmiocli", - "version": "2024.11.1", + "version": "2025.7.17", "description": "webMethods.io Integration API CLI Tool", "bin": { "wmiocli": "./wmiocli.js" diff --git a/wmiocli.js b/wmiocli.js index 20c58c8..25061fc 100644 --- a/wmiocli.js +++ b/wmiocli.js @@ -4,7 +4,7 @@ * Apache-2.0 */ -const versionNo = "2024.11.1" +const versionNo = "2025.07.17" const { Command, Option } = require('commander'); const { exit } = require('process'); const readline = require('readline-sync'); From 8694de7643721e34f4b9ee0fe84053fb4f9995f1 Mon Sep 17 00:00:00 2001 From: Trevor Dolby Date: Tue, 29 Jul 2025 18:05:46 -0500 Subject: [PATCH 4/4] Fix project-import Signed-off-by: Trevor Dolby --- projects.js | 2 +- wmiocli.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects.js b/projects.js index b682dc2..06fedf3 100644 --- a/projects.js +++ b/projects.js @@ -76,7 +76,7 @@ $ node wmiocli.js -d tenant.int-aws-us.webmethods.io -u user -p password - project-export myproject.zip MyNewProjectName + project-import myproject.zip MyNewProjectName \x1b[32mGet Project Assets:\x1b[0m $ node wmiocli.js diff --git a/wmiocli.js b/wmiocli.js index 25061fc..70ce76c 100644 --- a/wmiocli.js +++ b/wmiocli.js @@ -4,7 +4,7 @@ * Apache-2.0 */ -const versionNo = "2025.07.17" +const versionNo = "2025.7.17" const { Command, Option } = require('commander'); const { exit } = require('process'); const readline = require('readline-sync');