From 2252a69aad76b2513b94927ef919097a5cf2dd92 Mon Sep 17 00:00:00 2001 From: Zoey Kaiser Date: Fri, 9 Aug 2024 19:00:40 +0200 Subject: [PATCH 1/8] Began adding server side access to session data on local --- src/module.ts | 28 ++++++++----------- .../server/services/local/getServerSession.ts | 7 +++++ src/runtime/server/services/local/getToken.ts | 8 ++++++ src/runtime/utils/generateTypes.ts | 25 +++++++++++++++++ 4 files changed, 52 insertions(+), 16 deletions(-) create mode 100644 src/runtime/server/services/local/getServerSession.ts create mode 100644 src/runtime/server/services/local/getToken.ts create mode 100644 src/runtime/utils/generateTypes.ts diff --git a/src/module.ts b/src/module.ts index 5aaf8388..71d148aa 100644 --- a/src/module.ts +++ b/src/module.ts @@ -23,6 +23,7 @@ import type { AuthProviders, RefreshHandler } from './runtime/types' +import { generateModuleTypes } from './runtime/utils/generateTypes' const topLevelDefaults = { isEnabled: true, @@ -202,26 +203,21 @@ export default defineNuxtModule({ inline: [resolve('./runtime')] } ) - nitroConfig.alias['#auth'] = resolve('./runtime/server/services') + + // If AuthJS is selected, inject authjs server-side services + if (selectedProvider === 'authjs') { + nitroConfig.alias['#auth'] = resolve('./runtime/server/services/authjs') + } + + // If local is selected, inject local server-side services + if (selectedProvider === 'local') { + nitroConfig.alias['#auth'] = resolve('./runtime/server/services/local') + } }) addTypeTemplate({ filename: 'types/auth.d.ts', - getContents: () => - [ - '// AUTO-GENERATED BY @sidebase/nuxt-auth', - "declare module '#auth' {", - ` const { getServerSession, getToken, NuxtAuthHandler }: typeof import('${resolve('./runtime/server/services')}')`, - ...(options.provider.type === 'local' - ? [genInterface( - 'SessionData', - (options.provider as any).session.dataType - )] - : [] - ), - '}', - '' - ].join('\n') + getContents: () => generateModuleTypes(options.provider) }) addTypeTemplate({ diff --git a/src/runtime/server/services/local/getServerSession.ts b/src/runtime/server/services/local/getServerSession.ts new file mode 100644 index 00000000..ff90d4ad --- /dev/null +++ b/src/runtime/server/services/local/getServerSession.ts @@ -0,0 +1,7 @@ +import type { H3Event } from 'h3' +import { useRuntimeConfig } from '#app' +import { useTypedBackendConfig } from '../../../helpers' + +export function getServerSession (event: H3Event) { + const config = useTypedBackendConfig(useRuntimeConfig(), 'local') +} diff --git a/src/runtime/server/services/local/getToken.ts b/src/runtime/server/services/local/getToken.ts new file mode 100644 index 00000000..3b5fad7f --- /dev/null +++ b/src/runtime/server/services/local/getToken.ts @@ -0,0 +1,8 @@ +import { getCookie, type H3Event } from 'h3' +import { useRuntimeConfig } from '#app' +import { useTypedBackendConfig } from '../../../helpers' + +export function getLocalServerToken (event: H3Event) { + const config = useTypedBackendConfig(useRuntimeConfig(), 'local') + return getCookie(event, config.token.cookieName) +} diff --git a/src/runtime/utils/generateTypes.ts b/src/runtime/utils/generateTypes.ts new file mode 100644 index 00000000..f3a58b1d --- /dev/null +++ b/src/runtime/utils/generateTypes.ts @@ -0,0 +1,25 @@ +import { genInterface } from 'knitwork' +import { createResolver } from '@nuxt/kit' +import type { AuthProviders } from '../types' + +export function generateModuleTypes (provider: AuthProviders) { + const { resolve } = createResolver(import.meta.url) + + const providerSpecificTypes: string[] = [] + + if (provider.type === 'authjs') { + providerSpecificTypes.push(` const { getServerSession, getToken, NuxtAuthHandler }: typeof import('${resolve('./runtime/server/services')}')`) + } + + if (provider.type === 'local') { + providerSpecificTypes.push(genInterface('SessionData', (provider as any).session.dataType)) + } + + return [ + '// AUTO-GENERATED BY @sidebase/nuxt-auth', + "declare module '#auth' {", + ...providerSpecificTypes, + '}', + '' + ].join('\n') +} From 9fa1c056bd775527e910c9150a6b2dcc49501c48 Mon Sep 17 00:00:00 2001 From: Zoey Kaiser Date: Fri, 9 Aug 2024 20:27:27 +0200 Subject: [PATCH 2/8] clean up module.ts --- src/module.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/module.ts b/src/module.ts index 71d148aa..f5c3bf8f 100644 --- a/src/module.ts +++ b/src/module.ts @@ -12,7 +12,6 @@ import { } from '@nuxt/kit' import { defu } from 'defu' import { joinURL } from 'ufo' -import { genInterface } from 'knitwork' import type { DeepRequired } from 'ts-essentials' import type { NuxtModule } from 'nuxt/schema' import { getOriginAndPathnameFromURL, isProduction } from './runtime/helpers' @@ -126,7 +125,10 @@ const PACKAGE_NAME = 'sidebase-auth' export default defineNuxtModule({ meta: { name: PACKAGE_NAME, - configKey: 'auth' + configKey: 'auth', + compatibility: { + nuxt: '>=3.0.0' + } }, setup (userOptions, nuxt) { const logger = useLogger(PACKAGE_NAME) @@ -165,7 +167,7 @@ export default defineNuxtModule({ if (!isProduction) { const authjsAddition = selectedProvider === 'authjs' - ? ', ensure that `NuxtAuthHandler({ ... })` is there, see https://sidebase.io/nuxt-auth/configuration/nuxt-auth-handler' + ? ', ensure that `NuxtAuthHandler({ ... })` is there, see https://auth.sidebase.io/guide/authjs/nuxt-auth-handler' : '' logger.info( `Selected provider: ${selectedProvider}. Auth API location is \`${options.computed.fullBaseUrl}\`${authjsAddition}` From 657a5a01f534d222b65dd4d07c7879d3fd324c24 Mon Sep 17 00:00:00 2001 From: Zoey Kaiser Date: Fri, 9 Aug 2024 20:29:34 +0200 Subject: [PATCH 3/8] fix: correctly import authjs service services --- src/runtime/server/services/authjs/index.ts | 1 + src/runtime/server/services/index.ts | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 src/runtime/server/services/authjs/index.ts delete mode 100644 src/runtime/server/services/index.ts diff --git a/src/runtime/server/services/authjs/index.ts b/src/runtime/server/services/authjs/index.ts new file mode 100644 index 00000000..f6ee14c7 --- /dev/null +++ b/src/runtime/server/services/authjs/index.ts @@ -0,0 +1 @@ +export { NuxtAuthHandler, getServerSession, getToken } from './nuxtAuthHandler' diff --git a/src/runtime/server/services/index.ts b/src/runtime/server/services/index.ts deleted file mode 100644 index 423ab845..00000000 --- a/src/runtime/server/services/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { NuxtAuthHandler, getServerSession, getToken } from './authjs/nuxtAuthHandler' From df4c8eb6d0a2bffe230ead89fae64f06a96757d6 Mon Sep 17 00:00:00 2001 From: Zoey Kaiser Date: Fri, 9 Aug 2024 21:24:26 +0200 Subject: [PATCH 4/8] Added first functional version of server-side local session access --- playground-local/server/api/session.get.ts | 7 +++ playground-local/server/api/token.get.ts | 7 +++ .../server/services/local/getServerSession.ts | 50 +++++++++++++++++-- src/runtime/server/services/local/getToken.ts | 12 +++-- src/runtime/server/services/local/index.ts | 2 + src/runtime/utils/generateTypes.ts | 3 +- 6 files changed, 73 insertions(+), 8 deletions(-) create mode 100644 playground-local/server/api/session.get.ts create mode 100644 playground-local/server/api/token.get.ts create mode 100644 src/runtime/server/services/local/index.ts diff --git a/playground-local/server/api/session.get.ts b/playground-local/server/api/session.get.ts new file mode 100644 index 00000000..99852017 --- /dev/null +++ b/playground-local/server/api/session.get.ts @@ -0,0 +1,7 @@ +import { defineEventHandler } from 'h3' +import { getServerSession } from '#auth' + +export default defineEventHandler(async (event) => { + const session = await getServerSession(event) + return { session: session ?? null } +}) diff --git a/playground-local/server/api/token.get.ts b/playground-local/server/api/token.get.ts new file mode 100644 index 00000000..acaf83e8 --- /dev/null +++ b/playground-local/server/api/token.get.ts @@ -0,0 +1,7 @@ +import { defineEventHandler } from 'h3' +import { getToken } from '#auth' + +export default defineEventHandler((event) => { + const token = getToken(event) + return { token: token ?? null } +}) diff --git a/src/runtime/server/services/local/getServerSession.ts b/src/runtime/server/services/local/getServerSession.ts index ff90d4ad..3fe4831f 100644 --- a/src/runtime/server/services/local/getServerSession.ts +++ b/src/runtime/server/services/local/getServerSession.ts @@ -1,7 +1,49 @@ -import type { H3Event } from 'h3' -import { useRuntimeConfig } from '#app' -import { useTypedBackendConfig } from '../../../helpers' +import { createError, type H3Event } from 'h3' +import getURL from 'requrl' +import { joinURL } from 'ufo' +import { jsonPointerGet, useTypedBackendConfig } from '../../../helpers' +import { getToken } from './getToken' + +// @ts-expect-error - #auth not defined +import type { SessionData } from '#auth' +import { useRuntimeConfig } from '#imports' + +function joinPathToApiURL (event: H3Event, path: string) { + const { origin, pathname, fullBaseUrl } = useRuntimeConfig().public.auth.computed + + let baseURL + if (origin) { + // Case 1: An origin was supplied by the developer in the runtime-config. Use it by returning the already assembled full base url that contains it + baseURL = fullBaseUrl + } else { + // Case 2: An origin was not supplied, we determine it from the request + const determinedOrigin = getURL(event.node.req, false) + baseURL = joinURL(determinedOrigin, pathname) + } + + const base = path.startsWith('/') ? pathname : baseURL + return joinURL(base, path) +} + +export async function getServerSession (event: H3Event): Promise { + const token = getToken(event) + if (!token) { + return null + } -export function getServerSession (event: H3Event) { const config = useTypedBackendConfig(useRuntimeConfig(), 'local') + const { path, method } = config.endpoints.getSession + + // Compose heads to request the session + const headers = new Headers(token ? { [config.token.headerName]: token } as HeadersInit : undefined) + + try { + const url = joinPathToApiURL(event, path) + const result = await $fetch(url, { method, headers }) + const { dataResponsePointer: sessionDataResponsePointer } = config.session + return jsonPointerGet(result, sessionDataResponsePointer) + } catch (err) { + console.error(err) + throw createError({ statusCode: 401, statusMessage: 'Session could not be retrieved.' }) + } } diff --git a/src/runtime/server/services/local/getToken.ts b/src/runtime/server/services/local/getToken.ts index 3b5fad7f..6160aa45 100644 --- a/src/runtime/server/services/local/getToken.ts +++ b/src/runtime/server/services/local/getToken.ts @@ -1,8 +1,14 @@ import { getCookie, type H3Event } from 'h3' -import { useRuntimeConfig } from '#app' import { useTypedBackendConfig } from '../../../helpers' +import { formatToken } from '../../../utils/local' +import { useRuntimeConfig } from '#imports' -export function getLocalServerToken (event: H3Event) { +export function getToken (event: H3Event) { const config = useTypedBackendConfig(useRuntimeConfig(), 'local') - return getCookie(event, config.token.cookieName) + const token = getCookie(event, config.token.cookieName) + if (!token) { + return null + } + + return formatToken(token) } diff --git a/src/runtime/server/services/local/index.ts b/src/runtime/server/services/local/index.ts new file mode 100644 index 00000000..d6d0f4b0 --- /dev/null +++ b/src/runtime/server/services/local/index.ts @@ -0,0 +1,2 @@ +export { getToken } from './getToken' +export { getServerSession } from './getServerSession' diff --git a/src/runtime/utils/generateTypes.ts b/src/runtime/utils/generateTypes.ts index f3a58b1d..82dc74b9 100644 --- a/src/runtime/utils/generateTypes.ts +++ b/src/runtime/utils/generateTypes.ts @@ -8,10 +8,11 @@ export function generateModuleTypes (provider: AuthProviders) { const providerSpecificTypes: string[] = [] if (provider.type === 'authjs') { - providerSpecificTypes.push(` const { getServerSession, getToken, NuxtAuthHandler }: typeof import('${resolve('./runtime/server/services')}')`) + providerSpecificTypes.push(` const { getServerSession, getToken, NuxtAuthHandler }: typeof import('${resolve('./runtime/server/services/authjs')}')`) } if (provider.type === 'local') { + providerSpecificTypes.push(` const { getServerSession, getToken }: typeof import('${resolve('./runtime/server/services/local')}')`) providerSpecificTypes.push(genInterface('SessionData', (provider as any).session.dataType)) } From 04d6ab70ebd6df8802a0fa863bca5ebd960557b6 Mon Sep 17 00:00:00 2001 From: Zoey Kaiser Date: Sat, 10 Aug 2024 16:47:54 +0200 Subject: [PATCH 5/8] Added Server side ultis for refresh provider --- src/module.ts | 10 +--------- .../server/services/refresh/getRefreshToken.ts | 13 +++++++++++++ src/runtime/server/services/refresh/index.ts | 2 ++ src/runtime/utils/generateTypes.ts | 5 +++++ 4 files changed, 21 insertions(+), 9 deletions(-) create mode 100644 src/runtime/server/services/refresh/getRefreshToken.ts create mode 100644 src/runtime/server/services/refresh/index.ts diff --git a/src/module.ts b/src/module.ts index f5c3bf8f..c54be6d5 100644 --- a/src/module.ts +++ b/src/module.ts @@ -206,15 +206,7 @@ export default defineNuxtModule({ } ) - // If AuthJS is selected, inject authjs server-side services - if (selectedProvider === 'authjs') { - nitroConfig.alias['#auth'] = resolve('./runtime/server/services/authjs') - } - - // If local is selected, inject local server-side services - if (selectedProvider === 'local') { - nitroConfig.alias['#auth'] = resolve('./runtime/server/services/local') - } + nitroConfig.alias['#auth'] = resolve(`./runtime/server/services/${options.provider.type}`) }) addTypeTemplate({ diff --git a/src/runtime/server/services/refresh/getRefreshToken.ts b/src/runtime/server/services/refresh/getRefreshToken.ts new file mode 100644 index 00000000..e5698bc4 --- /dev/null +++ b/src/runtime/server/services/refresh/getRefreshToken.ts @@ -0,0 +1,13 @@ +import { getCookie, type H3Event } from 'h3' +import { useTypedBackendConfig } from '../../../helpers' +import { useRuntimeConfig } from '#imports' + +export function getRefreshToken (event: H3Event) { + const config = useTypedBackendConfig(useRuntimeConfig(), 'refresh') + const token = getCookie(event, config.refreshToken.cookieName) + if (!token) { + return null + } + + return token +} diff --git a/src/runtime/server/services/refresh/index.ts b/src/runtime/server/services/refresh/index.ts new file mode 100644 index 00000000..07fca97d --- /dev/null +++ b/src/runtime/server/services/refresh/index.ts @@ -0,0 +1,2 @@ +export { getToken, getServerSession } from '../local' +export { getRefreshToken } from './getRefreshToken' diff --git a/src/runtime/utils/generateTypes.ts b/src/runtime/utils/generateTypes.ts index 82dc74b9..3fe072dc 100644 --- a/src/runtime/utils/generateTypes.ts +++ b/src/runtime/utils/generateTypes.ts @@ -16,6 +16,11 @@ export function generateModuleTypes (provider: AuthProviders) { providerSpecificTypes.push(genInterface('SessionData', (provider as any).session.dataType)) } + if (provider.type === 'refresh') { + providerSpecificTypes.push(` const { getServerSession, getToken, getRefreshToken }: typeof import('${resolve('./runtime/server/services/refresh')}')`) + providerSpecificTypes.push(genInterface('SessionData', (provider as any).session.dataType)) + } + return [ '// AUTO-GENERATED BY @sidebase/nuxt-auth', "declare module '#auth' {", From 70f9b362a0c578b2e74b3af5d886ee31f8c91421 Mon Sep 17 00:00:00 2001 From: Zoey Kaiser Date: Thu, 22 Aug 2024 19:48:42 +0200 Subject: [PATCH 6/8] removed outdated refresh logic --- .../server/services/refresh/getRefreshToken.ts | 13 ------------- src/runtime/server/services/refresh/index.ts | 2 -- src/runtime/utils/generateTypes.ts | 7 +------ 3 files changed, 1 insertion(+), 21 deletions(-) delete mode 100644 src/runtime/server/services/refresh/getRefreshToken.ts delete mode 100644 src/runtime/server/services/refresh/index.ts diff --git a/src/runtime/server/services/refresh/getRefreshToken.ts b/src/runtime/server/services/refresh/getRefreshToken.ts deleted file mode 100644 index e5698bc4..00000000 --- a/src/runtime/server/services/refresh/getRefreshToken.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { getCookie, type H3Event } from 'h3' -import { useTypedBackendConfig } from '../../../helpers' -import { useRuntimeConfig } from '#imports' - -export function getRefreshToken (event: H3Event) { - const config = useTypedBackendConfig(useRuntimeConfig(), 'refresh') - const token = getCookie(event, config.refreshToken.cookieName) - if (!token) { - return null - } - - return token -} diff --git a/src/runtime/server/services/refresh/index.ts b/src/runtime/server/services/refresh/index.ts deleted file mode 100644 index 07fca97d..00000000 --- a/src/runtime/server/services/refresh/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { getToken, getServerSession } from '../local' -export { getRefreshToken } from './getRefreshToken' diff --git a/src/runtime/utils/generateTypes.ts b/src/runtime/utils/generateTypes.ts index 3fe072dc..1cae25fa 100644 --- a/src/runtime/utils/generateTypes.ts +++ b/src/runtime/utils/generateTypes.ts @@ -16,14 +16,9 @@ export function generateModuleTypes (provider: AuthProviders) { providerSpecificTypes.push(genInterface('SessionData', (provider as any).session.dataType)) } - if (provider.type === 'refresh') { - providerSpecificTypes.push(` const { getServerSession, getToken, getRefreshToken }: typeof import('${resolve('./runtime/server/services/refresh')}')`) - providerSpecificTypes.push(genInterface('SessionData', (provider as any).session.dataType)) - } - return [ '// AUTO-GENERATED BY @sidebase/nuxt-auth', - "declare module '#auth' {", + `declare module '#auth' {`, ...providerSpecificTypes, '}', '' From 10402c03084b397d61e66a0702f074b9c18073ba Mon Sep 17 00:00:00 2001 From: Zoey Kaiser Date: Thu, 22 Aug 2024 19:51:38 +0200 Subject: [PATCH 7/8] fix: lint --- .../server/services/local/getServerSession.ts | 12 +++++++----- src/runtime/server/services/local/getToken.ts | 6 +++--- src/runtime/utils/generateTypes.ts | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/runtime/server/services/local/getServerSession.ts b/src/runtime/server/services/local/getServerSession.ts index 3fe4831f..5e12c685 100644 --- a/src/runtime/server/services/local/getServerSession.ts +++ b/src/runtime/server/services/local/getServerSession.ts @@ -1,4 +1,4 @@ -import { createError, type H3Event } from 'h3' +import { type H3Event, createError } from 'h3' import getURL from 'requrl' import { joinURL } from 'ufo' import { jsonPointerGet, useTypedBackendConfig } from '../../../helpers' @@ -8,14 +8,15 @@ import { getToken } from './getToken' import type { SessionData } from '#auth' import { useRuntimeConfig } from '#imports' -function joinPathToApiURL (event: H3Event, path: string) { +function joinPathToApiURL(event: H3Event, path: string) { const { origin, pathname, fullBaseUrl } = useRuntimeConfig().public.auth.computed let baseURL if (origin) { // Case 1: An origin was supplied by the developer in the runtime-config. Use it by returning the already assembled full base url that contains it baseURL = fullBaseUrl - } else { + } + else { // Case 2: An origin was not supplied, we determine it from the request const determinedOrigin = getURL(event.node.req, false) baseURL = joinURL(determinedOrigin, pathname) @@ -25,7 +26,7 @@ function joinPathToApiURL (event: H3Event, path: string) { return joinURL(base, path) } -export async function getServerSession (event: H3Event): Promise { +export async function getServerSession(event: H3Event): Promise { const token = getToken(event) if (!token) { return null @@ -42,7 +43,8 @@ export async function getServerSession (event: H3Event): Promise(url, { method, headers }) const { dataResponsePointer: sessionDataResponsePointer } = config.session return jsonPointerGet(result, sessionDataResponsePointer) - } catch (err) { + } + catch (err) { console.error(err) throw createError({ statusCode: 401, statusMessage: 'Session could not be retrieved.' }) } diff --git a/src/runtime/server/services/local/getToken.ts b/src/runtime/server/services/local/getToken.ts index 6160aa45..9dd026b6 100644 --- a/src/runtime/server/services/local/getToken.ts +++ b/src/runtime/server/services/local/getToken.ts @@ -1,14 +1,14 @@ -import { getCookie, type H3Event } from 'h3' +import { type H3Event, getCookie } from 'h3' import { useTypedBackendConfig } from '../../../helpers' import { formatToken } from '../../../utils/local' import { useRuntimeConfig } from '#imports' -export function getToken (event: H3Event) { +export function getToken(event: H3Event) { const config = useTypedBackendConfig(useRuntimeConfig(), 'local') const token = getCookie(event, config.token.cookieName) if (!token) { return null } - return formatToken(token) + return formatToken(token, config) } diff --git a/src/runtime/utils/generateTypes.ts b/src/runtime/utils/generateTypes.ts index 1cae25fa..7834fd3d 100644 --- a/src/runtime/utils/generateTypes.ts +++ b/src/runtime/utils/generateTypes.ts @@ -2,7 +2,7 @@ import { genInterface } from 'knitwork' import { createResolver } from '@nuxt/kit' import type { AuthProviders } from '../types' -export function generateModuleTypes (provider: AuthProviders) { +export function generateModuleTypes(provider: AuthProviders) { const { resolve } = createResolver(import.meta.url) const providerSpecificTypes: string[] = [] From e9b8654b60d0b5c16e78ad4fef00abd73a86c0a7 Mon Sep 17 00:00:00 2001 From: Zoey Kaiser Date: Thu, 22 Aug 2024 20:07:20 +0200 Subject: [PATCH 8/8] Added Middleware examples --- playground-local/app.vue | 20 ++++++++++++++++--- .../server/api/protected/inline.ts | 10 ++++++++++ .../server/api/protected/middleware.ts | 3 +++ playground-local/server/api/session.get.ts | 5 +---- playground-local/server/api/token.get.ts | 5 +---- playground-local/server/middleware/auth.ts | 14 +++++++++++++ .../server/services/local/getServerSession.ts | 2 +- src/runtime/server/services/local/getToken.ts | 7 ++++--- 8 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 playground-local/server/api/protected/inline.ts create mode 100644 playground-local/server/api/protected/middleware.ts create mode 100644 playground-local/server/middleware/auth.ts diff --git a/playground-local/app.vue b/playground-local/app.vue index 6ccd2788..c2b6d45e 100644 --- a/playground-local/app.vue +++ b/playground-local/app.vue @@ -41,9 +41,23 @@ const password = ref('') refresh session (required: true)
- - navigate to Login Page - +

Navigation

+

Navigate to different pages below to test out different things:

+
+ + -> API endpoint protected inline + +
+ + -> API endpoint protected middleware + +
+ + -> navigate to Login Page + +
+
+
diff --git a/playground-local/server/api/protected/inline.ts b/playground-local/server/api/protected/inline.ts new file mode 100644 index 00000000..8a7e77d9 --- /dev/null +++ b/playground-local/server/api/protected/inline.ts @@ -0,0 +1,10 @@ +import { eventHandler } from 'h3' +import { getServerSession } from '#auth' + +export default eventHandler(async (event) => { + const session = await getServerSession(event) + if (!session) { + return { status: 'unauthenticated!' } + } + return { status: 'authenticated!', text: 'im protected by an in-endpoint check', session } +}) diff --git a/playground-local/server/api/protected/middleware.ts b/playground-local/server/api/protected/middleware.ts new file mode 100644 index 00000000..485da1ac --- /dev/null +++ b/playground-local/server/api/protected/middleware.ts @@ -0,0 +1,3 @@ +import { eventHandler } from 'h3' + +export default eventHandler(() => ({ status: 'authenticated', text: 'you only see me if you are logged in, as a server-middleware protects me' })) diff --git a/playground-local/server/api/session.get.ts b/playground-local/server/api/session.get.ts index 99852017..5d5e4b5b 100644 --- a/playground-local/server/api/session.get.ts +++ b/playground-local/server/api/session.get.ts @@ -1,7 +1,4 @@ import { defineEventHandler } from 'h3' import { getServerSession } from '#auth' -export default defineEventHandler(async (event) => { - const session = await getServerSession(event) - return { session: session ?? null } -}) +export default defineEventHandler(event => getServerSession(event)) diff --git a/playground-local/server/api/token.get.ts b/playground-local/server/api/token.get.ts index acaf83e8..cd349d63 100644 --- a/playground-local/server/api/token.get.ts +++ b/playground-local/server/api/token.get.ts @@ -1,7 +1,4 @@ import { defineEventHandler } from 'h3' import { getToken } from '#auth' -export default defineEventHandler((event) => { - const token = getToken(event) - return { token: token ?? null } -}) +export default defineEventHandler(event => getToken(event)) diff --git a/playground-local/server/middleware/auth.ts b/playground-local/server/middleware/auth.ts new file mode 100644 index 00000000..8b6ce9a9 --- /dev/null +++ b/playground-local/server/middleware/auth.ts @@ -0,0 +1,14 @@ +import { createError, eventHandler } from 'h3' +import { getServerSession } from '#auth' + +export default eventHandler(async (event) => { + // Only protect a certain backend route + if (!event.node.req.url?.startsWith('/api/protected/middleware')) { + return + } + + const session = await getServerSession(event) + if (!session) { + throw createError({ statusMessage: 'Unauthenticated', statusCode: 403 }) + } +}) diff --git a/src/runtime/server/services/local/getServerSession.ts b/src/runtime/server/services/local/getServerSession.ts index 5e12c685..7147767a 100644 --- a/src/runtime/server/services/local/getServerSession.ts +++ b/src/runtime/server/services/local/getServerSession.ts @@ -36,7 +36,7 @@ export async function getServerSession(event: H3Event): Promise