diff --git a/package.json b/package.json
index 59c321dc97..583d05fc24 100644
--- a/package.json
+++ b/package.json
@@ -111,7 +111,7 @@
"fuse.js": "7.0.0",
"google-timezones-json": "1.2.0",
"hls.js": "patch:hls.js@npm%3A1.5.7#~/.yarn/patches/hls.js-npm-1.5.7-f5bbd3d060.patch",
- "home-assistant-js-websocket": "9.2.1",
+ "home-assistant-js-websocket": "9.3.0",
"idb-keyval": "6.2.1",
"intl-messageformat": "10.5.11",
"js-yaml": "4.1.0",
diff --git a/src/data/cloud.ts b/src/data/cloud.ts
index 5db22590c4..e3d62b513b 100644
--- a/src/data/cloud.ts
+++ b/src/data/cloud.ts
@@ -1,6 +1,8 @@
import { EntityFilter } from "../common/entity/entity_filter";
import { HomeAssistant } from "../types";
+type StrictConnectionMode = "disabled" | "guard_page" | "drop_connection";
+
interface CloudStatusNotLoggedIn {
logged_in: false;
cloud: "disconnected" | "connecting" | "connected";
@@ -19,6 +21,7 @@ export interface CloudPreferences {
alexa_enabled: boolean;
remote_enabled: boolean;
remote_allow_remote_enable: boolean;
+ strict_connection: StrictConnectionMode;
google_secure_devices_pin: string | undefined;
cloudhooks: { [webhookId: string]: CloudWebhook };
alexa_report_state: boolean;
@@ -141,6 +144,7 @@ export const updateCloudPref = (
google_secure_devices_pin?: CloudPreferences["google_secure_devices_pin"];
tts_default_voice?: CloudPreferences["tts_default_voice"];
remote_allow_remote_enable?: CloudPreferences["remote_allow_remote_enable"];
+ strict_connection?: CloudPreferences["strict_connection"];
}
) =>
hass.callWS({
diff --git a/src/panels/config/cloud/account/cloud-remote-pref.ts b/src/panels/config/cloud/account/cloud-remote-pref.ts
index cd9d509f81..508ac04f22 100644
--- a/src/panels/config/cloud/account/cloud-remote-pref.ts
+++ b/src/panels/config/cloud/account/cloud-remote-pref.ts
@@ -21,6 +21,7 @@ import {
import type { HomeAssistant } from "../../../../types";
import { showToast } from "../../../../util/toast";
import { showCloudCertificateDialog } from "../dialog-cloud-certificate/show-dialog-cloud-certificate";
+import { showAlertDialog } from "../../../lovelace/custom-card-helpers";
@customElement("cloud-remote-pref")
export class CloudRemotePref extends LitElement {
@@ -33,7 +34,7 @@ export class CloudRemotePref extends LitElement {
return nothing;
}
- const { remote_enabled, remote_allow_remote_enable } =
+ const { remote_enabled, remote_allow_remote_enable, strict_connection } =
this.cloudStatus.prefs;
const {
@@ -153,6 +154,61 @@ export class CloudRemotePref extends LitElement {
@change=${this._toggleAllowRemoteEnabledChanged}
>
+
+ ${this.hass.localize(
+ "ui.panel.config.cloud.account.remote.strict_connection"
+ )}
+ ${this.hass.localize(
+ "ui.panel.config.cloud.account.remote.strict_connection_secondary"
+ )}
+
+
+ ${this.hass.localize(
+ "ui.panel.config.cloud.account.remote.strict_connection_modes.disabled"
+ )}
+
+
+ ${this.hass.localize(
+ "ui.panel.config.cloud.account.remote.strict_connection_modes.guard_page"
+ )}
+
+
+ ${this.hass.localize(
+ "ui.panel.config.cloud.account.remote.strict_connection_modes.drop_connection"
+ )}
+
+
+
+ ${strict_connection !== "disabled"
+ ? html`
+ ${this.hass.localize(
+ "ui.panel.config.cloud.account.remote.strict_connection_link"
+ )}
+ ${this.hass.localize(
+ "ui.panel.config.cloud.account.remote.strict_connection_link_secondary"
+ )}
+ ${this.hass.localize(
+ "ui.panel.config.cloud.account.remote.strict_connection_create_link"
+ )}
+ `
+ : nothing}
${this.hass.localize(
@@ -223,6 +279,18 @@ export class CloudRemotePref extends LitElement {
}
}
+ private async _setStrictConnectionMode(ev) {
+ const mode = ev.target.value;
+ try {
+ await updateCloudPref(this.hass, {
+ strict_connection: mode,
+ });
+ fireEvent(this, "ha-refresh-cloud-status");
+ } catch (err: any) {
+ alert(err.message);
+ }
+ }
+
private async _copyURL(ev): Promise {
const url = ev.currentTarget.url;
await copyToClipboard(url);
@@ -231,6 +299,40 @@ export class CloudRemotePref extends LitElement {
});
}
+ private async _createLoginUrl() {
+ try {
+ const result = await this.hass.callService(
+ "cloud",
+ "create_temporary_strict_connection_url",
+ undefined,
+ undefined,
+ false,
+ true
+ );
+ showAlertDialog(this, {
+ title: this.hass.localize(
+ "ui.panel.config.cloud.account.remote.strict_connection_link"
+ ),
+ text: html`${this.hass.localize(
+ "ui.panel.config.cloud.account.remote.strict_connection_link_created_message"
+ )}
+ ${result.response.url}
+
+
+ ${this.hass.localize(
+ "ui.panel.config.cloud.account.remote.strict_connection_copy_link"
+ )}
+ `,
+ });
+ } catch (err: any) {
+ showAlertDialog(this, { text: err.message });
+ }
+ }
+
static get styles(): CSSResultGroup {
return css`
.preparing {
diff --git a/src/state/connection-mixin.ts b/src/state/connection-mixin.ts
index b00cc43b28..e376529501 100644
--- a/src/state/connection-mixin.ts
+++ b/src/state/connection-mixin.ts
@@ -83,7 +83,8 @@ export const connectionMixin = >(
service,
serviceData,
target,
- notifyOnError = true
+ notifyOnError = true,
+ returnResponse = false
) => {
if (__DEV__ || this.hass?.debugConnection) {
// eslint-disable-next-line no-console
@@ -101,7 +102,8 @@ export const connectionMixin = >(
domain,
service,
serviceData ?? {},
- target
+ target,
+ returnResponse
)) as ServiceCallResponse;
} catch (err: any) {
if (
diff --git a/src/translations/en.json b/src/translations/en.json
index 18b28941f5..65b153f522 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -3837,6 +3837,19 @@
"advanced_options": "Advanced options",
"external_activation": "Allow external activation of remote control",
"external_activation_secondary": "Allows you to turn on remote control from your Nabu Casa account page, even if you're outside your local network",
+ "strict_connection": "Restrict access to logged in users",
+ "strict_connection_secondary": "When a user is not logged in to your Home Assistant instance, they will not be able to access your instance remotely",
+ "strict_connection_mode": "Mode",
+ "strict_connection_modes": {
+ "disabled": "Disabled",
+ "guard_page": "Guard page",
+ "drop_connection": "Drop connection"
+ },
+ "strict_connection_link": "Create login link",
+ "strict_connection_link_secondary": "You can create a link that will give temporary access to the login page.",
+ "strict_connection_create_link": "Create link",
+ "strict_connection_link_created_message": "Give this link to the person you want to give remote access to the login page of your Home Assistant instance.",
+ "strict_connection_copy_link": "Copy link",
"certificate_info": "Certificate info",
"certificate_expire": "Will be renewed at {date}",
"more_info": "More info"
diff --git a/src/types.ts b/src/types.ts
index cb0e1931f9..c6b32be85d 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -190,6 +190,7 @@ export interface Context {
export interface ServiceCallResponse {
context: Context;
+ response?: any;
}
export interface ServiceCallRequest {
@@ -241,7 +242,8 @@ export interface HomeAssistant {
service: ServiceCallRequest["service"],
serviceData?: ServiceCallRequest["serviceData"],
target?: ServiceCallRequest["target"],
- notifyOnError?: boolean
+ notifyOnError?: boolean,
+ returnResponse?: boolean
): Promise;
callApi(
method: "GET" | "POST" | "PUT" | "DELETE",
diff --git a/yarn.lock b/yarn.lock
index 28ce42d768..b546d2a82f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9703,7 +9703,7 @@ __metadata:
gulp-rename: "npm:2.0.0"
gulp-zopfli-green: "npm:6.0.1"
hls.js: "patch:hls.js@npm%3A1.5.7#~/.yarn/patches/hls.js-npm-1.5.7-f5bbd3d060.patch"
- home-assistant-js-websocket: "npm:9.2.1"
+ home-assistant-js-websocket: "npm:9.3.0"
html-minifier-terser: "npm:7.2.0"
husky: "npm:9.0.11"
idb-keyval: "npm:6.2.1"
@@ -9777,10 +9777,10 @@ __metadata:
languageName: unknown
linkType: soft
-"home-assistant-js-websocket@npm:9.2.1":
- version: 9.2.1
- resolution: "home-assistant-js-websocket@npm:9.2.1"
- checksum: 10/0508aacb4285c805953e620968ef7ca7fc9c3cdac18fa723dd9af128dff74ef2ec65fad4079353b80363cd1daec6d2798b46d2d40a7e4ff5c0807ac71080bf58
+"home-assistant-js-websocket@npm:9.3.0":
+ version: 9.3.0
+ resolution: "home-assistant-js-websocket@npm:9.3.0"
+ checksum: 10/0afbe9f327c3f917187422db1b800383530846724ed8985bb076f6312a10580baeff706d45fba3d840348b76e261eab3f3f7c0b4597340d7575b9b09fc41b0c7
languageName: node
linkType: hard