diff --git a/src/runtime/composables/oidcAuth.ts b/src/runtime/composables/oidcAuth.ts index f6bdc17..268302e 100644 --- a/src/runtime/composables/oidcAuth.ts +++ b/src/runtime/composables/oidcAuth.ts @@ -1,6 +1,7 @@ import type { ComputedRef, Ref } from '#imports' import type { ProviderKeys, UserSession } from '../types' import { computed, navigateTo, useRequestFetch, useState } from '#imports' +import { parsePath } from '../server/utils/path' const useSessionState = () => useState('nuxt-oidc-auth-session', undefined) @@ -13,7 +14,7 @@ export function useOidcAuth() { const currentProvider: ComputedRef = computed(() => sessionState.value?.provider || undefined) async function fetch() { - useSessionState().value = (await useRequestFetch()('/api/_auth/session', { + useSessionState().value = (await useRequestFetch()(parsePath('/api/_auth/session'), { headers: { Accept: 'text/json', }, @@ -26,7 +27,7 @@ export function useOidcAuth() { * @returns {Promise} */ async function refresh(): Promise { - useSessionState().value = (await useRequestFetch()('/api/_auth/refresh', { + useSessionState().value = (await useRequestFetch()(parsePath('/api/_auth/refresh'), { headers: { Accept: 'text/json', }, @@ -43,7 +44,7 @@ export function useOidcAuth() { */ async function login(provider?: ProviderKeys | 'dev', params?: Record): Promise { const queryParams = params ? `?${new URLSearchParams(params).toString()}` : '' - await navigateTo(`/auth${provider ? `/${provider}` : ''}/login${queryParams}`, { external: true, redirectCode: 302 }) + await navigateTo(parsePath(`/auth${provider ? `/${provider}` : ''}/login${queryParams}`), { external: true, redirectCode: 302 }) } /** @@ -54,14 +55,14 @@ export function useOidcAuth() { * @returns {Promise} */ async function logout(provider?: ProviderKeys | 'dev', logoutRedirectUri?: string): Promise { - await navigateTo(`/auth${provider ? `/${provider}` : currentProvider.value ? `/${currentProvider.value}` : ''}/logout${logoutRedirectUri ? `?logout_redirect_uri=${logoutRedirectUri}` : ''}`, { external: true, redirectCode: 302 }) + await navigateTo(parsePath(`/auth${provider ? `/${provider}` : currentProvider.value ? `/${currentProvider.value}` : ''}/logout${logoutRedirectUri ? `?logout_redirect_uri=${logoutRedirectUri}` : ''}`), { external: true, redirectCode: 302 }) } /** * Clears the current user session. Mainly for debugging, in production, always use the `logout` function, which completely cleans the state. */ async function clear() { - await useRequestFetch()('/api/_auth/session', { + await useRequestFetch()(parsePath('/api/_auth/session'), { method: 'DELETE', headers: { Accept: 'text/json', diff --git a/src/runtime/server/handler/callback.ts b/src/runtime/server/handler/callback.ts index 33a4f91..2cebbd5 100644 --- a/src/runtime/server/handler/callback.ts +++ b/src/runtime/server/handler/callback.ts @@ -12,6 +12,7 @@ import { getUserSessionId, setUserSession, useAuthSession } from '../utils/sessi // @ts-expect-error - Missing Nitro type exports in Nuxt import { useRuntimeConfig, useStorage } from '#imports' import { textToBase64 } from 'undio' +import { parsePath } from '../utils/path' function callbackEventHandler({ onSuccess }: OAuthConfig) { const logger = useOidcLogger() @@ -33,7 +34,7 @@ function callbackEventHandler({ onSuccess }: OAuthConfig) { // Check for admin consent callback if (admin_consent) { const url = getRequestURL(event) - sendRedirect(event, `${url.origin}/auth/${provider}/login`, 200) + sendRedirect(event, url.origin + parsePath(`/auth/${provider}/login`), 200) } // Verify id_token, if available (hybrid flow) @@ -210,6 +211,6 @@ function callbackEventHandler({ onSuccess }: OAuthConfig) { export default callbackEventHandler({ async onSuccess(event, { user, callbackRedirectUrl }) { await setUserSession(event, user as UserSession) - return sendRedirect(event, callbackRedirectUrl || '/' as string) + return sendRedirect(event, parsePath(callbackRedirectUrl ?? '/')) }, }) diff --git a/src/runtime/server/utils/path.ts b/src/runtime/server/utils/path.ts new file mode 100644 index 0000000..f2b4922 --- /dev/null +++ b/src/runtime/server/utils/path.ts @@ -0,0 +1,9 @@ +import { useRuntimeConfig } from '#imports' + +/** + * Adds Nuxt baseURL to the passed path if set + */ +export function parsePath(path: string) { + const nuxtBaseUrl: string = useRuntimeConfig().app.baseURL ?? '/' + return `${nuxtBaseUrl}${path.startsWith('/') ? path.slice(1) : path}` +} diff --git a/src/runtime/server/utils/session.ts b/src/runtime/server/utils/session.ts index de55f4d..c610194 100644 --- a/src/runtime/server/utils/session.ts +++ b/src/runtime/server/utils/session.ts @@ -9,6 +9,7 @@ import { configMerger, refreshAccessToken, useOidcLogger } from './oidc' import { decryptToken, encryptToken } from './security' // @ts-expect-error - Missing Nitro type exports in Nuxt import { useRuntimeConfig, useStorage } from '#imports' +import { parsePath } from './path' const sessionName = 'nuxt-oidc-auth' let sessionConfig: Pick & AuthSessionConfig @@ -87,7 +88,7 @@ export async function refreshUserSession(event: H3Event) { } catch (error) { logger.error(error) - return sendRedirect(event, `/auth/${provider}/logout`) + return sendRedirect(event, parsePath(`/auth/${provider}/logout`)) } const { user, tokens, expiresIn, parsedAccessToken } = tokenRefreshResponse