homebridge-virtual-accessories 3.16.4 → 3.16.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,5 +2,5 @@
2
2
  *
3
3
  */
4
4
  export interface UpdatableChargingStatus {
5
- updateChargingStatus(charging: boolean, charge: number, accessoryId: string): void;
5
+ updateChargingStatus(charging: boolean | undefined, charge: number | undefined, accessoryId: string): void;
6
6
  }
@@ -15,7 +15,7 @@ export declare class Battery extends Accessory implements UpdatableChargingStatu
15
15
  getBatteryLevelHandler(): Promise<CharacteristicValue>;
16
16
  getChargingStateHandler(): Promise<CharacteristicValue>;
17
17
  protected getJsonState(): string;
18
- updateChargingStatus(charging: boolean, charge: number, accessoryId: string): void;
18
+ updateChargingStatus(charging: boolean | undefined, charge: number | undefined, accessoryId: string): void;
19
19
  static get BATTERY_LEVEL_NORMAL(): number;
20
20
  static get BATTERY_LEVEL_LOW(): number;
21
21
  static get NOT_CHARGING(): number;
@@ -1 +1 @@
1
- {"version":3,"file":"virtualAccessoryBattery.js","sourceRoot":"","sources":["../../src/accessories/virtualAccessoryBattery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"virtualAccessoryBattery.js","sourceRoot":"","sources":["../../src/accessories/virtualAccessoryBattery.ts"],"names":[],"mappings":"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"}
@@ -25,5 +25,6 @@ export declare class WebhookServer {
25
25
  private booleanIsValid;
26
26
  private processRequest;
27
27
  private parametersArePresent;
28
+ private usingStringValues;
28
29
  private usingQueryParams;
29
30
  }
@@ -4,7 +4,7 @@ import { BinarySensor } from './sensors/binarySensor.js';
4
4
  import { SensorValueUpdateNotAllowed } from './errors.js';
5
5
  import express from 'express';
6
6
  function ToBoolean(value) {
7
- switch (value) {
7
+ switch (value.toLowerCase()) {
8
8
  case 'true':
9
9
  return true;
10
10
  case 'false':
@@ -41,12 +41,14 @@ export class WebhookServer {
41
41
  const routeHumidity = '/humidity';
42
42
  this.log.info(`[${this.serverName}] Setting up route: ${routeHumidity}`);
43
43
  this.server.post(routeHumidity, (request, response) => {
44
+ if (!this.parametersArePresent(request, response)) {
45
+ return;
46
+ }
44
47
  const useQueryParams = this.usingQueryParams(request);
45
48
  const accessoryId = (useQueryParams) ? request.query.id : request.body.id;
46
49
  const humidity = (useQueryParams) ? request.query.value : request.body.value;
47
- if (this.parametersArePresent(request, response) &&
48
- this.accessoryIdIsValid(accessoryId, response) &&
49
- this.percentageIsValid(humidity, response)) {
50
+ if (this.accessoryIdIsValid(accessoryId, response) &&
51
+ this.percentageIsValid(humidity, response, request)) {
50
52
  this.processRequest(routeHumidity, accessoryId, ['humidifierdehumidifier', 'measurement'], Number(humidity), response);
51
53
  }
52
54
  });
@@ -55,12 +57,14 @@ export class WebhookServer {
55
57
  const routeTemperature = '/temperature';
56
58
  this.log.info(`[${this.serverName}] Setting up route: ${routeTemperature}`);
57
59
  this.server.post(routeTemperature, (request, response) => {
60
+ if (!this.parametersArePresent(request, response)) {
61
+ return;
62
+ }
58
63
  const useQueryParams = this.usingQueryParams(request);
59
64
  const accessoryId = (useQueryParams) ? request.query.id : request.body.id;
60
65
  const temperature = (useQueryParams) ? request.query.value : request.body.value;
61
- if (this.parametersArePresent(request, response) &&
62
- this.accessoryIdIsValid(accessoryId, response) &&
63
- this.numberIsValid(temperature, response)) {
66
+ if (this.accessoryIdIsValid(accessoryId, response) &&
67
+ this.numberIsValid(temperature, response, request)) {
64
68
  this.processRequest(routeTemperature, accessoryId, ['heatercooler', 'measurement'], Number(temperature), response);
65
69
  }
66
70
  });
@@ -69,13 +73,15 @@ export class WebhookServer {
69
73
  const routeObstruction = '/obstruction';
70
74
  this.log.info(`[${this.serverName}] Setting up route: ${routeObstruction}`);
71
75
  this.server.post(routeObstruction, (request, response) => {
76
+ if (!this.parametersArePresent(request, response)) {
77
+ return;
78
+ }
72
79
  const useQueryParams = this.usingQueryParams(request);
73
80
  const accessoryId = (useQueryParams) ? request.query.id : request.body.id;
74
- const obstruction = ((useQueryParams) ? request.query.value : request.body.value).toString();
75
- if (this.parametersArePresent(request, response) &&
76
- this.accessoryIdIsValid(accessoryId, response) &&
77
- this.booleanIsValid(obstruction, response)) {
78
- this.processRequest(routeObstruction, accessoryId, ['garagedoor'], ToBoolean(obstruction), response);
81
+ const obstruction = (useQueryParams) ? request.query.value : request.body.value;
82
+ if (this.accessoryIdIsValid(accessoryId, response) &&
83
+ this.booleanIsValid(obstruction, response, request)) {
84
+ this.processRequest(routeObstruction, accessoryId, ['garagedoor'], ToBoolean(obstruction.toString()), response);
79
85
  }
80
86
  });
81
87
  // id
@@ -83,14 +89,16 @@ export class WebhookServer {
83
89
  const routeTriggerAlarm = '/triggeralarm';
84
90
  this.log.info(`[${this.serverName}] Setting up route: ${routeTriggerAlarm}`);
85
91
  this.server.post(routeTriggerAlarm, (request, response) => {
92
+ if (!this.parametersArePresent(request, response)) {
93
+ return;
94
+ }
86
95
  const useQueryParams = this.usingQueryParams(request);
87
96
  const accessoryId = (useQueryParams) ? request.query.id : request.body.id;
88
- const trigger = ((useQueryParams) ? request.query.value : request.body.value).toString();
89
- if (this.parametersArePresent(request, response) &&
90
- this.accessoryIdIsValid(accessoryId, response) &&
91
- this.booleanIsValid(trigger, response)) {
97
+ const trigger = (useQueryParams) ? request.query.value : request.body.value;
98
+ if (this.accessoryIdIsValid(accessoryId, response) &&
99
+ this.booleanIsValid(trigger, response, request)) {
92
100
  // eslint-disable-next-line max-len
93
- this.processRequest(routeTriggerAlarm, accessoryId, ['securitysystem'], (ToBoolean(trigger) ? SecurityServiceTriggerType.TriggerAlarm : SecurityServiceTriggerType.None), response);
101
+ this.processRequest(routeTriggerAlarm, accessoryId, ['securitysystem'], (ToBoolean(trigger.toString()) ? SecurityServiceTriggerType.TriggerAlarm : SecurityServiceTriggerType.None), response);
94
102
  }
95
103
  });
96
104
  // id
@@ -98,14 +106,16 @@ export class WebhookServer {
98
106
  const routeTriggerPanic = '/triggerpanic';
99
107
  this.log.info(`[${this.serverName}] Setting up route: ${routeTriggerPanic}`);
100
108
  this.server.post(routeTriggerPanic, (request, response) => {
109
+ if (!this.parametersArePresent(request, response)) {
110
+ return;
111
+ }
101
112
  const useQueryParams = this.usingQueryParams(request);
102
113
  const accessoryId = (useQueryParams) ? request.query.id : request.body.id;
103
- const trigger = ((useQueryParams) ? request.query.value : request.body.value).toString();
104
- if (this.parametersArePresent(request, response) &&
105
- this.accessoryIdIsValid(accessoryId, response) &&
106
- this.booleanIsValid(trigger, response)) {
114
+ const trigger = (useQueryParams) ? request.query.value : request.body.value;
115
+ if (this.accessoryIdIsValid(accessoryId, response) &&
116
+ this.booleanIsValid(trigger, response, request)) {
107
117
  // eslint-disable-next-line max-len
108
- this.processRequest(routeTriggerPanic, accessoryId, ['securitysystem'], (ToBoolean(trigger) ? SecurityServiceTriggerType.TriggerPanic : SecurityServiceTriggerType.None), response);
118
+ this.processRequest(routeTriggerPanic, accessoryId, ['securitysystem'], (ToBoolean(trigger.toString()) ? SecurityServiceTriggerType.TriggerPanic : SecurityServiceTriggerType.None), response);
109
119
  }
110
120
  });
111
121
  // id
@@ -113,13 +123,15 @@ export class WebhookServer {
113
123
  const routeTriggerSensor = '/triggersensor';
114
124
  this.log.info(`[${this.serverName}] Setting up route: ${routeTriggerSensor}`);
115
125
  this.server.post(routeTriggerSensor, (request, response) => {
126
+ if (!this.parametersArePresent(request, response)) {
127
+ return;
128
+ }
116
129
  const useQueryParams = this.usingQueryParams(request);
117
130
  const accessoryId = (useQueryParams) ? request.query.id : request.body.id;
118
- const trigger = ((useQueryParams) ? request.query.value : request.body.value).toString();
119
- if (this.parametersArePresent(request, response) &&
120
- this.accessoryIdIsValid(accessoryId, response) &&
121
- this.booleanIsValid(trigger, response)) {
122
- this.processRequest(routeTriggerSensor, accessoryId, ['sensor'], ToBoolean(trigger), response);
131
+ const trigger = (useQueryParams) ? request.query.value : request.body.value;
132
+ if (this.accessoryIdIsValid(accessoryId, response) &&
133
+ this.booleanIsValid(trigger, response, request)) {
134
+ this.processRequest(routeTriggerSensor, accessoryId, ['sensor'], ToBoolean(trigger.toString()), response);
123
135
  }
124
136
  });
125
137
  // id
@@ -128,15 +140,21 @@ export class WebhookServer {
128
140
  const routeChargingState = '/chargingstate';
129
141
  this.log.info(`[${this.serverName}] Setting up route: ${routeChargingState}`);
130
142
  this.server.post(routeChargingState, (request, response) => {
143
+ if (!this.parametersArePresent(request, response)) {
144
+ return;
145
+ }
131
146
  const useQueryParams = this.usingQueryParams(request);
132
147
  const accessoryId = (useQueryParams) ? request.query.id : request.body.id;
133
- const charging = ((useQueryParams) ? request.query.charging : request.body.charging).toString();
134
- const charge = (useQueryParams) ? Number(request.query.charge) : request.body.charge;
135
- if (this.parametersArePresent(request, response) &&
136
- this.accessoryIdIsValid(accessoryId, response) &&
137
- this.booleanIsValid(charging, response) &&
138
- this.numberIsValid(charge, response)) {
139
- const chargingState = new ChargingState(ToBoolean(charging), Number(charge));
148
+ const charging = (useQueryParams) ? request.query.charging : request.body.charging;
149
+ const charge = (useQueryParams) ? request.query.charge : request.body.charge;
150
+ if (charging === undefined && charge === undefined) {
151
+ response.status(HttpResponse.BadRequest).send('At least one of charging or charge must be supplied');
152
+ return;
153
+ }
154
+ if (this.accessoryIdIsValid(accessoryId, response) &&
155
+ (charging === undefined || this.booleanIsValid(charging, response, request)) &&
156
+ (charge === undefined || this.percentageIsValid(charge, response, request))) {
157
+ const chargingState = new ChargingState(charging === undefined ? undefined : ToBoolean(charging.toString()), charge === undefined ? undefined : Number(charge));
140
158
  this.processRequest(routeChargingState, accessoryId, ['battery'], chargingState, response);
141
159
  }
142
160
  });
@@ -194,19 +212,25 @@ export class WebhookServer {
194
212
  }
195
213
  accessoryIdIsValid(accessoryId, response) {
196
214
  const patternRegex = new RegExp(WebhookServer.accessoryIdPattern);
197
- const isValidAccessoryId = ((accessoryId !== undefined) &&
215
+ const isValidAccessoryId = (typeof accessoryId === 'string' &&
198
216
  patternRegex.test(accessoryId));
199
217
  if (!isValidAccessoryId) {
200
- const errorMsg = `Invalid accessory id: ${accessoryId}`;
218
+ // Do not invoke conversion methods on malformed objects or arrays.
219
+ const invalidId = accessoryId !== null && typeof accessoryId === 'object' ? typeof accessoryId : String(accessoryId);
220
+ const errorMsg = `Invalid accessory id: ${invalidId}`;
201
221
  this.log.error(`[${this.serverName}] ${errorMsg}`);
202
222
  response.status(HttpResponse.BadRequest).send(`${errorMsg}`);
203
223
  return false;
204
224
  }
205
225
  return true;
206
226
  }
207
- percentageIsValid(value, response) {
227
+ percentageIsValid(value, response, request) {
228
+ if (!this.numberIsValid(value, response, request)) {
229
+ return false;
230
+ }
208
231
  const valuePercent = Number(value);
209
- if (isNaN(valuePercent) || valuePercent < 0 || valuePercent > 100) {
232
+ if (!Number.isInteger(valuePercent) || valuePercent < 0 || valuePercent > 100 ||
233
+ (typeof value === 'string' && !/^[+-]?\d+$/.test(value))) {
210
234
  const errorMsg = `Invalid value: ${value}. Value must be a percentage`;
211
235
  this.log.error(`[${this.serverName}] ${errorMsg}`);
212
236
  response.status(HttpResponse.BadRequest).send(`${errorMsg}`);
@@ -214,20 +238,29 @@ export class WebhookServer {
214
238
  }
215
239
  return true;
216
240
  }
217
- numberIsValid(value, response) {
218
- const valueNumber = Number(value);
219
- if (isNaN(valueNumber)) {
220
- const errorMsg = `Invalid value: ${value}. Value must be a number`;
241
+ numberIsValid(value, response, request) {
242
+ const isScalar = this.usingStringValues(request)
243
+ ? typeof value === 'string' && value === value.trim() && /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(value)
244
+ : typeof value === 'number';
245
+ if (!isScalar || !Number.isFinite(Number(value))) {
246
+ // Do not invoke conversion methods on malformed objects or arrays.
247
+ const invalidValue = value !== null && typeof value === 'object' ? typeof value : String(value);
248
+ const errorMsg = `Invalid value: ${invalidValue}. Value must be a finite number`;
221
249
  this.log.error(`[${this.serverName}] ${errorMsg}`);
222
250
  response.status(HttpResponse.BadRequest).send(`${errorMsg}`);
223
251
  return false;
224
252
  }
225
253
  return true;
226
254
  }
227
- booleanIsValid(value, response) {
228
- const valueBoolean = ['true', 'false'].includes(value.toLowerCase());
255
+ booleanIsValid(value, response, request) {
256
+ const valueBoolean = (this.usingStringValues(request)
257
+ ? typeof value === 'string' && ['true', 'false'].includes(value.toLowerCase())
258
+ : typeof value === 'boolean');
229
259
  if (!valueBoolean) {
230
- const errorMsg = `Invalid value: ${value}. Value must be a boolean`;
260
+ // Avoid invoking user-supplied conversion methods when reporting malformed values.
261
+ const invalidValue = value !== null && (typeof value === 'object' || typeof value === 'function')
262
+ ? typeof value : String(value);
263
+ const errorMsg = `Invalid value: ${invalidValue}. Value must be a boolean`;
231
264
  this.log.error(`[${this.serverName}] ${errorMsg}`);
232
265
  response.status(HttpResponse.BadRequest).send(`${errorMsg}`);
233
266
  return false;
@@ -284,13 +317,20 @@ export class WebhookServer {
284
317
  }
285
318
  }
286
319
  parametersArePresent(request, response) {
320
+ const header = request.header(this.UseQueryParamsHeader)?.trim().toLowerCase();
321
+ if (header !== undefined && header !== 'true' && header !== 'false') {
322
+ const errorMsg = `Invalid ${this.UseQueryParamsHeader} header. Value must be true or false`;
323
+ this.log.error(`[${this.serverName}] ${errorMsg}`);
324
+ response.status(HttpResponse.BadRequest).send(errorMsg);
325
+ return false;
326
+ }
287
327
  const useQueryParams = this.usingQueryParams(request);
288
328
  this.log.debug(`[${this.serverName}] ${this.UseQueryParamsHeader}: ${useQueryParams}`);
289
329
  this.log.debug(`[${this.serverName}] Request: ${request.method} ${request.path}`);
290
330
  this.log.debug(`[${this.serverName}] POST body: ${JSON.stringify(request.body)}`);
291
331
  this.log.debug(`[${this.serverName}] POST query: ${JSON.stringify(request.query)}`);
292
332
  // POST body
293
- if (!useQueryParams && JSON.stringify(request.body) === '{}') {
333
+ if (!useQueryParams && (request.body == null || JSON.stringify(request.body) === '{}')) {
294
334
  const errorMsg = 'No parameters found in POST body';
295
335
  this.log.error(`[${this.serverName}] ${errorMsg}`);
296
336
  response.status(HttpResponse.BadRequest).send(`${errorMsg}`);
@@ -305,9 +345,12 @@ export class WebhookServer {
305
345
  }
306
346
  return true;
307
347
  }
348
+ usingStringValues(request) {
349
+ return this.usingQueryParams(request) || request.is('application/x-www-form-urlencoded') === 'application/x-www-form-urlencoded';
350
+ }
308
351
  usingQueryParams(request) {
309
352
  const useQueryParamsHeader = request.header(this.UseQueryParamsHeader);
310
- return (useQueryParamsHeader === undefined) ? false : ToBoolean(useQueryParamsHeader);
353
+ return (useQueryParamsHeader === undefined) ? false : ToBoolean(useQueryParamsHeader.trim());
311
354
  }
312
355
  }
313
356
  class HttpResponse {
@@ -1 +1 @@
1
- {"version":3,"file":"webhookServer.js","sourceRoot":"","sources":["../src/webhookServer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webhookServer.js","sourceRoot":"","sources":["../src/webhookServer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "homebridge-virtual-accessories",
3
3
  "displayName": "Virtual Accessories for Homebridge",
4
4
  "type": "module",
5
- "version": "3.16.4",
5
+ "version": "3.16.5",
6
6
  "description": "Virtual HomeKit accessories for Homebridge.",
7
7
  "author": "justjam2023 (Renzo Zanelli - renzo.zanelli6@gmail.com)",
8
8
  "license": "MIT",
@@ -102,7 +102,8 @@
102
102
  "homebridge": "^1.8.0 || ^2.0.0-beta.0"
103
103
  },
104
104
  "scripts": {
105
- "build": "rimraf ./dist && tsc",
105
+ "build": "rimraf ./dist && tsc && npm test",
106
+ "test": "node --test test/*.test.js",
106
107
  "generate-schemas": "node scripts/generate-schemas.js",
107
108
  "generate-template": "node scripts/generate-template.js",
108
109
  "lint": "eslint . --max-warnings=0",
@@ -111,7 +112,7 @@
111
112
  },
112
113
  "dependencies": {
113
114
  "@js-joda/core": "^6.0.0",
114
- "@js-joda/timezone": "^2.22.0",
115
+ "@js-joda/timezone": "^3.0.0",
115
116
  "@justjam2013/net-ping": "^2.0.0",
116
117
  "@types/express": "^5.0.3",
117
118
  "cheerio": "^1.2.0",
@@ -0,0 +1,450 @@
1
+ /* global fetch */
2
+ import assert from 'node:assert/strict';
3
+ import { once } from 'node:events';
4
+ import { URLSearchParams } from 'node:url';
5
+ import { test } from 'node:test';
6
+ import { Battery } from '../dist/accessories/virtualAccessoryBattery.js';
7
+ import { WebhookServer } from '../dist/webhookServer.js';
8
+ import { SecurityServiceTriggerType } from '../dist/accessories/virtualAccessorySecuritySystem.js';
9
+
10
+ // Run with npm test (builds the source before testing).
11
+ test('accessory IDs reject malformed HTTP input without dispatching updates', async (t) => {
12
+ const webhook = new WebhookServer({ info() {}, error() {}, debug() {} }, 0);
13
+ const updates = [];
14
+ webhook.processRequest = (route, id, types, value, response) => {
15
+ updates.push({ route, id });
16
+ response.sendStatus(200);
17
+ };
18
+ const server = webhook.server.listen(0, '127.0.0.1');
19
+ t.after(() => new Promise((resolve, reject) => server.close(error => error ? reject(error) : resolve())));
20
+ await once(server, 'listening');
21
+ const base = `http://127.0.0.1:${server.address().port}`;
22
+ const routes = ['/humidity', '/temperature', '/obstruction', '/triggeralarm', '/triggerpanic', '/triggersensor', '/chargingstate'];
23
+
24
+ for (const route of routes) {
25
+ const fields = route === '/chargingstate' ? { charging: false, charge: 0 }
26
+ : { value: route === '/humidity' || route === '/temperature' ? 0 : false };
27
+ const invalidIds = [
28
+ [{ toString: 1 }, 'object'], [{}, 'object'], [[], 'object'], [['a00005'], 'object'],
29
+ [[{ toString: 1 }], 'object'], [null, 'null'], [12345, '12345'], [false, 'false'],
30
+ [undefined, 'undefined'], ['', ''], ['abcd', 'abcd'], ['invalid id', 'invalid id'],
31
+ ];
32
+ for (const [id, description] of invalidIds) {
33
+ await t.test(`${route} rejects JSON id ${JSON.stringify(id)}`, async () => {
34
+ const before = updates.length;
35
+ const response = await fetch(`${base}${route}`, {
36
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
37
+ body: JSON.stringify({ id, ...fields }),
38
+ });
39
+ assert.equal(response.status, 400);
40
+ assert.equal(await response.text(), `Invalid accessory id: ${description}`);
41
+ assert.equal(updates.length, before);
42
+ });
43
+ }
44
+ for (const mode of ['query', 'form']) {
45
+ for (const id of ['id[toString]=1', 'id[]=a00005', 'id[0][toString]=1', 'id=a00005&id=b00006']) {
46
+ await t.test(`${route} rejects ${mode} ${id}`, async () => {
47
+ const before = updates.length;
48
+ const encoded = `${id}&${new URLSearchParams(fields)}`;
49
+ const options = mode === 'query' ? { headers: { 'Use-Query-Params': 'true' } }
50
+ : { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: encoded };
51
+ const response = await fetch(`${base}${route}${mode === 'query' ? `?${encoded}` : ''}`, { method: 'POST', ...options });
52
+ assert.equal(response.status, 400);
53
+ assert.match(await response.text(), /^Invalid accessory id: (object|undefined)$/);
54
+ assert.equal(updates.length, before);
55
+ });
56
+ }
57
+ }
58
+ for (const mode of ['JSON', 'query', 'form']) {
59
+ for (const id of ['a00005', '12345', 'AbC-09']) {
60
+ await t.test(`${route} accepts ${mode} string id ${id}`, async () => {
61
+ const before = updates.length;
62
+ const payload = { id, ...fields };
63
+ const encoded = new URLSearchParams(payload).toString();
64
+ const options = mode === 'query' ? { headers: { 'Use-Query-Params': 'true' } }
65
+ : mode === 'JSON' ? { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }
66
+ : { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: encoded };
67
+ const response = await fetch(`${base}${route}${mode === 'query' ? `?${encoded}` : ''}`, { method: 'POST', ...options });
68
+ assert.equal(response.status, 200, await response.text());
69
+ assert.equal(updates.length, before + 1);
70
+ assert.deepEqual(updates.at(-1), { route, id });
71
+ });
72
+ }
73
+ }
74
+ }
75
+ });
76
+
77
+ test('boolean webhook validation rejects malformed values and preserves valid booleans', async (t) => {
78
+ const webhook = new WebhookServer({ info() {}, error() {}, debug() {} }, 0);
79
+ const updates = [];
80
+ webhook.processRequest = (route, id, types, value, response) => {
81
+ updates.push(value);
82
+ response.sendStatus(200);
83
+ };
84
+ const server = webhook.server.listen(0, '127.0.0.1');
85
+ t.after(() => new Promise((resolve, reject) => server.close(error => error ? reject(error) : resolve())));
86
+ await once(server, 'listening');
87
+ const base = `http://127.0.0.1:${server.address().port}`;
88
+
89
+ for (const route of ['/obstruction', '/triggeralarm', '/triggerpanic', '/triggersensor', '/chargingstate']) {
90
+ const field = route === '/chargingstate' ? 'charging' : 'value';
91
+ const invalid = [null, { toString: 1 }, {}, [], [true], [false], ['true'], [{ toString: 1 }],
92
+ 0, 1, '', 'invalid', 'true', 'false', 'TRUE', 'False', undefined];
93
+ for (const value of invalid) {
94
+ // An omitted charging field is valid when charge is supplied.
95
+ if (route === '/chargingstate' && value === undefined) {
96
+ continue;
97
+ }
98
+ await t.test(`${route} rejects ${JSON.stringify(value)}`, async () => {
99
+ const before = updates.length;
100
+ const response = await fetch(`${base}${route}`, {
101
+ method: 'POST',
102
+ headers: { 'Content-Type': 'application/json' },
103
+ body: JSON.stringify({ id: 'a00005', [field]: value, charge: 50 }),
104
+ });
105
+ assert.equal(response.status, 400);
106
+ assert.match(await response.text(), /^Invalid value: .*\. Value must be a boolean$/);
107
+ assert.equal(updates.length, before);
108
+ });
109
+ }
110
+ for (const mode of ['query', 'form']) {
111
+ for (const value of ['', ' ', ' true', 'false ', 'true\n', '1', '0', 'yes', 'null', 'undefined']) {
112
+ await t.test(`${route} rejects ${mode} boolean ${JSON.stringify(value)}`, async () => {
113
+ const before = updates.length;
114
+ const encoded = new URLSearchParams({ id: 'a00005', [field]: value, charge: 50 }).toString();
115
+ const options = mode === 'query' ? { headers: { 'Use-Query-Params': 'true' } }
116
+ : { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: encoded };
117
+ const response = await fetch(`${base}${route}${mode === 'query' ? `?${encoded}` : ''}`, { method: 'POST', ...options });
118
+ assert.equal(response.status, 400, await response.text());
119
+ assert.equal(updates.length, before);
120
+ });
121
+ }
122
+ }
123
+ for (const value of [true, false, 'true', 'false', 'TRUE', 'FALSE', 'True', 'False']) {
124
+ const expected = String(value).toLowerCase() === 'true';
125
+ for (const mode of ['JSON', 'query', 'form']) {
126
+ if (mode === 'JSON' && typeof value !== 'boolean') {
127
+ continue;
128
+ }
129
+ const query = mode === 'query';
130
+ await t.test(`${route} accepts ${mode} ${value}`, async () => {
131
+ const before = updates.length;
132
+ const response = await fetch(`${base}${route}${query ? `?id=a00005&${field}=${value}&charge=50` : ''}`, {
133
+ method: 'POST',
134
+ headers: { 'Content-Type': mode === 'form' ? 'application/x-www-form-urlencoded' : 'application/json', 'Use-Query-Params': String(query) },
135
+ body: mode === 'form' ? new URLSearchParams({ id: 'a00005', [field]: value, charge: 50 }).toString()
136
+ : JSON.stringify({ id: 'a00005', [field]: value, charge: 50 }),
137
+ });
138
+ assert.equal(response.status, 200);
139
+ assert.equal(updates.length, before + 1);
140
+ if (route === '/chargingstate') {
141
+ assert.equal(updates.at(-1).charging, expected);
142
+ }
143
+ else if (route === '/obstruction' || route === '/triggersensor') {
144
+ assert.equal(updates.at(-1), expected);
145
+ }
146
+ else {
147
+ const trigger = route === '/triggeralarm' ? SecurityServiceTriggerType.TriggerAlarm : SecurityServiceTriggerType.TriggerPanic;
148
+ assert.equal(updates.at(-1), expected ? trigger : SecurityServiceTriggerType.None);
149
+ }
150
+ });
151
+ }
152
+ }
153
+ }
154
+ });
155
+
156
+ test('webhook routes handle missing bodies before reading fields', async (t) => {
157
+ const webhook = new WebhookServer({ info() {}, error() {}, debug() {} }, 0);
158
+ const updates = [];
159
+ webhook.processRequest = (route, id, types, value, response) => {
160
+ updates.push({ route, id, value });
161
+ response.sendStatus(200);
162
+ };
163
+ const server = webhook.server.listen(0, '127.0.0.1');
164
+ t.after(() => new Promise((resolve, reject) => server.close(error => error ? reject(error) : resolve())));
165
+ await once(server, 'listening');
166
+ const base = `http://127.0.0.1:${server.address().port}`;
167
+ const routes = ['/humidity', '/temperature', '/obstruction', '/triggeralarm', '/triggerpanic', '/triggersensor', '/chargingstate'];
168
+ const missingBodies = [
169
+ ['no body or content type', {}],
170
+ ['empty JSON body', { headers: { 'Content-Type': 'application/json' } }],
171
+ ['unparsed text body', { headers: { 'Content-Type': 'text/plain' }, body: 'id=a00005&value=true' }],
172
+ ['empty JSON object', { headers: { 'Content-Type': 'application/json' }, body: '{}' }],
173
+ ];
174
+ for (const route of routes) {
175
+ for (const [label, options] of missingBodies) {
176
+ await t.test(`${route} rejects ${label}`, async () => {
177
+ const before = updates.length;
178
+ const response = await fetch(`${base}${route}?id=a00005&value=true&charging=true&charge=50`, {
179
+ method: 'POST', ...options,
180
+ });
181
+ assert.equal(response.status, 400);
182
+ assert.equal(await response.text(), 'No parameters found in POST body');
183
+ assert.equal(updates.length, before);
184
+ });
185
+ }
186
+ await t.test(`${route} rejects empty query mode without a body`, async () => {
187
+ const before = updates.length;
188
+ const response = await fetch(`${base}${route}`, {
189
+ method: 'POST', headers: { 'Use-Query-Params': 'true' },
190
+ });
191
+ assert.equal(response.status, 400);
192
+ assert.equal(await response.text(), 'No parameters found in POST query. The webhook server is using query parameters');
193
+ assert.equal(updates.length, before);
194
+ });
195
+ const numeric = route === '/humidity' || route === '/temperature';
196
+ const payload = route === '/chargingstate'
197
+ ? { id: 'a00005', charging: false, charge: 0 }
198
+ : { id: 'a00005', value: numeric ? 0 : false };
199
+ for (const mode of ['JSON', 'query', 'form']) {
200
+ await t.test(`${route} preserves ${mode} updates`, async () => {
201
+ const before = updates.length;
202
+ const query = new URLSearchParams(payload).toString();
203
+ const options = mode === 'query'
204
+ ? { headers: { 'Use-Query-Params': 'true' } }
205
+ : mode === 'JSON'
206
+ ? { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }
207
+ : { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: query };
208
+ const response = await fetch(`${base}${route}${mode === 'query' ? `?${query}` : ''}`, {
209
+ method: 'POST', ...options,
210
+ });
211
+ assert.equal(response.status, 200);
212
+ assert.equal(updates.length, before + 1);
213
+ assert.equal(updates.at(-1).id, payload.id);
214
+ assert.equal(updates.at(-1).route, route);
215
+ const actual = updates.at(-1).value;
216
+ if (route === '/chargingstate') {
217
+ assert.equal(actual.charging, false);
218
+ assert.equal(actual.charge, 0);
219
+ }
220
+ else {
221
+ const alarm = route === '/triggeralarm' || route === '/triggerpanic';
222
+ assert.equal(actual, numeric ? 0 : alarm ? SecurityServiceTriggerType.None : false);
223
+ }
224
+ });
225
+ }
226
+ }
227
+ });
228
+
229
+
230
+ test('charging updates preserve omitted battery properties', async (t) => {
231
+ // Homebridge normally initializes these characteristic constants at startup.
232
+ t.mock.getter(Battery, 'NOT_CHARGING', () => 0);
233
+ t.mock.getter(Battery, 'CHARGING', () => 1);
234
+ t.mock.getter(Battery, 'NOT_CHARGEABLE', () => 2);
235
+ const log = { info() {}, error() {}, debug() {} };
236
+ const webhook = new WebhookServer(log, 0);
237
+ const updates = [];
238
+ const state = { charging: true, charge: 42 };
239
+ // Exercise real route dispatch and Battery.updateChargingStatus without HomeKit setup.
240
+ const battery = {
241
+ log,
242
+ accessoryConfiguration: { accessoryID: 'a00005', accessoryType: 'battery' },
243
+ getChargingState: () => state.charging ? Battery.CHARGING : Battery.NOT_CHARGING,
244
+ updateChargingState(value) {
245
+ state.charging = value === Battery.CHARGING;
246
+ return value;
247
+ },
248
+ updateBatteryLevel(value) {
249
+ state.charge = value;
250
+ return value;
251
+ },
252
+ saveState() {},
253
+ updateChargingStatus(charging, charge, id) {
254
+ updates.push({ charging, charge, id });
255
+ Battery.prototype.updateChargingStatus.call(this, charging, charge, id);
256
+ },
257
+ };
258
+ webhook.addAccessory(battery);
259
+ const server = webhook.server.listen(0, '127.0.0.1');
260
+ t.after(() => new Promise((resolve, reject) => server.close(error => error ? reject(error) : resolve())));
261
+ await once(server, 'listening');
262
+ const base = `http://127.0.0.1:${server.address().port}/chargingstate`;
263
+ const cases = [
264
+ ['charge only', { charge: 75 }, 200],
265
+ ['zero charge', { charge: 0 }, 200],
266
+ ['full charge', { charge: 100 }, 200],
267
+ ['charging only', { charging: true }, 200],
268
+ ['not charging', { charging: false }, 200],
269
+ ['both properties', { charge: 75, charging: false }, 200],
270
+ ['both falsy values', { charge: 0, charging: false }, 200],
271
+ ['neither property', {}, 400],
272
+ ['invalid charging alone', { charging: 'invalid' }, 400],
273
+ ['invalid charging with charge', { charging: 'invalid', charge: 75 }, 400],
274
+ ['null charge alone', { charge: null }, 400],
275
+ ['null charge with charging', { charge: null, charging: false }, 400],
276
+ ['array charging with charge', { charging: [true], charge: 0 }, 400],
277
+ ['fractional charge', { charge: 75.5 }, 400],
278
+ ['negative charge', { charge: -1, charging: false }, 400],
279
+ ['excess charge', { charge: 101, charging: false }, 400],
280
+ ['invalid charge alone', { charge: 'invalid' }, 400],
281
+ ['invalid charge with charging', { charge: 'invalid', charging: false }, 400],
282
+ ];
283
+ for (const mode of ['JSON', 'query', 'form']) {
284
+ for (const [label, fields, status] of cases) {
285
+ if (mode !== 'JSON' && Array.isArray(fields.charging)) {
286
+ continue;
287
+ }
288
+ await t.test(`${mode}: ${label}`, async () => {
289
+ Object.assign(state, { charging: true, charge: 42 });
290
+ const before = updates.length;
291
+ const payload = { id: 'a00005', ...fields };
292
+ const query = new URLSearchParams(payload).toString();
293
+ const options = mode === 'query'
294
+ ? { headers: { 'Use-Query-Params': 'true' } }
295
+ : mode === 'JSON'
296
+ ? { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }
297
+ : { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: query };
298
+ const response = await fetch(`${base}${mode === 'query' ? `?${query}` : ''}`, { method: 'POST', ...options });
299
+ assert.equal(response.status, status, await response.text());
300
+ assert.equal(updates.length, before + (status === 200 ? 1 : 0));
301
+ if (status === 200) {
302
+ assert.deepEqual(updates.at(-1), { id: payload.id, charging: fields.charging, charge: fields.charge });
303
+ assert.deepEqual(state, { charging: true, charge: 42, ...fields });
304
+ }
305
+ else {
306
+ assert.deepEqual(state, { charging: true, charge: 42 });
307
+ }
308
+ });
309
+ }
310
+ }
311
+ });
312
+
313
+
314
+ test('Use-Query-Params headers reject invalid values and select the requested parameter source', async (t) => {
315
+ const webhook = new WebhookServer({ info() {}, error() {}, debug() {} }, 0);
316
+ const updates = [];
317
+ webhook.processRequest = (route, id, types, value, response) => {
318
+ updates.push({ route, id });
319
+ response.sendStatus(200);
320
+ };
321
+ const server = webhook.server.listen(0, '127.0.0.1');
322
+ t.after(() => new Promise((resolve, reject) => server.close(error => error ? reject(error) : resolve())));
323
+ await once(server, 'listening');
324
+ const base = `http://127.0.0.1:${server.address().port}`;
325
+ const routes = ['/humidity', '/temperature', '/obstruction', '/triggeralarm', '/triggerpanic', '/triggersensor', '/chargingstate'];
326
+ for (const route of routes) {
327
+ const payload = { id: 'body-id', value: route === '/humidity' || route === '/temperature' ? 50 : true, charge: 50, charging: true };
328
+ const query = new URLSearchParams({ ...payload, id: 'query-id' });
329
+ for (const header of ['yes', '1', '', ' ', 'true,false', 'tru e']) {
330
+ for (const withBody of [true, false]) {
331
+ await t.test(`${route} rejects header ${JSON.stringify(header)} ${withBody ? 'with' : 'without'} body`, async () => {
332
+ const before = updates.length;
333
+ const response = await fetch(`${base}${route}?${query}`, {
334
+ method: 'POST',
335
+ headers: { 'Content-Type': 'application/json', 'Use-Query-Params': header },
336
+ ...(withBody ? { body: JSON.stringify(payload) } : {}),
337
+ });
338
+ assert.equal(response.status, 400);
339
+ assert.equal(await response.text(), 'Invalid Use-Query-Params header. Value must be true or false');
340
+ assert.equal(updates.length, before);
341
+ });
342
+ }
343
+ }
344
+ for (const header of [undefined, 'true', 'TRUE', 'True', 'false', 'FALSE', 'False', ' \tTrUe\t ', ' \tFaLsE\t ']) {
345
+ for (const name of ['Use-Query-Params', 'use-query-params', 'UsE-QuErY-PaRaMs']) {
346
+ await t.test(`${route} accepts ${name}: ${JSON.stringify(header)}`, async () => {
347
+ const before = updates.length;
348
+ const response = await fetch(`${base}${route}?${query}`, {
349
+ method: 'POST',
350
+ headers: { 'Content-Type': 'application/json', ...(header === undefined ? {} : { [name]: header }) },
351
+ body: JSON.stringify(payload),
352
+ });
353
+ assert.equal(response.status, 200, await response.text());
354
+ assert.equal(updates.length, before + 1);
355
+ assert.deepEqual(updates.at(-1), { route, id: header?.trim().toLowerCase() === 'true' ? 'query-id' : 'body-id' });
356
+ });
357
+ }
358
+ }
359
+ }
360
+ });
361
+
362
+ test('numeric webhook inputs require finite scalar numbers', async (t) => {
363
+ const webhook = new WebhookServer({ info() {}, error() {}, debug() {} }, 0);
364
+ const updates = [];
365
+ webhook.processRequest = (route, id, types, value, response) => {
366
+ updates.push(value);
367
+ response.sendStatus(200);
368
+ };
369
+ const server = webhook.server.listen(0, '127.0.0.1');
370
+ t.after(() => new Promise((resolve, reject) => server.close(error => error ? reject(error) : resolve())));
371
+ await once(server, 'listening');
372
+ const base = `http://127.0.0.1:${server.address().port}`;
373
+ for (const route of ['/humidity', '/temperature', '/chargingstate']) {
374
+ const field = route === '/chargingstate' ? 'charge' : 'value';
375
+ const invalid = [
376
+ null, true, false, [], [0], [50], ['50'], {}, { toString: 1 }, { valueOf: 0 },
377
+ '50', '50.5', '', ' \t ', 'NaN', 'Infinity', '-Infinity', '1e309', '12oops',
378
+ ];
379
+ for (const value of invalid) {
380
+ await t.test(`${route} rejects JSON ${JSON.stringify(value)}`, async () => {
381
+ const before = updates.length;
382
+ const response = await fetch(`${base}${route}`, {
383
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
384
+ body: JSON.stringify({ id: 'a00005', [field]: value, charging: false }),
385
+ });
386
+ assert.equal(response.status, 400);
387
+ assert.match(await response.text(), /Value must be a finite number/);
388
+ assert.equal(updates.length, before);
389
+ });
390
+ }
391
+ for (const mode of ['JSON', 'query', 'form']) {
392
+ // Expected validity is explicit, independent of the implementation's parsing rules.
393
+ const cases = [
394
+ [0, true, true], [75, true, true], [100, true, true],
395
+ [72.5, false, true], [-5.5, false, true], [-1, false, true], [101, false, true],
396
+ ['0', true, true], ['75', true, true], ['100', true, true], ['+75', true, true], ['075', true, true],
397
+ ['-0', true, true], ['75.0', false, true], ['72.5', false, true], ['-5.5', false, true],
398
+ ['.5', false, true], ['5.', false, true], ['+72.5', false, true],
399
+ ['-1', false, true], ['101', false, true],
400
+ ...[' 25 ', '', ' ', 'NaN', 'Infinity', '-Infinity', '1e309', '1e1', '0x10', '0b10', '12oops', 'true', '75\n', '75\r', '75\t', '9'.repeat(400)]
401
+ .map(value => [value, false, false]),
402
+ ];
403
+ for (const [value, percentageValid, numberValid] of cases) {
404
+ await t.test(`${route} ${mode} scalar ${JSON.stringify(value)}`, async () => {
405
+ const before = updates.length;
406
+ const payload = { id: 'a00005', [field]: value };
407
+ const encoded = new URLSearchParams(payload).toString();
408
+ const options = mode === 'query' ? { headers: { 'Use-Query-Params': 'true' } }
409
+ : mode === 'JSON' ? { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }
410
+ : { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: encoded };
411
+ const response = await fetch(`${base}${route}${mode === 'query' ? `?${encoded}` : ''}`, { method: 'POST', ...options });
412
+ const valid = (mode !== 'JSON' || typeof value === 'number') &&
413
+ (route === '/temperature' ? numberValid : percentageValid);
414
+ assert.equal(response.status, valid ? 200 : 400, await response.text());
415
+ assert.equal(updates.length, before + (valid ? 1 : 0));
416
+ if (valid) {
417
+ if (route === '/chargingstate') {
418
+ assert.equal(updates.at(-1).charge, Number(value));
419
+ assert.equal(updates.at(-1).charging, undefined);
420
+ }
421
+ else {
422
+ assert.equal(updates.at(-1), Number(value));
423
+ }
424
+ }
425
+ });
426
+ }
427
+ }
428
+ }
429
+ for (const route of ['/humidity', '/temperature', '/obstruction', '/triggeralarm', '/triggerpanic', '/triggersensor', '/chargingstate']) {
430
+ const fields = route === '/chargingstate' ? ['charge', 'charging'] : ['value'];
431
+ for (const field of fields) {
432
+ const scalar = field === 'charge' || route === '/humidity' || route === '/temperature' ? '50' : 'true';
433
+ for (const mode of ['query', 'form']) {
434
+ const shapes = mode === 'query' ? [`${field}=${scalar}&${field}=${scalar}`]
435
+ : [`${field}=${scalar}&${field}=${scalar}`, `${field}[]=${scalar}`, `${field}[toString]=1`];
436
+ for (const shape of shapes) {
437
+ await t.test(`${route} rejects ${mode} structured ${shape}`, async () => {
438
+ const before = updates.length;
439
+ const encoded = `id=a00005&${shape}`;
440
+ const options = mode === 'query' ? { headers: { 'Use-Query-Params': 'true' } }
441
+ : { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: encoded };
442
+ const response = await fetch(`${base}${route}${mode === 'query' ? `?${encoded}` : ''}`, { method: 'POST', ...options });
443
+ assert.equal(response.status, 400, await response.text());
444
+ assert.equal(updates.length, before);
445
+ });
446
+ }
447
+ }
448
+ }
449
+ }
450
+ });