diff --git a/public/badges/oauth2_authorize_callback.svg b/public/badges/oauth2_authorize_callback.svg new file mode 100644 index 00000000..e564366a --- /dev/null +++ b/public/badges/oauth2_authorize_callback.svg @@ -0,0 +1 @@ +OAUTH2 CALLBACK \ No newline at end of file diff --git a/redirect.json b/redirect.json index 283d0d10..62478c56 100644 --- a/redirect.json +++ b/redirect.json @@ -253,6 +253,19 @@ "description": "manage your systems network configuration", "introduced": "2022.5" }, + { + "redirect": "oauth2_authorize_callback", + "deprecated": true, + "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", diff --git a/src-11ty/redirect-page.html b/src-11ty/redirect-page.html index b483b24c..fe3c6bce 100644 --- a/src-11ty/redirect-page.html +++ b/src-11ty/redirect-page.html @@ -19,7 +19,7 @@ flex: 1; } .card-actions { - padding-right: 8px; + padding: 0 8px; height: 37px; } .card-actions a { @@ -53,10 +53,18 @@
+ {% if redirect.redirect == "oauth2_authorize_callback" %} +

Link account to Home Assistant?

+
+ Linking your account will grant your Home Assistant instance access to your + account. All credentials are stored locally. +
+ {% else %}

Open page in your Home Assistant?

You've been linked to the page that will {{ redirect.description }}.
+ {% endif %}
It looks like you came back to this page after you clicked the link. If the @@ -64,10 +72,17 @@

Open page in your Home Assistant?

our troubleshooting steps.
+ {% if redirect.redirect == "oauth2_authorize_callback" %} +
+ + +
+ {% else %}
+ {% endif %}
diff --git a/src/const.ts b/src/const.ts index ce2c08d0..fbc690c7 100644 --- a/src/const.ts +++ b/src/const.ts @@ -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; diff --git a/src/entrypoints/my-redirect.ts b/src/entrypoints/my-redirect.ts index 4ef131ce..99154abf 100644 --- a/src/entrypoints/my-redirect.ts +++ b/src/entrypoints/my-redirect.ts @@ -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)}`; }; @@ -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 = ` - Open Link + ${openLink.innerText} `; + 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 = ` + + ${buttonCaption} + + `; + } + if (isMobile) { (document.querySelector(".footer") as HTMLDivElement).style.display = "none"; @@ -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); diff --git a/src/util/validate.ts b/src/util/validate.ts index c8aa918a..af78842f 100644 --- a/src/util/validate.ts +++ b/src/util/validate.ts @@ -24,7 +24,7 @@ export const validateParam = ( paramType: ParamType, value: string ): string | undefined => { - if (paramType === "string") { + if (paramType === "string" || paramType === "string?") { return undefined; }