Skip to content

Commit 0943dad

Browse files
authored
feat: add createSession(event, userId) server utility (#300)
1 parent b17373d commit 0943dad

File tree

4 files changed

+57
-2
lines changed

4 files changed

+57
-2
lines changed

docs/content/2.core-concepts/4.auto-imports-aliases.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ description: What the module registers for you.
99
Use auto-imported utilities from @onmax/nuxt-better-auth.
1010
1111
- Client (auto-imported in Vue): `useUserSession()`, `useSignIn()`, `useSignUp()`
12-
- Server (auto-imported in `server/`): `serverAuth(event?)`, `getRequestSession(event)`, `getUserSession(event)`, `setSessionCookie(event, token)`, `requireUserSession(event, options?)`
12+
- Server (auto-imported in `server/`): `serverAuth(event?)`, `getRequestSession(event)`, `getUserSession(event)`, `createSession(event, userId)`, `setSessionCookie(event, token)`, `requireUserSession(event, options?)`
1313
- Component: `<BetterAuthState>` for auth-ready rendering
1414
- Alias `#nuxt-better-auth` exports types: `AuthUser`, `AuthSession`, `AuthSocialProviderId`
1515
- Use `getRequestSession(event)` over repeated `getUserSession(event)` calls — it caches per request
@@ -33,6 +33,7 @@ Source: https://github.com/nuxt-modules/better-auth
3333
- `serverAuth(event?)`
3434
- `getRequestSession(event)`
3535
- `getUserSession(event)`
36+
- `createSession(event, userId)`
3637
- `setSessionCookie(event, token)`
3738
- `requireUserSession(event, options?)`
3839

@@ -56,6 +57,7 @@ export default defineEventHandler(async (event) => {
5657
Use `getRequestSession(event)` when multiple handlers or middleware in the same request need session data. The helper should be preferred over repeated `getUserSession(event)` calls in the same request chain.
5758
`getUserSession(event)` does not memoize by itself.
5859

60+
Use `createSession(event, userId)` when a custom server handler finishes its own verification logic and needs a Better Auth session record without reaching into module internals.
5961
Use `setSessionCookie(event, token)` when a custom server handler completes its own verification step and needs to attach a Better Auth session cookie to the response.
6062

6163
### Client Composables (auto-imported in Vue components)

docs/content/5.api/2.server-utils.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,24 @@ export default defineServerAuth({
103103
This uses Better Auth's plugin API and does not require a module-specific option.
104104
::
105105

106+
## createSession
107+
108+
Creates a Better Auth session for a user and returns the created session record. Use this helper in custom server-side authentication flows after your handler verifies the user identity.
109+
110+
```ts [server/api/custom-auth.post.ts]
111+
export default defineEventHandler(async (event) => {
112+
const userId = await verifyCustomLoginAndReturnUserId(event)
113+
const session = await createSession(event, userId)
114+
115+
return {
116+
sessionId: session.id,
117+
token: session.token,
118+
}
119+
})
120+
```
121+
122+
Pair this helper with your preferred cookie strategy. When you also use the module cookie helper, you can set the returned token on the response after creating the session.
123+
106124
## setSessionCookie
107125

108126
Sets the Better Auth session token cookie on the current response. Use this helper in custom server-side authentication flows after you obtain or create a valid Better Auth session token.

src/runtime/server/utils/session.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { AppSession, RequireSessionOptions } from '#nuxt-better-auth'
1+
import type { AppSession, AuthSession, RequireSessionOptions } from '#nuxt-better-auth'
22
import type { H3Event } from 'h3'
33
import { createError } from 'h3'
44
import { matchesUser } from '../../utils/match-user'
@@ -323,6 +323,11 @@ export async function setSessionCookie(event: H3Event, token: string): Promise<v
323323
])
324324
}
325325

326+
export async function createSession(event: H3Event, userId: string): Promise<AuthSession> {
327+
const context = await getServerAuthContext(event)
328+
return context.internalAdapter.createSession?.(userId, false) as Promise<AuthSession>
329+
}
330+
326331
export async function requireUserSession(event: H3Event, options?: RequireSessionOptions): Promise<AppSession> {
327332
const session = await getRequestSession(event)
328333

test/get-request-session.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,3 +353,33 @@ describe('setSessionCookie', () => {
353353
expect(getSessionMock).toHaveBeenCalledTimes(1)
354354
})
355355
})
356+
357+
describe('createSession', () => {
358+
beforeEach(() => {
359+
vi.clearAllMocks()
360+
getSessionMock.mockReset()
361+
createSessionMock.mockReset()
362+
})
363+
364+
it('delegates to Better Auth internalAdapter.createSession with dontRememberMe disabled', async () => {
365+
createSessionMock.mockResolvedValue({
366+
id: 's1',
367+
userId: 'u1',
368+
token: 'token-1',
369+
expiresAt: new Date(),
370+
createdAt: new Date(),
371+
updatedAt: new Date(),
372+
})
373+
374+
const { createSession } = await import('../src/runtime/server/utils/session')
375+
const event = createEvent()
376+
const session = await createSession(event, 'u1')
377+
378+
expect(createSessionMock).toHaveBeenCalledWith('u1', false)
379+
expect(session).toMatchObject({
380+
id: 's1',
381+
userId: 'u1',
382+
token: 'token-1',
383+
})
384+
})
385+
})

0 commit comments

Comments
 (0)