diff --git a/plugins/alexa/.vscode/settings.json b/plugins/alexa/.vscode/settings.json
index 3a74f5bd0b..964a62559e 100644
--- a/plugins/alexa/.vscode/settings.json
+++ b/plugins/alexa/.vscode/settings.json
@@ -1,4 +1,4 @@
{
- "scrypted.debugHost": "10.10.0.51",
+ "scrypted.debugHost": "scrypted-server",
}
\ No newline at end of file
diff --git a/plugins/alexa/CHANGELOG.md b/plugins/alexa/CHANGELOG.md
new file mode 100644
index 0000000000..db7ff27632
--- /dev/null
+++ b/plugins/alexa/CHANGELOG.md
@@ -0,0 +1,148 @@
+
+Changelog
+
+### 0.3.0
+
+alexa/google-home: additional auth token checks to harden endpoints for cloud sharing
+alexa: removed unneeded packages (#1319)
+alexa: added support for `light`, `outlet`, and `fan` device types (#1318)
+
+
+### 0.2.10
+
+alexa: fix potential response race
+
+
+### 0.2.9
+
+alexa: fix race condition in sendResponse
+
+
+### 0.2.8
+
+alexa: display camera on doorbell press (#1066)
+
+
+### 0.2.7
+
+alexa: added helpful error messages regarding token expiration (#1007)
+
+
+### 0.2.6
+
+alexa: fix doorbells
+
+
+### 0.2.5
+
+alexa: publish w/ storage fix
+
+
+### 0.2.4
+
+alexa: add setting to publish debug events to console (#685)
+
+
+### 0.2.3
+
+webrtc/alexa: add option to disable TURN on peers that already have externally reachable addresses
+
+
+### 0.2.1
+
+alexa: set screen ratio to 720p (#625)
+
+
+### 0.2.0
+
+alexa: refactor code structure (#606)
+
+
+### 0.1.0
+
+alexa: ensure we are talking to the correct API endpoint (#580)
+
+
+### 0.0.20
+
+alexa: provide hint that medium resolution is always used.
+
+
+### 0.0.19
+
+various: minor cleanups
+alexa: added logging around `tokenInfo` resets (#488)
+sdk: rename sdk.version to sdk.serverVersion
+plugins: update tsconfig.json
+alexa: publish beta
+
+
+### 0.0.18
+
+alexa: rethrow login failure error
+added support for type `Garage` and refactored the controller for future support (#479)
+updated install instructions (#478)
+webrtc/alexa: fix race condition with intercoms and track not received yet.
+
+
+### 0.0.17
+
+alexa: close potential security hole if scrypted is exposed to the internet directly (ie, user is not using the cloud plugin against recommendations)
+
+
+### 0.0.16
+
+plugins: remove postinstall
+plugins: add tsconfig.json
+alexa: doorbell motion sensor support
+
+
+### 0.0.15
+
+alexa: fix harmless crash in log
+
+
+### 0.0.14
+
+alexa: fix empty endpoint list
+
+
+### 0.0.13
+
+all: prune package.json
+alexa: fix doorbell syncing
+
+
+### 0.0.12
+
+alexa: publish
+
+
+### 0.0.10
+
+alexa: 2 way audio
+
+
+### 0.0.4
+
+alexa: 2 way audio
+alexa: motion events
+
+
+### 0.0.3
+
+webrtc: refactor
+alexa: use rtc signaling channel
+alexa: publish
+
+
+### 0.0.1
+
+alexa: doorbells
+alexa: sync devices properly
+alexa: add camera/doorbell, fix webrtc to work with amazon reqs
+alexa: initial pass with working cameras
+cloud: stub out alexa
+
+
+
diff --git a/plugins/alexa/package-lock.json b/plugins/alexa/package-lock.json
index 73897acf1c..75b5681305 100644
--- a/plugins/alexa/package-lock.json
+++ b/plugins/alexa/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@scrypted/alexa",
- "version": "0.3.0",
+ "version": "0.3.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@scrypted/alexa",
- "version": "0.3.0",
+ "version": "0.3.1",
"dependencies": {
"axios": "^1.3.4",
"uuid": "^9.0.0"
diff --git a/plugins/alexa/package.json b/plugins/alexa/package.json
index 0cab56cbee..69882940b5 100644
--- a/plugins/alexa/package.json
+++ b/plugins/alexa/package.json
@@ -1,6 +1,6 @@
{
"name": "@scrypted/alexa",
- "version": "0.3.0",
+ "version": "0.3.1",
"scripts": {
"scrypted-setup-project": "scrypted-setup-project",
"prescrypted-setup-project": "scrypted-package-json",
diff --git a/plugins/alexa/src/main.ts b/plugins/alexa/src/main.ts
index 3b905ad56f..7c72913fc8 100644
--- a/plugins/alexa/src/main.ts
+++ b/plugins/alexa/src/main.ts
@@ -47,7 +47,11 @@ class AlexaPlugin extends ScryptedDeviceBase implements HttpRequestHandler, Mixi
onPut(oldValue: boolean, newValue: boolean) {
DEBUG = newValue;
}
- }
+ },
+ pairedUserId: {
+ title: "Pairing Key",
+ description: "The pairing key used to validate requests from Alexa. Clear this key or delete the plugin to allow pairing with a different Alexa login.",
+ },
});
accessToken: Promise;
@@ -608,6 +612,13 @@ class AlexaPlugin extends ScryptedDeviceBase implements HttpRequestHandler, Mixi
// validate this. old tokens will be grandfathered in.
if (getcookieResponse.data.expiry && getcookieResponse.data.clientId !== 'amazon')
throw new Error('client id mismatch');
+ if (!this.storageSettings.values.pairedUserId) {
+ this.storageSettings.values.pairedUserId = getcookieResponse.data.id;
+ }
+ else if (this.storageSettings.values.pairedUserId !== getcookieResponse.data.id) {
+ this.log.a('This plugin is already paired with a different account. Clear the existing key in the plugin settings to pair this plugin with a different account.');
+ throw new Error('user id mismatch');
+ }
this.validAuths.add(authorization);
}
catch (e) {
diff --git a/plugins/google-home/.vscode/settings.json b/plugins/google-home/.vscode/settings.json
index 44d4d203fc..964a62559e 100644
--- a/plugins/google-home/.vscode/settings.json
+++ b/plugins/google-home/.vscode/settings.json
@@ -1,4 +1,4 @@
{
- "scrypted.debugHost": "koushik-ubuntu",
+ "scrypted.debugHost": "scrypted-server",
}
\ No newline at end of file
diff --git a/plugins/google-home/package-lock.json b/plugins/google-home/package-lock.json
index a51ab1fec6..51894042b5 100644
--- a/plugins/google-home/package-lock.json
+++ b/plugins/google-home/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@scrypted/google-home",
- "version": "0.0.56",
+ "version": "0.0.57",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@scrypted/google-home",
- "version": "0.0.56",
+ "version": "0.0.57",
"dependencies": {
"@googleapis/homegraph": "^2.0.0",
"@homebridge/ciao": "^1.1.5",
diff --git a/plugins/google-home/package.json b/plugins/google-home/package.json
index 6e3acb4aa9..da8b10a318 100644
--- a/plugins/google-home/package.json
+++ b/plugins/google-home/package.json
@@ -25,7 +25,8 @@
"interfaces": [
"HttpRequestHandler",
"EngineIOHandler",
- "MixinProvider"
+ "MixinProvider",
+ "Settings"
],
"pluginDependencies": [
"@scrypted/cloud",
@@ -48,5 +49,5 @@
"@types/lodash": "^4.14.168",
"@types/url-parse": "^1.4.3"
},
- "version": "0.0.56"
+ "version": "0.0.57"
}
diff --git a/plugins/google-home/src/main.ts b/plugins/google-home/src/main.ts
index a1c553033a..0e2f69ae2b 100644
--- a/plugins/google-home/src/main.ts
+++ b/plugins/google-home/src/main.ts
@@ -1,5 +1,5 @@
import type { homegraph_v1 } from "@googleapis/homegraph/v1";
-import sdk, { EngineIOHandler, HttpRequest, HttpRequestHandler, HttpResponse, MixinProvider, Refresh, ScryptedDevice, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedInterfaceProperty } from '@scrypted/sdk';
+import sdk, { EngineIOHandler, HttpRequest, HttpRequestHandler, HttpResponse, MixinProvider, Refresh, ScryptedDevice, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedInterfaceProperty, Setting, SettingValue, Settings } from '@scrypted/sdk';
import type { SmartHomeV1DisconnectRequest, SmartHomeV1DisconnectResponse, SmartHomeV1ExecuteRequest, SmartHomeV1ExecuteResponse, SmartHomeV1ExecuteResponseCommands } from 'actions-on-google/dist/service/smarthome/api/v1';
import axios from 'axios';
import { GoogleAuth } from "google-auth-library";
@@ -8,6 +8,7 @@ import throttle from 'lodash/throttle';
import './commands';
import { supportedTypes } from './common';
import './types';
+import { StorageSettings } from '@scrypted/sdk/storage-settings';
import { canAccess } from './commands/camerastream';
import { commandHandlers } from './handlers';
@@ -44,10 +45,36 @@ const googleAuth = new GoogleAuth({
const includeToken = 3;
-class GoogleHome extends ScryptedDeviceBase implements HttpRequestHandler, EngineIOHandler, MixinProvider {
- linkTracker = localStorage.getItem('linkTracker');
- agentUserId = localStorage.getItem('agentUserId');
- localAuthorization = localStorage.getItem('localAuthorization');
+class GoogleHome extends ScryptedDeviceBase implements HttpRequestHandler, EngineIOHandler, MixinProvider, Settings {
+ storageSettings = new StorageSettings(this, {
+ // the tracker tracks whether this device has been reported in a sync request payload.
+ // this is because reporting too many devices in the initial sync fails upstream at google.
+ linkTracker: {
+ hide: true,
+ persistedDefaultValue: Math.random().toString(),
+ },
+ agentUserId: {
+ hide: true,
+ persistedDefaultValue: uuidv4(),
+ },
+ localAuthorization: {
+ hide: true,
+ persistedDefaultValue: uuidv4(),
+ },
+ pairedUserId: {
+ title: "Pairing Key",
+ description: "The pairing key used to validate requests from Google Home. Clear this key or delete the plugin to allow pairing with a different Google Home login.",
+ },
+ });
+ get linkTracker() {
+ return this.storageSettings.values.linkTracker;
+ }
+ get agentUserId() {
+ return this.storageSettings.values.agentUserId;
+ }
+ get localAuthorization() {
+ return this.storageSettings.values.localAuthorization;
+ }
reportQueue = new Set();
reportStateThrottled = throttle(() => this.reportState(), 2000);
throttleSync = throttle(() => this.requestSync(), 15000, {
@@ -71,23 +98,6 @@ class GoogleHome extends ScryptedDeviceBase implements HttpRequestHandler, Engin
this.googleAuthClient = googleAuth.fromJSON(this.jwt);
}
- // the tracker tracks whether this device has been reported in a sync request payload.
- // this is because reporting too many devices in the initial sync fails upstream at google.
- if (!this.linkTracker) {
- this.linkTracker = Math.random().toString();
- localStorage.setItem('linkTracker', this.linkTracker);
- }
-
- if (!this.agentUserId) {
- this.agentUserId = uuidv4();
- localStorage.setItem('agentUserId', this.agentUserId);
- }
-
- if (!this.localAuthorization) {
- this.localAuthorization = uuidv4();
- localStorage.setItem('localAuthorization', this.localAuthorization);
- }
-
try {
this.defaultIncluded = JSON.parse(localStorage.getItem('defaultIncluded'));
}
@@ -150,6 +160,14 @@ class GoogleHome extends ScryptedDeviceBase implements HttpRequestHandler, Engin
});
}
+ getSettings(): Promise {
+ return this.storageSettings.getSettings();
+ }
+
+ putSetting(key: string, value: SettingValue): Promise {
+ return this.storageSettings.putSetting(key, value);
+ }
+
async isSyncable(device: ScryptedDevice): Promise {
const plugins = await this.plugins;
const mixins = (device.mixins || []).slice();
@@ -528,6 +546,13 @@ class GoogleHome extends ScryptedDeviceBase implements HttpRequestHandler, Engin
// validate this. old tokens will be grandfathered in.
if (getcookieResponse.data.expiry && getcookieResponse.data.clientId !== 'google')
throw new Error('client id mismatch');
+ if (!this.storageSettings.values.pairedUserId) {
+ this.storageSettings.values.pairedUserId = getcookieResponse.data.id;
+ }
+ else if (this.storageSettings.values.pairedUserId !== getcookieResponse.data.id) {
+ this.log.a('This plugin is already paired with a different account. Clear the existing key in the plugin settings to pair this plugin with a different account.');
+ throw new Error('user id mismatch');
+ }
this.validAuths.add(authorization);
}
catch (e) {
diff --git a/plugins/google-home/tsconfig.json b/plugins/google-home/tsconfig.json
index 34a847ad82..ba9b4d395b 100644
--- a/plugins/google-home/tsconfig.json
+++ b/plugins/google-home/tsconfig.json
@@ -1,6 +1,6 @@
{
"compilerOptions": {
- "module": "commonjs",
+ "module": "Node16",
"target": "ES2021",
"resolveJsonModule": true,
"moduleResolution": "Node16",