UNPKG

homebridge-adt-pulse

Version:
255 lines 10.1 kB
import { HomebridgePluginUiServer, RequestError } from '@homebridge/plugin-ui-utils'; import _ from 'lodash'; import { isErrorLike, serializeError } from 'serialize-error'; import { ADTPulseAuth } from '../lib/auth.js'; import { configServerLogin, configServerRequestCode, configServerValidate } from '../lib/schema.js'; import { debugLog } from '../lib/utility.js'; class ADTPulseConfigServer extends HomebridgePluginUiServer { #auth; #userInput; startBackend() { this.onRequest('/initialize', this.initialize.bind(this)); this.onRequest('/get-methods', this.getMethods.bind(this)); this.onRequest('/request-code', this.requestCode.bind(this)); this.onRequest('/validate', this.validate.bind(this)); this.onRequest('/generate-config', this.generateConfig.bind(this)); this.ready(); } async initialize(payload) { const parsedPayload = configServerLogin.safeParse(payload); if (!parsedPayload.success) { debugLog(null, 'server.ts / ADTPulseConfigServer.initialize()', 'error', 'Invalid payload'); return { action: 'UI_INITIALIZE', success: false, info: { message: 'Invalid payload', }, }; } this.#auth = new ADTPulseAuth({ subdomain: parsedPayload.data.subdomain, username: parsedPayload.data.username, password: parsedPayload.data.password, }, { debug: false, }); this.#userInput = { subdomain: parsedPayload.data.subdomain, username: parsedPayload.data.username, password: parsedPayload.data.password, }; return { action: 'UI_INITIALIZE', success: true, info: null, }; } async getMethods() { if (this.#auth === undefined || this.#userInput === undefined) { debugLog(null, 'server.ts / ADTPulseConfigServer.getMethods()', 'error', 'Auth API has not been initialized'); return { action: 'UI_GET_METHODS', success: false, info: { message: 'Auth API has not been initialized', }, }; } try { const response = await this.#auth.getVerificationMethods(); if (!response.success) { if (response.info.message) { debugLog(null, 'server.ts / ADTPulseConfigServer.getMethods()', 'error', response.info.message); } return { action: 'UI_GET_METHODS', success: false, info: response.info, }; } return { action: 'UI_GET_METHODS', success: true, info: response.info, }; } catch (error) { throw new RequestError('Failed to get methods', { message: error, }); } } async requestCode(payload) { if (this.#auth === undefined || this.#userInput === undefined) { debugLog(null, 'server.ts / ADTPulseConfigServer.requestCode()', 'error', 'Auth API has not been initialized'); return { action: 'UI_REQUEST_CODE', success: false, info: { message: 'Auth API has not been initialized', }, }; } const parsedPayload = configServerRequestCode.safeParse(payload); if (!parsedPayload.success) { debugLog(null, 'server.ts / ADTPulseConfigServer.requestCode()', 'error', 'Invalid payload'); return { action: 'UI_REQUEST_CODE', success: false, info: { message: 'Invalid payload', }, }; } try { const response = await this.#auth.requestCode(parsedPayload.data.methodId); if (!response.success) { if (response.info.message) { debugLog(null, 'server.ts / ADTPulseConfigServer.requestCode()', 'error', response.info.message); } return { action: 'UI_REQUEST_CODE', success: false, info: response.info, }; } return { action: 'UI_REQUEST_CODE', success: true, info: response.info, }; } catch (error) { const serializedError = (isErrorLike(error)) ? serializeError(error) : serializeError(new Error('Unknown error')); debugLog(null, 'server.ts / ADTPulseConfigServer.requestCode()', 'error', 'Method encountered an error during execution'); return { action: 'UI_REQUEST_CODE', success: false, info: { error: serializedError, }, }; } } async validate(payload) { if (this.#auth === undefined || this.#userInput === undefined) { debugLog(null, 'server.ts / ADTPulseConfigServer.validate()', 'error', 'Auth API has not been initialized'); return { action: 'UI_VALIDATE', success: false, info: { message: 'Auth API has not been initialized', }, }; } const parsedPayload = configServerValidate.safeParse(payload); if (!parsedPayload.success) { debugLog(null, 'server.ts / ADTPulseConfigServer.validate()', 'error', 'Invalid payload'); return { action: 'UI_VALIDATE', success: false, info: { message: 'Invalid payload', }, }; } try { const requests = [ this.#auth.validateCode.bind(this.#auth, parsedPayload.data.otpCode), this.#auth.getTrustedDevices.bind(this.#auth), this.#auth.addTrustedDevice.bind(this.#auth, parsedPayload.data.deviceName), this.#auth.completeSignIn.bind(this.#auth), ]; for (let i = 0; i < requests.length; i += 1) { const response = await requests[i](); if (!response.success) { if (response.info.message) { debugLog(null, 'server.ts / ADTPulseConfigServer.validate()', 'error', response.info.message); } return { action: 'UI_VALIDATE', success: false, info: response.info, }; } } return { action: 'UI_VALIDATE', success: true, info: null, }; } catch (error) { const serializedError = (isErrorLike(error)) ? serializeError(error) : serializeError(new Error('Unknown error')); debugLog(null, 'server.ts / ADTPulseConfigServer.validate()', 'error', 'Method encountered an error during execution'); return { action: 'UI_VALIDATE', success: false, info: { error: serializedError, }, }; } } async generateConfig(payload) { if (this.#auth === undefined || this.#userInput === undefined) { debugLog(null, 'server.ts / ADTPulseConfigServer.generateConfig()', 'error', 'Auth API has not been initialized'); return { action: 'UI_GENERATE_CONFIG', success: false, info: { message: 'Auth API has not been initialized', }, }; } try { let payloadSensors = payload.oldConfig.sensors ?? []; if (payload.updateSensors === true) { const response = await this.#auth.getSensors(); if (!response.success) { return { action: 'UI_GENERATE_CONFIG', success: false, info: { message: 'Failed to get new sensors', }, }; } payloadSensors = _.merge(payloadSensors, response.info.sensors); } return { action: 'UI_GENERATE_CONFIG', success: true, info: { config: { platform: payload.oldConfig.platform ?? 'ADTPulse', name: payload.oldConfig.name ?? 'ADT Pulse', subdomain: this.#userInput.subdomain, username: this.#userInput.username, password: this.#userInput.password, fingerprint: this.#auth.getFingerprint(), mode: payload.oldConfig.mode ?? 'normal', speed: payload.oldConfig.speed ?? 1, options: payload.oldConfig.options ?? [], sensors: payloadSensors, }, }, }; } catch (error) { const serializedError = (isErrorLike(error)) ? serializeError(error) : serializeError(new Error('Unknown error')); debugLog(null, 'server.ts / ADTPulseConfigServer.generateConfig()', 'error', 'Method encountered an error during execution'); return { action: 'UI_GENERATE_CONFIG', success: false, info: { error: serializedError, }, }; } } } const instance = new ADTPulseConfigServer(); instance.startBackend(); //# sourceMappingURL=server.js.map