mirror of
https://github.com/Lissy93/dashy.git
synced 2025-12-06 16:43:13 +01:00
✨ Started working on server-side endoint for action buttons (#383)
This commit is contained in:
parent
32ca8996d2
commit
ae94fdfc76
2 changed files with 93 additions and 0 deletions
11
server.js
11
server.js
|
|
@ -22,6 +22,7 @@ require('./services/config-validator'); // Include and kicks off the config file
|
||||||
|
|
||||||
/* Include route handlers for API endpoints */
|
/* Include route handlers for API endpoints */
|
||||||
const statusCheck = require('./services/status-check'); // Used by the status check feature, uses GET
|
const statusCheck = require('./services/status-check'); // Used by the status check feature, uses GET
|
||||||
|
const actionButton = require('./services/action-buttons-call'); // Used by action buttons, to execute users web hooks
|
||||||
const saveConfig = require('./services/save-config'); // Saves users new conf.yml to file-system
|
const saveConfig = require('./services/save-config'); // Saves users new conf.yml to file-system
|
||||||
const rebuild = require('./services/rebuild-app'); // A script to programmatically trigger a build
|
const rebuild = require('./services/rebuild-app'); // A script to programmatically trigger a build
|
||||||
const systemInfo = require('./services/system-info'); // Basic system info, for resource widget
|
const systemInfo = require('./services/system-info'); // Basic system info, for resource widget
|
||||||
|
|
@ -84,6 +85,16 @@ const app = express()
|
||||||
printWarning(`Error running status check for ${req.url}\n`, e);
|
printWarning(`Error running status check for ${req.url}\n`, e);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
// GET endpoint for executing web-hooks for action buttons
|
||||||
|
.use(ENDPOINTS.actionButtonCall, (req, res) => {
|
||||||
|
try {
|
||||||
|
actionButton(req.url, async (results) => {
|
||||||
|
await res.end(results);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
printWarning(`Error executing web hook for ${req.url}\n`, e);
|
||||||
|
}
|
||||||
|
})
|
||||||
// POST Endpoint used to save config, by writing conf.yml to disk
|
// POST Endpoint used to save config, by writing conf.yml to disk
|
||||||
.use(ENDPOINTS.save, method('POST', (req, res) => {
|
.use(ENDPOINTS.save, method('POST', (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
82
services/action-buttons-call.js
Normal file
82
services/action-buttons-call.js
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
/**
|
||||||
|
* Endpoint called from the client, to execute action buttons,
|
||||||
|
* by making GET request to web hook URL, and returning response
|
||||||
|
*/
|
||||||
|
const axios = require('axios').default;
|
||||||
|
const https = require('https');
|
||||||
|
|
||||||
|
/* Makes human-readable response text for failed check */
|
||||||
|
const makeErrorMessage = (data) => `❌ Service Unavailable: ${data.hostname || 'Server'} `
|
||||||
|
+ `resulted in ${data.code || 'a fatal error'} ${data.errno ? `(${data.errno})` : ''}`;
|
||||||
|
|
||||||
|
/* Kicks of a HTTP request, then formats and renders results */
|
||||||
|
const makeRequest = (url, options, render) => {
|
||||||
|
const {
|
||||||
|
headers, enableInsecure, maxRedirects,
|
||||||
|
} = options;
|
||||||
|
const startTime = new Date();
|
||||||
|
// Create HTTPS agent for request
|
||||||
|
const requestMaker = axios.create({
|
||||||
|
httpsAgent: new https.Agent({
|
||||||
|
rejectUnauthorized: !enableInsecure,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
// Make request, with params
|
||||||
|
requestMaker.request({
|
||||||
|
url,
|
||||||
|
headers,
|
||||||
|
maxRedirects,
|
||||||
|
}).then((response) => ({
|
||||||
|
statusCode: response.status,
|
||||||
|
responseText: response.statusText,
|
||||||
|
successStatus: true,
|
||||||
|
timeTaken: (new Date() - startTime),
|
||||||
|
})).catch((error) => ({
|
||||||
|
successStatus: false,
|
||||||
|
message: makeErrorMessage(error),
|
||||||
|
})).then((results) => {
|
||||||
|
// Request completed (either successfully, or failed) - render results
|
||||||
|
render(JSON.stringify(results));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const decodeHeaders = (maybeHeaders) => {
|
||||||
|
if (!maybeHeaders) return {};
|
||||||
|
const decodedHeaders = decodeURIComponent(maybeHeaders);
|
||||||
|
let parsedHeaders = {};
|
||||||
|
try {
|
||||||
|
parsedHeaders = JSON.parse(decodedHeaders);
|
||||||
|
} catch (e) { /* Not valid JSON, will just return false */ }
|
||||||
|
return parsedHeaders;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Returned if the URL param is not present or correct */
|
||||||
|
const immediateError = (render) => {
|
||||||
|
render(JSON.stringify({
|
||||||
|
successStatus: false,
|
||||||
|
message: '❌ Missing URL or Malformed Options',
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Main function, will check if a URL present, and call function */
|
||||||
|
module.exports = (paramStr, render) => {
|
||||||
|
// If no parameters passed, then fail
|
||||||
|
if (!paramStr || !paramStr.includes('=')) {
|
||||||
|
immediateError(render);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Prepare the parameters, which are got from the URL
|
||||||
|
const params = new URLSearchParams(paramStr);
|
||||||
|
const url = decodeURIComponent(params.get('url'));
|
||||||
|
const maxRedirects = decodeURIComponent(params.get('maxRedirects')) || 0;
|
||||||
|
const headers = decodeHeaders(params.get('headers'));
|
||||||
|
const enableInsecure = !!params.get('enableInsecure');
|
||||||
|
// Check target URL is present
|
||||||
|
if (!url || url === 'undefined') immediateError(render);
|
||||||
|
// Put options together
|
||||||
|
const options = {
|
||||||
|
headers, enableInsecure, maxRedirects,
|
||||||
|
};
|
||||||
|
// Make the request
|
||||||
|
makeRequest(url, options, render);
|
||||||
|
};
|
||||||
Loading…
Reference in a new issue