Skip to content

Commit 4141146

Browse files
committed
init: nuxt better auth module
0 parents  commit 4141146

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+10603
-0
lines changed

.editorconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
root = true
2+
3+
[*]
4+
indent_size = 2
5+
indent_style = space
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false

.github/workflows/ci.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
lint:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- uses: actions/checkout@v6
17+
18+
- uses: actions/setup-node@v6
19+
with:
20+
node-version: 20
21+
22+
- run: npm i -g --force corepack@latest && corepack enable
23+
24+
- name: Install dependencies
25+
run: npx nypm@latest i
26+
27+
- name: Lint
28+
run: npm run lint
29+
30+
test:
31+
runs-on: ubuntu-latest
32+
33+
steps:
34+
- uses: actions/checkout@v6
35+
36+
- uses: actions/setup-node@v6
37+
with:
38+
node-version: 20
39+
40+
- run: npm i -g --force corepack@latest && corepack enable
41+
42+
- name: Install dependencies
43+
run: npx nypm@latest i
44+
45+
- name: Playground prepare
46+
run: npm run dev:prepare
47+
48+
- name: Test
49+
run: npm run test

.gitignore

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Dependencies
2+
node_modules
3+
4+
# Logs
5+
*.log*
6+
7+
# Temp directories
8+
.temp
9+
.tmp
10+
.cache
11+
12+
# Yarn
13+
**/.yarn/cache
14+
**/.yarn/*state*
15+
16+
# Generated dirs
17+
dist
18+
19+
# Nuxt
20+
.nuxt
21+
.output
22+
.data
23+
.vercel_build_output
24+
.build-*
25+
.netlify
26+
27+
# Env
28+
.env
29+
30+
# Testing
31+
reports
32+
coverage
33+
*.lcov
34+
.nyc_output
35+
36+
# VSCode
37+
.vscode/*
38+
!.vscode/settings.json
39+
!.vscode/tasks.json
40+
!.vscode/launch.json
41+
!.vscode/extensions.json
42+
!.vscode/*.code-snippets
43+
44+
# Intellij idea
45+
*.iml
46+
.idea
47+
48+
# OSX
49+
.DS_Store
50+
.AppleDouble
51+
.LSOverride
52+
.AppleDB
53+
.AppleDesktop
54+
Network Trash Folder
55+
Temporary Items
56+
.apdisk

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
enable-pre-post-scripts=true

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"eslint.experimental.useFlatConfig": true
3+
}

README.md

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Nuxt Better Auth
2+
3+
[![npm version][npm-version-src]][npm-version-href]
4+
[![npm downloads][npm-downloads-src]][npm-downloads-href]
5+
[![License][license-src]][license-href]
6+
[![Nuxt][nuxt-src]][nuxt-href]
7+
8+
Nuxt module for [Better Auth](https://better-auth.com) integration with route protection, session management, and role-based access.
9+
10+
## Features
11+
12+
- Route Protection - Declarative access rules via `routeRules`
13+
- Session Management - Server and client plugins that sync auth state
14+
- Role-Based Access - Support for `admin`, `user`, and custom roles
15+
- Tier Gating - Generic tier system for subscription/premium features
16+
- Auto-Imports - `useUserSession`, `usePageAccess`, `requireUserSession`, `getUserSession`
17+
18+
## Quick Start
19+
20+
### 1. Install
21+
22+
```bash
23+
pnpm add nuxt-better-auth better-auth drizzle-orm
24+
```
25+
26+
### 2. Create Server Config
27+
28+
Create `server/auth.config.ts`:
29+
30+
```ts
31+
import { admin } from 'better-auth/plugins'
32+
import { defineServerAuth } from 'nuxt-better-auth'
33+
34+
export default defineServerAuth(({ runtimeConfig, db }) => ({
35+
appName: 'My App',
36+
plugins: [admin()],
37+
emailAndPassword: { enabled: true },
38+
}))
39+
```
40+
41+
### 3. Create Client Config
42+
43+
Create `app/auth.client.ts`:
44+
45+
```ts
46+
import { adminClient } from 'better-auth/client/plugins'
47+
import { createAuthClient } from 'better-auth/vue'
48+
49+
export function createAppAuthClient(baseURL: string) {
50+
return createAuthClient({
51+
baseURL,
52+
plugins: [adminClient()],
53+
})
54+
}
55+
56+
export type AppAuthClient = ReturnType<typeof createAppAuthClient>
57+
```
58+
59+
### 4. Add Type Extensions
60+
61+
Create `shared/types/auth.d.ts`:
62+
63+
```ts
64+
import '#nuxt-better-auth'
65+
66+
declare module '#nuxt-better-auth' {
67+
interface AuthUser {
68+
role?: string | null
69+
banned?: boolean | null
70+
}
71+
}
72+
```
73+
74+
### 5. Configure Nuxt
75+
76+
```ts
77+
export default defineNuxtConfig({
78+
modules: ['nuxt-better-auth'],
79+
80+
runtimeConfig: {
81+
betterAuthSecret: '', // BETTER_AUTH_SECRET env var
82+
public: { siteUrl: 'http://localhost:3000' },
83+
},
84+
85+
routeRules: {
86+
'/app/**': { auth: 'user' },
87+
'/admin/**': { auth: 'user', requiresAdmin: true },
88+
'/login': { auth: 'guest' },
89+
},
90+
})
91+
```
92+
93+
### 6. Setup Database
94+
95+
Set the global database instance in a server plugin:
96+
97+
```ts
98+
// server/plugins/db.ts
99+
export default defineNitroPlugin(() => {
100+
;(globalThis as any).__nuxt_better_auth_db = yourDrizzleInstance
101+
})
102+
```
103+
104+
## Route Rules
105+
106+
| Option | Type | Description |
107+
|--------|------|-------------|
108+
| `auth` | `boolean \| 'guest' \| 'user'` | Auth requirement |
109+
| `role` | `string \| string[]` | Required role(s) |
110+
| `requiresAdmin` | `boolean` | Shorthand for `role: 'admin'` |
111+
| `tier` | `string \| string[]` | Required tier |
112+
113+
## Composables
114+
115+
### `useUserSession()`
116+
117+
```ts
118+
const { user, session, loggedIn, ready, client, signIn, signUp, signOut, fetchSession, updateUser } = useUserSession()
119+
```
120+
121+
### `usePageAccess()`
122+
123+
```ts
124+
const { hasAccess, showPaywall, paywallConfig } = usePageAccess()
125+
```
126+
127+
## Server Utils
128+
129+
```ts
130+
// Require auth
131+
const { user, session } = await requireUserSession(event)
132+
133+
// Require admin
134+
const { user } = await requireUserSession(event, { role: 'admin' })
135+
136+
// Optional session
137+
const session = await getUserSession(event)
138+
```
139+
140+
## Module Aliases
141+
142+
| Alias | Points To |
143+
|-------|-----------|
144+
| `#auth/server` | `server/auth.config.ts` |
145+
| `#auth/client` | `app/auth.client.ts` |
146+
| `#nuxt-better-auth` | Module type augmentation |
147+
148+
## Development
149+
150+
```bash
151+
pnpm install
152+
pnpm dev:prepare
153+
pnpm dev
154+
```
155+
156+
## License
157+
158+
MIT
159+
160+
<!-- Badges -->
161+
[npm-version-src]: https://img.shields.io/npm/v/nuxt-better-auth/latest.svg?style=flat&colorA=020420&colorB=00DC82
162+
[npm-version-href]: https://npmjs.com/package/nuxt-better-auth
163+
164+
[npm-downloads-src]: https://img.shields.io/npm/dm/nuxt-better-auth.svg?style=flat&colorA=020420&colorB=00DC82
165+
[npm-downloads-href]: https://npm.chart.dev/nuxt-better-auth
166+
167+
[license-src]: https://img.shields.io/npm/l/nuxt-better-auth.svg?style=flat&colorA=020420&colorB=00DC82
168+
[license-href]: https://npmjs.com/package/nuxt-better-auth
169+
170+
[nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt.js
171+
[nuxt-href]: https://nuxt.com

eslint.config.mjs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// @ts-check
2+
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'
3+
4+
// Run `npx @eslint/config-inspector` to inspect the resolved config interactively
5+
export default createConfigForNuxt({
6+
features: {
7+
// Rules for module authors
8+
tooling: true,
9+
// Rules for formatting
10+
stylistic: true,
11+
},
12+
dirs: {
13+
src: [
14+
'./playground',
15+
],
16+
},
17+
})
18+
.append(
19+
// your custom flat config here...
20+
)

package.json

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"name": "nuxt-better-auth",
3+
"version": "0.1.0",
4+
"description": "Nuxt module for Better Auth integration with route protection, session management, and role-based access",
5+
"repository": "your-org/nuxt-better-auth",
6+
"license": "MIT",
7+
"type": "module",
8+
"exports": {
9+
".": { "types": "./dist/types.d.mts", "import": "./dist/module.mjs" }
10+
},
11+
"main": "./dist/module.mjs",
12+
"typesVersions": { "*": { ".": ["./dist/types.d.mts"] } },
13+
"files": ["dist"],
14+
"scripts": {
15+
"prepack": "nuxt-module-build build",
16+
"dev": "pnpm dev:prepare && nuxi dev playground",
17+
"dev:build": "nuxi build playground",
18+
"dev:prepare": "nuxt-module-build build --stub && nuxi prepare playground",
19+
"release": "pnpm lint && pnpm test && pnpm prepack && changelogen --release && npm publish && git push --follow-tags",
20+
"lint": "eslint .",
21+
"test": "vitest run",
22+
"test:watch": "vitest watch",
23+
"test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
24+
},
25+
"dependencies": {
26+
"@nuxt/kit": "^4.2.2",
27+
"defu": "^6.1.4",
28+
"radix3": "^1.1.2"
29+
},
30+
"peerDependencies": {
31+
"better-auth": ">=1.0.0",
32+
"drizzle-orm": ">=0.30.0"
33+
},
34+
"devDependencies": {
35+
"@nuxt/devtools": "^3.1.1",
36+
"@nuxt/eslint-config": "^1.11.0",
37+
"@nuxt/module-builder": "^1.0.2",
38+
"@nuxt/schema": "^4.2.2",
39+
"@nuxt/test-utils": "^3.21.0",
40+
"@types/better-sqlite3": "^7.6.13",
41+
"@types/node": "latest",
42+
"better-auth": "^1.2.8",
43+
"better-sqlite3": "^11.9.1",
44+
"changelogen": "^0.6.2",
45+
"consola": "^3.4.2",
46+
"drizzle-orm": "^0.38.4",
47+
"eslint": "^9.39.1",
48+
"nuxt": "^4.2.2",
49+
"typescript": "~5.9.3",
50+
"vitest": "^4.0.15",
51+
"vue-tsc": "^3.1.7"
52+
}
53+
}

0 commit comments

Comments
 (0)