@habityzer/nuxt-symfony-kinde-layer 2.4.1 → 2.4.2
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/CHANGELOG.md +7 -0
- package/README.md +20 -0
- package/app/composables/useAuth.ts +3 -2
- package/app/plugins/auth-guard.client.ts +4 -3
- package/package.json +1 -2
- package/server/api/symfony/[...].ts +23 -28
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [2.4.2](https://github.com/Habityzer/nuxt-symfony-kinde-layer/compare/v2.4.1...v2.4.2) (2026-03-19)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Remove unused @nuxt/image dependency ([631f4f6](https://github.com/Habityzer/nuxt-symfony-kinde-layer/commit/631f4f601e8dbb5753d06adc5471f7a54632a636))
|
|
7
|
+
|
|
1
8
|
## [2.4.1](https://github.com/Habityzer/nuxt-symfony-kinde-layer/compare/v2.4.0...v2.4.1) (2026-03-17)
|
|
2
9
|
|
|
3
10
|
|
package/README.md
CHANGED
|
@@ -224,6 +224,22 @@ kindeAuth: {
|
|
|
224
224
|
}
|
|
225
225
|
```
|
|
226
226
|
|
|
227
|
+
### Disabling layer modules
|
|
228
|
+
|
|
229
|
+
You can disable individual modules provided by the layer by setting them to `false` in your project's `nuxt.config.ts`. The layer is still used via `extends`; only the module is disabled. For example, if you do not use `@nuxt/image`:
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
export default defineNuxtConfig({
|
|
233
|
+
extends: ['@habityzer/nuxt-symfony-kinde-layer'],
|
|
234
|
+
image: false,
|
|
235
|
+
// ...
|
|
236
|
+
})
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Route groups (optional)
|
|
240
|
+
|
|
241
|
+
As an alternative to listing only public routes, you can use Nuxt route groups (e.g. `(protected)/dashboard`) and check `to.meta.groups` in middleware. For example, put protected pages under `pages/(protected)/` and in a custom middleware use `if (to.meta.groups?.includes('protected') && !isAuthenticated()) return navigateTo('/login')`. The layer's auth guard uses `publicRoutes` / `protectedRoutes` by default; route groups are optional for projects that prefer convention-based protection.
|
|
242
|
+
|
|
227
243
|
## E2E Testing
|
|
228
244
|
|
|
229
245
|
The layer supports E2E testing with app tokens:
|
|
@@ -353,6 +369,10 @@ Add these to your workflow:
|
|
|
353
369
|
|
|
354
370
|
## Troubleshooting
|
|
355
371
|
|
|
372
|
+
### Error handling and Nuxt 5 readiness
|
|
373
|
+
|
|
374
|
+
The layer uses Nuxt 4.4+ / Nuxt 5 style errors: `createError({ status, statusText })` instead of the deprecated `statusCode`/`statusMessage`. When handling errors from the proxy or auth composable, prefer reading `error.status` and `error.statusText`. The deprecated `statusCode` and `statusMessage` remain supported on `NuxtError` for backward compatibility during migration.
|
|
375
|
+
|
|
356
376
|
### Cookie Name Conflicts
|
|
357
377
|
|
|
358
378
|
If you see authentication issues, ensure each project has a unique cookie prefix:
|
|
@@ -90,8 +90,9 @@ export const useAuth = () => {
|
|
|
90
90
|
userProfile.value = response
|
|
91
91
|
return response
|
|
92
92
|
} catch (error) {
|
|
93
|
-
// Silently handle auth errors on public pages
|
|
94
|
-
|
|
93
|
+
// Silently handle auth errors on public pages (support both status and statusCode for Nuxt 4.4+ / 5)
|
|
94
|
+
const err = error as { status?: number, statusCode?: number } | undefined
|
|
95
|
+
if (err && typeof err === 'object' && (err.status === 401 || err.statusCode === 401)) {
|
|
95
96
|
console.debug('Auth check failed - user not logged in')
|
|
96
97
|
} else {
|
|
97
98
|
console.error('Failed to fetch user profile:', error)
|
|
@@ -12,9 +12,10 @@ export default defineNuxtPlugin(() => {
|
|
|
12
12
|
const e2eTokenCookieName = requireString(middlewareConfig.e2eTokenCookieName, 'kindeAuth.middleware.e2eTokenCookieName')
|
|
13
13
|
const appTokenPrefix = requireString(middlewareConfig.appTokenPrefix, 'kindeAuth.middleware.appTokenPrefix')
|
|
14
14
|
const clockSkewSeconds = requireNonNegativeNumber(middlewareConfig.clockSkewSeconds, 'kindeAuth.middleware.clockSkewSeconds')
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
15
|
+
const cookieOptions = { maxAge: 60 * 60 * 24 * 7, refresh: true }
|
|
16
|
+
const idToken = useCookie<string | null>(`${cookiePrefix}${idTokenBaseName}`, cookieOptions)
|
|
17
|
+
const accessToken = useCookie<string | null>(`${cookiePrefix}${accessTokenBaseName}`, cookieOptions)
|
|
18
|
+
const e2eToken = useCookie<string | null>(`${cookiePrefix}${e2eTokenCookieName}`, cookieOptions)
|
|
18
19
|
const mode = middlewareConfig.mode || 'privateByDefault'
|
|
19
20
|
const publicRoutes: string[] = middlewareConfig.publicRoutes || ['/']
|
|
20
21
|
const protectedRoutes: string[] = middlewareConfig.protectedRoutes || []
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@habityzer/nuxt-symfony-kinde-layer",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "Shared Nuxt layer for Symfony + Kinde authentication integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./nuxt.config.ts",
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@habityzer/nuxt-kinde-auth": "^1.2.2",
|
|
27
27
|
"@nuxt/eslint": "^1.9.0",
|
|
28
|
-
"@nuxt/image": "^1.11.0",
|
|
29
28
|
"@nuxt/ui": "^4.0.1",
|
|
30
29
|
"@pinia/nuxt": "^0.11.2",
|
|
31
30
|
"@vueuse/core": "^13.9.0",
|
|
@@ -67,8 +67,8 @@ export default defineEventHandler(async (event) => {
|
|
|
67
67
|
|
|
68
68
|
if (!kinde?.client || !kinde?.sessionManager) {
|
|
69
69
|
throw createError({
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
status: 500,
|
|
71
|
+
statusText:
|
|
72
72
|
'Kinde authentication not initialized. Module may not be loaded correctly.'
|
|
73
73
|
})
|
|
74
74
|
}
|
|
@@ -99,15 +99,15 @@ export default defineEventHandler(async (event) => {
|
|
|
99
99
|
|
|
100
100
|
if (!token || token.trim() === '') {
|
|
101
101
|
throw createError({
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
status: 401,
|
|
103
|
+
statusText: 'Unauthorized - Please log in'
|
|
104
104
|
})
|
|
105
105
|
}
|
|
106
106
|
} catch (error) {
|
|
107
107
|
console.error('❌ [SYMFONY PROXY] Auth error:', error)
|
|
108
108
|
throw createError({
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
status: 401,
|
|
110
|
+
statusText:
|
|
111
111
|
error instanceof Error ? error.message : 'Authentication failed'
|
|
112
112
|
})
|
|
113
113
|
}
|
|
@@ -116,8 +116,8 @@ export default defineEventHandler(async (event) => {
|
|
|
116
116
|
|
|
117
117
|
if (!token && !isPublicRoute) {
|
|
118
118
|
throw createError({
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
status: 401,
|
|
120
|
+
statusText: 'No authentication token available'
|
|
121
121
|
})
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -182,33 +182,28 @@ export default defineEventHandler(async (event) => {
|
|
|
182
182
|
|
|
183
183
|
return response
|
|
184
184
|
} catch (error) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
statusCode
|
|
188
|
-
|
|
189
|
-
? error.statusCode
|
|
190
|
-
: 'unknown',
|
|
191
|
-
message: error instanceof Error ? error.message : 'unknown'
|
|
192
|
-
})
|
|
193
|
-
// Handle Symfony API errors
|
|
194
|
-
const statusCode
|
|
195
|
-
= error && typeof error === 'object' && 'statusCode' in error
|
|
196
|
-
? (error.statusCode as number)
|
|
185
|
+
const err = error as Record<string, unknown> | undefined
|
|
186
|
+
const status
|
|
187
|
+
= err && typeof err === 'object' && ('status' in err || 'statusCode' in err)
|
|
188
|
+
? (err.status as number) ?? (err.statusCode as number)
|
|
197
189
|
: 500
|
|
198
|
-
const
|
|
199
|
-
=
|
|
200
|
-
? (
|
|
190
|
+
const statusText
|
|
191
|
+
= err && typeof err === 'object' && ('statusText' in err || 'statusMessage' in err)
|
|
192
|
+
? (err.statusText as string) ?? (err.statusMessage as string)
|
|
201
193
|
: error instanceof Error
|
|
202
194
|
? error.message
|
|
203
195
|
: 'Symfony API error'
|
|
196
|
+
console.error('❌ [SYMFONY PROXY] Symfony API error:', {
|
|
197
|
+
path,
|
|
198
|
+
status,
|
|
199
|
+
message: statusText
|
|
200
|
+
})
|
|
204
201
|
const data
|
|
205
|
-
=
|
|
206
|
-
? error.data
|
|
207
|
-
: undefined
|
|
202
|
+
= err && typeof err === 'object' && 'data' in err ? err.data : undefined
|
|
208
203
|
|
|
209
204
|
throw createError({
|
|
210
|
-
|
|
211
|
-
|
|
205
|
+
status,
|
|
206
|
+
statusText,
|
|
212
207
|
data
|
|
213
208
|
})
|
|
214
209
|
}
|