mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Auth: Make it clearer where you are logging in to (#17459)
This commit is contained in:
parent
4986b013a2
commit
ac20cf292a
@ -1,8 +1,16 @@
|
|||||||
import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
|
import {
|
||||||
|
css,
|
||||||
|
CSSResultGroup,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
nothing,
|
||||||
|
PropertyValues,
|
||||||
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import punycode from "punycode";
|
import punycode from "punycode";
|
||||||
import { applyThemesOnElement } from "../common/dom/apply_themes_on_element";
|
import { applyThemesOnElement } from "../common/dom/apply_themes_on_element";
|
||||||
import { extractSearchParamsObject } from "../common/url/search-params";
|
import { extractSearchParamsObject } from "../common/url/search-params";
|
||||||
|
import "../components/ha-alert";
|
||||||
import {
|
import {
|
||||||
AuthProvider,
|
AuthProvider,
|
||||||
AuthUrlSearchParams,
|
AuthUrlSearchParams,
|
||||||
@ -14,6 +22,11 @@ import "./ha-auth-flow";
|
|||||||
|
|
||||||
import("./ha-pick-auth-provider");
|
import("./ha-pick-auth-provider");
|
||||||
|
|
||||||
|
const appNames = {
|
||||||
|
"https://home-assistant.io/iOS": "iOS",
|
||||||
|
"https://home-assistant.io/android": "Android",
|
||||||
|
};
|
||||||
|
|
||||||
@customElement("ha-authorize")
|
@customElement("ha-authorize")
|
||||||
export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
||||||
@property() public clientId?: string;
|
@property() public clientId?: string;
|
||||||
@ -26,6 +39,10 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _authProviders?: AuthProvider[];
|
@state() private _authProviders?: AuthProvider[];
|
||||||
|
|
||||||
|
@state() private _ownInstance = false;
|
||||||
|
|
||||||
|
@state() private _error?: string;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.translationFragment = "page-authorize";
|
this.translationFragment = "page-authorize";
|
||||||
@ -42,39 +59,47 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
|
if (this._error) {
|
||||||
|
return html`<ha-alert alert-type="error"
|
||||||
|
>${this._error} ${this.redirectUri}</ha-alert
|
||||||
|
>`;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this._authProviders) {
|
if (!this._authProviders) {
|
||||||
return html`
|
return html`
|
||||||
<p>${this.localize("ui.panel.page-authorize.initializing")}</p>
|
<p>${this.localize("ui.panel.page-authorize.initializing")}</p>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't have a good approach yet to map text markup in localization.
|
|
||||||
// So we sanitize the translation with innerText and then inject
|
|
||||||
// the name with a bold tag.
|
|
||||||
const loggingInWith = document.createElement("div");
|
|
||||||
loggingInWith.innerText = this.localize(
|
|
||||||
"ui.panel.page-authorize.logging_in_with",
|
|
||||||
"authProviderName",
|
|
||||||
"NAME"
|
|
||||||
);
|
|
||||||
loggingInWith.innerHTML = loggingInWith.innerHTML.replace(
|
|
||||||
"**NAME**",
|
|
||||||
`<b>${this._authProvider!.name}</b>`
|
|
||||||
);
|
|
||||||
|
|
||||||
const inactiveProviders = this._authProviders.filter(
|
const inactiveProviders = this._authProviders.filter(
|
||||||
(prv) => prv !== this._authProvider
|
(prv) => prv !== this._authProvider
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const app = this.clientId && this.clientId in appNames;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<p>
|
${!this._ownInstance
|
||||||
${this.localize(
|
? html`<ha-alert .alertType=${app ? "info" : "warning"}>
|
||||||
"ui.panel.page-authorize.authorizing_client",
|
${app
|
||||||
"clientId",
|
? this.localize("ui.panel.page-authorize.authorizing_app", {
|
||||||
this.clientId ? punycode.toASCII(this.clientId) : this.clientId
|
app: appNames[this.clientId!],
|
||||||
)}
|
})
|
||||||
</p>
|
: this.localize("ui.panel.page-authorize.authorizing_client", {
|
||||||
${loggingInWith}
|
clientId: html`<b
|
||||||
|
>${this.clientId
|
||||||
|
? punycode.toASCII(this.clientId)
|
||||||
|
: this.clientId}</b
|
||||||
|
>`,
|
||||||
|
})}
|
||||||
|
</ha-alert>`
|
||||||
|
: html`<p>${this.localize("ui.panel.page-authorize.authorizing")}</p>`}
|
||||||
|
${inactiveProviders.length > 0
|
||||||
|
? html`<p>
|
||||||
|
${this.localize("ui.panel.page-authorize.logging_in_with", {
|
||||||
|
authProviderName: html`<b>${this._authProvider!.name}</b>`,
|
||||||
|
})}
|
||||||
|
</p>`
|
||||||
|
: nothing}
|
||||||
|
|
||||||
<ha-auth-flow
|
<ha-auth-flow
|
||||||
.resources=${this.resources}
|
.resources=${this.resources}
|
||||||
@ -100,6 +125,31 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
|||||||
|
|
||||||
protected firstUpdated(changedProps: PropertyValues) {
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
|
|
||||||
|
if (!this.redirectUri) {
|
||||||
|
this._error = "Invalid redirect URI";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let url: URL;
|
||||||
|
|
||||||
|
try {
|
||||||
|
url = new URL(this.redirectUri);
|
||||||
|
} catch (err) {
|
||||||
|
this._error = "Invalid redirect URI";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
// eslint-disable-next-line no-script-url
|
||||||
|
["javascript:", "data:", "vbscript:", "file:", "about:"].includes(
|
||||||
|
url.protocol
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
this._error = "Invalid redirect URI";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this._fetchAuthProviders();
|
this._fetchAuthProviders();
|
||||||
|
|
||||||
if (matchMedia("(prefers-color-scheme: dark)").matches) {
|
if (matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||||
@ -118,15 +168,10 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.redirectUri) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we are logging into the instance that is hosting this auth form
|
// If we are logging into the instance that is hosting this auth form
|
||||||
// we will register the service worker to start preloading.
|
// we will register the service worker to start preloading.
|
||||||
const tempA = document.createElement("a");
|
if (url.host === location.host) {
|
||||||
tempA.href = this.redirectUri!;
|
this._ownInstance = true;
|
||||||
if (tempA.host === location.host) {
|
|
||||||
registerServiceWorker(this, false);
|
registerServiceWorker(this, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,13 +201,14 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (authProviders.length === 0) {
|
if (authProviders.length === 0) {
|
||||||
alert("No auth providers returned. Unable to finish login.");
|
this._error = "No auth providers returned. Unable to finish login.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._authProviders = authProviders;
|
this._authProviders = authProviders;
|
||||||
this._authProvider = authProviders[0];
|
this._authProvider = authProviders[0];
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
this._error = "Unable to fetch auth providers.";
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
console.error("Error loading auth providers", err);
|
console.error("Error loading auth providers", err);
|
||||||
}
|
}
|
||||||
@ -182,6 +228,10 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
|||||||
display: block;
|
display: block;
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
}
|
}
|
||||||
|
ha-alert {
|
||||||
|
display: block;
|
||||||
|
margin: 16px 0;
|
||||||
|
}
|
||||||
p {
|
p {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
|
@ -5294,8 +5294,10 @@
|
|||||||
},
|
},
|
||||||
"page-authorize": {
|
"page-authorize": {
|
||||||
"initializing": "Initializing",
|
"initializing": "Initializing",
|
||||||
|
"authorizing": "Login to your Home Assistant instance",
|
||||||
|
"authorizing_app": "You're about to give the Home Assistant Companion app for {app} access to your Home Assistant instance.",
|
||||||
"authorizing_client": "You're about to give {clientId} access to your Home Assistant instance.",
|
"authorizing_client": "You're about to give {clientId} access to your Home Assistant instance.",
|
||||||
"logging_in_with": "Logging in with **{authProviderName}**.",
|
"logging_in_with": "Logging in with {authProviderName}.",
|
||||||
"pick_auth_provider": "Or log in with",
|
"pick_auth_provider": "Or log in with",
|
||||||
"abort_intro": "Login aborted",
|
"abort_intro": "Login aborted",
|
||||||
"store_token": "Keep me logged in",
|
"store_token": "Keep me logged in",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user