Auth: Make it clearer where you are logging in to (#17459)

This commit is contained in:
Bram Kragten 2023-08-08 14:43:55 +02:00 committed by GitHub
parent 4986b013a2
commit ac20cf292a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 84 additions and 32 deletions

View File

@ -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 punycode from "punycode";
import { applyThemesOnElement } from "../common/dom/apply_themes_on_element";
import { extractSearchParamsObject } from "../common/url/search-params";
import "../components/ha-alert";
import {
AuthProvider,
AuthUrlSearchParams,
@ -14,6 +22,11 @@ import "./ha-auth-flow";
import("./ha-pick-auth-provider");
const appNames = {
"https://home-assistant.io/iOS": "iOS",
"https://home-assistant.io/android": "Android",
};
@customElement("ha-authorize")
export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
@property() public clientId?: string;
@ -26,6 +39,10 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
@state() private _authProviders?: AuthProvider[];
@state() private _ownInstance = false;
@state() private _error?: string;
constructor() {
super();
this.translationFragment = "page-authorize";
@ -42,39 +59,47 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
}
protected render() {
if (this._error) {
return html`<ha-alert alert-type="error"
>${this._error} ${this.redirectUri}</ha-alert
>`;
}
if (!this._authProviders) {
return html`
<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(
(prv) => prv !== this._authProvider
);
const app = this.clientId && this.clientId in appNames;
return html`
<p>
${this.localize(
"ui.panel.page-authorize.authorizing_client",
"clientId",
this.clientId ? punycode.toASCII(this.clientId) : this.clientId
)}
</p>
${loggingInWith}
${!this._ownInstance
? html`<ha-alert .alertType=${app ? "info" : "warning"}>
${app
? this.localize("ui.panel.page-authorize.authorizing_app", {
app: appNames[this.clientId!],
})
: this.localize("ui.panel.page-authorize.authorizing_client", {
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
.resources=${this.resources}
@ -100,6 +125,31 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
protected firstUpdated(changedProps: PropertyValues) {
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();
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
// we will register the service worker to start preloading.
const tempA = document.createElement("a");
tempA.href = this.redirectUri!;
if (tempA.host === location.host) {
if (url.host === location.host) {
this._ownInstance = true;
registerServiceWorker(this, false);
}
}
@ -156,13 +201,14 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
}
if (authProviders.length === 0) {
alert("No auth providers returned. Unable to finish login.");
this._error = "No auth providers returned. Unable to finish login.";
return;
}
this._authProviders = authProviders;
this._authProvider = authProviders[0];
} catch (err: any) {
this._error = "Unable to fetch auth providers.";
// eslint-disable-next-line
console.error("Error loading auth providers", err);
}
@ -182,6 +228,10 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
display: block;
margin-top: 24px;
}
ha-alert {
display: block;
margin: 16px 0;
}
p {
font-size: 14px;
line-height: 20px;

View File

@ -5294,8 +5294,10 @@
},
"page-authorize": {
"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.",
"logging_in_with": "Logging in with **{authProviderName}**.",
"logging_in_with": "Logging in with {authProviderName}.",
"pick_auth_provider": "Or log in with",
"abort_intro": "Login aborted",
"store_token": "Keep me logged in",