Skip to content

Commit

Permalink
Auth: Make it clearer where you are logging in to (#17459)
Browse files Browse the repository at this point in the history
  • Loading branch information
bramkragten authored Aug 8, 2023
1 parent 4986b01 commit ac20cf2
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 32 deletions.
112 changes: 81 additions & 31 deletions src/auth/ha-authorize.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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;
Expand All @@ -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";
Expand All @@ -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}
Expand All @@ -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) {
Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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);
}
Expand All @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

0 comments on commit ac20cf2

Please sign in to comment.