@onmax/nuxt-better-auth 0.0.2-alpha.14 → 0.0.2-alpha.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,115 +0,0 @@
1
- # Database Integration
2
-
3
- ## NuxtHub Setup
4
-
5
- ```ts
6
- // nuxt.config.ts
7
- export default defineNuxtConfig({
8
- modules: ['@nuxthub/core', '@onmax/nuxt-better-auth'],
9
- hub: { database: true },
10
- auth: {
11
- secondaryStorage: true, // Optional: KV for session caching
12
- schema: {
13
- usePlural: false, // user vs users
14
- casing: 'camelCase' // camelCase or snake_case
15
- }
16
- }
17
- })
18
- ```
19
-
20
- ## Schema Generation
21
-
22
- The module auto-generates Drizzle schema from Better Auth tables. Schema available via:
23
-
24
- ```ts
25
- import { user, session, account, verification } from '#auth/database'
26
- ```
27
-
28
- ## Database Dialect
29
-
30
- Supports: `sqlite`, `postgresql`, `mysql`
31
-
32
- Schema syntax adapts to dialect:
33
-
34
- - SQLite: `integer('id').primaryKey()`
35
- - PostgreSQL/MySQL: `uuid('id').primaryKey()` or `text('id').primaryKey()`
36
-
37
- ## Schema Options
38
-
39
- ```ts
40
- auth: {
41
- schema: {
42
- usePlural: true, // tables: users, sessions, accounts
43
- casing: 'snake_case' // columns: created_at, updated_at
44
- }
45
- }
46
- ```
47
-
48
- | Option | Default | Description |
49
- | ----------- | ------------- | ------------------------ |
50
- | `usePlural` | `false` | Pluralize table names |
51
- | `casing` | `'camelCase'` | Column naming convention |
52
-
53
- ## Extending Schema
54
-
55
- Add custom columns via NuxtHub's schema hooks:
56
-
57
- ```ts
58
- // server/plugins/extend-schema.ts
59
- export default defineNitroPlugin(() => {
60
- useNitroApp().hooks.hook('hub:db:schema:extend', (schema) => {
61
- // Add custom tables or extend existing
62
- })
63
- })
64
- ```
65
-
66
- ## Secondary Storage (KV)
67
-
68
- Enable session caching with KV:
69
-
70
- ```ts
71
- auth: {
72
- secondaryStorage: true
73
- }
74
- ```
75
-
76
- Requires `hub.kv: true` in config. Improves session lookup performance.
77
-
78
- ## Server Config with DB
79
-
80
- Database adapter injected via context:
81
-
82
- ```ts
83
- // server/auth.config.ts
84
- import { defineServerAuth } from '#auth/server'
85
-
86
- export default defineServerAuth(({ db }) => ({
87
- database: db, // Already configured when hub.database: true
88
- emailAndPassword: { enabled: true }
89
- }))
90
- ```
91
-
92
- ## Manual Database Setup
93
-
94
- Without NuxtHub, configure manually:
95
-
96
- ```ts
97
- // server/auth.config.ts
98
- import { drizzle } from 'drizzle-orm/...'
99
- import { defineServerAuth } from '#auth/server'
100
-
101
- const db = drizzle(...)
102
-
103
- export default defineServerAuth(() => ({
104
- database: drizzleAdapter(db, { provider: 'sqlite' })
105
- }))
106
- ```
107
-
108
- ## Migrations
109
-
110
- Better Auth creates tables automatically on first run. For production, generate migrations:
111
-
112
- ```bash
113
- # Using Better Auth CLI
114
- npx better-auth generate
115
- ```
@@ -1,126 +0,0 @@
1
- # Installation & Configuration
2
-
3
- ## Install
4
-
5
- ```bash
6
- pnpm add @onmax/nuxt-better-auth better-auth
7
- ```
8
-
9
- **Version Requirements:**
10
-
11
- - `@onmax/nuxt-better-auth`: `^0.0.2-alpha.12` (alpha)
12
- - `better-auth`: `^1.0.0` (module tested with `1.4.7`)
13
- - `@nuxthub/core`: `^0.10.0` (optional, for database)
14
-
15
- ## Module Setup
16
-
17
- ```ts
18
- // nuxt.config.ts
19
- export default defineNuxtConfig({
20
- modules: ['@onmax/nuxt-better-auth'],
21
- auth: {
22
- serverConfig: 'server/auth.config', // default
23
- clientConfig: 'app/auth.config', // default
24
- clientOnly: false, // true for external auth backend
25
- redirects: {
26
- login: '/login', // redirect when auth required
27
- guest: '/' // redirect when already logged in
28
- }
29
- }
30
- })
31
- ```
32
-
33
- ## Environment Variables
34
-
35
- ```bash
36
- # Required (min 32 chars)
37
- BETTER_AUTH_SECRET=your-secret-key-at-least-32-characters
38
-
39
- # Required in production for OAuth
40
- NUXT_PUBLIC_SITE_URL=https://your-domain.com
41
- ```
42
-
43
- ## Server Config
44
-
45
- ```ts
46
- // server/auth.config.ts
47
- import { defineServerAuth } from '#auth/server'
48
-
49
- export default defineServerAuth(({ runtimeConfig, db }) => ({
50
- emailAndPassword: { enabled: true },
51
- // OAuth providers
52
- socialProviders: {
53
- github: {
54
- clientId: runtimeConfig.github.clientId,
55
- clientSecret: runtimeConfig.github.clientSecret
56
- }
57
- },
58
- // Session configuration (optional)
59
- session: {
60
- expiresIn: 60 * 60 * 24 * 7, // 7 days (default)
61
- updateAge: 60 * 60 * 24, // Update every 24h (default)
62
- freshAge: 60 * 60 * 24, // Consider fresh for 24h (default, 0 to disable)
63
- cookieCache: {
64
- enabled: true,
65
- maxAge: 60 * 5 // 5 minutes cookie cache
66
- }
67
- }
68
- }))
69
- ```
70
-
71
- Context available in `defineServerAuth`:
72
-
73
- - `runtimeConfig` - Nuxt runtime config
74
- - `db` - Database adapter (when NuxtHub enabled)
75
-
76
- ### Session Options
77
-
78
- | Option | Default | Description |
79
- | ----------------------- | ------------------ | --------------------------------------------- |
80
- | `expiresIn` | `604800` (7 days) | Session lifetime in seconds |
81
- | `updateAge` | `86400` (24 hours) | How often to refresh session expiry |
82
- | `freshAge` | `86400` (24 hours) | Session considered "fresh" period (0 = never) |
83
- | `cookieCache.enabled` | `false` | Enable cookie caching to reduce DB queries |
84
- | `cookieCache.maxAge` | `300` (5 minutes) | Cookie cache lifetime |
85
- | `disableSessionRefresh` | `false` | Disable automatic session refresh |
86
-
87
- ## Client Config
88
-
89
- ```ts
90
- // app/auth.config.ts
91
- import { createAppAuthClient } from '#auth/client'
92
-
93
- export default createAppAuthClient({
94
- // Client-side plugin options (e.g., passkey, twoFactor)
95
- })
96
- ```
97
-
98
- ## NuxtHub Integration
99
-
100
- ```ts
101
- // nuxt.config.ts
102
- export default defineNuxtConfig({
103
- modules: ['@nuxthub/core', '@onmax/nuxt-better-auth'],
104
- hub: { database: true },
105
- auth: {
106
- secondaryStorage: true // Enable KV for session caching
107
- }
108
- })
109
- ```
110
-
111
- See [references/database.md](database.md) for schema setup.
112
-
113
- ## Client-Only Mode
114
-
115
- For external auth backends (microservices, separate servers):
116
-
117
- ```ts
118
- // nuxt.config.ts
119
- export default defineNuxtConfig({
120
- auth: {
121
- clientOnly: true, // No local auth server
122
- }
123
- })
124
- ```
125
-
126
- See [references/client-only.md](client-only.md) for full setup.
@@ -1,138 +0,0 @@
1
- # Better Auth Plugins
2
-
3
- The module supports all Better Auth plugins. Configure in both server and client configs.
4
-
5
- ## Server Plugin Setup
6
-
7
- ```ts
8
- // server/auth.config.ts
9
- import { defineServerAuth } from '#auth/server'
10
-
11
- export default defineServerAuth(({ runtimeConfig }) => ({
12
- emailAndPassword: { enabled: true },
13
- plugins: [
14
- admin(),
15
- twoFactor({ issuer: 'MyApp' }),
16
- passkey(),
17
- multiSession()
18
- ]
19
- }))
20
- ```
21
-
22
- ## Client Plugin Setup
23
-
24
- ```ts
25
- // app/auth.config.ts
26
- import { createAppAuthClient } from '#auth/client'
27
- import { adminClient, twoFactorClient, passkeyClient, multiSessionClient } from 'better-auth/client/plugins'
28
-
29
- export default createAppAuthClient({
30
- plugins: [
31
- adminClient(),
32
- twoFactorClient(),
33
- passkeyClient(),
34
- multiSessionClient()
35
- ]
36
- })
37
- ```
38
-
39
- ## Common Plugins
40
-
41
- ### Admin
42
-
43
- Role-based access control:
44
-
45
- ```ts
46
- // Server
47
- import { admin } from 'better-auth/plugins'
48
- plugins: [admin()]
49
-
50
- // Client
51
- import { adminClient } from 'better-auth/client/plugins'
52
- plugins: [adminClient()]
53
- ```
54
-
55
- Usage:
56
-
57
- ```ts
58
- // Protect route
59
- await requireUserSession(event, { user: { role: 'admin' } })
60
-
61
- // Client: set user role
62
- await client.admin.setRole({ userId: 'xxx', role: 'admin' })
63
- ```
64
-
65
- ### Two-Factor (2FA)
66
-
67
- ```ts
68
- // Server
69
- import { twoFactor } from 'better-auth/plugins'
70
- plugins: [twoFactor({ issuer: 'MyApp' })]
71
-
72
- // Client
73
- import { twoFactorClient } from 'better-auth/client/plugins'
74
- plugins: [twoFactorClient()]
75
- ```
76
-
77
- Usage:
78
-
79
- ```ts
80
- // Enable 2FA
81
- const { totpURI } = await client.twoFactor.enable({ password: 'xxx' })
82
- // Show QR code with totpURI
83
-
84
- // Verify OTP on login
85
- await client.twoFactor.verifyTotp({ code: '123456' })
86
- ```
87
-
88
- ### Passkey
89
-
90
- WebAuthn/FIDO2 authentication:
91
-
92
- ```ts
93
- // Server
94
- import { passkey } from 'better-auth/plugins'
95
- plugins: [passkey()]
96
-
97
- // Client
98
- import { passkeyClient } from 'better-auth/client/plugins'
99
- plugins: [passkeyClient()]
100
- ```
101
-
102
- Usage:
103
-
104
- ```ts
105
- // Register passkey
106
- await client.passkey.addPasskey()
107
-
108
- // Sign in with passkey
109
- await signIn.passkey()
110
- ```
111
-
112
- ### Multi-Session
113
-
114
- Allow multiple concurrent sessions:
115
-
116
- ```ts
117
- // Server
118
- import { multiSession } from 'better-auth/plugins'
119
- plugins: [multiSession()]
120
-
121
- // Client
122
- import { multiSessionClient } from 'better-auth/client/plugins'
123
- plugins: [multiSessionClient()]
124
- ```
125
-
126
- Usage:
127
-
128
- ```ts
129
- // List all sessions
130
- const sessions = await client.multiSession.listDeviceSessions()
131
-
132
- // Revoke specific session
133
- await client.multiSession.revokeSession({ sessionId: 'xxx' })
134
- ```
135
-
136
- ## Plugin Type Inference
137
-
138
- Types from plugins are automatically inferred. See [references/types.md](types.md) for type augmentation.
@@ -1,105 +0,0 @@
1
- # Route Protection
2
-
3
- Three layers of protection: route rules, page meta, and server middleware.
4
-
5
- ## Route Rules (Global)
6
-
7
- Define auth requirements in `nuxt.config.ts`:
8
-
9
- ```ts
10
- export default defineNuxtConfig({
11
- routeRules: {
12
- '/admin/**': { auth: { user: { role: 'admin' } } },
13
- '/dashboard/**': { auth: 'user' },
14
- '/login': { auth: 'guest' },
15
- '/public/**': { auth: false }
16
- }
17
- })
18
- ```
19
-
20
- ## Auth Modes
21
-
22
- | Mode | Behavior |
23
- | ----------------- | ------------------------------------------------------ |
24
- | `'user'` | Requires authenticated user |
25
- | `'guest'` | Only unauthenticated users (redirects logged-in users) |
26
- | `{ user: {...} }` | Requires user matching specific properties |
27
- | `false` | No protection |
28
-
29
- ## Page Meta (Per-Page)
30
-
31
- Override or define auth for specific pages:
32
-
33
- ```vue
34
- <script setup>
35
- // Require authentication
36
- definePageMeta({ auth: 'user' })
37
- </script>
38
- ```
39
-
40
- ```vue
41
- <script setup>
42
- // Require admin role
43
- definePageMeta({
44
- auth: { user: { role: 'admin' } }
45
- })
46
- </script>
47
- ```
48
-
49
- ```vue
50
- <script setup>
51
- // Guest-only (login page)
52
- definePageMeta({ auth: 'guest' })
53
- </script>
54
- ```
55
-
56
- ## User Property Matching
57
-
58
- ```ts
59
- // Single value
60
- { auth: { user: { role: 'admin' } } }
61
-
62
- // OR logic (array)
63
- { auth: { user: { role: ['admin', 'moderator'] } } }
64
-
65
- // AND logic (multiple fields)
66
- { auth: { user: { role: 'admin', verified: true } } }
67
- ```
68
-
69
- ## Redirect Configuration
70
-
71
- ```ts
72
- // nuxt.config.ts
73
- export default defineNuxtConfig({
74
- auth: {
75
- redirects: {
76
- login: '/login', // Where to redirect unauthenticated users
77
- guest: '/dashboard' // Where to redirect logged-in users from guest pages
78
- }
79
- }
80
- })
81
- ```
82
-
83
- ## Server Middleware
84
-
85
- Auth middleware runs on all `/api/**` routes matching `routeRules`.
86
-
87
- For custom API protection, use `requireUserSession()`:
88
-
89
- ```ts
90
- // server/api/admin/[...].ts
91
- export default defineEventHandler(async (event) => {
92
- await requireUserSession(event, { user: { role: 'admin' } })
93
- // Handle request
94
- })
95
- ```
96
-
97
- ## Priority Order
98
-
99
- 1. `definePageMeta({ auth })` - highest priority
100
- 2. `routeRules` patterns - matched by path
101
- 3. Default: no protection
102
-
103
- ## Prerendered Pages
104
-
105
- Auth checks skip during prerender hydration. Session fetched client-side after hydration completes.
@@ -1,135 +0,0 @@
1
- # Server-Side Authentication
2
-
3
- ## serverAuth()
4
-
5
- Get the Better Auth instance for advanced operations:
6
-
7
- ```ts
8
- // server/api/custom.ts
9
- export default defineEventHandler(async (event) => {
10
- const auth = serverAuth()
11
- // Access full Better Auth API
12
- const sessions = await auth.api.listSessions({ headers: event.headers })
13
- return sessions
14
- })
15
- ```
16
-
17
- Module-level singleton (safe to call multiple times - returns cached instance).
18
-
19
- ### Available Server Methods
20
-
21
- Via `serverAuth().api`:
22
-
23
- ```ts
24
- const auth = serverAuth()
25
-
26
- // Session management
27
- await auth.api.listSessions({ headers: event.headers })
28
- await auth.api.revokeSession({ sessionId: 'xxx' }, { headers: event.headers })
29
- await auth.api.revokeOtherSessions({ headers: event.headers })
30
- await auth.api.revokeSessions({ headers: event.headers })
31
-
32
- // User management (with admin plugin)
33
- await auth.api.setRole({ userId: 'xxx', role: 'admin' }, { headers: event.headers })
34
- ```
35
-
36
- ## getUserSession()
37
-
38
- Get current session without throwing (returns null if not authenticated):
39
-
40
- ```ts
41
- export default defineEventHandler(async (event) => {
42
- const result = await getUserSession(event)
43
- if (!result) {
44
- return { guest: true }
45
- }
46
- return { user: result.user }
47
- })
48
- ```
49
-
50
- Returns `{ user: AuthUser, session: AuthSession } | null`.
51
-
52
- ## requireUserSession()
53
-
54
- Enforce authentication - throws if not authenticated:
55
-
56
- ```ts
57
- export default defineEventHandler(async (event) => {
58
- const { user, session } = await requireUserSession(event)
59
- // user and session are guaranteed to exist
60
- return { userId: user.id }
61
- })
62
- ```
63
-
64
- - Throws `401` if not authenticated
65
- - Throws `403` if user matching fails
66
-
67
- ## User Matching
68
-
69
- Restrict access based on user properties:
70
-
71
- ```ts
72
- // Single value - exact match
73
- await requireUserSession(event, {
74
- user: { role: 'admin' }
75
- })
76
-
77
- // Array - OR logic (any value matches)
78
- await requireUserSession(event, {
79
- user: { role: ['admin', 'moderator'] }
80
- })
81
-
82
- // Multiple fields - AND logic (all must match)
83
- await requireUserSession(event, {
84
- user: { role: 'admin', verified: true }
85
- })
86
- ```
87
-
88
- ## Custom Rules
89
-
90
- For complex validation logic:
91
-
92
- ```ts
93
- await requireUserSession(event, {
94
- rule: ({ user, session }) => {
95
- return user.subscription?.active && user.points > 100
96
- }
97
- })
98
-
99
- // Combined with user matching
100
- await requireUserSession(event, {
101
- user: { verified: true },
102
- rule: ({ user }) => user.subscription?.plan === 'pro'
103
- })
104
- ```
105
-
106
- ## Pattern Examples
107
-
108
- ```ts
109
- // Admin-only endpoint
110
- export default defineEventHandler(async (event) => {
111
- const { user } = await requireUserSession(event, {
112
- user: { role: 'admin' }
113
- })
114
- return getAdminData()
115
- })
116
-
117
- // Premium feature
118
- export default defineEventHandler(async (event) => {
119
- await requireUserSession(event, {
120
- rule: ({ user }) => ['pro', 'enterprise'].includes(user.plan)
121
- })
122
- return getPremiumContent()
123
- })
124
-
125
- // Owner-only resource
126
- export default defineEventHandler(async (event) => {
127
- const id = getRouterParam(event, 'id')
128
- const { user } = await requireUserSession(event)
129
- const resource = await getResource(id)
130
- if (resource.ownerId !== user.id) {
131
- throw createError({ statusCode: 403 })
132
- }
133
- return resource
134
- })
135
- ```