Skip to content

Commit c470319

Browse files
committed
feat: add sessionHooks to extend user sessions
1 parent c60fde7 commit c470319

File tree

8 files changed

+62
-2
lines changed

8 files changed

+62
-2
lines changed

README.md

+19
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,25 @@ export default oauth.githubEventHandler({
188188

189189
Make sure to set the callback URL in your OAuth app settings as `<your-domain>/auth/github`.
190190

191+
### Extend Session
192+
193+
We leverage hooks to let you extend the session data with your own data or to log when the user clear its session.
194+
195+
```ts
196+
// server/plugins/session.ts
197+
export default defineNitroPlugin(() => {
198+
sessionHooks.hook('verify', async (session, event) => {
199+
// extend User Session by calling your database
200+
// or
201+
// throw createError({ ... }) if session is invalid for example
202+
})
203+
204+
sessionHooks.hook('clear', async (session, event) => {
205+
// Log that user logged out
206+
})
207+
})
208+
```
209+
191210
## Development
192211

193212
```bash

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"dependencies": {
3333
"@nuxt/kit": "^3.8.2",
3434
"defu": "^6.1.3",
35+
"hookable": "^5.5.3",
3536
"ofetch": "^1.3.3",
3637
"ohash": "^1.1.3"
3738
},

playground/auth.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ declare module '#auth-utils' {
1111
battledotnet?: any
1212
linkedin?: any
1313
}
14+
extended?: any
1415
loggedInAt: number
1516
}
1617
}

playground/server/plugins/session.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export default defineNitroPlugin(() => {
2+
sessionHooks.hook('verify', async (session) => {
3+
// Extend User Session
4+
// Or throw createError({ ... }) if session is invalid
5+
session.extended = {
6+
fromHooks: true
7+
}
8+
})
9+
10+
sessionHooks.hook('clear', async () => {
11+
// Log that user logged out
12+
})
13+
})
14+

pnpm-lock.yaml

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/module.ts

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export default defineNuxtModule<ModuleOptions>({
3939
{
4040
from: resolver.resolve('./runtime/server/utils/session'),
4141
imports: [
42+
'sessionHooks',
4243
'getUserSession',
4344
'setUserSession',
4445
'clearUserSession',

src/runtime/server/api/session.get.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { eventHandler } from 'h3'
2-
import { requireUserSession } from '../utils/session'
2+
import { requireUserSession, sessionHooks } from '../utils/session'
33

44
export default eventHandler(async (event) => {
5-
return await requireUserSession(event)
5+
const session = await requireUserSession(event)
6+
7+
await sessionHooks.callHookParallel('verify', event, session)
8+
9+
return session
610
})

src/runtime/server/utils/session.ts

+17
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
11
import type { H3Event, SessionConfig } from 'h3'
22
import { useSession, createError } from 'h3'
33
import { defu } from 'defu'
4+
import { createHooks } from 'hookable'
45
import { useRuntimeConfig } from '#imports'
56
import type { UserSession } from '#auth-utils'
67

8+
export interface SessionHooks {
9+
/**
10+
* Called when fetching the session from the API
11+
* - Add extra properties to the session
12+
* - Throw an error if the session could not be verified (with a database for example)
13+
*/
14+
'verify': (session: UserSession, event: H3Event) => void | Promise<void>
15+
/**
16+
* Called before clearing the session
17+
*/
18+
'clear': (session: UserSession, event: H3Event) => void | Promise<void>
19+
}
20+
21+
export const sessionHooks = createHooks<SessionHooks>()
22+
723
export async function getUserSession (event: H3Event) {
824
return (await _useSession(event)).data
925
}
@@ -23,6 +39,7 @@ export async function setUserSession (event: H3Event, data: UserSession) {
2339
export async function clearUserSession (event: H3Event) {
2440
const session = await _useSession(event)
2541

42+
await sessionHooks.callHookParallel('clear', event, session)
2643
await session.clear()
2744

2845
return true

0 commit comments

Comments
 (0)