Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/content/2.core-concepts/4.auto-imports-aliases.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ description: What the module registers for you.
Use auto-imported utilities from @onmax/nuxt-better-auth.

- Client (auto-imported in Vue): `useUserSession()`, `useSignIn()`, `useSignUp()`
- Server (auto-imported in `server/`): `serverAuth(event?)`, `getRequestSession(event)`, `getUserSession(event)`, `setSessionCookie(event, token)`, `requireUserSession(event, options?)`
- Server (auto-imported in `server/`): `serverAuth(event?)`, `getRequestSession(event)`, `getUserSession(event)`, `createSession(event, userId)`, `setSessionCookie(event, token)`, `requireUserSession(event, options?)`
- Component: `<BetterAuthState>` for auth-ready rendering
- Alias `#nuxt-better-auth` exports types: `AuthUser`, `AuthSession`, `AuthSocialProviderId`
- Use `getRequestSession(event)` over repeated `getUserSession(event)` calls — it caches per request
Expand All @@ -33,6 +33,7 @@ Source: https://github.com/nuxt-modules/better-auth
- `serverAuth(event?)`
- `getRequestSession(event)`
- `getUserSession(event)`
- `createSession(event, userId)`
- `setSessionCookie(event, token)`
- `requireUserSession(event, options?)`

Expand All @@ -56,6 +57,7 @@ export default defineEventHandler(async (event) => {
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.
`getUserSession(event)` does not memoize by itself.

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.
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.

### Client Composables (auto-imported in Vue components)
Expand Down
18 changes: 18 additions & 0 deletions docs/content/5.api/2.server-utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,24 @@ export default defineServerAuth({
This uses Better Auth's plugin API and does not require a module-specific option.
::

## createSession

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.

```ts [server/api/custom-auth.post.ts]
export default defineEventHandler(async (event) => {
const userId = await verifyCustomLoginAndReturnUserId(event)
const session = await createSession(event, userId)

return {
sessionId: session.id,
token: session.token,
}
})
```

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.

## setSessionCookie

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.
Expand Down
7 changes: 6 additions & 1 deletion src/runtime/server/utils/session.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { AppSession, RequireSessionOptions } from '#nuxt-better-auth'
import type { AppSession, AuthSession, RequireSessionOptions } from '#nuxt-better-auth'
import type { H3Event } from 'h3'
import { createError } from 'h3'
import { matchesUser } from '../../utils/match-user'
Expand Down Expand Up @@ -323,6 +323,11 @@ export async function setSessionCookie(event: H3Event, token: string): Promise<v
])
}

export async function createSession(event: H3Event, userId: string): Promise<AuthSession> {
const context = await getServerAuthContext(event)
return context.internalAdapter.createSession?.(userId, false) as Promise<AuthSession>
}

export async function requireUserSession(event: H3Event, options?: RequireSessionOptions): Promise<AppSession> {
const session = await getRequestSession(event)

Expand Down
30 changes: 30 additions & 0 deletions test/get-request-session.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,3 +353,33 @@ describe('setSessionCookie', () => {
expect(getSessionMock).toHaveBeenCalledTimes(1)
})
})

describe('createSession', () => {
beforeEach(() => {
vi.clearAllMocks()
getSessionMock.mockReset()
createSessionMock.mockReset()
})

it('delegates to Better Auth internalAdapter.createSession with dontRememberMe disabled', async () => {
createSessionMock.mockResolvedValue({
id: 's1',
userId: 'u1',
token: 'token-1',
expiresAt: new Date(),
createdAt: new Date(),
updatedAt: new Date(),
})

const { createSession } = await import('../src/runtime/server/utils/session')
const event = createEvent()
const session = await createSession(event, 'u1')

expect(createSessionMock).toHaveBeenCalledWith('u1', false)
expect(session).toMatchObject({
id: 's1',
userId: 'u1',
token: 'token-1',
})
})
})
Loading