/** * Auth composable using @logto/nuxt * * Uses useLogtoTokens() for token management with SSR→client sync. */ export const useAuth = () => { const { getToken, initTokens, idToken } = useLogtoTokens() const me = useState<{ id?: string | null } | null>('me', () => null) const isAuthenticated = computed(() => !!me.value?.id) const loggedIn = isAuthenticated /** * Get access token for a resource. * Tokens are synced from SSR via useState, auto-refreshes if expired. */ const getAccessToken = async (resource: string, _organizationId?: string): Promise => { return getToken(resource as Parameters[0]) } const getOrganizationToken = getAccessToken /** * Get ID token. * Uses useState for SSR→client sync, falls back to API on client if needed. */ const getIdToken = async (): Promise => { // SSR or client with synced token if (idToken.value) { return idToken.value } // Client fallback - fetch from API if (!import.meta.server) { const response = await $fetch<{ id_token: string | null }>('/api/auth/id-token') return response.id_token } return null } /** * Get ID token claims (decoded). */ const getIdTokenClaims = async () => { const response = await $fetch<{ claims: Record | null }>('/api/auth/id-token-claims') return response.claims } const signIn = async (_redirectUri?: string) => { await navigateTo('/sign-in', { external: true }) } const login = signIn const signOut = async (_logoutRedirectUri?: string) => { await navigateTo('/sign-out', { external: true }) } const logout = signOut const fetch = async () => { // Initialize tokens on SSR await initTokens() } return { isAuthenticated, loggedIn, user: me, signIn, login, signOut, logout, fetch, getAccessToken, getOrganizationToken, getIdToken, getIdTokenClaims, } }