mirror of
https://github.com/Hypfer/Valetudo.git
synced 2025-10-26 11:27:27 +00:00
refactor: Misc cleanup
This commit is contained in:
parent
8e0605683a
commit
9fa98dfdac
@ -5,6 +5,14 @@ const Valetudo = require("./lib/Valetudo");
|
||||
|
||||
const valetudo = new Valetudo();
|
||||
|
||||
/*
|
||||
This is the easiest and most complete Mitigation against CWE-1321 Prototype Pollution
|
||||
We do that after new Valetudo() to not interfere with any (library) code.
|
||||
|
||||
This way, this should only interfere with malicious user input (if any)
|
||||
*/
|
||||
Object.freeze(Object.prototype);
|
||||
|
||||
process.on("unhandledRejection", (reason, promise) => {
|
||||
Logger.error("unhandledRejection", {
|
||||
reason: reason,
|
||||
|
||||
@ -148,7 +148,6 @@ class Valetudo {
|
||||
//eslint-disable-next-line no-undef
|
||||
global.gc();
|
||||
|
||||
//@ts-ignore
|
||||
const rssAfter = process.memoryUsage.rss();
|
||||
const rssDiff = rss - rssAfter;
|
||||
|
||||
|
||||
@ -29,8 +29,29 @@ class ZoneCleaningCapabilityMqttHandle extends CapabilityMqttHandle {
|
||||
|
||||
if (Array.isArray(req?.zones)) {
|
||||
await this.capability.start(req.zones.map(z => {
|
||||
if (!(z.points)) {
|
||||
throw new Error("Invalid Zone");
|
||||
}
|
||||
|
||||
return new ValetudoZone({
|
||||
points: z.points,
|
||||
points: {
|
||||
pA: {
|
||||
x: z.points.pA?.x,
|
||||
y: z.points.pA?.y,
|
||||
},
|
||||
pB: {
|
||||
x: z.points.pB?.x,
|
||||
y: z.points.pB?.y,
|
||||
},
|
||||
pC: {
|
||||
x: z.points.pC?.x,
|
||||
y: z.points.pC?.y,
|
||||
},
|
||||
pD: {
|
||||
x: z.points.pD?.x,
|
||||
y: z.points.pD?.y,
|
||||
},
|
||||
},
|
||||
iterations: z.iterations
|
||||
});
|
||||
}));
|
||||
|
||||
@ -29,7 +29,13 @@ class NTPClientRouter {
|
||||
});
|
||||
|
||||
this.router.put("/config", this.validator, (req, res) => {
|
||||
this.config.set("ntpClient", req.body);
|
||||
this.config.set("ntpClient", {
|
||||
enabled: req.body.enabled,
|
||||
server: req.body.server,
|
||||
port: req.body.port,
|
||||
interval: req.body.interval,
|
||||
timeout: req.body.timeout
|
||||
});
|
||||
|
||||
res.sendStatus(200);
|
||||
});
|
||||
|
||||
@ -61,19 +61,26 @@ class TimerRouter {
|
||||
typeof req.body.minute === "number" &&
|
||||
req.body.action && typeof req.body.action.type === "string"
|
||||
) {
|
||||
const storedTimers = this.config.get("timers");
|
||||
const newTimer = new ValetudoTimer({
|
||||
enabled: req.body.enabled === true,
|
||||
dow: req.body.dow,
|
||||
hour: req.body.hour,
|
||||
minute: req.body.minute,
|
||||
action: req.body.action
|
||||
});
|
||||
const action = TimerRouter.MAP_ACTION_FROM_BODY(req.body);
|
||||
|
||||
storedTimers[newTimer.id] = newTimer;
|
||||
if (!action) {
|
||||
res.sendStatus(400);
|
||||
} else {
|
||||
const storedTimers = this.config.get("timers");
|
||||
const newTimer = new ValetudoTimer({
|
||||
enabled: req.body.enabled === true,
|
||||
dow: req.body.dow,
|
||||
hour: req.body.hour,
|
||||
minute: req.body.minute,
|
||||
action: action
|
||||
});
|
||||
|
||||
storedTimers[newTimer.id] = newTimer;
|
||||
|
||||
this.config.set("timers", storedTimers);
|
||||
res.sendStatus(200);
|
||||
}
|
||||
|
||||
this.config.set("timers", storedTimers);
|
||||
res.sendStatus(200);
|
||||
} else {
|
||||
res.sendStatus(400);
|
||||
}
|
||||
@ -90,19 +97,25 @@ class TimerRouter {
|
||||
typeof req.body.minute === "number" &&
|
||||
req.body.action && typeof req.body.action.type === "string"
|
||||
) {
|
||||
const newTimer = new ValetudoTimer({
|
||||
id: req.params.id,
|
||||
enabled: req.body.enabled === true,
|
||||
dow: req.body.dow,
|
||||
hour: req.body.hour,
|
||||
minute: req.body.minute,
|
||||
action: req.body.action
|
||||
});
|
||||
const action = TimerRouter.MAP_ACTION_FROM_BODY(req.body);
|
||||
|
||||
storedTimers[newTimer.id] = newTimer;
|
||||
if (!action) {
|
||||
res.sendStatus(400);
|
||||
} else {
|
||||
const newTimer = new ValetudoTimer({
|
||||
id: req.params.id,
|
||||
enabled: req.body.enabled === true,
|
||||
dow: req.body.dow,
|
||||
hour: req.body.hour,
|
||||
minute: req.body.minute,
|
||||
action: action
|
||||
});
|
||||
|
||||
this.config.set("timers", storedTimers);
|
||||
res.sendStatus(200);
|
||||
storedTimers[newTimer.id] = newTimer;
|
||||
|
||||
this.config.set("timers", storedTimers);
|
||||
res.sendStatus(200);
|
||||
}
|
||||
} else {
|
||||
res.sendStatus(400);
|
||||
}
|
||||
@ -129,6 +142,35 @@ class TimerRouter {
|
||||
getRouter() {
|
||||
return this.router;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {object} body
|
||||
*/
|
||||
static MAP_ACTION_FROM_BODY(body) {
|
||||
let action;
|
||||
|
||||
switch (body.action.type) {
|
||||
case ValetudoTimer.ACTION_TYPE.FULL_CLEANUP:
|
||||
action = {
|
||||
type: ValetudoTimer.ACTION_TYPE.FULL_CLEANUP,
|
||||
params: {}
|
||||
};
|
||||
break;
|
||||
case ValetudoTimer.ACTION_TYPE.SEGMENT_CLEANUP:
|
||||
action = {
|
||||
type: ValetudoTimer.ACTION_TYPE.SEGMENT_CLEANUP,
|
||||
params: {
|
||||
segment_ids: body.action.params.segment_ids,
|
||||
iterations: body.action.params.iterations,
|
||||
custom_order: body.action.params.custom_order,
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TimerRouter;
|
||||
|
||||
@ -83,7 +83,7 @@ class ValetudoRouter {
|
||||
});
|
||||
|
||||
this.router.put("/config/interfaces/mqtt", this.validator, (req, res) => {
|
||||
let mqttConfig = req.body;
|
||||
let mqttConfig = ValetudoRouter.MAP_MQTT_CONFIG(req.body);
|
||||
let oldConfig = this.config.get("mqtt");
|
||||
|
||||
|
||||
@ -177,6 +177,51 @@ class ValetudoRouter {
|
||||
hub.shutdown();
|
||||
});
|
||||
}
|
||||
|
||||
static MAP_MQTT_CONFIG(obj) {
|
||||
return {
|
||||
enabled: obj.enabled,
|
||||
connection: {
|
||||
host: obj.connection.host,
|
||||
port: obj.connection.port,
|
||||
tls: {
|
||||
enabled: obj.connection.tls.enabled,
|
||||
ca: obj.connection.tls.ca
|
||||
},
|
||||
authentication: {
|
||||
credentials: {
|
||||
enabled: obj.connection.authentication.credentials.enabled,
|
||||
username: obj.connection.authentication.credentials.username,
|
||||
password: obj.connection.authentication.credentials.password
|
||||
},
|
||||
clientCertificate: {
|
||||
enabled: obj.connection.authentication.clientCertificate.enabled,
|
||||
certificate: obj.connection.authentication.clientCertificate.certificate,
|
||||
key: obj.connection.authentication.clientCertificate.key
|
||||
}
|
||||
}
|
||||
},
|
||||
identity: {
|
||||
friendlyName: obj.identity.friendlyName,
|
||||
identifier: obj.identity.identifier
|
||||
},
|
||||
customizations: {
|
||||
topicPrefix: obj.customizations.topicPrefix,
|
||||
provideMapData: obj.customizations.provideMapData
|
||||
},
|
||||
interfaces: {
|
||||
homie: {
|
||||
enabled: obj.interfaces.homie.enabled,
|
||||
addICBINVMapProperty: obj.interfaces.homie.addICBINVMapProperty,
|
||||
cleanAttributesOnShutdown: obj.interfaces.homie.cleanAttributesOnShutdown
|
||||
},
|
||||
homeassistant: {
|
||||
enabled: obj.interfaces.homeassistant.enabled,
|
||||
cleanAutoconfOnShutdown: obj.interfaces.homeassistant.cleanAutoconfOnShutdown
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const MAGIC_PRIVACY_STRING = "<redacted>";
|
||||
|
||||
@ -18,12 +18,38 @@ class CombinedVirtualRestrictionsCapabilityRouter extends CapabilityRouter {
|
||||
const virtualRestrictions = new ValetudoVirtualRestrictions({
|
||||
virtualWalls: req.body.virtualWalls.map(requestWall => {
|
||||
return new ValetudoVirtualWall({
|
||||
points: requestWall.points
|
||||
points: {
|
||||
pA: {
|
||||
x: requestWall.points.pA.x,
|
||||
y: requestWall.points.pA.y
|
||||
},
|
||||
pB: {
|
||||
x: requestWall.points.pB.x,
|
||||
y: requestWall.points.pB.y
|
||||
}
|
||||
}
|
||||
});
|
||||
}),
|
||||
restrictedZones: req.body.restrictedZones.map(requestZone => {
|
||||
return new ValetudoRestrictedZone({
|
||||
points: requestZone.points,
|
||||
points: {
|
||||
pA: {
|
||||
x: requestZone.points.pA.x,
|
||||
y: requestZone.points.pA.y
|
||||
},
|
||||
pB: {
|
||||
x: requestZone.points.pB.x,
|
||||
y: requestZone.points.pB.y
|
||||
},
|
||||
pC: {
|
||||
x: requestZone.points.pC.x,
|
||||
y: requestZone.points.pC.y
|
||||
},
|
||||
pD: {
|
||||
x: requestZone.points.pD.x,
|
||||
y: requestZone.points.pD.y
|
||||
}
|
||||
},
|
||||
type: requestZone.type
|
||||
});
|
||||
})
|
||||
|
||||
@ -14,7 +14,17 @@ class DoNotDisturbCapabilityRouter extends CapabilityRouter {
|
||||
this.router.put("/", this.validator, async (req, res) => {
|
||||
if (req.body.start && req.body.end) {
|
||||
try {
|
||||
await this.capability.setDndConfiguration(new ValetudoDNDConfiguration(req.body));
|
||||
await this.capability.setDndConfiguration(new ValetudoDNDConfiguration({
|
||||
enabled: req.body.enabled,
|
||||
start: {
|
||||
hour: req.body.start.hour,
|
||||
minute: req.body.start.minute,
|
||||
},
|
||||
end: {
|
||||
hour: req.body.end.hour,
|
||||
minute: req.body.end.minute,
|
||||
}
|
||||
}));
|
||||
|
||||
res.sendStatus(200);
|
||||
} catch (e) {
|
||||
|
||||
@ -7,7 +7,10 @@ class GoToLocationCapabilityRouter extends CapabilityRouter {
|
||||
if (req.body.action === "goto" && req.body.coordinates !== undefined) {
|
||||
try {
|
||||
await this.capability.goTo(new ValetudoGoToLocation({
|
||||
coordinates: req.body.coordinates
|
||||
coordinates: {
|
||||
x: req.body.coordinates.x,
|
||||
y: req.body.coordinates.y
|
||||
}
|
||||
}));
|
||||
res.sendStatus(200);
|
||||
} catch (e) {
|
||||
|
||||
@ -26,8 +26,14 @@ class MapSegmentEditCapabilityRouter extends CapabilityRouter {
|
||||
try {
|
||||
await this.capability.splitSegment(
|
||||
new ValetudoMapSegment({id: req.body.segment_id}),
|
||||
req.body.pA,
|
||||
req.body.pB
|
||||
{
|
||||
x: req.body.pA.x,
|
||||
y: req.body.pA.y,
|
||||
},
|
||||
{
|
||||
x: req.body.pB.x,
|
||||
y: req.body.pB.y,
|
||||
}
|
||||
);
|
||||
|
||||
res.sendStatus(200);
|
||||
|
||||
@ -121,7 +121,26 @@ class WifiConfigurationCapabilityRouter extends CapabilityRouter {
|
||||
|
||||
this.router.put("/", this.validator, async (req, res) => {
|
||||
try {
|
||||
await this.capability.setWifiConfiguration(new ValetudoWifiConfiguration(req.body));
|
||||
let typeSpecificSettings;
|
||||
|
||||
switch (req.body.credentials.type) {
|
||||
case ValetudoWifiConfiguration.CREDENTIALS_TYPE.WPA2_PSK:
|
||||
typeSpecificSettings = {
|
||||
password: req.body.credentials.typeSpecificSettings.password
|
||||
};
|
||||
break;
|
||||
default:
|
||||
typeSpecificSettings = {};
|
||||
}
|
||||
|
||||
await this.capability.setWifiConfiguration(new ValetudoWifiConfiguration({
|
||||
ssid: req.body.ssid,
|
||||
credentials: {
|
||||
type: req.body.credentials.type,
|
||||
typeSpecificSettings: typeSpecificSettings
|
||||
}
|
||||
}));
|
||||
|
||||
res.sendStatus(200);
|
||||
} catch (e) {
|
||||
this.sendErrorResponse(req, res, e);
|
||||
|
||||
@ -12,7 +12,24 @@ class ZoneCleaningCapabilityRouter extends CapabilityRouter {
|
||||
}
|
||||
|
||||
return new ValetudoZone({
|
||||
points: z.points,
|
||||
points: {
|
||||
pA: {
|
||||
x: z.points.pA?.x,
|
||||
y: z.points.pA?.y,
|
||||
},
|
||||
pB: {
|
||||
x: z.points.pB?.x,
|
||||
y: z.points.pB?.y,
|
||||
},
|
||||
pC: {
|
||||
x: z.points.pC?.x,
|
||||
y: z.points.pC?.y,
|
||||
},
|
||||
pD: {
|
||||
x: z.points.pD?.x,
|
||||
y: z.points.pD?.y,
|
||||
},
|
||||
},
|
||||
iterations: z.iterations
|
||||
});
|
||||
}));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user