Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions public/badges/oauth2_authorize_callback.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions redirect.json
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,19 @@
"description": "manage your systems network configuration",
"introduced": "2022.5"
},
{
"redirect": "oauth2_authorize_callback",
"deprecated": true,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

marked deprecated to hide it.

"name": "OAuth2 Authorize Callback",
"badge": "OAuth2 Callback",
"description": "(replaced in UI)",
"introduced": "2022.6",
"params": {
"code": "string?",
"error": "string?",
"state": "string"
}
},
{
"redirect": "people",
"name": "People",
Expand Down
17 changes: 16 additions & 1 deletion src-11ty/redirect-page.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
flex: 1;
}
.card-actions {
padding-right: 8px;
padding: 0 8px;
height: 37px;
}
.card-actions a {
Expand Down Expand Up @@ -53,21 +53,36 @@
</style>

<div class="ha-card">
{% if redirect.redirect == "oauth2_authorize_callback" %}
<h1 class="card-header">Link account to Home Assistant?</h1>
<div class="card-content">
Linking your account will grant your Home Assistant instance access to your
account. All credentials are stored locally.
</div>
{% else %}
<h1 class="card-header">Open page in your Home Assistant?</h1>
<div class="card-content">
You've been linked to the page that will {{ redirect.description }}.
</div>
{% endif %}

<div class="highlight">
It looks like you came back to this page after you clicked the link. If the
link didn't work, make sure your instance URL below is correct and check
<a href="/faq#404">our troubleshooting steps</a>.
</div>

{% if redirect.redirect == "oauth2_authorize_callback" %}
<div class="card-actions">
<div class="fake-button decline-link">DECLINE</div>
<div class="fake-button open-link">LINK ACCOUNT</div>
</div>
{% else %}
<div class="card-actions">
<div></div>
<div class="fake-button open-link">OPEN LINK</div>
</div>
{% endif %}
</div>

<div class="instance-footer"></div>
Expand Down
2 changes: 1 addition & 1 deletion src/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export const HASS_URL = "hassUrl";
export const DEFAULT_HASS_URL = "http://homeassistant.local:8123";
export const MOBILE_URL = "homeassistant://navigate";

export type ParamType = "url" | "string";
export type ParamType = "url" | "string" | "string?";

export interface Redirect {
redirect: string;
Expand Down
43 changes: 36 additions & 7 deletions src/entrypoints/my-redirect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ const createRedirectParams = (): string => {
return "";
}
const params = {};
Object.entries(redirectParams).forEach(([key, type]) => {
for (const [key, type] of Object.entries(redirectParams)) {
if (!userParams[key] && type.endsWith("?")) {
continue;
}
if (!userParams[key] || validateParam(type, userParams[key])) {
throw Error("Wrong parameters");
}
params[key] = userParams[key];
});
}
return `?${createSearchParam(params)}`;
};

Expand Down Expand Up @@ -61,12 +64,39 @@ const render = (showTroubleshooting: boolean) => {

const redirectUrl = `${instanceUrl}/_my_redirect/${window.redirect.redirect}${params}`;

document.querySelector(".open-link")!.outerHTML = `
const openLink = document.querySelector(".open-link") as HTMLElement;
openLink.outerHTML = `
<a href="${redirectUrl}" class='open-link' rel="noopener">
<mwc-button>Open Link</mwc-button>
<mwc-button>${openLink.innerText}</mwc-button>
</a>
`;

if (window.redirect.redirect === "oauth2_authorize_callback") {
const params = extractSearchParamsObject();

let buttonCaption = "DECLINE";

// User already rejected, hide link button
if ("error" in params) {
document.querySelector(".card-header")!.innerHTML =
"Account linking rejected";
buttonCaption = "NOTIFY HOME ASSISTANT OF REJECTION";
(document.querySelector(".open-link") as HTMLElement).style.visibility =
"hidden";
}

const declineLink = document.querySelector(".decline-link")!;
const declineParams = createSearchParam({
error: params.error || "access_denied",
state: params.state,
});
declineLink.outerHTML = `
<a href="${instanceUrl}/_my_redirect/${window.redirect.redirect}?${declineParams}" class='decline-link' rel="noopener">
<mwc-button>${buttonCaption}</mwc-button>
</a>
`;
}

if (isMobile) {
(document.querySelector(".footer") as HTMLDivElement).style.display =
"none";
Expand All @@ -90,9 +120,8 @@ const render = (showTroubleshooting: boolean) => {
return;
}

(document.querySelector(
".highlight"
) as HTMLDivElement).style.display = showTroubleshooting ? "block" : "none";
(document.querySelector(".highlight") as HTMLDivElement).style.display =
showTroubleshooting ? "block" : "none";
};

render(false);
Expand Down
2 changes: 1 addition & 1 deletion src/util/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const validateParam = (
paramType: ParamType,
value: string
): string | undefined => {
if (paramType === "string") {
if (paramType === "string" || paramType === "string?") {
return undefined;
}

Expand Down