mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Allow storing thread credentials in phone keychain (#20743)
* Allow storing thread credentials in phone keychain * Update dialog-thread-dataset.ts * use preferred of dataset if available
This commit is contained in:
parent
9264adb799
commit
bfa293ae3a
@ -129,6 +129,15 @@ interface EMOutgoingMessageAssistShow extends EMMessage {
|
||||
};
|
||||
}
|
||||
|
||||
interface EMOutgoingMessageThreadStoreInPlatformKeychain extends EMMessage {
|
||||
type: "thread/store_in_platform_keychain";
|
||||
payload: {
|
||||
mac_extended_address: string;
|
||||
border_agent_id: string | null;
|
||||
active_operational_dataset: string;
|
||||
};
|
||||
}
|
||||
|
||||
type EMOutgoingMessageWithoutAnswer =
|
||||
| EMMessageResultError
|
||||
| EMMessageResultSuccess
|
||||
@ -146,7 +155,8 @@ type EMOutgoingMessageWithoutAnswer =
|
||||
| EMOutgoingMessageMatterCommission
|
||||
| EMOutgoingMessageSidebarShow
|
||||
| EMOutgoingMessageTagWrite
|
||||
| EMOutgoingMessageThemeUpdate;
|
||||
| EMOutgoingMessageThemeUpdate
|
||||
| EMOutgoingMessageThreadStoreInPlatformKeychain;
|
||||
|
||||
interface EMIncomingMessageRestart {
|
||||
id: number;
|
||||
@ -239,6 +249,7 @@ export interface ExternalConfig {
|
||||
hasExoPlayer: boolean;
|
||||
canCommissionMatter: boolean;
|
||||
canImportThreadCredentials: boolean;
|
||||
canTransferThreadCredentialsToKeychain: boolean;
|
||||
hasAssist: boolean;
|
||||
hasBarCodeScanner: number;
|
||||
}
|
||||
|
@ -0,0 +1,90 @@
|
||||
import { LitElement, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { HassDialog } from "../../../../../dialogs/make-dialog-manager";
|
||||
import { HomeAssistant } from "../../../../../types";
|
||||
import { DialogThreadDatasetParams } from "./show-dialog-thread-dataset";
|
||||
import { createCloseHeading } from "../../../../../components/ha-dialog";
|
||||
|
||||
@customElement("ha-dialog-thread-dataset")
|
||||
class DialogThreadDataset extends LitElement implements HassDialog {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@state() private _params?: DialogThreadDatasetParams;
|
||||
|
||||
public async showDialog(
|
||||
params: DialogThreadDatasetParams
|
||||
): Promise<Promise<void>> {
|
||||
this._params = params;
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
this._params = undefined;
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this._params) {
|
||||
return nothing;
|
||||
}
|
||||
const network = this._params.network;
|
||||
const dataset = network.dataset!;
|
||||
const otbrInfo = this._params.otbrInfo;
|
||||
|
||||
const hasOTBR =
|
||||
otbrInfo &&
|
||||
dataset.extended_pan_id &&
|
||||
otbrInfo.active_dataset_tlvs?.includes(dataset.extended_pan_id);
|
||||
|
||||
const canImportKeychain =
|
||||
hasOTBR &&
|
||||
!this.hass.auth.external?.config.canTransferThreadCredentialsToKeychain &&
|
||||
network.routers?.length;
|
||||
|
||||
return html`<ha-dialog
|
||||
open
|
||||
.hideActions=${!canImportKeychain}
|
||||
@closed=${this.closeDialog}
|
||||
.heading=${createCloseHeading(this.hass, network.name)}
|
||||
>
|
||||
<div>
|
||||
Network name: ${dataset.network_name}<br />
|
||||
Channel: ${dataset.channel}<br />
|
||||
Dataset id: ${dataset.dataset_id}<br />
|
||||
Pan id: ${dataset.pan_id}<br />
|
||||
Extended Pan id: ${dataset.extended_pan_id}<br />
|
||||
|
||||
${hasOTBR
|
||||
? html`OTBR URL: ${otbrInfo.url}<br />
|
||||
Active dataset TLVs: ${otbrInfo.active_dataset_tlvs}`
|
||||
: nothing}
|
||||
</div>
|
||||
${canImportKeychain
|
||||
? html`<ha-button slot="primary-action" @click=${this._sendCredentials}
|
||||
>Send credentials to phone</ha-button
|
||||
>`
|
||||
: nothing}
|
||||
</ha-dialog>`;
|
||||
}
|
||||
|
||||
private _sendCredentials() {
|
||||
this.hass.auth.external!.fireMessage({
|
||||
type: "thread/store_in_platform_keychain",
|
||||
payload: {
|
||||
mac_extended_address:
|
||||
this._params?.network.dataset?.preferred_extended_address ||
|
||||
this._params!.network.routers![0]!.extended_address,
|
||||
border_agent_id:
|
||||
this._params?.network.dataset?.preferred_border_agent_id ||
|
||||
this._params!.network.routers![0]!.border_agent_id,
|
||||
active_operational_dataset: this._params!.otbrInfo!.active_dataset_tlvs,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-dialog-thread-dataset": DialogThreadDataset;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { OTBRInfo } from "../../../../../data/otbr";
|
||||
import { ThreadNetwork } from "./thread-config-panel";
|
||||
|
||||
export interface DialogThreadDatasetParams {
|
||||
network: ThreadNetwork;
|
||||
otbrInfo?: OTBRInfo;
|
||||
}
|
||||
|
||||
export const showThreadDatasetDialog = (
|
||||
element: HTMLElement,
|
||||
dialogParams: DialogThreadDatasetParams
|
||||
): void => {
|
||||
fireEvent(element, "show-dialog", {
|
||||
dialogTag: "ha-dialog-thread-dataset",
|
||||
dialogImport: () => import("./dialog-thread-dataset"),
|
||||
dialogParams,
|
||||
});
|
||||
};
|
@ -55,8 +55,9 @@ import { HomeAssistant } from "../../../../../types";
|
||||
import { brandsUrl } from "../../../../../util/brands-url";
|
||||
import { fileDownload } from "../../../../../util/file_download";
|
||||
import { documentationUrl } from "../../../../../util/documentation-url";
|
||||
import { showThreadDatasetDialog } from "./show-dialog-thread-dataset";
|
||||
|
||||
interface ThreadNetwork {
|
||||
export interface ThreadNetwork {
|
||||
name: string;
|
||||
dataset?: ThreadDataSet;
|
||||
routers?: ThreadRouter[];
|
||||
@ -164,7 +165,7 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) {
|
||||
${network.name}${network.dataset
|
||||
? html`<div>
|
||||
<ha-icon-button
|
||||
.networkDataset=${network.dataset}
|
||||
.network=${network}
|
||||
.path=${mdiInformationOutline}
|
||||
@click=${this._showDatasetInfo}
|
||||
></ha-icon-button
|
||||
@ -306,33 +307,8 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
|
||||
private async _showDatasetInfo(ev: Event) {
|
||||
const dataset = (ev.currentTarget as any).networkDataset as ThreadDataSet;
|
||||
if (this._otbrInfo) {
|
||||
if (
|
||||
dataset.extended_pan_id &&
|
||||
this._otbrInfo.active_dataset_tlvs?.includes(dataset.extended_pan_id)
|
||||
) {
|
||||
showAlertDialog(this, {
|
||||
title: dataset.network_name,
|
||||
text: html`Network name: ${dataset.network_name}<br />
|
||||
Channel: ${dataset.channel}<br />
|
||||
Dataset id: ${dataset.dataset_id}<br />
|
||||
Pan id: ${dataset.pan_id}<br />
|
||||
Extended Pan id: ${dataset.extended_pan_id}<br />
|
||||
OTBR URL: ${this._otbrInfo.url}<br />
|
||||
Active dataset TLVs: ${this._otbrInfo.active_dataset_tlvs}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
showAlertDialog(this, {
|
||||
title: dataset.network_name,
|
||||
text: html`Network name: ${dataset.network_name}<br />
|
||||
Channel: ${dataset.channel}<br />
|
||||
Dataset id: ${dataset.dataset_id}<br />
|
||||
Pan id: ${dataset.pan_id}<br />
|
||||
Extended Pan id: ${dataset.extended_pan_id}`,
|
||||
});
|
||||
const network = (ev.currentTarget as any).network as ThreadNetwork;
|
||||
showThreadDatasetDialog(this, { network, otbrInfo: this._otbrInfo });
|
||||
}
|
||||
|
||||
private _importExternalThreadCredentials() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user