diff --git a/app/composables/useAuth.ts b/app/composables/useAuth.ts new file mode 100644 index 0000000..b1bfbd8 --- /dev/null +++ b/app/composables/useAuth.ts @@ -0,0 +1,33 @@ +// Access the provided Zitadel auth instance + a small JSON helper for /api calls. +// `auth.fetch` auto-attaches the Bearer access token. +export function useAuth() { + const { $auth } = useNuxtApp() as unknown as { + $auth: { + isAuthenticated: Ref; + isLoading: Ref; + user: Ref<{ sub: string; name: string; email: string } | null>; + error: Ref; + login: () => void; + logout: () => Promise; + fetch: (url: string, init?: RequestInit) => Promise; + }; + }; + + async function api(path: string, init?: RequestInit): Promise { + const res = await $auth.fetch(`/api${path}`, init); + if (!res.ok) { + let message = `${res.status}`; + try { + const body = await res.json(); + message = body?.statusMessage || body?.message || message; + } catch { + // non-JSON error body + } + throw new Error(message); + } + if (res.status === 204) return undefined as T; + return (await res.json()) as T; + } + + return { auth: $auth, api }; +} diff --git a/app/pages/auth/callback.vue b/app/pages/auth/callback.vue new file mode 100644 index 0000000..43a557a --- /dev/null +++ b/app/pages/auth/callback.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/app/pages/index.vue b/app/pages/index.vue new file mode 100644 index 0000000..8dd5eed --- /dev/null +++ b/app/pages/index.vue @@ -0,0 +1,376 @@ + + + + + diff --git a/app/plugins/auth.client.ts b/app/plugins/auth.client.ts new file mode 100644 index 0000000..7f6406d --- /dev/null +++ b/app/plugins/auth.client.ts @@ -0,0 +1,13 @@ +import { useZitadelAuth } from "@kuns/zitadel-auth/vue"; + +// Wire the framework-agnostic Zitadel OIDC client to Nuxt's router (client-only SPA). +// Provides `$auth` (reactive state + login/logout/fetch). The adapter installs a +// router guard that redirects unauthenticated users to the Zitadel hosted login. +export default defineNuxtPlugin(() => { + const cfg = useRuntimeConfig().public; + const auth = useZitadelAuth(useRouter() as never, { + clientId: cfg.zitadelClientId as string, + issuer: cfg.zitadelIssuer as string, + }); + return { provide: { auth } }; +});