mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-14 20:03:52 +00:00
Refactor/socket controller (#212)
* refactor(socket): dictionary cleanup * refactor(socket): detangle socket from EventTimer * refactor(socket): poll object * refactor(socket): wip, extract data responsibilities to provider * fix: issue with onAir * refactor: create data provider and validation utils * refactor: remove deprecated endpoint * refactor: detangle and validate ontime controller * refactor: detangle and validate events controller * refactor: validate routers * refactor: handle post failure in modals
This commit is contained in:
@@ -1,24 +1,28 @@
|
||||
// get database
|
||||
import { db, data } from '../app.js';
|
||||
import { removeUndefined } from '../utils/parserUtils.js';
|
||||
import { failEmptyObjects } from '../utils/routerUtils.js';
|
||||
import { DataProvider } from '../classes/data-provider/DataProvider.js';
|
||||
|
||||
// Create controller for GET request to 'event'
|
||||
// Returns ACK message
|
||||
export const getEvent = async (req, res) => {
|
||||
res.json(data.event);
|
||||
res.json(DataProvider.getEventData());
|
||||
};
|
||||
|
||||
// Create controller for POST request to 'event'
|
||||
// Returns ACK message
|
||||
export const postEvent = async (req, res) => {
|
||||
if (!req.body) {
|
||||
res.status(400).send('No object found in request');
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
// TODO: validate data
|
||||
|
||||
try {
|
||||
data.event = { ...data.event, ...req.body };
|
||||
await db.write();
|
||||
res.sendStatus(200);
|
||||
const newEvent = removeUndefined({
|
||||
title: req.body?.title,
|
||||
url: req.body?.url,
|
||||
publicInfo: req.body?.publicInfo,
|
||||
backstageInfo: req.body?.backstageInfo,
|
||||
endMessage: req.body?.endMessage,
|
||||
});
|
||||
const newData = await DataProvider.setEventData(newEvent);
|
||||
res.status(200).send(newData);
|
||||
} catch (error) {
|
||||
res.status(400).send(error);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { body, validationResult } from 'express-validator';
|
||||
|
||||
export const eventSanitizer = [
|
||||
body('title').optional().isString().trim().escape(),
|
||||
body('url').optional().isString().trim().escape(),
|
||||
body('publicInfo').optional().isString().trim().escape(),
|
||||
body('backstageInfo').optional().isString().trim().escape(),
|
||||
body('endMessage').optional().isString().trim().escape(),
|
||||
(req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
next();
|
||||
},
|
||||
];
|
||||
@@ -1,7 +1,3 @@
|
||||
// get database
|
||||
import { data, db } from '../app.js';
|
||||
|
||||
// utils
|
||||
import {
|
||||
block as blockDef,
|
||||
delay as delayDef,
|
||||
@@ -10,87 +6,36 @@ import {
|
||||
import { generateId } from '../utils/generate_id.js';
|
||||
import { MAX_EVENTS } from '../settings.js';
|
||||
import { getPreviousPlayable } from '../utils/eventUtils.js';
|
||||
import { DataProvider } from '../classes/data-provider/DataProvider.js';
|
||||
import { failEmptyObjects } from '../utils/routerUtils.js';
|
||||
import { socketProvider } from '../classes/socket/SocketController.js';
|
||||
|
||||
// import socket provider
|
||||
const socket = socketProvider;
|
||||
|
||||
async function _insertAndSync(newEvent) {
|
||||
if (newEvent.order) {
|
||||
const events = data.events;
|
||||
await _insertAt(newEvent, newEvent.order);
|
||||
const events = DataProvider.getEvents();
|
||||
await DataProvider.insertEventAt(newEvent, newEvent.order);
|
||||
const previousId = events?.[newEvent.order - 1]?.id;
|
||||
_insertEventInTimerAfterId(newEvent, previousId);
|
||||
} else if (newEvent.after) {
|
||||
await _insertAfterId(newEvent, newEvent.after);
|
||||
await DataProvider.insertEventAfterId(newEvent, newEvent.after);
|
||||
_insertEventInTimerAfterId(newEvent, newEvent.after);
|
||||
} else {
|
||||
await _insertAt(newEvent, 0);
|
||||
await DataProvider.insertEventAt(newEvent, 0);
|
||||
_insertEventInTimerAfterId(newEvent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insets an event after a given index
|
||||
* @param entry
|
||||
* @param index
|
||||
* @return {Promise<void>}
|
||||
* @private
|
||||
*/
|
||||
async function _insertAt(entry, index) {
|
||||
// get events
|
||||
const events = data.events;
|
||||
const count = events.length;
|
||||
const order = entry.order;
|
||||
|
||||
// Remove order field from object
|
||||
delete entry.order;
|
||||
|
||||
// Insert at beginning
|
||||
if (order === 0) {
|
||||
events.unshift(entry);
|
||||
}
|
||||
|
||||
// insert at end
|
||||
else if (order >= count) {
|
||||
events.push(entry);
|
||||
}
|
||||
|
||||
// insert in the middle
|
||||
else {
|
||||
events.splice(index, 0, entry);
|
||||
}
|
||||
|
||||
// save events
|
||||
data.events = events;
|
||||
await db.write();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Inserts an entry after an element with given Id
|
||||
* @param entry
|
||||
* @param id
|
||||
* @return {Promise<void>}
|
||||
* @private
|
||||
*/
|
||||
async function _insertAfterId(entry, id) {
|
||||
const index = [...data.events].findIndex((event) => event.id === id);
|
||||
await _insertAt(entry, index + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description deletes an event from the db given its id
|
||||
* @param eventId
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
async function _removeById(eventId) {
|
||||
data.events = Array.from(data.events).filter((e) => e.id !== eventId);
|
||||
await db.write();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description returns all events of type event
|
||||
* @return {unknown[]}
|
||||
*/
|
||||
function getEventEvents() {
|
||||
// return data.events.filter((e) => e.type === 'event');
|
||||
return Array.from(data.events).filter((e) => e.type === 'event');
|
||||
const events = DataProvider.getEvents();
|
||||
return Array.from(events).filter((e) => e.type === 'event');
|
||||
}
|
||||
|
||||
// Updates timer object
|
||||
@@ -112,7 +57,7 @@ function _insertEventInTimerAfterId(event, previousId) {
|
||||
try {
|
||||
global.timer.insertEventAfterId(event, previousId);
|
||||
} catch (error) {
|
||||
global.timer.error('SERVER', `Unable to update object: ${error}`);
|
||||
socket.error('SERVER', `Unable to update object: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,7 +80,7 @@ function _deleteTimerId(entryId) {
|
||||
// Create controller for GET request to '/events'
|
||||
// Returns -
|
||||
export const eventsGetAll = async (req, res) => {
|
||||
res.json(data.events);
|
||||
res.json(DataProvider.getEvents());
|
||||
};
|
||||
|
||||
// Create controller for GET request to '/events/:eventId'
|
||||
@@ -146,7 +91,7 @@ export const eventsGetById = async (req, res) => {
|
||||
if (id == null) {
|
||||
res.status(400).send(`No eventId found in request`);
|
||||
} else {
|
||||
const event = data.events.find((e) => e.id === id);
|
||||
const event = DataProvider.getEventById(id);
|
||||
res.json(event);
|
||||
}
|
||||
};
|
||||
@@ -154,13 +99,12 @@ export const eventsGetById = async (req, res) => {
|
||||
// Create controller for POST request to '/events/'
|
||||
// Returns -
|
||||
export const eventsPost = async (req, res) => {
|
||||
// TODO: Validate event
|
||||
if (!req.body) {
|
||||
res.status(400).send(`No object found in request`);
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.events.length > MAX_EVENTS) {
|
||||
const numEvents = DataProvider.getNumEvents();
|
||||
if (numEvents > MAX_EVENTS) {
|
||||
const error = `ERROR: Reached limit number of ${MAX_EVENTS} events`;
|
||||
res.status(400).send(error);
|
||||
return;
|
||||
@@ -187,7 +131,7 @@ export const eventsPost = async (req, res) => {
|
||||
}
|
||||
|
||||
try {
|
||||
_insertAndSync(newEvent);
|
||||
await _insertAndSync(newEvent);
|
||||
res.sendStatus(201);
|
||||
} catch (error) {
|
||||
res.status(400).send(error);
|
||||
@@ -197,41 +141,33 @@ export const eventsPost = async (req, res) => {
|
||||
// Create controller for PUT request to '/events/'
|
||||
// Returns -
|
||||
export const eventsPut = async (req, res) => {
|
||||
// no valid params
|
||||
if (!req.body) {
|
||||
res.status(400).send(`No object found`);
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const eventId = req.body.id;
|
||||
if (!eventId) {
|
||||
res.status(400).send(`Object malformed: id missing`);
|
||||
return;
|
||||
}
|
||||
|
||||
const eventIndex = data.events.findIndex((e) => e.id === eventId);
|
||||
if (eventIndex === -1) {
|
||||
res.status(400).send(`No Id found found`);
|
||||
const eventDataFromRequest = req.body;
|
||||
const eventId = eventDataFromRequest.id;
|
||||
const event = DataProvider.getEventById(eventId);
|
||||
if (typeof event === 'undefined') {
|
||||
res.status(400).send(`No event with ID found`);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const e = data.events[eventIndex];
|
||||
data.events[eventIndex] = { ...e, ...req.body };
|
||||
data.events[eventIndex].revision++;
|
||||
await db.write();
|
||||
const newData = DataProvider.updateEventById(eventId, eventDataFromRequest);
|
||||
|
||||
if (data.events[eventIndex].skip) {
|
||||
if (newData.skip) {
|
||||
_deleteTimerId(eventId);
|
||||
// if it is a skip, i make sure it is deleted from timer
|
||||
// if it is a skip, make sure it is deleted from timer
|
||||
// event id might already not exist
|
||||
} else {
|
||||
try {
|
||||
_updateTimersSingle(eventId, req.body);
|
||||
_updateTimersSingle(newData.id, eventDataFromRequest);
|
||||
} catch (error) {
|
||||
if (error === 'Event not found') {
|
||||
const { id: previousId } = getPreviousPlayable(data.events, e.id);
|
||||
_insertEventInTimerAfterId(data.events[eventIndex], previousId);
|
||||
const events = DataProvider.getEvents();
|
||||
const { id: previousId } = getPreviousPlayable(events, newData.id);
|
||||
_insertEventInTimerAfterId(newData, previousId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,16 +186,14 @@ export const eventsPatch = async (req, res) => {
|
||||
};
|
||||
|
||||
export const eventsReorder = async (req, res) => {
|
||||
// TODO: Validate event
|
||||
if (!req.body) {
|
||||
res.status(400).send(`No object found in request`);
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { index, from, to } = req.body;
|
||||
|
||||
// get events
|
||||
const events = data.events;
|
||||
const events = DataProvider.getEvents();
|
||||
const idx = events.findIndex((e) => e.id === index, from);
|
||||
|
||||
// Check if item is at given index
|
||||
@@ -276,8 +210,7 @@ export const eventsReorder = async (req, res) => {
|
||||
events.splice(to, 0, reorderedItem);
|
||||
|
||||
// save events
|
||||
data.events = events;
|
||||
await db.write();
|
||||
await DataProvider.setEventData(events);
|
||||
|
||||
// update timer
|
||||
_updateTimers();
|
||||
@@ -291,15 +224,9 @@ export const eventsReorder = async (req, res) => {
|
||||
// Create controller for PATCH request to '/events/applydelay/:eventId'
|
||||
// Returns -
|
||||
export const eventsApplyDelay = async (req, res) => {
|
||||
// no valid params
|
||||
if (!req.params.eventId) {
|
||||
res.status(400).send(`No id found in request`);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// get events
|
||||
const events = data.events;
|
||||
const events = DataProvider.getEvents();
|
||||
|
||||
// AUX
|
||||
let delayIndex = null;
|
||||
@@ -340,8 +267,7 @@ export const eventsApplyDelay = async (req, res) => {
|
||||
if (blockIndex) events.splice(blockIndex - 1, 1);
|
||||
|
||||
// update events
|
||||
data.events = events;
|
||||
await db.write();
|
||||
await DataProvider.setEvents(events);
|
||||
|
||||
// update timer
|
||||
_updateTimers();
|
||||
@@ -355,20 +281,15 @@ export const eventsApplyDelay = async (req, res) => {
|
||||
// Create controller for DELETE request to '/events/:eventId'
|
||||
// Returns -
|
||||
export const eventsDelete = async (req, res) => {
|
||||
// no valid params
|
||||
if (!req.params.eventId) {
|
||||
res.status(400).send(`No id found in request`);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const eventId = req.params.eventId;
|
||||
|
||||
// remove new event
|
||||
await _removeById(req.params.eventId);
|
||||
|
||||
await DataProvider.deleteEvent(eventId);
|
||||
// update timer
|
||||
_deleteTimerId(req.params.eventId);
|
||||
_deleteTimerId(eventId);
|
||||
|
||||
res.sendStatus(201);
|
||||
res.sendStatus(204);
|
||||
} catch (error) {
|
||||
res.status(400).send(error);
|
||||
}
|
||||
@@ -378,14 +299,9 @@ export const eventsDelete = async (req, res) => {
|
||||
// Returns -
|
||||
export const eventsDeleteAll = async (req, res) => {
|
||||
try {
|
||||
// set with nothing
|
||||
data.events = [];
|
||||
await db.write();
|
||||
|
||||
// update timer object
|
||||
await DataProvider.deleteAllEvents();
|
||||
global.timer.clearEventList();
|
||||
|
||||
res.sendStatus(201);
|
||||
res.sendStatus(204);
|
||||
} catch (error) {
|
||||
res.status(400).send(error);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { body, param, validationResult } from 'express-validator';
|
||||
|
||||
export const eventsPutValidator = [
|
||||
body('id').isString().exists(),
|
||||
(req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
next();
|
||||
},
|
||||
];
|
||||
|
||||
export const paramsMustHaveEventId = [
|
||||
param('eventId').exists(),
|
||||
(req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
next();
|
||||
},
|
||||
];
|
||||
@@ -1,10 +1,11 @@
|
||||
import fs from 'fs';
|
||||
import { data, db } from '../app.js';
|
||||
import { networkInterfaces } from 'os';
|
||||
import { fileHandler } from '../utils/parser.js';
|
||||
import { generateId } from '../utils/generate_id.js';
|
||||
import { resolveDbPath } from '../modules/loadDb.js';
|
||||
import { DataProvider } from '../classes/data-provider/DataProvider.js';
|
||||
import { failEmptyObjects, failIsNotArray } from '../utils/routerUtils.js';
|
||||
import { mergeObject } from '../utils/parserUtils.js';
|
||||
|
||||
// Create controller for GET request to '/ontime/poll'
|
||||
// Returns data for current state
|
||||
@@ -22,7 +23,8 @@ export const poll = async (req, res) => {
|
||||
// Create controller for GET request to '/ontime/db'
|
||||
// Returns -
|
||||
export const dbDownload = async (req, res) => {
|
||||
const fileTitle = data?.event?.title || 'ontime events';
|
||||
const { title } = DataProvider.getEventData();
|
||||
const fileTitle = title || 'ontime events';
|
||||
const dbInDisk = resolveDbPath();
|
||||
|
||||
res.download(dbInDisk, `${fileTitle}.json`, (err) => {
|
||||
@@ -48,18 +50,13 @@ const uploadAndParse = async (file, req, res, options) => {
|
||||
} else if (result.message === 'success') {
|
||||
// explicitly write objects
|
||||
if (typeof result !== 'undefined') {
|
||||
if (!options.onlyEvents) {
|
||||
const mergedData = DataProvider.safeMerge(data, result.data);
|
||||
data.event = mergedData.event;
|
||||
data.settings = mergedData.settings;
|
||||
data.osc = mergedData.osc;
|
||||
data.http = mergedData.http;
|
||||
data.aliases = mergedData.aliases;
|
||||
data.userFields = mergedData.userFields;
|
||||
const newEvents = result.data.events || [];
|
||||
if (options.onlyEvents) {
|
||||
await DataProvider.setEvents(newEvents);
|
||||
} else {
|
||||
await DataProvider.mergeIntoData(result.data);
|
||||
}
|
||||
data.events = result.data.events || [];
|
||||
global.timer.setupWithEventList(result.data.events || []);
|
||||
await db.write();
|
||||
global.timer.setupWithEventList(newEvents);
|
||||
}
|
||||
res.sendStatus(200);
|
||||
} else {
|
||||
@@ -71,7 +68,7 @@ const uploadAndParse = async (file, req, res, options) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* @description Gets information on IPV4 non internal interfaces
|
||||
* @description Gets information on IPV4 non-internal interfaces
|
||||
* @returns {array} - Array of objects {name: ip}
|
||||
*/
|
||||
const getNetworkInterfaces = () => {
|
||||
@@ -96,15 +93,8 @@ const getNetworkInterfaces = () => {
|
||||
// Create controller for POST request to '/ontime/info'
|
||||
// Returns -
|
||||
export const getInfo = async (req, res) => {
|
||||
const version = data.settings.version;
|
||||
const serverPort = data.settings.serverPort;
|
||||
|
||||
const osc = {
|
||||
port: data.osc.port,
|
||||
portOut: data.osc.portOut,
|
||||
targetIP: data.osc.targetIP,
|
||||
enabled: data.osc.enabled,
|
||||
};
|
||||
const { version, serverPort } = DataProvider.getSettings();
|
||||
const osc = DataProvider.getOsc();
|
||||
|
||||
// get nif and inject localhost
|
||||
const ni = getNetworkInterfaces();
|
||||
@@ -122,18 +112,16 @@ export const getInfo = async (req, res) => {
|
||||
// Create controller for POST request to '/ontime/aliases'
|
||||
// Returns -
|
||||
export const getAliases = async (req, res) => {
|
||||
// send aliases array
|
||||
res.status(200).send(data.aliases);
|
||||
const aliases = DataProvider.getAliases();
|
||||
res.status(200).send(aliases);
|
||||
};
|
||||
|
||||
// Create controller for POST request to '/ontime/aliases'
|
||||
// Returns ACK message
|
||||
export const postAliases = async (req, res) => {
|
||||
if (!req.body) {
|
||||
res.status(400).send('No object found in request');
|
||||
if (failIsNotArray()) {
|
||||
return;
|
||||
}
|
||||
// TODO: validate data
|
||||
try {
|
||||
const newAliases = [];
|
||||
req.body.forEach((a) => {
|
||||
@@ -144,9 +132,8 @@ export const postAliases = async (req, res) => {
|
||||
pathAndParams: a.pathAndParams,
|
||||
});
|
||||
});
|
||||
data.aliases = newAliases;
|
||||
await db.write();
|
||||
res.sendStatus(200);
|
||||
await DataProvider.setAliases(newAliases);
|
||||
res.status(200).send(newAliases);
|
||||
} catch (error) {
|
||||
res.status(400).send(error);
|
||||
}
|
||||
@@ -155,27 +142,21 @@ export const postAliases = async (req, res) => {
|
||||
// Create controller for GET request to '/ontime/userfields'
|
||||
// Returns -
|
||||
export const getUserFields = async (req, res) => {
|
||||
// send userFields array
|
||||
res.status(200).send(data.userFields);
|
||||
const userFields = DataProvider.getUserFields();
|
||||
res.status(200).send(userFields);
|
||||
};
|
||||
|
||||
// Create controller for POST request to '/ontime/userfields'
|
||||
// Returns ACK message
|
||||
export const postUserFields = async (req, res) => {
|
||||
if (!req.body) {
|
||||
res.status(400).send('No object found in request');
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const newUserFields = { ...data.userFields };
|
||||
for (const field in newUserFields) {
|
||||
if (typeof req.body[field] !== 'undefined') {
|
||||
newUserFields[field] = req.body[field];
|
||||
}
|
||||
}
|
||||
data.userFields = newUserFields;
|
||||
await db.write();
|
||||
res.sendStatus(200);
|
||||
const persistedData = DataProvider.getUserFields();
|
||||
const newData = mergeObject(persistedData, req.body);
|
||||
await DataProvider.setUserFields(newData);
|
||||
res.status(200).send(newData);
|
||||
} catch (error) {
|
||||
res.status(400).send(error);
|
||||
}
|
||||
@@ -184,12 +165,8 @@ export const postUserFields = async (req, res) => {
|
||||
// Create controller for POST request to '/ontime/settings'
|
||||
// Returns -
|
||||
export const getSettings = async (req, res) => {
|
||||
const version = data.settings.version;
|
||||
const serverPort = data.settings.serverPort;
|
||||
const pinCode = data.settings.pinCode;
|
||||
const timeFormat = data.settings.timeFormat;
|
||||
const { version, serverPort, pinCode, timeFormat } = DataProvider.getSettings();
|
||||
|
||||
// send object with network information
|
||||
res.status(200).send({
|
||||
version,
|
||||
serverPort,
|
||||
@@ -201,12 +178,12 @@ export const getSettings = async (req, res) => {
|
||||
// Create controller for POST request to '/ontime/settings'
|
||||
// Returns ACK message
|
||||
export const postSettings = async (req, res) => {
|
||||
if (!req.body) {
|
||||
res.status(400).send('No object found in request');
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
let pin = data.settings.pinCode;
|
||||
const settings = DataProvider.getSettings();
|
||||
let pin = settings.pinCode;
|
||||
if (typeof req.body?.pinCode === 'string') {
|
||||
if (req.body?.pinCode.length === 0) {
|
||||
pin = null;
|
||||
@@ -215,20 +192,20 @@ export const postSettings = async (req, res) => {
|
||||
}
|
||||
}
|
||||
|
||||
let timeFormat = data.settings.timeFormat;
|
||||
let format = settings.timeFormat;
|
||||
if (typeof req.body?.timeFormat === 'string') {
|
||||
if (req.body?.timeFormat === '12' || req.body?.timeFormat === '24') {
|
||||
timeFormat = req.body.timeFormat;
|
||||
format = req.body.timeFormat;
|
||||
}
|
||||
}
|
||||
|
||||
data.settings = {
|
||||
...data.settings,
|
||||
const newData = {
|
||||
...settings,
|
||||
pinCode: pin,
|
||||
timeFormat: timeFormat,
|
||||
timeFormat: format,
|
||||
};
|
||||
await db.write();
|
||||
res.sendStatus(200);
|
||||
DataProvider.setSettings(newData);
|
||||
res.status(200).send(newData);
|
||||
} catch (error) {
|
||||
res.status(400).send(error);
|
||||
}
|
||||
@@ -239,7 +216,8 @@ export const postSettings = async (req, res) => {
|
||||
* @method GET
|
||||
*/
|
||||
export const getViewSettings = async (req, res) => {
|
||||
res.status(200).send({ ...data.views });
|
||||
const views = DataProvider.getViews();
|
||||
res.status(200).send(views);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -247,33 +225,14 @@ export const getViewSettings = async (req, res) => {
|
||||
* @method POST
|
||||
*/
|
||||
export const postViewSettings = async (req, res) => {
|
||||
if (!req.body) {
|
||||
res.status(400).send('No object found in request');
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
data.views = {
|
||||
overrideStyles: req.body?.overrideStyles ?? data.views.overrideStyles,
|
||||
};
|
||||
await db.write();
|
||||
res.sendStatus(200);
|
||||
} catch (error) {
|
||||
res.status(400).send(error);
|
||||
}
|
||||
};
|
||||
|
||||
// Create controller for POST request to '/ontime/info'
|
||||
// Returns ACK message
|
||||
export const postInfo = async (req, res) => {
|
||||
if (!req.body) {
|
||||
res.status(400).send('No object found in request');
|
||||
return;
|
||||
}
|
||||
// TODO: validate data
|
||||
try {
|
||||
data.settings = { ...data.settings, ...req.body };
|
||||
await db.write();
|
||||
res.sendStatus(200);
|
||||
const newData = { overrideStyles: req.body.overrideStyles };
|
||||
DataProvider.setViews(newData);
|
||||
res.status(200).send(newData);
|
||||
} catch (error) {
|
||||
res.status(400).send(error);
|
||||
}
|
||||
@@ -282,25 +241,22 @@ export const postInfo = async (req, res) => {
|
||||
// Create controller for POST request to '/ontime/osc'
|
||||
// Returns -
|
||||
export const getOSC = async (req, res) => {
|
||||
// send object with network information
|
||||
res.status(200).send(data.osc);
|
||||
const osc = DataProvider.getOsc();
|
||||
res.status(200).send(osc);
|
||||
};
|
||||
|
||||
// Create controller for POST request to '/ontime/osc'
|
||||
// Returns ACK message
|
||||
export const postOSC = async (req, res) => {
|
||||
if (!req.body) {
|
||||
res.status(400).send('No object found in request');
|
||||
if (failEmptyObjects(req.body, res)) {
|
||||
return;
|
||||
}
|
||||
// TODO: validate data
|
||||
|
||||
try {
|
||||
data.osc = { ...data.osc, ...req.body };
|
||||
await db.write();
|
||||
res.sendStatus(200);
|
||||
await DataProvider.setOsc(req.body);
|
||||
res.send(req.body).status(200);
|
||||
} catch (error) {
|
||||
res.status(400).send(error);
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -313,7 +269,7 @@ export const dbUpload = async (req, res) => {
|
||||
}
|
||||
const options = req.query;
|
||||
const file = req.file.path;
|
||||
uploadAndParse(file, req, res, options);
|
||||
await uploadAndParse(file, req, res, options);
|
||||
};
|
||||
|
||||
// Create controller for POST request to '/ontime/dbpath'
|
||||
@@ -323,5 +279,5 @@ export const dbPathToUpload = async (req, res) => {
|
||||
res.status(400).send({ message: 'Path to file not found' });
|
||||
return;
|
||||
}
|
||||
uploadAndParse(req.body.path, req, res);
|
||||
await uploadAndParse(req.body.path, req, res);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import { body, check, validationResult } from 'express-validator';
|
||||
|
||||
/**
|
||||
* @description Validates object for POST /ontime/views
|
||||
*/
|
||||
export const viewValidator = [
|
||||
check('overrideStyles').isBoolean().withMessage('overrideStyles value must be boolean'),
|
||||
(req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
next();
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* @description Validates object for POST /ontime/aliases
|
||||
*/
|
||||
export const validateAliases = [
|
||||
body().isArray(),
|
||||
body('*.enabled').isBoolean(),
|
||||
body('*.alias').isString().trim(),
|
||||
body('*.pathAndParams').isString().trim(),
|
||||
(req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
next();
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* @description Validates object for POST /ontime/userfields
|
||||
*/
|
||||
export const validateUserFields = [
|
||||
body('user0').exists().isString().trim(),
|
||||
body('user1').exists().isString().trim(),
|
||||
body('user2').exists().isString().trim(),
|
||||
body('user3').exists().isString().trim(),
|
||||
body('user4').exists().isString().trim(),
|
||||
body('user5').exists().isString().trim(),
|
||||
body('user6').exists().isString().trim(),
|
||||
body('user7').exists().isString().trim(),
|
||||
body('user8').exists().isString().trim(),
|
||||
body('user9').exists().isString().trim(),
|
||||
(req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
next();
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* @description Validates object for POST /ontime/settings
|
||||
*/
|
||||
export const validateSettings = [
|
||||
body('pinCode').isString().isLength({ min: 0, max: 4 }).optional({ nullable: true }),
|
||||
body('timeFormat').isString().isIn(['12', '24']),
|
||||
(req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
next();
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* @description Validates object for POST /ontime/osc
|
||||
*/
|
||||
export const validateOSC = [
|
||||
body('port').exists().isInt({ min: 0, max: 65353 }),
|
||||
body('portOut').exists().isInt({ min: 0, max: 65353 }),
|
||||
body('targetIP').exists().isIP(),
|
||||
body('enabled').exists().isBoolean(),
|
||||
(req, res, next) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
next();
|
||||
},
|
||||
];
|
||||
Reference in New Issue
Block a user