diff --git a/cast/src/launcher/layout/hc-cast.ts b/cast/src/launcher/layout/hc-cast.ts index 2b58d6347d..28d26a9df1 100644 --- a/cast/src/launcher/layout/hc-cast.ts +++ b/cast/src/launcher/layout/hc-cast.ts @@ -181,7 +181,7 @@ class HcCast extends LitElement { private async _handlePickView(ev: Event) { const path = (ev.currentTarget as any).getAttribute("data-path"); await ensureConnectedCastSession(this.castManager!, this.auth!); - castSendShowLovelaceView(this.castManager, path); + castSendShowLovelaceView(this.castManager, path, this.auth.data.hassUrl); } private async _handleLogout() { diff --git a/cast/src/receiver/layout/hc-main.ts b/cast/src/receiver/layout/hc-main.ts index 935456a98f..298487bd0f 100644 --- a/cast/src/receiver/layout/hc-main.ts +++ b/cast/src/receiver/layout/hc-main.ts @@ -33,7 +33,6 @@ import { castContext } from "../cast_context"; import "./hc-launch-screen"; let resourcesLoaded = false; - @customElement("hc-main") export class HcMain extends HassElement { @state() private _showDemo = false; @@ -46,6 +45,8 @@ export class HcMain extends HassElement { @state() private _urlPath?: string | null; + private _hassUUID?: string; + private _unsubLovelace?: UnsubscribeFunc; public processIncomingMessage(msg: HassMessage) { @@ -125,6 +126,7 @@ export class HcMain extends HassElement { if (this.hass) { status.hassUrl = this.hass.auth.data.hassUrl; + status.hassUUID = this._hassUUID; status.lovelacePath = this._lovelacePath; status.urlPath = this._urlPath; } @@ -163,6 +165,18 @@ export class HcMain extends HassElement { }; private async _handleGetStatusMessage(msg: GetStatusMessage) { + if ( + (this.hass && msg.hassUUID && msg.hassUUID !== this._hassUUID) || + (this.hass && msg.hassUrl && msg.hassUrl !== this.hass.auth.data.hassUrl) + ) { + this._error = "Not connected to the same Home Assistant instance."; + this._sendError( + ReceiverErrorCode.WRONG_INSTANCE, + this._error, + msg.senderId! + ); + } + this._sendStatus(msg.senderId!); } @@ -179,6 +193,7 @@ export class HcMain extends HassElement { expires_in: 0, }), }); + this._hassUUID = msg.hassUUID; } catch (err: any) { const errorMessage = this._getErrorMessage(err); this._error = errorMessage; @@ -209,9 +224,29 @@ export class HcMain extends HassElement { if (!this.hass) { this._sendStatus(msg.senderId!); this._error = "Cannot show Lovelace because we're not connected."; - this._sendError(ReceiverErrorCode.NOT_CONNECTED, this._error); + this._sendError( + ReceiverErrorCode.NOT_CONNECTED, + this._error, + msg.senderId! + ); return; } + + if ( + (msg.hassUUID && msg.hassUUID !== this._hassUUID) || + (msg.hassUrl && msg.hassUrl !== this.hass.auth.data.hassUrl) + ) { + this._sendStatus(msg.senderId!); + this._error = + "Cannot show Lovelace because we're not connected to the same Home Assistant instance."; + this._sendError( + ReceiverErrorCode.WRONG_INSTANCE, + this._error, + msg.senderId! + ); + return; + } + this._error = undefined; if (msg.urlPath === "lovelace") { msg.urlPath = null; diff --git a/src/cast/receiver_messages.ts b/src/cast/receiver_messages.ts index 953d766abd..8b59962538 100644 --- a/src/cast/receiver_messages.ts +++ b/src/cast/receiver_messages.ts @@ -8,6 +8,8 @@ import { BaseCastMessage } from "./types"; export interface GetStatusMessage extends BaseCastMessage { type: "get_status"; + hassUrl?: string; + hassUUID?: string; } export interface ConnectMessage extends BaseCastMessage { @@ -15,12 +17,15 @@ export interface ConnectMessage extends BaseCastMessage { refreshToken: string; clientId: string | null; hassUrl: string; + hassUUID?: string; } export interface ShowLovelaceViewMessage extends BaseCastMessage { type: "show_lovelace_view"; viewPath: string | number | null; urlPath: string | null; + hassUrl: string; + hassUUID?: string; } export interface ShowDemoMessage extends BaseCastMessage { @@ -43,6 +48,7 @@ export const castSendAuth = (cast: CastManager, auth: Auth) => export const castSendShowLovelaceView = ( cast: CastManager, + hassUrl: string, viewPath: ShowLovelaceViewMessage["viewPath"], urlPath?: string | null ) => @@ -50,6 +56,7 @@ export const castSendShowLovelaceView = ( type: "show_lovelace_view", viewPath, urlPath: urlPath || null, + hassUrl: CAST_DEV ? CAST_DEV_HASS_URL : hassUrl, }); export const castSendShowDemo = (cast: CastManager) => diff --git a/src/cast/sender_messages.ts b/src/cast/sender_messages.ts index 1a6eda58f0..4706a0d1ae 100644 --- a/src/cast/sender_messages.ts +++ b/src/cast/sender_messages.ts @@ -7,6 +7,7 @@ export interface ReceiverStatusMessage extends BaseCastMessage { connected: boolean; showDemo: boolean; hassUrl?: string; + hassUUID?: string; lovelacePath?: string | number | null; urlPath?: string | null; } @@ -23,6 +24,7 @@ export const enum ReceiverErrorCode { CONNECTION_LOST = 3, HASS_URL_MISSING = 4, NO_HTTPS = 5, + WRONG_INSTANCE = 20, NOT_CONNECTED = 21, FETCH_CONFIG_FAILED = 22, } diff --git a/src/panels/lovelace/special-rows/hui-cast-row.ts b/src/panels/lovelace/special-rows/hui-cast-row.ts index c384bce228..c29edd95e8 100644 --- a/src/panels/lovelace/special-rows/hui-cast-row.ts +++ b/src/panels/lovelace/special-rows/hui-cast-row.ts @@ -122,6 +122,7 @@ class HuiCastRow extends LitElement implements LovelaceRow { await ensureConnectedCastSession(this._castManager!, this.hass.auth); castSendShowLovelaceView( this._castManager!, + this.hass.auth.data.hassUrl, this._config!.view, this._config!.dashboard );