homebridge-adt-pulse
Version:
Homebridge security system platform for ADT Pulse
546 lines • 27.9 kB
JavaScript
import axios from 'axios';
import _ from 'lodash';
import { serializeError } from 'serialize-error';
import { collectionSensorActions, itemDoSubmitHandlerRelativeUrls, itemDoSubmitHandlerUrlParamsArms, itemDoSubmitHandlerUrlParamsArmStates, itemDoSubmitHandlerUrlParamsHrefs, itemGatewayInformationStatuses, itemOrbSecurityButtonButtonTexts, itemOrbSecurityButtonLoadingTexts, itemOrbSecurityButtonRelativeUrls, itemOrbSecurityButtonUrlParamsArms, itemOrbSecurityButtonUrlParamsArmStates, itemOrbSecurityButtonUrlParamsHrefs, itemPanelInformationStatuses, itemPortalVersions, itemSensorInformationDeviceTypes, itemSensorInformationStatuses, itemSensorStatusIcons, itemSensorStatusStatuses, } from './items.js';
import { debugLog, getDetectReportUrl, getPackageVersion, isEmptyOrbTextSummary, isPluginOutdated, isUnknownDoSubmitHandlerCollection, isUnknownGatewayDevice, isUnknownOrbSecurityButtonCollection, isUnknownPanelDevice, removePersonalIdentifiableInformation, stackTracer, } from './utility.js';
export async function detectApiDoSubmitHandlers(handlers, logger, debugMode) {
const detectedNewHandlers = handlers.filter((handler) => (!itemDoSubmitHandlerRelativeUrls.includes(handler.relativeUrl)
|| (handler.urlParams.arm !== null
&& !itemDoSubmitHandlerUrlParamsArms.includes(handler.urlParams.arm))
|| (handler.urlParams.armState !== null
&& !itemDoSubmitHandlerUrlParamsArmStates.includes(handler.urlParams.armState))
|| !itemDoSubmitHandlerUrlParamsHrefs.includes(handler.urlParams.href)));
if (detectedNewHandlers.length > 0) {
const cleanedData = removePersonalIdentifiableInformation(detectedNewHandlers);
try {
const outdated = await isPluginOutdated();
if (outdated) {
if (logger !== null) {
logger.warn('Plugin has detected new do submit handlers. You are running an older plugin version, please update soon.');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiDoSubmitHandlers()', 'warn', 'Plugin has detected new do submit handlers. You are running an older plugin version, please update soon');
}
return false;
}
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiDoSubmitHandlers()', 'error', 'Failed to check if plugin is outdated');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
if (logger !== null) {
logger.warn('Plugin has detected new do submit handlers. Notifying plugin author about this discovery ...');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiDoSubmitHandlers()', 'warn', 'Plugin has detected new do submit handlers. Notifying plugin author about this discovery');
}
stackTracer('detect-content', cleanedData);
try {
await axios.post(getDetectReportUrl(), JSON.stringify(cleanedData, null, 2), {
family: 4,
headers: {
'User-Agent': 'homebridge-adt-pulse',
'X-Title': `Detected new do submit handlers (v${getPackageVersion()})`,
},
});
return true;
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiDoSubmitHandlers()', 'error', 'Failed to notify plugin author about the new do submit handlers');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
}
return false;
}
export async function detectApiGatewayInformation(device, logger, debugMode) {
const detectedNewStatus = (device.status !== null && !itemGatewayInformationStatuses.includes(device.status));
if (detectedNewStatus) {
const cleanedData = removePersonalIdentifiableInformation(device);
try {
const outdated = await isPluginOutdated();
if (outdated) {
if (logger !== null) {
logger.warn('Plugin has detected new gateway information. You are running an older plugin version, please update soon.');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiGatewayInformation()', 'warn', 'Plugin has detected new gateway information. You are running an older plugin version, please update soon');
}
return false;
}
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiGatewayInformation()', 'error', 'Failed to check if plugin is outdated');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
if (logger !== null) {
logger.warn('Plugin has detected new gateway information. Notifying plugin author about this discovery ...');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiGatewayInformation()', 'warn', 'Plugin has detected new gateway information. Notifying plugin author about this discovery');
}
stackTracer('detect-content', cleanedData);
try {
await axios.post(getDetectReportUrl(), JSON.stringify(cleanedData, null, 2), {
family: 4,
headers: {
'User-Agent': 'homebridge-adt-pulse',
'X-Title': `Detected new gateway information (v${getPackageVersion()})`,
},
});
return true;
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiGatewayInformation()', 'error', 'Failed to notify plugin author about the new gateway information');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
}
return false;
}
export async function detectApiOrbSecurityButtons(buttons, logger, debugMode) {
const detectedNewButtons = buttons.filter((button) => ((!button.buttonDisabled
&& ((button.buttonText !== null
&& !itemOrbSecurityButtonButtonTexts.includes(button.buttonText))
|| !itemOrbSecurityButtonLoadingTexts.includes(button.loadingText)
|| !itemOrbSecurityButtonRelativeUrls.includes(button.relativeUrl)
|| !itemOrbSecurityButtonUrlParamsArms.includes(button.urlParams.arm)
|| !itemOrbSecurityButtonUrlParamsArmStates.includes(button.urlParams.armState)
|| !itemOrbSecurityButtonUrlParamsHrefs.includes(button.urlParams.href)))
|| (button.buttonDisabled
&& (button.buttonText !== null
&& !itemOrbSecurityButtonLoadingTexts.includes(button.buttonText)))));
if (detectedNewButtons.length > 0) {
const cleanedData = removePersonalIdentifiableInformation(detectedNewButtons);
try {
const outdated = await isPluginOutdated();
if (outdated) {
if (logger !== null) {
logger.warn('Plugin has detected new orb security buttons. You are running an older plugin version, please update soon.');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiOrbSecurityButtons()', 'warn', 'Plugin has detected new orb security buttons. You are running an older plugin version, please update soon');
}
return false;
}
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiOrbSecurityButtons()', 'error', 'Failed to check if plugin is outdated');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
if (logger !== null) {
logger.warn('Plugin has detected new orb security buttons. Notifying plugin author about this discovery ...');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiOrbSecurityButtons()', 'warn', 'Plugin has detected new orb security buttons. Notifying plugin author about this discovery');
}
stackTracer('detect-content', cleanedData);
try {
await axios.post(getDetectReportUrl(), JSON.stringify(cleanedData, null, 2), {
family: 4,
headers: {
'User-Agent': 'homebridge-adt-pulse',
'X-Title': `Detected new orb security buttons (v${getPackageVersion()})`,
},
});
return true;
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiOrbSecurityButtons()', 'error', 'Failed to notify plugin author about the new orb security buttons');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
}
return false;
}
export async function detectApiPanelInformation(device, logger, debugMode) {
const detectedNewStatus = (device.status !== null && !itemPanelInformationStatuses.includes(device.status));
if (detectedNewStatus) {
const cleanedData = removePersonalIdentifiableInformation(device);
try {
const outdated = await isPluginOutdated();
if (outdated) {
if (logger !== null) {
logger.warn('Plugin has detected new panel information. You are running an older plugin version, please update soon.');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiPanelInformation()', 'warn', 'Plugin has detected new panel information. You are running an older plugin version, please update soon');
}
return false;
}
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiPanelInformation()', 'error', 'Failed to check if plugin is outdated');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
if (logger !== null) {
logger.warn('Plugin has detected new panel information. Notifying plugin author about this discovery ...');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiPanelInformation()', 'warn', 'Plugin has detected new panel information. Notifying plugin author about this discovery');
}
stackTracer('detect-content', cleanedData);
try {
await axios.post(getDetectReportUrl(), JSON.stringify(cleanedData, null, 2), {
family: 4,
headers: {
'User-Agent': 'homebridge-adt-pulse',
'X-Title': `Detected new panel information (v${getPackageVersion()})`,
},
});
return true;
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiPanelInformation()', 'error', 'Failed to notify plugin author about the new panel information');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
}
return false;
}
export async function detectApiPanelStatus(summary, logger, debugMode) {
const detectedUnknownPieces = summary.rawData.unknownPieces.length > 0;
if (detectedUnknownPieces) {
const cleanedData = removePersonalIdentifiableInformation(summary);
try {
const outdated = await isPluginOutdated();
if (outdated) {
if (logger !== null) {
logger.warn('Plugin has detected a new panel state and/or status. You are running an older plugin version, please update soon.');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiPanelStatus()', 'warn', 'Plugin has detected a new panel state and/or status. You are running an older plugin version, please update soon');
}
return false;
}
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiPanelStatus()', 'error', 'Failed to check if plugin is outdated');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
if (logger !== null) {
logger.warn('Plugin has detected a new panel state and/or status. Notifying plugin author about this discovery ...');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiPanelStatus()', 'warn', 'Plugin has detected a new panel state and/or status. Notifying plugin author about this discovery');
}
stackTracer('detect-content', cleanedData);
try {
await axios.post(getDetectReportUrl(), JSON.stringify(cleanedData, null, 2), {
family: 4,
headers: {
'User-Agent': 'homebridge-adt-pulse',
'X-Title': `Detected a new panel state and/or status (v${getPackageVersion()})`,
},
});
return true;
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiPanelStatus()', 'error', 'Failed to notify plugin author about the new panel state and/or status');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
}
return false;
}
export async function detectApiSensorsInformation(sensors, logger, debugMode) {
const detectedNewInformation = sensors.filter((sensor) => (!itemSensorInformationDeviceTypes.includes(sensor.deviceType)
|| !itemSensorInformationStatuses.includes(sensor.status)));
if (detectedNewInformation.length > 0) {
const cleanedData = removePersonalIdentifiableInformation(detectedNewInformation);
try {
const outdated = await isPluginOutdated();
if (outdated) {
if (logger !== null) {
logger.warn('Plugin has detected new sensors information. You are running an older plugin version, please update soon.');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiSensorsInformation()', 'warn', 'Plugin has detected new sensors information. You are running an older plugin version, please update soon');
}
return false;
}
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiSensorsInformation()', 'error', 'Failed to check if plugin is outdated');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
if (logger !== null) {
logger.warn('Plugin has detected new sensors information. Notifying plugin author about this discovery ...');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiSensorsInformation()', 'warn', 'Plugin has detected new sensors information. Notifying plugin author about this discovery');
}
stackTracer('detect-content', cleanedData);
try {
await axios.post(getDetectReportUrl(), JSON.stringify(cleanedData, null, 2), {
family: 4,
headers: {
'User-Agent': 'homebridge-adt-pulse',
'X-Title': `Detected new sensors information (v${getPackageVersion()})`,
},
});
return true;
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiSensorsInformation()', 'error', 'Failed to notify plugin author about the new sensors information');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
}
return false;
}
export async function detectApiSensorsStatus(sensors, logger, debugMode) {
const detectedNewStatuses = sensors.filter((sensor) => !itemSensorStatusIcons.includes(sensor.icon) || sensor.statuses.some((sensorStatus) => !itemSensorStatusStatuses.includes(sensorStatus)));
if (detectedNewStatuses.length > 0) {
const cleanedData = removePersonalIdentifiableInformation(detectedNewStatuses);
try {
const outdated = await isPluginOutdated();
if (outdated) {
if (logger !== null) {
logger.warn('Plugin has detected new sensors status. You are running an older plugin version, please update soon.');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiSensorsStatus()', 'warn', 'Plugin has detected new sensors status. You are running an older plugin version, please update soon');
}
return false;
}
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiSensorsStatus()', 'error', 'Failed to check if plugin is outdated');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
if (logger !== null) {
logger.warn('Plugin has detected new sensors status. Notifying plugin author about this discovery ...');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectApiSensorsStatus()', 'warn', 'Plugin has detected new sensors status. Notifying plugin author about this discovery');
}
stackTracer('detect-content', cleanedData);
try {
await axios.post(getDetectReportUrl(), JSON.stringify(cleanedData, null, 2), {
family: 4,
headers: {
'User-Agent': 'homebridge-adt-pulse',
'X-Title': `Detected new sensors status (v${getPackageVersion()})`,
},
});
return true;
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectApiSensorsStatus()', 'error', 'Failed to notify plugin author about the new sensors status');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
}
return false;
}
export async function detectGlobalDebugParser(data, logger, debugMode) {
const forceArmHandlerAnomaly = data.method === 'forceArmHandler' && isUnknownDoSubmitHandlerCollection(data.response) && !data.rawHtml.includes('p_whiteBoxMiddleCenter') && !data.rawHtml.includes('p_armDisarmWrapper');
const generateSensorsConfigAnomaly = data.method === 'generateSensorsConfig' && data.response.length < 1;
const getGatewayInformationAnomaly = data.method === 'getGatewayInformation' && isUnknownGatewayDevice(data.response);
const getOrbSecurityButtonsAnomaly = data.method === 'getOrbSecurityButtons' && isUnknownOrbSecurityButtonCollection(data.response) && !data.rawHtml.includes('Status Unavailable');
const getPanelInformationAnomaly = data.method === 'getPanelInformation' && isUnknownPanelDevice(data.response);
const getPanelStatusAnomaly = data.method === 'getPanelStatus' && isEmptyOrbTextSummary(data.response);
const getSensorsInformationAnomaly = data.method === 'getSensorsInformation' && data.response.length < 1;
const getSensorsStatusAnomaly = data.method === 'getSensorsStatus' && data.response.length < 1 && !data.rawHtml.includes('id="orbSensorsList"');
if (forceArmHandlerAnomaly
|| generateSensorsConfigAnomaly
|| getGatewayInformationAnomaly
|| getOrbSecurityButtonsAnomaly
|| getPanelInformationAnomaly
|| getPanelStatusAnomaly
|| getSensorsInformationAnomaly
|| getSensorsStatusAnomaly) {
const cleanedData = removePersonalIdentifiableInformation(data);
const loggedData = _.omit(cleanedData, ['rawHtml']);
try {
const outdated = await isPluginOutdated();
if (outdated) {
if (logger !== null) {
logger.warn(`Plugin has detected a parser anomaly for "${data.method}". You are running an older plugin version, please update soon.`);
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectGlobalDebugParser()', 'warn', `Plugin has detected a parser anomaly for "${data.method}". You are running an older plugin version, please update soon`);
}
return false;
}
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectGlobalDebugParser()', 'error', 'Failed to check if plugin is outdated');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
if (logger !== null) {
logger.warn(`Plugin has detected a parser anomaly for "${data.method}". Notifying plugin author about this discovery ...`);
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectGlobalDebugParser()', 'warn', `Plugin has detected a parser anomaly for "${data.method}". Notifying plugin author about this discovery`);
}
stackTracer('detect-content', loggedData);
try {
await axios.post(getDetectReportUrl(), JSON.stringify(cleanedData, null, 2), {
family: 4,
headers: {
'User-Agent': 'homebridge-adt-pulse',
'X-Title': `Detected a parser anomaly for "${data.method}" (v${getPackageVersion()})`,
},
});
return true;
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectGlobalDebugParser()', 'error', `Failed to notify plugin author about the parser anomaly for "${data.method}"`);
stackTracer('serialize-error', serializeError(error));
}
return false;
}
}
return false;
}
export async function detectGlobalPortalVersion(version, logger, debugMode) {
const detectedNewVersion = (version.version !== null && !itemPortalVersions.includes(version.version));
if (detectedNewVersion) {
const cleanedData = removePersonalIdentifiableInformation(version);
try {
const outdated = await isPluginOutdated();
if (outdated) {
if (logger !== null) {
logger.warn('Plugin has detected a new portal version. You are running an older plugin version, please update soon.');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectGlobalPortalVersion()', 'warn', 'Plugin has detected a new portal version. You are running an older plugin version, please update soon');
}
return false;
}
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectGlobalPortalVersion()', 'error', 'Failed to check if plugin is outdated');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
if (logger !== null) {
logger.warn('Plugin has detected a new portal version. Notifying plugin author about this discovery ...');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectGlobalPortalVersion()', 'warn', 'Plugin has detected a new portal version. Notifying plugin author about this discovery');
}
stackTracer('detect-content', cleanedData);
try {
await axios.post(getDetectReportUrl(), JSON.stringify(cleanedData, null, 2), {
family: 4,
headers: {
'User-Agent': 'homebridge-adt-pulse',
'X-Title': `Detected a new portal version (v${getPackageVersion()})`,
},
});
return true;
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectGlobalPortalVersion()', 'error', 'Failed to notify plugin author about the new portal version');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
}
return false;
}
export async function detectPlatformUnknownSensorsAction(sensors, logger, debugMode) {
const detectedNewActions = sensors.filter((sensor) => {
const sensorStatusStatuses = sensor.status.statuses;
const sensorType = sensor.type;
const stringifiedStatuses = sensorStatusStatuses.join(', ');
const currentType = collectionSensorActions.find((collectionSensorAction) => collectionSensorAction.type === sensorType);
if (currentType === undefined) {
return false;
}
return !currentType.statuses.includes(stringifiedStatuses);
});
if (detectedNewActions.length > 0) {
const cleanedData = removePersonalIdentifiableInformation(detectedNewActions);
try {
const outdated = await isPluginOutdated();
if (outdated) {
if (logger !== null) {
logger.warn('Plugin has detected unknown sensors action. You are running an older plugin version, please update soon.');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectPlatformUnknownSensorsAction()', 'warn', 'Plugin has detected unknown sensors action. You are running an older plugin version, please update soon');
}
return false;
}
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectPlatformUnknownSensorsAction()', 'error', 'Failed to check if plugin is outdated');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
if (logger !== null) {
logger.warn('Plugin has detected unknown sensors action. Notifying plugin author about this discovery ...');
}
if (debugMode) {
debugLog(logger, 'detect.ts / detectPlatformUnknownSensorsAction()', 'warn', 'Plugin has detected unknown sensors action. Notifying plugin author about this discovery');
}
stackTracer('detect-content', cleanedData);
try {
await axios.post(getDetectReportUrl(), JSON.stringify(cleanedData, null, 2), {
family: 4,
headers: {
'User-Agent': 'homebridge-adt-pulse',
'X-Title': `Detected unknown sensors action (v${getPackageVersion()})`,
},
});
return true;
}
catch (error) {
if (debugMode === true) {
debugLog(logger, 'detect.ts / detectPlatformUnknownSensorsAction()', 'error', 'Failed to notify plugin author about the unknown sensors action');
stackTracer('serialize-error', serializeError(error));
}
return false;
}
}
return false;
}
//# sourceMappingURL=detect.js.map