Auth Files and Components

PreviousNext

A complex component used to setup Auth.

Docs
ha-componentsblock

Preview

Loading preview…
providers/HomeAssistantProvider.tsx
"use client";

import { type ReactNode, useEffect, useState } from "react";
import { haWebSocket } from "@/lib/haWebsocket";
import { getAccessToken, login, exchangeCodeForToken, ENV } from "@/lib/haAuth";

export function HomeAssistantProvider({ children, useProxy = false }: { children: ReactNode; useProxy?: boolean }) {
    const [ready, setReady] = useState(false);
    const [token, setToken] = useState<string | null>(() => getAccessToken());

    useEffect(() => {
        if (token) return;

        const searchParams = new URLSearchParams(window.location.search);
        const code = searchParams.get("code");

        if (code) {
            exchangeCodeForToken(code)
                .then(() => {
                    setToken(getAccessToken());
                    // Clean Code from URL
                    window.history.replaceState({}, "", window.location.pathname);
                })
                .catch((err) => {
                    console.error("Failed to exchange code for token:", err);
                });
        } else {
            login(); // redirect to HA OAuth2
        }
    }, []);

    useEffect(() => {
        if (!token) return;
        if (useProxy && !ENV.PROXY_URL) {
            console.error("PROXY_URL is required when useProxy is enabled");
            return;
        }

        async function connect() {
            try {
                await haWebSocket.connect(
                    useProxy ? ENV.PROXY_URL! : `${ENV.HA_HOST}:${ENV.HA_PORT}`,
                    token!,
                    useProxy,
                );
                setReady(true);
            } catch (err) {
                console.error("Failed to connect to HA WebSocket:", err);
            }
        }

        connect();
    }, [token, useProxy]);

    if (!ready) {
        return <div>Connecting to Home Assistant...</div>;
    }

    return <>{children}</>;
}

Installation

npx shadcn@latest add @ha-components/auth

Usage

import { Auth } from "@/components/auth"
<Auth />