create-nuxt-base 1.0.3 → 1.1.1

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.
package/AUTH.md ADDED
@@ -0,0 +1,289 @@
1
+ # Better Auth Integration
2
+
3
+ This document describes the Better Auth integration in the nuxt-base-starter template.
4
+
5
+ ## Overview
6
+
7
+ The template uses [Better Auth](https://www.better-auth.com/) for authentication with the following features:
8
+
9
+ | Feature | Status | Description |
10
+ |-----------------------|--------|----------------------------------------|
11
+ | Email & Password | ✅ | Standard email/password authentication |
12
+ | Two-Factor Auth (2FA) | ✅ | TOTP-based 2FA with backup codes |
13
+ | Passkey (WebAuthn) | ✅ | Passwordless authentication |
14
+ | Session Management | ✅ | Cookie-based sessions with SSR support |
15
+ | Password Hashing | ✅ | Client-side SHA256 hashing |
16
+
17
+ ## Architecture
18
+
19
+ ```
20
+ ┌─────────────────────────────────────────────────────────────────┐
21
+ │ FRONTEND (Nuxt) │
22
+ ├─────────────────────────────────────────────────────────────────┤
23
+ │ │
24
+ │ ┌─────────────────┐ ┌─────────────────┐ │
25
+ │ │ auth-client │───▶│ useBetterAuth │ │
26
+ │ │ (lib/) │ │ (composable) │ │
27
+ │ └────────┬────────┘ └────────┬────────┘ │
28
+ │ │ │ │
29
+ │ │ SHA256 Hashing │ Cookie-based State │
30
+ │ │ Plugin Config │ Session Validation │
31
+ │ │ │ │
32
+ └───────────┼──────────────────────┼──────────────────────────────┘
33
+ │ │
34
+ ▼ ▼
35
+ ┌─────────────────────────────────────────────────────────────────┐
36
+ │ BACKEND (nest-server) │
37
+ ├─────────────────────────────────────────────────────────────────┤
38
+ │ /iam/sign-in/email /iam/session │
39
+ │ /iam/sign-up/email /iam/sign-out │
40
+ │ /iam/passkey/* /iam/two-factor/* │
41
+ └─────────────────────────────────────────────────────────────────┘
42
+ ```
43
+
44
+ ## Files
45
+
46
+ | File | Purpose |
47
+ |--------------------------------------|----------------------------------|
48
+ | `app/lib/auth-client.ts` | Better Auth client configuration |
49
+ | `app/composables/use-better-auth.ts` | Auth state management composable |
50
+ | `app/pages/auth/login.vue` | Login page |
51
+ | `app/pages/auth/register.vue` | Registration page |
52
+ | `app/pages/auth/2fa.vue` | Two-factor authentication page |
53
+ | `app/pages/auth/forgot-password.vue` | Password reset request |
54
+ | `app/pages/auth/reset-password.vue` | Password reset form |
55
+ | `app/utils/crypto.ts` | SHA256 hashing utility |
56
+
57
+ ## Usage
58
+
59
+ ### Basic Authentication
60
+
61
+ ```typescript
62
+ // In a Vue component
63
+ const { signIn, signUp, signOut, user, isAuthenticated } = useBetterAuth();
64
+
65
+ // Sign in
66
+ const result = await signIn.email({
67
+ email: 'user@example.com',
68
+ password: 'password123',
69
+ });
70
+
71
+ // Sign up
72
+ const result = await signUp.email({
73
+ email: 'user@example.com',
74
+ name: 'John Doe',
75
+ password: 'password123',
76
+ });
77
+
78
+ // Sign out
79
+ await signOut();
80
+
81
+ // Check auth state
82
+ if (isAuthenticated.value) {
83
+ console.log('User:', user.value);
84
+ }
85
+ ```
86
+
87
+ ### Passkey Authentication
88
+
89
+ ```typescript
90
+ import { authClient } from '~/lib/auth-client';
91
+
92
+ // Sign in with passkey
93
+ const result = await authClient.signIn.passkey();
94
+
95
+ if (result.error) {
96
+ console.error('Passkey login failed:', result.error.message);
97
+ } else {
98
+ // Validate session to get user data (passkey returns session only)
99
+ await validateSession();
100
+ navigateTo('/app');
101
+ }
102
+ ```
103
+
104
+ ### Two-Factor Authentication
105
+
106
+ ```typescript
107
+ import { authClient } from '~/lib/auth-client';
108
+
109
+ // Verify TOTP code
110
+ const result = await authClient.twoFactor.verifyTotp({
111
+ code: '123456',
112
+ trustDevice: true,
113
+ });
114
+
115
+ // Verify backup code
116
+ const result = await authClient.twoFactor.verifyBackupCode({
117
+ code: 'backup-code-here',
118
+ });
119
+ ```
120
+
121
+ ### Session Validation
122
+
123
+ ```typescript
124
+ const { validateSession, user } = useBetterAuth();
125
+
126
+ // On app init, validate the session
127
+ const isValid = await validateSession();
128
+
129
+ if (isValid) {
130
+ console.log('Session valid, user:', user.value);
131
+ } else {
132
+ console.log('No valid session');
133
+ }
134
+ ```
135
+
136
+ ## Configuration
137
+
138
+ ### Environment Variables
139
+
140
+ ```env
141
+ # API URL (required)
142
+ API_URL=http://localhost:3000
143
+
144
+ # Or via Vite
145
+ VITE_API_URL=http://localhost:3000
146
+ ```
147
+
148
+ ### Custom Configuration
149
+
150
+ ```typescript
151
+ import { createBetterAuthClient } from '~/lib/auth-client';
152
+
153
+ // Create a custom client
154
+ const customClient = createBetterAuthClient({
155
+ baseURL: 'https://api.example.com',
156
+ basePath: '/auth', // Default: '/iam'
157
+ twoFactorRedirectPath: '/login/2fa', // Default: '/auth/2fa'
158
+ enableAdmin: false,
159
+ enableTwoFactor: true,
160
+ enablePasskey: true,
161
+ });
162
+ ```
163
+
164
+ ## Security
165
+
166
+ ### Password Hashing
167
+
168
+ Passwords are hashed with SHA256 on the client-side before transmission:
169
+
170
+ ```typescript
171
+ // This happens automatically in auth-client.ts
172
+ const hashedPassword = await sha256(plainPassword);
173
+ // Result: 64-character hex string
174
+ ```
175
+
176
+ **Why client-side hashing?**
177
+ 1. Prevents plain text passwords in network logs
178
+ 2. Works with nest-server's `normalizePasswordForIam()` which detects SHA256 hashes
179
+ 3. Server re-hashes with bcrypt for storage
180
+
181
+ ### Cookie-Based Sessions
182
+
183
+ Sessions are stored in cookies for SSR compatibility:
184
+
185
+ | Cookie | Purpose |
186
+ |-----------------------------|----------------------------|
187
+ | `auth-state` | User data (SSR-compatible) |
188
+ | `token` | Session token |
189
+ | `better-auth.session_token` | Better Auth native cookie |
190
+
191
+ ### Cross-Origin Requests
192
+
193
+ The client is configured with `credentials: 'include'` for cross-origin cookie handling:
194
+
195
+ ```typescript
196
+ // In auth-client.ts
197
+ fetchOptions: {
198
+ credentials: 'include',
199
+ }
200
+ ```
201
+
202
+ **Backend CORS Configuration:**
203
+ ```typescript
204
+ // In nest-server config
205
+ cors: {
206
+ origin: 'http://localhost:3001', // Not '*'
207
+ credentials: true,
208
+ }
209
+ ```
210
+
211
+ ## Better Auth Endpoints
212
+
213
+ The following endpoints are provided by the nest-server backend:
214
+
215
+ ### Authentication
216
+
217
+ | Endpoint | Method | Description |
218
+ |----------------------|--------|-----------------------------|
219
+ | `/iam/sign-in/email` | POST | Email/password sign in |
220
+ | `/iam/sign-up/email` | POST | Email/password registration |
221
+ | `/iam/sign-out` | POST | Sign out |
222
+ | `/iam/session` | GET | Get current session |
223
+
224
+ ### Passkey (WebAuthn)
225
+
226
+ | Endpoint | Method | Description |
227
+ |----------------------------------------------|--------|--------------------------|
228
+ | `/iam/passkey/generate-register-options` | GET | Get registration options |
229
+ | `/iam/passkey/verify-registration` | POST | Verify registration |
230
+ | `/iam/passkey/generate-authenticate-options` | GET | Get auth options |
231
+ | `/iam/passkey/verify-authentication` | POST | Verify authentication |
232
+ | `/iam/passkey/list-user-passkeys` | GET | List user's passkeys |
233
+ | `/iam/passkey/delete-passkey` | POST | Delete a passkey |
234
+
235
+ ### Two-Factor Authentication
236
+
237
+ | Endpoint | Method | Description |
238
+ |--------------------------------------|--------|--------------------|
239
+ | `/iam/two-factor/enable` | POST | Enable 2FA |
240
+ | `/iam/two-factor/disable` | POST | Disable 2FA |
241
+ | `/iam/two-factor/verify-totp` | POST | Verify TOTP code |
242
+ | `/iam/two-factor/verify-backup-code` | POST | Verify backup code |
243
+
244
+ ## Troubleshooting
245
+
246
+ ### "Passkey not found" Error
247
+
248
+ 1. Ensure the user has registered a passkey first
249
+ 2. Check that cookies are being sent (`credentials: 'include'`)
250
+ 3. Verify CORS is configured correctly on the backend
251
+
252
+ ### 2FA Redirect Not Working
253
+
254
+ Ensure the 2FA redirect is handled in the login page:
255
+
256
+ ```typescript
257
+ // Check for 2FA redirect in login response
258
+ if (result.data?.twoFactorRedirect) {
259
+ await navigateTo('/auth/2fa');
260
+ return;
261
+ }
262
+ ```
263
+
264
+ ### Session Not Persisting After Passkey Login
265
+
266
+ The passkey response only contains the session, not the user. Call `validateSession()`:
267
+
268
+ ```typescript
269
+ if (result.data?.session) {
270
+ await validateSession(); // Fetches user data
271
+ }
272
+ ```
273
+
274
+ ### Form Not Submitting (Nuxt UI)
275
+
276
+ Ensure UForm has the `:state` binding:
277
+
278
+ ```vue
279
+ <UForm :schema="schema" :state="formState" @submit="onSubmit">
280
+ <UInput v-model="formState.field" />
281
+ </UForm>
282
+ ```
283
+
284
+ ## References
285
+
286
+ - [Better Auth Documentation](https://www.better-auth.com/docs)
287
+ - [Better Auth Passkey Plugin](https://www.better-auth.com/docs/plugins/passkey)
288
+ - [Better Auth Two-Factor Plugin](https://www.better-auth.com/docs/plugins/two-factor)
289
+ - [nest-server Better Auth Integration](https://github.com/lenneTech/nest-server)
package/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [1.1.1](https://github.com/lenneTech/nuxt-base-starter/compare/v1.1.0...v1.1.1) (2026-01-20)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **auth:** auto-login after registration and improved passkey handling ([625128b](https://github.com/lenneTech/nuxt-base-starter/commit/625128b18fe812c141859946c196f8efb0738dca))
11
+ * **auth:** improve 2FA UX and document dev-mode proxy requirements ([4c4b1f4](https://github.com/lenneTech/nuxt-base-starter/commit/4c4b1f4d8b77fa93469ccc1a31d4f3292cc7c724))
12
+
13
+ ## [1.1.0](https://github.com/lenneTech/nuxt-base-starter/compare/v1.0.3...v1.1.0) (2026-01-20)
14
+
15
+
16
+ ### Features
17
+
18
+ * add complete Better-Auth integration with Passkey support and comprehensive documentation ([e0d470c](https://github.com/lenneTech/nuxt-base-starter/commit/e0d470c8229c37bed2948d929676620f344f4878))
19
+
20
+ ## [1.2.0](https://github.com/lenneTech/nuxt-base-starter/compare/v1.0.3...v1.2.0) (2026-01-20)
21
+
22
+
23
+ ### Features
24
+
25
+ * add complete Better-Auth integration with Passkey support and comprehensive documentation ([70fbec1](https://github.com/lenneTech/nuxt-base-starter/commit/70fbec14e38673c5185195fe05f0cd82bf72a800))
26
+
27
+ ## [1.1.0](https://github.com/lenneTech/nuxt-base-starter/compare/v1.0.3...v1.1.0) (2026-01-20)
28
+
5
29
  ### [1.0.3](https://github.com/lenneTech/nuxt-base-starter/compare/v1.0.2...v1.0.3) (2026-01-12)
6
30
 
7
31
  ### [1.0.2](https://github.com/lenneTech/nuxt-base-starter/compare/v1.0.1...v1.0.2) (2026-01-12)
package/README.md CHANGED
@@ -16,29 +16,37 @@ The development server starts at **http://localhost:3001**
16
16
 
17
17
  ### Core Framework
18
18
 
19
- | Technology | Version | Description |
20
- |------------|---------|-------------|
21
- | Nuxt | 4.x | Vue 3 meta-framework with SSR support |
22
- | TypeScript | 5.9.x | Strict type checking enabled |
23
- | Tailwind CSS | 4.x | Utility-first CSS with Vite plugin |
24
- | NuxtUI | 4.x | Component library with dark mode |
19
+ | Technology | Version | Description |
20
+ |--------------|---------|---------------------------------------|
21
+ | Nuxt | 4.x | Vue 3 meta-framework with SSR support |
22
+ | TypeScript | 5.9.x | Strict type checking enabled |
23
+ | Tailwind CSS | 4.x | Utility-first CSS with Vite plugin |
24
+ | NuxtUI | 4.x | Component library with dark mode |
25
25
 
26
26
  ### Authentication (Better Auth)
27
27
 
28
- - Email/password authentication with client-side password hashing
29
- - Two-factor authentication (2FA/TOTP)
30
- - Passkey/WebAuthn support
31
- - Password reset flow
32
- - Pre-built auth pages: login, register, forgot-password, reset-password, 2fa
28
+ Complete authentication system using [Better Auth](https://www.better-auth.com/):
29
+
30
+ | Feature | Description |
31
+ |--------------------|-------------------------------------------------------|
32
+ | Email/Password | Standard auth with client-side SHA256 hashing |
33
+ | Two-Factor (2FA) | TOTP-based 2FA with backup codes |
34
+ | Passkey/WebAuthn | Passwordless authentication (Touch ID, Face ID, etc.) |
35
+ | Password Reset | Email-based password reset flow |
36
+ | Session Management | SSR-compatible cookie-based sessions |
37
+
38
+ Pre-built auth pages: login, register, forgot-password, reset-password, 2fa
39
+
40
+ 📖 **See [AUTH.md](./AUTH.md) for detailed documentation**
33
41
 
34
42
  ### State & Data
35
43
 
36
- | Package | Purpose |
37
- |---------|---------|
38
- | Pinia | State management |
39
- | VueUse | Vue composition utilities |
40
- | @hey-api/client-fetch | Type-safe API client |
41
- | Valibot | Schema validation for forms |
44
+ | Package | Purpose |
45
+ |-----------------------|-----------------------------|
46
+ | Pinia | State management |
47
+ | VueUse | Vue composition utilities |
48
+ | @hey-api/client-fetch | Type-safe API client |
49
+ | Valibot | Schema validation for forms |
42
50
 
43
51
  ### SEO & Analytics
44
52
 
@@ -48,13 +56,13 @@ The development server starts at **http://localhost:3001**
48
56
 
49
57
  ### Developer Experience
50
58
 
51
- | Tool | Purpose |
52
- |------|---------|
53
- | OxLint | Fast linting |
54
- | OxFmt | Code formatting |
55
- | Playwright | E2E testing |
59
+ | Tool | Purpose |
60
+ |--------------------|------------------------------------|
61
+ | OxLint | Fast linting |
62
+ | OxFmt | Code formatting |
63
+ | Playwright | E2E testing |
56
64
  | @lenne.tech/bug.lt | Bug reporting to Linear (dev only) |
57
- | dayjs-nuxt | Date/time handling |
65
+ | dayjs-nuxt | Date/time handling |
58
66
 
59
67
  ### File Upload
60
68
 
@@ -95,17 +103,17 @@ my-project/
95
103
 
96
104
  ## Available Scripts
97
105
 
98
- | Script | Description |
99
- |--------|-------------|
100
- | `npm run dev` | Start development server |
101
- | `npm run build` | Build for production |
102
- | `npm run preview` | Preview production build |
106
+ | Script | Description |
107
+ |--------------------------|----------------------------------------|
108
+ | `npm run dev` | Start development server |
109
+ | `npm run build` | Build for production |
110
+ | `npm run preview` | Preview production build |
103
111
  | `npm run generate-types` | Generate TypeScript types from OpenAPI |
104
- | `npm run test` | Run Playwright E2E tests |
105
- | `npm run lint` | Run OxLint |
106
- | `npm run format` | Run OxFmt |
107
- | `npm run check` | Run lint + format check |
108
- | `npm run fix` | Auto-fix lint + format issues |
112
+ | `npm run test` | Run Playwright E2E tests |
113
+ | `npm run lint` | Run OxLint |
114
+ | `npm run format` | Run OxFmt |
115
+ | `npm run check` | Run lint + format check |
116
+ | `npm run fix` | Auto-fix lint + format issues |
109
117
 
110
118
  ## Environment Variables
111
119