From 18f80503e311a6c5713845cdf735151b019dc08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20H=C3=B6ffler?= Date: Mon, 1 Sep 2025 15:01:15 +0200 Subject: [PATCH] Added support for authFormat for api keys --- bin/oih-gen.js | 1 + lib/do-generate.js | 7 +++++-- lib/generate.js | 3 ++- lib/utils/functions.js | 3 ++- templates/component.json | 1 + templates/lib/actions/action.js | 6 +++++- templates/lib/triggers/trigger.js | 7 ++++++- templates/lib/utils/helpers.js | 15 ++++++++++++++- templates/lib/utils/helpers.test.js | 13 +++++++++++++ 9 files changed, 49 insertions(+), 7 deletions(-) diff --git a/bin/oih-gen.js b/bin/oih-gen.js index 7837e9b..727b2dc 100755 --- a/bin/oih-gen.js +++ b/bin/oih-gen.js @@ -63,6 +63,7 @@ async function oihGen() { outputDir: options.output, snapshot: options.snapshot, rateLimit: options.rateLimit, + authFormat: options.authFormat, syncParamFormat: options.syncParamFormat, paginationConfig: { pageTokenOption: { diff --git a/lib/do-generate.js b/lib/do-generate.js index 6c7c97c..8594f7c 100644 --- a/lib/do-generate.js +++ b/lib/do-generate.js @@ -18,9 +18,11 @@ const generate = require("./generate"); * @param {string} paginationConfig.pageTokenOption.fieldName * @param {number} rateLimit * @param {string} syncParamFormat + * @param {object} authFormat + * @param {string} authFormat.prefix * @returns {Promise<*>} */ -module.exports = async function doGenerate({ swaggerUrl, outputDir, connectorName, snapshot, paginationConfig, rateLimit, syncParamFormat }) { +module.exports = async function doGenerate({ swaggerUrl, outputDir, connectorName, snapshot, paginationConfig, rateLimit, syncParamFormat, authFormat, }) { const downloadedSpecFile = path.join(outputDir, "openapi-original.json"); const validatedSpecFile = path.join(outputDir, "openapi-validated.json"); const generatePath = path.join(outputDir, connectorName); @@ -49,7 +51,8 @@ module.exports = async function doGenerate({ swaggerUrl, outputDir, connectorNam snapshot: snapshot || "", paginationConfig, rateLimit: rateLimit || -1, - syncParamFormat: syncParamFormat + syncParamFormat: syncParamFormat, + authFormat: authFormat || {}, }); console.log("\x1b[32m", "Successfully generated. Connector has been saved in output directory:", generatePath); diff --git a/lib/generate.js b/lib/generate.js index 52d2e76..747f4a6 100644 --- a/lib/generate.js +++ b/lib/generate.js @@ -34,6 +34,7 @@ module.exports = async function generate({ suffixServiceNameToTitle = false, rateLimit = -1, syncParamFormat, + authFormat = {}, }) { let api = await SwaggerParser.parse(inputFile); if (!api.components) { @@ -53,7 +54,7 @@ module.exports = async function generate({ fse.removeSync(libDir); } - let componentJson = await getComponentJson(apiTitle, api, swaggerUrl, rateLimit, syncParamFormat, this); + let componentJson = await getComponentJson(apiTitle, api, swaggerUrl, rateLimit, syncParamFormat, authFormat, this); let existingNames = {}; // generate actions diff --git a/lib/utils/functions.js b/lib/utils/functions.js index 82dcda1..627a0e3 100644 --- a/lib/utils/functions.js +++ b/lib/utils/functions.js @@ -80,7 +80,7 @@ async function output(filename, text, data, outputDir) { //console.log('Writing file %s', filename); return await fse.outputFile(path.join(outputDir, filename), text); } -async function getComponentJson(apiTitle, api, swaggerUrl, rateLimit, syncParamFormat) { +async function getComponentJson(apiTitle, api, swaggerUrl, rateLimit, syncParamFormat, authFormat) { const textDescription = toText(api.info.description); const componentJson = Object.assign(JSON.parse(templates.componentTemplate), { @@ -90,6 +90,7 @@ async function getComponentJson(apiTitle, api, swaggerUrl, rateLimit, syncParamF url: swaggerUrl, rateLimit: parseInt(rateLimit), syncParamFormat: syncParamFormat, + authFormat: authFormat, }); await addCredentials(componentJson, api); diff --git a/templates/component.json b/templates/component.json index dd033e4..849ece3 100644 --- a/templates/component.json +++ b/templates/component.json @@ -4,6 +4,7 @@ "docsUrl": "", "url": "", "rateLimit": -1, + "authFormat": {}, "envVars": {}, "credentials": {}, "triggers": {}, diff --git a/templates/lib/actions/action.js b/templates/lib/actions/action.js index c3d3431..e27e7cb 100644 --- a/templates/lib/actions/action.js +++ b/templates/lib/actions/action.js @@ -12,7 +12,7 @@ */ const spec = require("../spec.json"); -const { mapFieldNames, getMetadata, mapFormDataBody, putAdditionalParamsInBody, executeCall } = require("../utils/helpers"); +const { mapFieldNames, getMetadata, mapFormDataBody, putAdditionalParamsInBody, executeCall, formatApiKey } = require("../utils/helpers"); const componentJson = require("../../component.json"); async function processAction(msg, cfg, snapshot, incomingMessageHeaders, tokenData) { @@ -35,6 +35,10 @@ async function processAction(msg, cfg, snapshot, incomingMessageHeaders, tokenDa logger.debug("Incoming message headers: %j", incomingMessageHeaders); logger.debug("Incoming token data: %j", tokenData); + if (cfg?.key && componentJson?.authFormat) { + cfg.key = formatApiKey(cfg.key, componentJson.authFormat); + } + const actionFunction = tokenData["function"]; logger.info("Starting to execute action '%s'", actionFunction); diff --git a/templates/lib/triggers/trigger.js b/templates/lib/triggers/trigger.js index 54e6568..8d5d14e 100644 --- a/templates/lib/triggers/trigger.js +++ b/templates/lib/triggers/trigger.js @@ -17,7 +17,8 @@ const { getMetadata, getElementDataFromResponse, executeCall, - getInitialSnapshotValue + getInitialSnapshotValue, + formatApiKey, } = require("../utils/helpers"); const { createPaginator } = require("../utils/paginator"); const componentJson = require("../../component.json"); @@ -43,6 +44,10 @@ async function processTrigger(msg, cfg, snapshot, incomingMessageHeaders, tokenD logger.debug("Incoming message headers: %j", incomingMessageHeaders); logger.debug("Incoming token data: %j", tokenData); + if (cfg?.key && componentJson?.authFormat) { + cfg.key = formatApiKey(cfg.key, componentJson.authFormat); + } + const triggerFunction = tokenData["function"]; logger.info("Starting to execute trigger \"%s\"", triggerFunction); diff --git a/templates/lib/utils/helpers.js b/templates/lib/utils/helpers.js index 95677d5..7fa4c99 100644 --- a/templates/lib/utils/helpers.js +++ b/templates/lib/utils/helpers.js @@ -306,6 +306,18 @@ async function getResponseData(response) { } } +function formatApiKey(key, format) { + let formattedKey = key; + + if (format.prefix) { + if (!formattedKey?.startsWith(format.prefix)) { + formattedKey = `${format.prefix}${formattedKey}`; + } + } + + return formattedKey; +} + module.exports = { compareDate, mapFieldNames, @@ -317,5 +329,6 @@ module.exports = { executeCall, getInitialSnapshotValue, getInputMetadataSchema, - putAdditionalParamsInBody + putAdditionalParamsInBody, + formatApiKey }; diff --git a/templates/lib/utils/helpers.test.js b/templates/lib/utils/helpers.test.js index 56f33f5..e2bd9ff 100644 --- a/templates/lib/utils/helpers.test.js +++ b/templates/lib/utils/helpers.test.js @@ -2,6 +2,7 @@ const { isMicrosoftJsonDate, getInitialSnapshotValue, compareDate, + formatApiKey } = require("./helpers"); const dayjs = require('dayjs'); @@ -56,4 +57,16 @@ describe("Helpers", () => { }); }); + + describe("formatApiKey", () => { + it("should prefix a key with a given prefix if it is missing", () => { + const tokenKey = formatApiKey('abcd123', { prefix: 'Token ' }); + expect(tokenKey).toEqual('Token abcd123'); + }); + + it("should not prefix a key if it's already correctly formatted", () => { + const BearerKey = formatApiKey('Bearer abcd123', { prefix: 'Bearer ' }); + expect(BearerKey).toEqual('Bearer abcd123'); + }); + }); });