UNPKG

n8n-nodes-base

Version:

Base nodes of n8n

96 lines 4.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.execute = execute; const n8n_workflow_1 = require("n8n-workflow"); const helpers_1 = require("../helpers"); async function execute(i) { const credentialType = (0, helpers_1.getActiveCredentialType)(this, i); const host = await (0, helpers_1.getHost)(this, credentialType); const endpointName = this.getNodeParameter('endpointName', i, '', { extractValue: true, }); const requestBodyRaw = this.getNodeParameter('requestBody', i); const requestBody = typeof requestBodyRaw === 'string' ? (0, n8n_workflow_1.jsonParse)(requestBodyRaw) : requestBodyRaw; // Step 1: Fetch the OpenAPI schema for this endpoint let detectedFormat = 'generic'; let invocationUrl = `${host}/serving-endpoints/${endpointName}/invocations`; // Default fallback let exampleRequestBody = ''; try { const openApiResponse = (await this.helpers.httpRequestWithAuthentication.call(this, credentialType, { method: 'GET', url: `${host}/api/2.0/serving-endpoints/${endpointName}/openapi`, headers: { Accept: 'application/json' }, json: true, })); if (openApiResponse?.length > 0) { const schemaInfo = (0, helpers_1.detectInputFormat)(openApiResponse[0]); detectedFormat = schemaInfo.format; const schemaUrl = schemaInfo.invocationUrl; // Only use the URL from the schema if it belongs to the same host as the // configured credential. This prevents a malicious or compromised endpoint // from returning an attacker-controlled server URL and causing the node to // forward the Databricks bearer token to an external host. if (!URL.canParse(schemaUrl)) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The serving endpoint returned an invalid server URL in its OpenAPI schema: ${schemaUrl}`); } if (new URL(schemaUrl).origin !== new URL(host).origin) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The serving endpoint's OpenAPI schema contains a server URL (${schemaUrl}) that does not match the configured Databricks host (${host}). This request has been blocked for security reasons.`); } invocationUrl = schemaUrl; exampleRequestBody = (0, helpers_1.generateExampleFromSchema)(schemaInfo.schema, detectedFormat); try { (0, helpers_1.validateRequestBody)(requestBody, detectedFormat); } catch (validationError) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `${validationError.message}\n\nDetected format: ${detectedFormat}\n\nExample request body:\n${exampleRequestBody}\n\nYour request body:\n${JSON.stringify(requestBody, null, 2)}`); } } } catch (error) { if (error instanceof n8n_workflow_1.NodeOperationError) { throw error; } this.logger.warn('Could not fetch or parse endpoint schema, using default URL', { endpointName, error: error.message, defaultUrl: invocationUrl, }); if (!exampleRequestBody) { exampleRequestBody = (0, helpers_1.generateExampleFromSchema)(null, detectedFormat); } } // Step 2: Make the request using the URL from schema try { const response = await this.helpers.httpRequestWithAuthentication.call(this, credentialType, { method: 'POST', url: invocationUrl, body: requestBody, headers: { 'Content-Type': 'application/json' }, json: true, }); return [ { json: { ...response, _metadata: { endpoint: endpointName, detectedFormat, invocationUrl }, }, pairedItem: { item: i }, }, ]; } catch (apiError) { if (apiError.statusCode === 400) { if (!exampleRequestBody) { exampleRequestBody = (0, helpers_1.generateExampleFromSchema)(null, detectedFormat); } const errorDetails = apiError.response?.body || apiError.message || 'Bad Request'; throw new n8n_workflow_1.NodeOperationError(this.getNode(), `API Error: 400 Bad Request\n\nThe endpoint rejected your request. This usually means the request body format is incorrect.\n\nError details: ${JSON.stringify(errorDetails, null, 2)}\n\nDetected format: ${detectedFormat}\n\nExpected request body format:\n${exampleRequestBody}\n\nYour request body:\n${JSON.stringify(requestBody, null, 2)}`); } throw apiError; } } //# sourceMappingURL=queryEndpoint.operation.js.map