homebridge-smartthings-oauth 1.0.66 → 1.0.67-beta.0

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.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [1.0.67-beta.0] - Optional SmartThings webhook signature verification
5
+
6
+ > Opt-in hardening for the webhook (tunnel) route. SmartThings already signs every inbound webhook POST with an HTTP Signature (RSA-SHA256 over the request body, using its rotating "Padlock CA" certificate), but the plugin previously did not verify it — any host that could reach the public webhook URL could forge device events. This release adds verification behind a new, **off-by-default** flag, so existing setups are unaffected until they opt in.
7
+
8
+ ### Added
9
+ - **`verifyWebhookSignatures` config option** (default `false`). When enabled, every inbound webhook POST must carry a valid SmartThings HTTP signature, a matching body digest, and a recent `Date` (within ±15 minutes) — otherwise it is rejected with **HTTP 401** before any processing. The signed-header set is required to cover `(request-target)`, `digest`, and `date`, so the digest is genuinely bound to the RSA signature. Only known SmartThings lifecycles (`PING`, `CONFIRMATION`, `INSTALL`, `UPDATE`, `UNINSTALL`, `CONFIGURATION`, `EVENT`) are processed; anything else is dropped with **HTTP 400**. Requires an `https` Server URL — if the Server URL is not https, verification stays disabled (with a logged warning) rather than breaking the webhook. The signing certificate is fetched from `key.smartthings.com` (key id validated to a safe path shape) and cached per key id with a size cap and brief negative caching (keys rotate ~monthly). When the flag is off, webhook handling is unchanged.
10
+
11
+ ### Security
12
+ - **Webhook endpoint hardening** (applies regardless of the flag): the inbound body is now capped (oversized POSTs get **HTTP 413**) to protect the public endpoint from memory exhaustion, and the `CONFIRMATION` lifecycle's outbound call is restricted to `https` URLs with no redirects and a timeout, reducing the server-side request forgery surface.
13
+
4
14
  ## [1.0.66] - Samsung Frame & Tizen TV Control + Laundry/Dishwasher Countdown
5
15
 
6
16
  > Consolidates the `1.0.66-beta.0`–`beta.7` work (see the beta entries below for full detail). Two themes: Samsung **Frame & Tizen TV** control over the local WebSocket (#46), and a working **remaining-time countdown** for Samsung washers, dryers, and dishwashers in Apple Home (#13). Does not include the in-progress air-purifier work (PR #48).
@@ -62,6 +62,13 @@
62
62
  "default": 3000,
63
63
  "description": "Port for webhook server (only used if Server URL is configured)"
64
64
  },
