|
| 1 | +/** |
| 2 | + * Endpoint called from the client, to execute action buttons, |
| 3 | + * by making GET request to web hook URL, and returning response |
| 4 | + */ |
| 5 | +const axios = require('axios').default; |
| 6 | +const https = require('https'); |
| 7 | + |
| 8 | +/* Makes human-readable response text for failed check */ |
| 9 | +const makeErrorMessage = (data) => `❌ Service Unavailable: ${data.hostname || 'Server'} ` |
| 10 | + + `resulted in ${data.code || 'a fatal error'} ${data.errno ? `(${data.errno})` : ''}`; |
| 11 | + |
| 12 | +/* Kicks of a HTTP request, then formats and renders results */ |
| 13 | +const makeRequest = (url, options, render) => { |
| 14 | + const { |
| 15 | + headers, enableInsecure, maxRedirects, |
| 16 | + } = options; |
| 17 | + const startTime = new Date(); |
| 18 | + // Create HTTPS agent for request |
| 19 | + const requestMaker = axios.create({ |
| 20 | + httpsAgent: new https.Agent({ |
| 21 | + rejectUnauthorized: !enableInsecure, |
| 22 | + }), |
| 23 | + }); |
| 24 | + // Make request, with params |
| 25 | + requestMaker.request({ |
| 26 | + url, |
| 27 | + headers, |
| 28 | + maxRedirects, |
| 29 | + }).then((response) => ({ |
| 30 | + statusCode: response.status, |
| 31 | + responseText: response.statusText, |
| 32 | + successStatus: true, |
| 33 | + timeTaken: (new Date() - startTime), |
| 34 | + })).catch((error) => ({ |
| 35 | + successStatus: false, |
| 36 | + message: makeErrorMessage(error), |
| 37 | + })).then((results) => { |
| 38 | + // Request completed (either successfully, or failed) - render results |
| 39 | + render(JSON.stringify(results)); |
| 40 | + }); |
| 41 | +}; |
| 42 | + |
| 43 | +const decodeHeaders = (maybeHeaders) => { |
| 44 | + if (!maybeHeaders) return {}; |
| 45 | + const decodedHeaders = decodeURIComponent(maybeHeaders); |
| 46 | + let parsedHeaders = {}; |
| 47 | + try { |
| 48 | + parsedHeaders = JSON.parse(decodedHeaders); |
| 49 | + } catch (e) { /* Not valid JSON, will just return false */ } |
| 50 | + return parsedHeaders; |
| 51 | +}; |
| 52 | + |
| 53 | +/* Returned if the URL param is not present or correct */ |
| 54 | +const immediateError = (render) => { |
| 55 | + render(JSON.stringify({ |
| 56 | + successStatus: false, |
| 57 | + message: '❌ Missing URL or Malformed Options', |
| 58 | + })); |
| 59 | +}; |
| 60 | + |
| 61 | +/* Main function, will check if a URL present, and call function */ |
| 62 | +module.exports = (paramStr, render) => { |
| 63 | + // If no parameters passed, then fail |
| 64 | + if (!paramStr || !paramStr.includes('=')) { |
| 65 | + immediateError(render); |
| 66 | + return; |
| 67 | + } |
| 68 | + // Prepare the parameters, which are got from the URL |
| 69 | + const params = new URLSearchParams(paramStr); |
| 70 | + const url = decodeURIComponent(params.get('url')); |
| 71 | + const maxRedirects = decodeURIComponent(params.get('maxRedirects')) || 0; |
| 72 | + const headers = decodeHeaders(params.get('headers')); |
| 73 | + const enableInsecure = !!params.get('enableInsecure'); |
| 74 | + // Check target URL is present |
| 75 | + if (!url || url === 'undefined') immediateError(render); |
| 76 | + // Put options together |
| 77 | + const options = { |
| 78 | + headers, enableInsecure, maxRedirects, |
| 79 | + }; |
| 80 | + // Make the request |
| 81 | + makeRequest(url, options, render); |
| 82 | +}; |
0 commit comments