65
+ "verifyWebhookSignatures": {
66
+ "title": "Verify SmartThings Webhook Signatures",
67
+ "type": "boolean",
68
+ "required": false,
69
+ "default": false,
70
+ "description": "When enabled, every inbound webhook POST must carry a valid SmartThings HTTP signature (and a recent timestamp) or it is rejected with HTTP 401. Only applies when an https Server URL is configured; with a non-https URL it stays disabled. Register/confirm your Server URL with SmartThings BEFORE enabling, then confirm real-time updates still work (polling continues either way). Off (default) preserves existing behavior."
71
+ },
65
72
  "GarageDoorMaxPoll": {
66
73
  "title": "Garage Door Max Poll",
67
74
  "type": "integer",
@@ -0,0 +1,45 @@
1
+ import { Logger } from 'homebridge';
2
+ import * as http from 'http';
3
+ export declare class SignatureVerifier {
4
+ private readonly log;
5
+ private readonly certCache;
6
+ private readonly inFlight;
7
+ private readonly negativeCache;
8
+ constructor(log: Logger);
9
+ /**
10
+ * Returns true only if the request carries a valid, fresh SmartThings signature over the
11
+ * given raw body. Logs a specific reason on failure to aid diagnosis of 401s.
12
+ */
13
+ verify(rawBody: Buffer, method: string | undefined, path: string, headers: http.IncomingHttpHeaders): Promise<boolean>;
14
+ /**
15
+ * Parses `Authorization: Signature keyId="...",signature="...",headers="...",algorithm="..."`.
16
+ * Returns null if the scheme is wrong or any required member is missing.
17
+ */
18
+ private parseSignatureHeader;
19
+ /**
20
+ * Confirms base64(sha256(rawBody)) equals the value in the Digest header.
21
+ * Accepts both `SHA256=` and `SHA-256=` prefixes.
22
+ */
23
+ private verifyDigest;
24
+ /**
25
+ * Rejects requests whose Date header is missing, unparseable, or outside the skew tolerance.
26
+ */
27
+ private verifyDateFreshness;
28
+ /**
29
+ * Builds the signing string from the signed header list, verbatim and in order.
30
+ * `(request-target)` => "<method> <path>"; every other token => "<name>: <value>".
31
+ * Returns null if any named header is absent or multi-valued.
32
+ */
33
+ private buildSigningString;
34
+ /**
35
+ * Returns the PEM cert for a keyId, using a per-keyId cache and de-duplicating concurrent
36
+ * fetches. keyId rotation is handled implicitly: a new keyId is simply a new cache key.
37
+ */
38
+ private getCertificate;
39
+ private fetchCertificate;
40
+ private computeExpiry;
41
+ private rsaVerify;
42
+ private pruneExpired;
43
+ private evictIfFull;
44
+ }
45
+ //# sourceMappingURL=signatureVerifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signatureVerifier.d.ts","sourceRoot":"","sources":["../../src/webhook/signatureVerifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AA0C7B,qBAAa,iBAAiB;IAKhB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJhC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAC3D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6C;IACtE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6B;gBAE9B,GAAG,EAAE,MAAM;IAExC;;;OAGG;IACU,MAAM,CACjB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,IAAI,CAAC,mBAAmB,GAChC,OAAO,CAAC,OAAO,CAAC;IAiDnB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAiC5B;;;OAGG;IACH,OAAO,CAAC,YAAY;IAkBpB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAqB3B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;;OAGG;YACW,cAAc;YAoCd,gBAAgB;IAqB9B,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,WAAW;CASpB"}
@@ -0,0 +1,320 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.SignatureVerifier = void 0;
40
+ const crypto = __importStar(require("crypto"));
41
+ const axios_1 = __importDefault(require("axios"));
42
+ /**
43
+ * Verifies the IETF HTTP Signature (draft-cavage) that SmartThings attaches to every
44
+ * inbound webhook POST. SmartThings signs requests with its rotating x.509 "Padlock CA"
45
+ * certificate (signatureType ST_PADLOCK); the public cert is served at
46
+ * `https://key.smartthings.com{keyId}` where keyId comes from the Authorization header.
47
+ *
48
+ * Every code path is total: any malformed input, fetch failure, or crypto error resolves
49
+ * to `false` (=> the caller returns 401). Nothing here throws to the request handler.
50
+ */
51
+ const KEY_HOST = 'https://key.smartthings.com';
52
+ const KEY_FETCH_TIMEOUT_MS = 5000;
53
+ // Hard cap so a cache entry can never outlive this even if validTo parsing misbehaves.
54
+ const CERT_TTL_CAP_MS = 24 * 60 * 60 * 1000;
55
+ // Reject requests whose Date header is outside this window (anti-replay; tolerant of clock skew).
56
+ const DATE_SKEW_TOLERANCE_MS = 15 * 60 * 1000;
57
+ // Bound the cert cache and briefly remember failed fetches so a flood of distinct keyIds
58
+ // can't drive unbounded outbound requests to key.smartthings.com.
59
+ const MAX_CERT_CACHE_ENTRIES = 32;
60
+ const NEGATIVE_CACHE_TTL_MS = 60 * 1000;
61
+ // SmartThings always signs these; require them in the signed set so the digest/date checks
62
+ // are actually bound to the RSA signature rather than self-referential.
63
+ const REQUIRED_SIGNED_HEADERS = ['(request-target)', 'digest', 'date'];
64
+ // keyId is attacker-influenced (it comes from the request header); only allow a safe path shape.
65
+ const KEY_ID_PATTERN = /^\/[A-Za-z0-9._\-/]+$/;
66
+ class SignatureVerifier {
67
+ constructor(log) {
68
+ this.log = log;
69
+ this.certCache = new Map();
70
+ this.inFlight = new Map();
71
+ this.negativeCache = new Map();
72
+ }
73
+ /**
74
+ * Returns true only if the request carries a valid, fresh SmartThings signature over the
75
+ * given raw body. Logs a specific reason on failure to aid diagnosis of 401s.
76
+ */
77
+ async verify(rawBody, method, path, headers) {
78
+ try {
79
+ const parsed = this.parseSignatureHeader(headers['authorization']);
80
+ if (!parsed) {
81
+ this.log.warn('Webhook signature: missing or malformed Authorization signature header');
82
+ return false;
83
+ }
84
+ // The RSA signature only authenticates the headers listed in `headers="..."`. Require the
85
+ // body-/replay-binding headers to be present, else digest/date are checked but not signed.
86
+ const signedSet = parsed.headers.map(h => h.toLowerCase());
87
+ if (!REQUIRED_SIGNED_HEADERS.every(h => signedSet.includes(h))) {
88
+ this.log.warn('Webhook signature: signed header list must include (request-target), digest, and date');
89
+ return false;
90
+ }
91
+ if (!this.verifyDigest(rawBody, headers['digest'])) {
92
+ this.log.warn('Webhook signature: body digest mismatch');
93
+ return false;
94
+ }
95
+ if (!this.verifyDateFreshness(headers['date'])) {
96
+ return false;
97
+ }
98
+ const signingString = this.buildSigningString(parsed.headers, method, path, headers);
99
+ if (signingString === null) {
100
+ this.log.warn('Webhook signature: could not build signing string (a signed header is missing)');
101
+ return false;
102
+ }
103
+ const certPem = await this.getCertificate(parsed.keyId);
104
+ if (!certPem) {
105
+ this.log.warn(`Webhook signature: could not obtain certificate for keyId ${parsed.keyId}`);
106
+ return false;
107
+ }
108
+ if (!this.rsaVerify(signingString, parsed.signature, certPem)) {
109
+ this.log.warn('Webhook signature: RSA signature verification failed');
110
+ return false;
111
+ }
112
+ return true;
113
+ }
114
+ catch (error) {
115
+ this.log.warn('Webhook signature: unexpected error during verification:', error);
116
+ return false;
117
+ }
118
+ }
119
+ /**
120
+ * Parses `Authorization: Signature keyId="...",signature="...",headers="...",algorithm="..."`.
121
+ * Returns null if the scheme is wrong or any required member is missing.
122
+ */
123
+ parseSignatureHeader(authHeader) {
124
+ if (typeof authHeader !== 'string') {
125
+ return null;
126
+ }
127
+ const trimmed = authHeader.trim();
128
+ if (!/^signature\s+/i.test(trimmed)) {
129
+ return null;
130
+ }
131
+ const paramStr = trimmed.replace(/^signature\s+/i, '');
132
+ const params = {};
133
+ const re = /(\w+)\s*=\s*"([^"]*)"/g;
134
+ let match;
135
+ while ((match = re.exec(paramStr)) !== null) {
136
+ params[match[1].toLowerCase()] = match[2];
137
+ }
138
+ const keyId = params['keyid'];
139
+ const signature = params['signature'];
140
+ const headers = params['headers'];
141
+ const algorithm = params['algorithm'];
142
+ if (!keyId || !signature || !headers || !algorithm) {
143
+ return null;
144
+ }
145
+ return {
146
+ keyId,
147
+ signature,
148
+ headers: headers.split(/\s+/).filter(h => h.length > 0),
149
+ algorithm,
150
+ };
151
+ }
152
+ /**
153
+ * Confirms base64(sha256(rawBody)) equals the value in the Digest header.
154
+ * Accepts both `SHA256=` and `SHA-256=` prefixes.
155
+ */
156
+ verifyDigest(rawBody, digestHeader) {
157
+ if (typeof digestHeader !== 'string') {
158
+ return false;
159
+ }
160
+ const m = /^\s*SHA-?256\s*=\s*(.+?)\s*$/i.exec(digestHeader);
161
+ if (!m) {
162
+ return false;
163
+ }
164
+ const expected = m[1];
165
+ const actual = crypto.createHash('sha256').update(rawBody).digest('base64');
166
+ const expectedBuf = Buffer.from(expected);
167
+ const actualBuf = Buffer.from(actual);
168
+ if (expectedBuf.length !== actualBuf.length) {
169
+ return false;
170
+ }
171
+ return crypto.timingSafeEqual(expectedBuf, actualBuf);
172
+ }
173
+ /**
174
+ * Rejects requests whose Date header is missing, unparseable, or outside the skew tolerance.
175
+ */
176
+ verifyDateFreshness(dateHeader) {
177
+ if (typeof dateHeader !== 'string') {
178
+ this.log.warn('Webhook signature: missing Date header');
179
+ return false;
180
+ }
181
+ const dateMs = Date.parse(dateHeader);
182
+ if (Number.isNaN(dateMs)) {
183
+ this.log.warn('Webhook signature: unparseable Date header');
184
+ return false;
185
+ }
186
+ const skew = Math.abs(Date.now() - dateMs);
187
+ if (skew > DATE_SKEW_TOLERANCE_MS) {
188
+ this.log.warn(`Webhook signature: Date header outside ${DATE_SKEW_TOLERANCE_MS / 60000}-minute window ` +
189
+ `(skew ${Math.round(skew / 1000)}s) - rejecting as stale/replayed. Check the host clock if this is unexpected.`);
190
+ return false;
191
+ }
192
+ return true;
193
+ }
194
+ /**
195
+ * Builds the signing string from the signed header list, verbatim and in order.
196
+ * `(request-target)` => "<method> <path>"; every other token => "<name>: <value>".
197
+ * Returns null if any named header is absent or multi-valued.
198
+ */
199
+ buildSigningString(headerList, method, path, headers) {
200
+ const lines = [];
201
+ for (const name of headerList) {
202
+ if (name === '(request-target)') {
203
+ lines.push(`(request-target): ${(method || '').toLowerCase()} ${path}`);
204
+ continue;
205
+ }
206
+ const value = headers[name];
207
+ if (value === undefined || Array.isArray(value)) {
208
+ return null;
209
+ }
210
+ lines.push(`${name}: ${value}`);
211
+ }
212
+ return lines.join('\n');
213
+ }
214
+ /**
215
+ * Returns the PEM cert for a keyId, using a per-keyId cache and de-duplicating concurrent
216
+ * fetches. keyId rotation is handled implicitly: a new keyId is simply a new cache key.
217
+ */
218
+ async getCertificate(keyId) {
219
+ this.pruneExpired();
220
+ const cached = this.certCache.get(keyId);
221
+ if (cached && Date.now() < cached.expiresAt) {
222
+ return cached.pem;
223
+ }
224
+ const negativeUntil = this.negativeCache.get(keyId);
225
+ if (negativeUntil !== undefined && Date.now() < negativeUntil) {
226
+ return null;
227
+ }
228
+ const existing = this.inFlight.get(keyId);
229
+ if (existing) {
230
+ return existing;
231
+ }
232
+ const fetchPromise = this.fetchCertificate(keyId)
233
+ .then(pem => {
234
+ if (pem) {
235
+ this.evictIfFull();
236
+ this.certCache.set(keyId, { pem, expiresAt: this.computeExpiry(pem) });
237
+ }
238
+ else {
239
+ this.negativeCache.set(keyId, Date.now() + NEGATIVE_CACHE_TTL_MS);
240
+ }
241
+ return pem;
242
+ })
243
+ .finally(() => {
244
+ this.inFlight.delete(keyId);
245
+ });
246
+ this.inFlight.set(keyId, fetchPromise);
247
+ return fetchPromise;
248
+ }
249
+ async fetchCertificate(keyId) {
250
+ // Defend against keyId injecting an absolute URL / different host or scheme, or a flood of
251
+ // distinct malformed keyIds. Only a plain key-path shape is allowed.
252
+ if (!KEY_ID_PATTERN.test(keyId)) {
253
+ this.log.warn(`Webhook signature: refusing to fetch certificate for malformed keyId ${keyId}`);
254
+ return null;
255
+ }
256
+ try {
257
+ const resp = await axios_1.default.get(`${KEY_HOST}${keyId}`, {
258
+ timeout: KEY_FETCH_TIMEOUT_MS,
259
+ responseType: 'text',
260
+ maxRedirects: 0,
261
+ validateStatus: status => status === 200,
262
+ });
263
+ return typeof resp.data === 'string' ? resp.data : String(resp.data);
264
+ }
265
+ catch (error) {
266
+ this.log.warn(`Webhook signature: failed to fetch certificate ${keyId}:`, error instanceof Error ? error.message : error);
267
+ return null;
268
+ }
269
+ }
270
+ computeExpiry(pem) {
271
+ const cap = Date.now() + CERT_TTL_CAP_MS;
272
+ try {
273
+ const validTo = Date.parse(new crypto.X509Certificate(pem).validTo);
274
+ if (!Number.isNaN(validTo)) {
275
+ return Math.min(validTo, cap);
276
+ }
277
+ }
278
+ catch (_a) {
279
+ // Fall through to the hard cap if the cert can't be parsed for an expiry.
280
+ }
281
+ return cap;
282
+ }
283
+ rsaVerify(signingString, signatureB64, certPem) {
284
+ try {
285
+ return crypto
286
+ .createVerify('RSA-SHA256')
287
+ .update(signingString)
288
+ .verify(certPem, signatureB64, 'base64');
289
+ }
290
+ catch (error) {
291
+ this.log.debug('Webhook signature: crypto verify threw:', error);
292
+ return false;
293
+ }
294
+ }
295
+ pruneExpired() {
296
+ const now = Date.now();
297
+ for (const [keyId, entry] of this.certCache) {
298
+ if (now >= entry.expiresAt) {
299
+ this.certCache.delete(keyId);
300
+ }
301
+ }
302
+ for (const [keyId, until] of this.negativeCache) {
303
+ if (now >= until) {
304
+ this.negativeCache.delete(keyId);
305
+ }
306
+ }
307
+ }
308
+ // Bound cache growth: if at capacity, drop the oldest entry (Map preserves insertion order).
309
+ evictIfFull() {
310
+ while (this.certCache.size >= MAX_CERT_CACHE_ENTRIES) {
311
+ const oldest = this.certCache.keys().next().value;
312
+ if (oldest === undefined) {
313
+ break;
314
+ }
315
+ this.certCache.delete(oldest);
316
+ }
317
+ }
318
+ }
319
+ exports.SignatureVerifier = SignatureVerifier;
320
+ //# sourceMappingURL=signatureVerifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signatureVerifier.js","sourceRoot":"","sources":["../../src/webhook/signatureVerifier.ts"],"names":[],"mappings":"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"}
@@ -9,11 +9,15 @@ export declare class WebhookServer {
9
9
  private eventHandlers;
10
10
  private authHandler;
11
11
  private isRunning;
12
+ private verifyEnabled;
13
+ private signatureVerifier;
12
14
  constructor(platform: IKHomeBridgeHomebridgePlatform, log: Logger);
13
15
  private startServer;
14
16
  setAuthHandler(auth: SmartThingsAuth): void;
15
17
  private handleOAuthCallback;
16
18
  private handleIncomingPost;
19
+ private handleLegacyPost;
20
+ private handleVerifiedPost;
17
21
  private handleSmartThingsLifecycle;
18
22
  private handlePing;
19
23
  private handleConfirmation;
@@ -1 +1 @@
1
- {"version":3,"file":"webhookServer.d.ts","sourceRoot":"","sources":["../../src/webhook/webhookServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGpC,OAAO,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,qBAAa,aAAa;IAOtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAPtB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,SAAS,CAAS;gBAGP,QAAQ,EAAE,8BAA8B,EACxC,GAAG,EAAE,MAAM;IAa9B,OAAO,CAAC,WAAW;IAgCZ,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;YAIpC,mBAAmB;YAanB,kBAAkB;IAmDhC,OAAO,CAAC,0BAA0B;IAgClC,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,kBAAkB;IAsB1B,OAAO,CAAC,oBAAoB;IAqC5B,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,qBAAqB;IAwBtB,eAAe,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI;IAIlE,OAAO,CAAC,mBAAmB;IAUpB,IAAI,IAAI,IAAI;IAOZ,eAAe,IAAI,OAAO;CAGlC"}
1
+ {"version":3,"file":"webhookServer.d.ts","sourceRoot":"","sources":["../../src/webhook/webhookServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGpC,OAAO,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AASnD,qBAAa,aAAa;IAStB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG;IATtB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,iBAAiB,CAAkC;gBAGxC,QAAQ,EAAE,8BAA8B,EACxC,GAAG,EAAE,MAAM;IAyB9B,OAAO,CAAC,WAAW;IAgCZ,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;YAIpC,mBAAmB;YAanB,kBAAkB;IAkDhC,OAAO,CAAC,gBAAgB;YAwCV,kBAAkB;IAgChC,OAAO,CAAC,0BAA0B;IAgClC,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,kBAAkB;IA4B1B,OAAO,CAAC,oBAAoB;IAqC5B,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,qBAAqB;IAwBtB,eAAe,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI;IAIlE,OAAO,CAAC,mBAAmB;IAUpB,IAAI,IAAI,IAAI;IAOZ,eAAe,IAAI,OAAO;CAGlC"}
@@ -39,7 +39,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.WebhookServer = void 0;
40
40
  const http = __importStar(require("http"));
41
41
  const url = __importStar(require("url"));
42
+ const signatureVerifier_1 = require("./signatureVerifier");
42
43
  const axios_1 = __importDefault(require("axios"));
44
+ // Lifecycles we process when signature verification is enabled. Anything else is dropped (400).
45
+ const KNOWN_LIFECYCLES = ['PING', 'CONFIRMATION', 'INSTALL', 'UPDATE', 'UNINSTALL', 'CONFIGURATION', 'EVENT'];
46
+ // Cap the inbound body on the public webhook endpoint. SmartThings lifecycle payloads are well under 1 KB.
47
+ const MAX_BODY_BYTES = 1024 * 1024;
43
48
  class WebhookServer {
44
49
  constructor(platform, log) {
45
50
  this.platform = platform;
@@ -48,6 +53,21 @@ class WebhookServer {
48
53
  this.eventHandlers = [];
49
54
  this.authHandler = null;
50
55
  this.isRunning = false;
56
+ this.verifyEnabled = false;
57
+ this.signatureVerifier = null;
58
+ // Opt-in HTTP signature verification of inbound SmartThings webhooks.
59
+ if (this.platform.config.verifyWebhookSignatures === true) {
60
+ const serverUrl = (this.platform.config.server_url || '').trim();
61
+ if (serverUrl.toLowerCase().startsWith('https://')) {
62
+ this.verifyEnabled = true;
63
+ this.signatureVerifier = new signatureVerifier_1.SignatureVerifier(this.log);
64
+ this.log.info('Webhook signature verification is ENABLED - unsigned/invalid requests will be rejected with 401');
65
+ }
66
+ else {
67
+ this.log.error('verifyWebhookSignatures is enabled but Server URL is not https. ' +
68
+ 'Signature verification is DISABLED for this run. Set an https Server URL to enable it.');
69
+ }
70
+ }
51
71
  // Only start the webhook server if server_url is configured
52
72
  // This is needed for both OAuth callback (traditional flow) and device events
53
73
  if (this.platform.config.server_url && this.platform.config.server_url.trim() !== '') {
@@ -107,46 +127,43 @@ class WebhookServer {
107
127
  }
108
128
  async handleIncomingPost(req, res) {
109
129
  try {
110
- let body = '';
130
+ // Accumulate as Buffer so signature verification can hash the exact received bytes.
131
+ const chunks = [];
132
+ let totalBytes = 0;
133
+ let aborted = false;
111
134
  req.on('data', chunk => {
112
- body += chunk.toString();
135
+ if (aborted) {
136
+ return;
137
+ }
138
+ const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
139
+ totalBytes += buf.length;
140
+ if (totalBytes > MAX_BODY_BYTES) {
141
+ // Guard a public endpoint against memory exhaustion. SmartThings payloads are tiny.
142
+ aborted = true;
143
+ this.log.warn('Rejected webhook POST on / - request body exceeds size limit (413)');
144
+ res.writeHead(413);
145
+ res.end();
146
+ req.destroy();
147
+ return;
148
+ }
149
+ chunks.push(buf);
113
150
  });
114
151
  req.on('end', () => {
115
- // Empty POSTs (tunnel/SmartThings health checks) must be acked, not 400'd —
116
- // a 400 can be treated by SmartThings as a failed lifecycle delivery.
117
- if (body.trim() === '') {
118
- this.log.debug('Received empty POST body on /, acknowledging');
119
- res.writeHead(200);
120
- res.end();
152
+ if (aborted) {
121
153
  return;
122
154
  }
123
- try {
124
- const parsed = JSON.parse(body);
125
- // Detect SmartThings lifecycle format
126
- // SmartApps use "lifecycle", API_ONLY/Connected Service apps use "messageType"
127
- const lifecycleType = parsed.lifecycle || parsed.messageType;
128
- if (lifecycleType) {
129
- parsed.lifecycle = lifecycleType; // Normalize to "lifecycle" for handler
130
- this.handleSmartThingsLifecycle(parsed, res);
131
- }
132
- else if (parsed.deviceId && parsed.capability) {
133
- // Legacy direct ShortEvent format (for compatibility)
134
- this.notifyEventHandlers(parsed);
135
- res.writeHead(200);
136
- res.end();
137
- }
138
- else {
139
- this.log.debug('Received unknown POST format on /, ignoring');
140
- res.writeHead(200);
141
- res.end();
142
- }
155
+ const rawBody = Buffer.concat(chunks);
156
+ if (this.verifyEnabled) {
157
+ this.handleVerifiedPost(rawBody, req, res).catch(error => {
158
+ this.log.error('Error handling verified webhook POST:', error);
159
+ if (!res.writableEnded) {
160
+ res.writeHead(500);
161
+ res.end();
162
+ }
163
+ });
143
164
  }
144
- catch (error) {
145
- // Malformed body — ack with 200 so SmartThings doesn't mark a lifecycle
146
- // delivery as failed; log for visibility.
147
- this.log.warn('Received unparseable POST body on /, acknowledging:', error);
148
- res.writeHead(200);
149
- res.end();
165
+ else {
166
+ this.handleLegacyPost(rawBody.toString(), res);
150
167
  }
151
168
  });
152
169
  }
@@ -156,6 +173,79 @@ class WebhookServer {
156
173
  res.end();
157
174
  }
158
175
  }
176
+ // Unauthenticated path (default). Behavior is unchanged from prior releases: every
177
+ // non-error case acks with 200 so SmartThings never marks a delivery as failed.
178
+ handleLegacyPost(body, res) {
179
+ // Empty POSTs (tunnel/SmartThings health checks) must be acked, not 400'd —
180
+ // a 400 can be treated by SmartThings as a failed lifecycle delivery.
181
+ if (body.trim() === '') {
182
+ this.log.debug('Received empty POST body on /, acknowledging');
183
+ res.writeHead(200);
184
+ res.end();
185
+ return;
186
+ }
187
+ try {
188
+ const parsed = JSON.parse(body);
189
+ // Detect SmartThings lifecycle format
190
+ // SmartApps use "lifecycle", API_ONLY/Connected Service apps use "messageType"
191
+ const lifecycleType = parsed.lifecycle || parsed.messageType;
192
+ if (lifecycleType) {
193
+ parsed.lifecycle = lifecycleType; // Normalize to "lifecycle" for handler
194
+ this.handleSmartThingsLifecycle(parsed, res);
195
+ }
196
+ else if (parsed.deviceId && parsed.capability) {
197
+ // Legacy direct ShortEvent format (for compatibility)
198
+ this.notifyEventHandlers(parsed);
199
+ res.writeHead(200);
200
+ res.end();
201
+ }
202
+ else {
203
+ this.log.debug('Received unknown POST format on /, ignoring');
204
+ res.writeHead(200);
205
+ res.end();
206
+ }
207
+ }
208
+ catch (error) {
209
+ // Malformed body — ack with 200 so SmartThings doesn't mark a lifecycle
210
+ // delivery as failed; log for visibility.
211
+ this.log.warn('Received unparseable POST body on /, acknowledging:', error);
212
+ res.writeHead(200);
213
+ res.end();
214
+ }
215
+ }
216
+ // Verified path (verifyWebhookSignatures enabled). Rejects anything without a valid
217
+ // SmartThings HTTP signature with 401, and only dispatches known lifecycles.
218
+ async handleVerifiedPost(rawBody, req, res) {
219
+ const path = url.parse(req.url || '/').pathname || '/';
220
+ const ok = await this.signatureVerifier.verify(rawBody, req.method, path, req.headers);
221
+ if (!ok) {
222
+ this.log.warn('Rejected webhook POST on / - HTTP signature verification failed (401)');
223
+ res.writeHead(401, { 'Content-Type': 'text/plain' });
224
+ res.end('Unauthorized');
225
+ return;
226
+ }
227
+ let parsed;
228
+ try {
229
+ parsed = JSON.parse(rawBody.toString());
230
+ }
231
+ catch (error) {
232
+ // The request was signed by SmartThings, so an unparseable body is anomalous - drop it.
233
+ this.log.warn('Dropping signed webhook POST with unparseable body (400):', error);
234
+ res.writeHead(400);
235
+ res.end();
236
+ return;
237
+ }
238
+ const lifecycleType = parsed.lifecycle || parsed.messageType;
239
+ if (lifecycleType && KNOWN_LIFECYCLES.includes(lifecycleType)) {
240
+ parsed.lifecycle = lifecycleType; // Normalize to "lifecycle" for handler
241
+ this.handleSmartThingsLifecycle(parsed, res);
242
+ }
243
+ else {
244
+ this.log.warn(`Dropping webhook POST with non-allowlisted lifecycle (lifecycle=${lifecycleType !== null && lifecycleType !== void 0 ? lifecycleType : 'none'}) (400)`);
245
+ res.writeHead(400);
246
+ res.end();
247
+ }
248
+ }
159
249
  handleSmartThingsLifecycle(body, res) {
160
250
  const lifecycle = body.lifecycle;
161
251
  this.log.debug(`Received SmartThings lifecycle event: ${lifecycle}`);
@@ -206,13 +296,20 @@ class WebhookServer {
206
296
  const confirmationUrl = (_a = body.confirmationData) === null || _a === void 0 ? void 0 : _a.confirmationUrl;
207
297
  if (confirmationUrl) {
208
298
  this.log.info('Received SmartThings CONFIRMATION - hitting confirmation URL');
209
- axios_1.default.get(confirmationUrl)
210
- .then(() => {
211
- this.log.info('Successfully confirmed SmartThings app registration');
212
- })
213
- .catch((error) => {
214
- this.log.error('Failed to confirm SmartThings app registration:', error);
215
- });
299
+ // Only call https URLs, never follow redirects, and time out — limits SSRF if a forged
300
+ // CONFIRMATION reaches this handler (always possible when verification is disabled).
301
+ if (typeof confirmationUrl === 'string' && /^https:\/\//i.test(confirmationUrl)) {
302
+ axios_1.default.get(confirmationUrl, { timeout: 5000, maxRedirects: 0 })
303
+ .then(() => {
304
+ this.log.info('Successfully confirmed SmartThings app registration');
305
+ })
306
+ .catch((error) => {
307
+ this.log.error('Failed to confirm SmartThings app registration:', error);
308
+ });
309
+ }
310
+ else {
311
+ this.log.error('Refusing to call non-https confirmation URL from CONFIRMATION lifecycle');
312
+ }
216
313
  const serverUrl = this.platform.config.server_url || '';
217
314
  res.writeHead(200, { 'Content-Type': 'application/json' });
218
315
  res.end(JSON.stringify({ targetUrl: serverUrl }));
@@ -1 +1 @@
1
- {"version":3,"file":"webhookServer.js","sourceRoot":"","sources":["../../src/webhook/webhookServer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webhookServer.js","sourceRoot":"","sources":["../../src/webhook/webhookServer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,2CAA6B;AAC7B,yCAA2B;AAI3B,2DAAwD;AACxD,kDAA0B;AAE1B,gGAAgG;AAChG,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;AAC9G,2GAA2G;AAC3G,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnC,MAAa,aAAa;IAQxB,YACmB,QAAwC,EACxC,GAAW;QADX,aAAQ,GAAR,QAAQ,CAAgC;QACxC,QAAG,GAAH,GAAG,CAAQ;QATtB,WAAM,GAAuB,IAAI,CAAC;QAClC,kBAAa,GAAoC,EAAE,CAAC;QACpD,gBAAW,GAA2B,IAAI,CAAC;QAC3C,cAAS,GAAG,KAAK,CAAC;QAClB,kBAAa,GAAG,KAAK,CAAC;QACtB,sBAAiB,GAA6B,IAAI,CAAC;QAMzD,sEAAsE;QACtE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,uBAAuB,KAAK,IAAI,EAAE,CAAC;YAC1D,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACjE,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBACnD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC1B,IAAI,CAAC,iBAAiB,GAAG,IAAI,qCAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACzD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,iGAAiG,CAAC,CAAC;YACnH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,kEAAkE;oBAC/E,wFAAwF,CAAC,CAAC;YAC9F,CAAC;QACH,CAAC;QACD,4DAA4D;QAC5D,8EAA8E;QAC9E,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACrF,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,yDAAyD;gBACtE,+DAA+D;gBAC/D,6BAA6B,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAEO,WAAW;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,IAAI,IAAI,CAAC;QAEvD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC3C,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAI,EAAE,IAAI,CAAC,CAAC;YAE5C,IAAI,SAAS,CAAC,QAAQ,KAAK,iBAAiB,EAAE,CAAC;gBAC7C,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrB,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBACjD,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;oBACzE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;oBACpD,GAAG,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;gBAC3D,CAAC;YACH,CAAC;iBAAM,IAAI,SAAS,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;gBACtC,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YAC5B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAC;YAC1D,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAChC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,cAAc,CAAC,IAAqB;QACzC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC1B,CAAC;IAEO,KAAK,CAAC,mBAAmB,CAAC,KAAU,EAAE,GAAwB;QACpE,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAChD,CAAC;YACD,MAAM,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;YAC/C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,GAAyB,EAAE,GAAwB;QAClF,IAAI,CAAC;YACH,oFAAoF;YACpF,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,IAAI,UAAU,GAAG,CAAC,CAAC;YACnB,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;gBACrB,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;gBACD,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChE,UAAU,IAAI,GAAG,CAAC,MAAM,CAAC;gBACzB,IAAI,UAAU,GAAG,cAAc,EAAE,CAAC;oBAChC,oFAAoF;oBACpF,OAAO,GAAG,IAAI,CAAC;oBACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;oBACpF,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;oBACnB,GAAG,CAAC,GAAG,EAAE,CAAC;oBACV,GAAG,CAAC,OAAO,EAAE,CAAC;oBACd,OAAO;gBACT,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;gBACD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACtC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;oBACvB,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;wBACvD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;wBAC/D,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;4BACvB,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;4BACnB,GAAG,CAAC,GAAG,EAAE,CAAC;wBACZ,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;YACvD,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,mFAAmF;IACnF,gFAAgF;IACxE,gBAAgB,CAAC,IAAY,EAAE,GAAwB;QAC7D,4EAA4E;QAC5E,sEAAsE;QACtE,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;YAC/D,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEhC,sCAAsC;YACtC,+EAA+E;YAC/E,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,WAAW,CAAC;YAC7D,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,CAAC,SAAS,GAAG,aAAa,CAAC,CAAC,uCAAuC;gBACzE,IAAI,CAAC,0BAA0B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC/C,CAAC;iBAAM,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBAChD,sDAAsD;gBACtD,IAAI,CAAC,mBAAmB,CAAC,MAAoB,CAAC,CAAC;gBAC/C,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;gBAC9D,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,wEAAwE;YACxE,0CAA0C;YAC1C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,qDAAqD,EAAE,KAAK,CAAC,CAAC;YAC5E,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,oFAAoF;IACpF,6EAA6E;IACrE,KAAK,CAAC,kBAAkB,CAAC,OAAe,EAAE,GAAyB,EAAE,GAAwB;QACnG,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,IAAI,GAAG,CAAC;QACvD,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,iBAAkB,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACxF,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAC;YACvF,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IAAI,MAAW,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,wFAAwF;YACxF,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,2DAA2D,EAAE,KAAK,CAAC,CAAC;YAClF,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,WAAW,CAAC;QAC7D,IAAI,aAAa,IAAI,gBAAgB,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YAC9D,MAAM,CAAC,SAAS,GAAG,aAAa,CAAC,CAAC,uCAAuC;YACzE,IAAI,CAAC,0BAA0B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mEAAmE,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,MAAM,SAAS,CAAC,CAAC;YACnH,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,0BAA0B,CAAC,IAAS,EAAE,GAAwB;QACpE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,yCAAyC,SAAS,EAAE,CAAC,CAAC;QAErE,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,MAAM;gBACT,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBAC3B,MAAM;YACR,KAAK,cAAc;gBACjB,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBACnC,MAAM;YACR,KAAK,OAAO;gBACV,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBACrC,MAAM;YACR,KAAK,SAAS;gBACZ,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;gBAC9B,MAAM;YACR,KAAK,eAAe,CAAC;YACrB,KAAK,QAAQ,CAAC;YACd,KAAK,WAAW;gBACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,SAAS,kCAAkC,CAAC,CAAC;gBACxE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC5B,MAAM;YACR;gBACE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,qCAAqC,SAAS,kBAAkB,CAAC,CAAC;gBACjF,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC5B,MAAM;QACV,CAAC;IACH,CAAC;IAEO,UAAU,CAAC,IAAS,EAAE,GAAwB;;QACpD,MAAM,SAAS,GAAG,MAAA,IAAI,CAAC,QAAQ,0CAAE,SAAS,CAAC;QAC3C,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;YAClE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,iGAAiG;YACjG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;YAChF,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAEO,kBAAkB,CAAC,IAAS,EAAE,GAAwB;;QAC5D,MAAM,eAAe,GAAG,MAAA,IAAI,CAAC,gBAAgB,0CAAE,eAAe,CAAC;QAC/D,IAAI,eAAe,EAAE,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;YAC9E,uFAAuF;YACvF,qFAAqF;YACrF,IAAI,OAAO,eAAe,KAAK,QAAQ,IAAI,cAAc,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;gBAChF,eAAK,CAAC,GAAG,CAAC,eAAe,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;qBAC3D,IAAI,CAAC,GAAG,EAAE;oBACT,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;gBACvE,CAAC,CAAC;qBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBACf,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,iDAAiD,EAAE,KAAK,CAAC,CAAC;gBAC3E,CAAC,CAAC,CAAC;YACP,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;YAC5F,CAAC;YACD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;YACxD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,oGAAoG;YACpG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;YACzF,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,IAAS,EAAE,GAAwB;QAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAEjC,yEAAyE;QACzE,IAAI,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,YAAY,EAAE,CAAC;YAC5B,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,SAAS,CAAC,YAAY,CAAC;YAC9D,IAAI,cAAc,IAAI,UAAU,EAAE,CAAC;gBACjC,IAAI,CAAC,qBAAqB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;QAED,wBAAwB;QACxB,MAAM,MAAM,GAAG,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,MAAM,CAAC;QACjC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,IAAI,UAAU,GAAG,CAAC,CAAC;YACnB,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;gBAC1B,IAAI,IAAI,CAAC,SAAS,KAAK,cAAc,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBAC1D,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;oBAC5B,MAAM,UAAU,GAAe;wBAC7B,QAAQ,EAAE,EAAE,CAAC,QAAQ;wBACrB,WAAW,EAAE,EAAE,CAAC,WAAW;wBAC3B,UAAU,EAAE,EAAE,CAAC,UAAU;wBACzB,SAAS,EAAE,EAAE,CAAC,SAAS;wBACvB,KAAK,EAAE,EAAE,CAAC,KAAK;qBAChB,CAAC;oBACF,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;oBACnH,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;oBACrC,UAAU,EAAE,CAAC;gBACf,CAAC;YACH,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,UAAU,iDAAiD,CAAC,CAAC;QAC3F,CAAC;QAED,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC7C,CAAC;IAEO,aAAa,CAAC,IAAS,EAAE,GAAwB;;QACvD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;QAE9D,4CAA4C;QAC5C,MAAM,cAAc,GAAG,MAAA,MAAA,IAAI,CAAC,WAAW,0CAAE,YAAY,0CAAE,cAAc,CAAC;QACtE,MAAM,UAAU,GAAG,MAAA,MAAA,IAAI,CAAC,WAAW,0CAAE,YAAY,0CAAE,UAAU,CAAC;QAC9D,IAAI,cAAc,IAAI,UAAU,EAAE,CAAC;YACjC,IAAI,CAAC,qBAAqB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QACzD,CAAC;QAED,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC;IAEO,qBAAqB,CAAC,cAAuB,EAAE,UAAmB;;QACxE,MAAM,YAAY,GAAG,MAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,0CAAE,YAAY,CAAC;QACtD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,YAAY,CAAC,iBAAiB,EAAE,CAAC;QACtD,MAAM,iBAAiB,GAAG,YAAY,CAAC,aAAa,EAAE,CAAC;QAEvD,MAAM,OAAO,GAAQ,EAAE,CAAC;QACxB,IAAI,cAAc,IAAI,cAAc,KAAK,YAAY,EAAE,CAAC;YACtD,OAAO,CAAC,gBAAgB,GAAG,cAAc,CAAC;YAC1C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,iDAAiD,cAAc,EAAE,CAAC,CAAC;QACnF,CAAC;QACD,IAAI,UAAU,IAAI,UAAU,KAAK,iBAAiB,EAAE,CAAC;YACnD,OAAO,CAAC,WAAW,GAAG,UAAU,CAAC;YACjC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,6CAA6C,UAAU,EAAE,CAAC,CAAC;QAC3E,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpC,YAAY,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAEM,eAAe,CAAC,OAAoC;QACzD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAEO,mBAAmB,CAAC,KAAiB;QAC3C,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;YACnC,IAAI,CAAC;gBACH,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;YACnD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,IAAI;QACT,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACpB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACzB,CAAC;IACH,CAAC;IAEM,eAAe;QACpB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AA3XD,sCA2XC"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "private": false,
3
3
  "displayName": "Homebridge Smartthings oAuth Plugin",
4
4
  "name": "homebridge-smartthings-oauth",
5
- "version": "1.0.66",
5
+ "version": "1.0.67-beta.0",
6
6
  "description": "Connects SmartThings devices to Homebridge. Automatically discovers devices.",
7
7
  "license": "Apache-2.0",
8
8
  "repository": {