create-nuxt-base 2.6.7 → 2.7.0
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/.claude/agent-memory/lt-dev-npm-package-maintainer/MEMORY.md +1 -0
- package/.claude/agent-memory/lt-dev-npm-package-maintainer/feedback_postcss_override_breadth.md +11 -0
- package/CHANGELOG.md +7 -0
- package/nuxt-base-template/.env.example +19 -8
- package/nuxt-base-template/CLAUDE.md +82 -30
- package/nuxt-base-template/app/middleware/admin.global.ts +7 -2
- package/nuxt-base-template/app/middleware/auth.global.ts +7 -2
- package/nuxt-base-template/app/middleware/guest.global.ts +7 -2
- package/nuxt-base-template/nuxt.config.ts +3 -3
- package/nuxt-base-template/package.json +24 -21
- package/nuxt-base-template/playwright.config.ts +3 -3
- package/nuxt-base-template/pnpm-lock.yaml +2051 -1555
- package/nuxt-base-template/tests/unit/lt-dev-env.test.ts +43 -0
- package/package.json +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# lt-dev-npm-package-maintainer Memory
|
|
2
2
|
|
|
3
3
|
- [Override Safety Rule](feedback_override_safety.md) — All pnpm.overrides targets MUST use fixed versions (no `>=`, `^`, `~`)
|
|
4
|
+
- [Postcss override breadth](feedback_postcss_override_breadth.md) — Bumping postcss override target alone is insufficient; LEFT-side range must also widen
|
|
4
5
|
- [Project Structure](project_structure.md) — Two-level package.json structure: root (create-nuxt-base) + nuxt-base-template/
|
package/.claude/agent-memory/lt-dev-npm-package-maintainer/feedback_postcss_override_breadth.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Postcss override left-side breadth
|
|
3
|
+
description: When bumping a postcss override target, also widen the LEFT-side selector or peer-dependency mismatches occur
|
|
4
|
+
type: feedback
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
When the `postcss` override is `postcss@<8.5.10: 8.5.X`, it ONLY replaces postcss versions below 8.5.10. Other postcss installs (e.g. via vite) stay at whatever they request natively (e.g. 8.5.12). When other plugins (like cssnano's `postcss-merge-rules`) require `postcss@^8.5.13` peer, the older 8.5.12 fails the peer check.
|
|
8
|
+
|
|
9
|
+
**Why:** Discovered on 2026-05-10 in nuxt-base-starter — bumping the target alone from 8.5.12 to 8.5.14 was insufficient because the old left-side selector `<8.5.10` did not catch the natively-installed 8.5.12. Build still worked but `pnpm install` showed unmet peer warnings until the LEFT side was widened to `<8.5.14`.
|
|
10
|
+
|
|
11
|
+
**How to apply:** When bumping any postcss override target to version X, also update the LEFT side to `postcss@<X` so the override actually catches versions below the new target. Pattern: `"postcss@<8.5.14": "8.5.14"`.
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
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
|
+
## [2.7.0](https://github.com/lenneTech/nuxt-base-starter/compare/v2.6.7...v2.7.0) (2026-05-10)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **template:** support lt dev multi-project mode via env-aware URLs and configurable auth cookie names ([e9971ee](https://github.com/lenneTech/nuxt-base-starter/commit/e9971eea3661cff59d5b72adf5f026a0ddce09e8))
|
|
11
|
+
|
|
5
12
|
### [2.6.7](https://github.com/lenneTech/nuxt-base-starter/compare/v2.6.6...v2.6.7) (2026-04-28)
|
|
6
13
|
|
|
7
14
|
### [2.6.6](https://github.com/lenneTech/nuxt-base-starter/compare/v2.6.5...v2.6.6) (2026-04-28)
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
# Local URLs — defaults for `nuxt dev` without `lt dev up`.
|
|
2
|
+
# When started via `lt dev up`, these are overridden to
|
|
3
|
+
# `https://<slug>.localhost` / `https://api.<slug>.localhost`.
|
|
1
4
|
NUXT_PUBLIC_SITE_URL=http://localhost:3001
|
|
2
5
|
NUXT_PUBLIC_APP_ENV=local
|
|
3
6
|
NODE_ENV=development
|
|
4
7
|
NUXT_API_URL=http://localhost:3000
|
|
5
8
|
NUXT_PUBLIC_API_URL=http://localhost:3000
|
|
6
9
|
NUXT_PUBLIC_WEB_PUSH_KEY=
|
|
7
|
-
# Local storage namespace prefix (prevents key collisions between projects on localhost)
|
|
10
|
+
# Local storage namespace prefix (prevents key collisions between projects on localhost).
|
|
11
|
+
# `lt dev up` overrides this with the project slug.
|
|
8
12
|
NUXT_PUBLIC_STORAGE_PREFIX=my-project-local
|
|
9
13
|
|
|
10
14
|
# ---------------------------------------------------------------------------
|
|
@@ -14,16 +18,23 @@ NUXT_PUBLIC_STORAGE_PREFIX=my-project-local
|
|
|
14
18
|
# (localhost:3000). The proxy strips the /api/ prefix before forwarding,
|
|
15
19
|
# so the backend receives the original path (e.g., /iam/sign-in).
|
|
16
20
|
#
|
|
17
|
-
# WHY: In
|
|
18
|
-
# (localhost:3000) are on different ports. Browsers enforce
|
|
19
|
-
# policy for cookies, which breaks session-based authentication.
|
|
21
|
+
# WHY: In classic mode (without `lt dev`), frontend (localhost:3001) and
|
|
22
|
+
# backend (localhost:3000) are on different ports. Browsers enforce
|
|
23
|
+
# same-origin policy for cookies, which breaks session-based authentication.
|
|
20
24
|
# The proxy makes all requests appear same-origin.
|
|
21
25
|
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
# — deployed stages call the backend directly via NUXT_PUBLIC_API_URL.
|
|
26
|
+
# WHEN TO LEAVE THIS `true`:
|
|
27
|
+
# - You run `pnpm dev` without Caddy (classic localhost:3000 + 3001 mode)
|
|
25
28
|
#
|
|
26
|
-
#
|
|
29
|
+
# WHEN TO SET TO `false` (or rely on `lt dev up`'s automatic override):
|
|
30
|
+
# - You run `lt dev up` — Caddy serves both subdomains under HTTPS with
|
|
31
|
+
# shared cookie domain `.<slug>.localhost`, and the vite-proxy is no
|
|
32
|
+
# longer needed.
|
|
33
|
+
# - You target a deployed stage (develop, test, preview, production) —
|
|
34
|
+
# those always call the backend directly via NUXT_PUBLIC_API_URL.
|
|
35
|
+
#
|
|
36
|
+
# Nuxt auto-maps this to runtimeConfig.public.apiProxy.
|
|
37
|
+
# `lt dev up` always exports NUXT_PUBLIC_API_PROXY=false.
|
|
27
38
|
NUXT_PUBLIC_API_PROXY=true
|
|
28
39
|
|
|
29
40
|
NUXT_PLAUSIBLE_API_URL=
|
|
@@ -35,12 +35,43 @@ nuxt.config.ts # Nuxt configuration
|
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
37
|
pnpm dev # Start dev server (port 3001)
|
|
38
|
-
pnpm run generate-types # Generate API types (API must be running on port 3000)
|
|
38
|
+
pnpm run generate-types # Generate API types (API must be running on port 3000 — or NUXT_API_URL)
|
|
39
39
|
pnpm test # Run Playwright E2E tests
|
|
40
40
|
pnpm run build # Build for production
|
|
41
41
|
pnpm run check # Full quality check (audit + format + lint + types + test + build)
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
## Local Development (Parallel Projects)
|
|
45
|
+
|
|
46
|
+
This template ships with env-aware URL configuration. To run multiple lt-projects on the same machine without colliding on `localhost:3000`/`localhost:3001` and without cross-wiring auth cookies:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
lt dev install # one-time per machine: Caddy + local CA
|
|
50
|
+
lt dev migrate # once per project: idempotent ENV patches
|
|
51
|
+
lt dev up # start App + API behind Caddy under https://<slug>.localhost
|
|
52
|
+
lt dev down # stop the detached processes + remove Caddy block
|
|
53
|
+
lt dev status # show running PIDs + active URLs
|
|
54
|
+
lt dev status --all # list all registered projects
|
|
55
|
+
lt dev doctor # diagnose Caddy / CA / DNS / port issues
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`lt dev up` exports the env vars the template respects:
|
|
59
|
+
|
|
60
|
+
- `PORT` — internal Nuxt dev server port (auto-allocated 4000+, never 3001)
|
|
61
|
+
- `NUXT_API_URL` — used by `generate-types` and the Vite dev proxy (when active) — `https://api.<slug>.localhost`
|
|
62
|
+
- `NUXT_PUBLIC_API_URL` — client-side API URL — `https://api.<slug>.localhost`
|
|
63
|
+
- `NUXT_PUBLIC_SITE_URL` — used by Playwright (`baseURL`, `webServer.url`) — `https://<slug>.localhost`
|
|
64
|
+
- `NUXT_PUBLIC_STORAGE_PREFIX` — LocalStorage namespace (prevents key collisions across parallel projects) — `<slug>`
|
|
65
|
+
- `NUXT_PUBLIC_API_PROXY` — always `false` under `lt dev up` because Caddy + cookie-domain make the vite-proxy obsolete
|
|
66
|
+
|
|
67
|
+
Without `lt dev up`, the template falls back to the defaults (port 3001, API on `localhost:3000`, `NUXT_PUBLIC_API_PROXY=true` for same-origin cookies in classic mode). All env vars are optional.
|
|
68
|
+
|
|
69
|
+
**Setting these manually** (e.g. in CI):
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
PORT=4011 NUXT_PUBLIC_SITE_URL=https://crm.localhost NUXT_PUBLIC_API_URL=https://api.crm.localhost pnpm dev
|
|
73
|
+
```
|
|
74
|
+
|
|
44
75
|
## Standards
|
|
45
76
|
|
|
46
77
|
| Rule | Value |
|
|
@@ -128,7 +159,24 @@ benefits and the local patch disappears on the next sync.
|
|
|
128
159
|
|
|
129
160
|
Auth is managed by `@lenne.tech/nuxt-extensions` via `useLtAuth()`. See the [nuxt-extensions CLAUDE.md](https://github.com/lenneTech/nuxt-extensions) for detailed auth cookie rules.
|
|
130
161
|
|
|
131
|
-
Key rule: Never manually write to the
|
|
162
|
+
Key rule: Never manually write to the auth-state cookie from custom middleware. Use `useLtAuth().setUser()` / `clearUser()` exclusively.
|
|
163
|
+
|
|
164
|
+
### Configurable cookie names (optional)
|
|
165
|
+
|
|
166
|
+
The auth cookies default to `lt-auth-state` and `lt-jwt-token`. Projects that need to coexist with another lenne.tech app on the same domain can override them in `nuxt.config.ts`:
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
ltExtensions: {
|
|
170
|
+
auth: {
|
|
171
|
+
cookieNames: {
|
|
172
|
+
state: 'my-app-auth-state',
|
|
173
|
+
token: 'my-app-jwt',
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Each key is independent — set only the one you need. The starter's global middleware (`app/middleware/auth.global.ts`, `guest.global.ts`, `admin.global.ts`) reads the resolved cookie name from `useRuntimeConfig().public.ltExtensions.auth.cookieNames.state` and falls back to the default.
|
|
132
180
|
|
|
133
181
|
## Security Overrides (pnpm)
|
|
134
182
|
|
|
@@ -136,34 +184,38 @@ The `pnpm.overrides` in `package.json` force vulnerable transitive dependencies
|
|
|
136
184
|
|
|
137
185
|
All override targets use fixed versions (not ranges) to prevent silent major-version jumps. See TurboOps incident (April 2026) in the agent memory for context.
|
|
138
186
|
|
|
139
|
-
| Override | Advisory
|
|
140
|
-
| -------------------------------- |
|
|
141
|
-
| `@hono/node-server@<1.19.14` | GHSA-7256-2wf4-hf2r, GHSA-92pp-h63x-v22m
|
|
142
|
-
| `brace-expansion@>=2.0.0 <2.0.3` | GHSA-f886-m6hf-6m8v
|
|
143
|
-
| `brace-expansion@>=4.0.0 <5.0.5` | GHSA-f886-m6hf-6m8v
|
|
144
|
-
| `drizzle-orm@<0.45.2` | GHSA-gpj5-g38j-94v9
|
|
145
|
-
| `readdir-glob@<2.0.3` | (transitive)
|
|
146
|
-
| `defu@<=6.1.4` | GHSA-mchp-fgcf-hmfj
|
|
147
|
-
| `devalue@<=5.6.3` | GHSA-77p6-w3v8-rqwf
|
|
148
|
-
| `effect@<3.20.0` | GHSA-j44v-mmf2-xvm9
|
|
149
|
-
| `fast-xml-
|
|
150
|
-
| `
|
|
151
|
-
| `h3
|
|
152
|
-
| `h3-
|
|
153
|
-
| `
|
|
154
|
-
| `
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
157
|
-
| `
|
|
158
|
-
| `
|
|
159
|
-
| `
|
|
160
|
-
| `
|
|
161
|
-
| `
|
|
162
|
-
| `
|
|
163
|
-
| `
|
|
164
|
-
| `
|
|
165
|
-
| `
|
|
166
|
-
| `
|
|
187
|
+
| Override | Advisory | Notes |
|
|
188
|
+
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
189
|
+
| `@hono/node-server@<1.19.14` | GHSA-7256-2wf4-hf2r, GHSA-92pp-h63x-v22m | Request smuggling + middleware bypass via repeated slashes |
|
|
190
|
+
| `brace-expansion@>=2.0.0 <2.0.3` | GHSA-f886-m6hf-6m8v | ReDoS via zero-step sequences |
|
|
191
|
+
| `brace-expansion@>=4.0.0 <5.0.5` | GHSA-f886-m6hf-6m8v | Same advisory, 5.x range |
|
|
192
|
+
| `drizzle-orm@<0.45.2` | GHSA-gpj5-g38j-94v9 | SQL injection via improperly escaped identifiers; transitive via @nuxtjs/seo>nuxt-link-checker>unstorage>db0 |
|
|
193
|
+
| `readdir-glob@<2.0.3` | (transitive) | Forces minimatch upgrade for brace-expansion fix |
|
|
194
|
+
| `defu@<=6.1.4` | GHSA-mchp-fgcf-hmfj | Prototype pollution |
|
|
195
|
+
| `devalue@<=5.6.3` | GHSA-77p6-w3v8-rqwf | XSS via crafted input |
|
|
196
|
+
| `effect@<3.20.0` | GHSA-j44v-mmf2-xvm9 | Denial of service |
|
|
197
|
+
| `fast-xml-builder@<1.1.7` | GHSA-5wm8-gmm8-39j9, GHSA-45c6-75p6-83cc | Attribute quote bypass + Comment regex bypass; transitive via @nuxtjs/seo>sitemap>fast-xml-parser |
|
|
198
|
+
| `fast-xml-parser@<5.7.3` | GHSA-gh4j-gqv2-49f6 | XMLBuilder: XML comment and CDATA injection via unescaped delimiters; transitive via @nuxtjs/seo>sitemap |
|
|
199
|
+
| `h3@<1.15.9` | GHSA-wr4h-v87w-p3r7 | Path traversal |
|
|
200
|
+
| `h3@>=2.0.0-0 <2.0.1-rc.18` | GHSA-q5pr-72pq-83v3 | Cookie DoS + SSE injection |
|
|
201
|
+
| `h3-next` | (alias fix) | `@nuxt/test-utils` pins h3-next to vulnerable RC; remove when h3 v2 stable releases |
|
|
202
|
+
| `hono@<4.12.18` | GHSA-rp6g-89hg-4gfv, GHSA-26pp-8wgv-hjvm, GHSA-r5rp-j6wh-rvv4, GHSA-wmmm-f939-6g9c, GHSA-xpcf-pg52-r92g, GHSA-458j-xx4x-4375, GHSA-9vqf-7f2p-gf9v, GHSA-69xw-7hcm-h432, GHSA-qp7p-654g-cw7p, GHSA-p77w-8qqv-26rm, GHSA-hm8q-7f3q-5f36 | SSRF, cookie validation, IP bypass, JSX injection, bodyLimit bypass, CSS injection in JSX SSR, cache leakage, JWT NumericDate validation; transitive via better-auth>prisma>@prisma/dev |
|
|
203
|
+
| `kysely@>=0.26.0 <=0.28.13` | GHSA-4hxq-5gxr-453h | SQL injection |
|
|
204
|
+
| `lodash@>=4.0.0 <=4.17.23` | GHSA-x5rq-j2xg-h7qm | Prototype pollution |
|
|
205
|
+
| `minimatch@>=9.0.0 <9.0.7` | GHSA-f886-m6hf-6m8v | ReDoS via brace-expansion |
|
|
206
|
+
| `node-forge@<1.4.0` | GHSA-997c-fj8j-rq5h | RSA signature forgery |
|
|
207
|
+
| `nuxt-og-image@>=6.2.5 <6.4.9` | GHSA-c2rm-g55x-8hr5 | SSRF — bypass of GHSA-pqhr-mp3f-hrpp / v6.2.5 fix (IPv6 + redirect); transitive via @nuxtjs/seo |
|
|
208
|
+
| `picomatch@<2.3.2` | GHSA-26j4-r882-m4jm | ReDoS |
|
|
209
|
+
| `picomatch@>=4.0.0 <4.0.4` | GHSA-26j4-r882-m4jm | Same advisory, 4.x range |
|
|
210
|
+
| `postcss@<8.5.14` | (defensive) | Force latest postcss patch across all consumers; covers historical advisories |
|
|
211
|
+
| `rollup@>=4.0.0 <4.60.3` | GHSA-gcx4-mw62-g3rm | DOM clobbering in output |
|
|
212
|
+
| `serialize-javascript@<=7.0.4` | GHSA-cqmj-v5x6-4hg7 | XSS via crafted object |
|
|
213
|
+
| `simple-git@<3.36.0` | GHSA-hffm-xvc3-vprc | Remote Code Execution; transitive via @nuxt/devtools |
|
|
214
|
+
| `srvx@<0.11.13` | GHSA-4r4v-8rg6-5crc | Open redirect |
|
|
215
|
+
| `tar@<=7.5.10` | GHSA-jg7w-cxjv-98c2 | Path traversal |
|
|
216
|
+
| `unhead@<=2.1.12` | GHSA-gxhp-jfhg-5fv8, GHSA-95h2-gj7x-gx9w | XSS via meta tags + hasDangerousProtocol() bypass via leading-zero padded HTML entities |
|
|
217
|
+
| `vite@>=7.0.0 <7.3.2` | GHSA-v2wj-q39q-566r, GHSA-p9ff-h696-f583, GHSA-4w7w-66w2-5vf9 | fs.deny bypass, arbitrary file read via WebSocket, path traversal in .map |
|
|
218
|
+
| `yaml@>=2.0.0 <2.8.3` | GHSA-4hm9-844j-jmxp | Code execution via crafted YAML |
|
|
167
219
|
|
|
168
220
|
The `ignoredOptionalDependencies` block suppresses 30 platform-specific native binaries (`@img/sharp-*`, `@resvg/resvg-js-*`) that are pulled in by `@nuxtjs/seo` 5.x's OG image engine. Only the host-platform binary is needed at build time.
|
|
169
221
|
|
|
@@ -4,13 +4,18 @@ export default defineNuxtRouteMiddleware(async (to) => {
|
|
|
4
4
|
return;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
// Cookie name is configurable via `ltExtensions.auth.cookieNames.state` in
|
|
8
|
+
// nuxt.config.ts. Fall back to the historical default so older module
|
|
9
|
+
// versions and missing config keep working unchanged.
|
|
10
|
+
const cookieName = (useRuntimeConfig().public as { ltExtensions?: { auth?: { cookieNames?: { state?: string } } } })?.ltExtensions?.auth?.cookieNames?.state || 'lt-auth-state';
|
|
11
|
+
|
|
7
12
|
let isAuthenticated = false;
|
|
8
13
|
let isAdmin = false;
|
|
9
14
|
|
|
10
15
|
// On client, read directly from document.cookie for accurate state
|
|
11
16
|
if (import.meta.client) {
|
|
12
17
|
try {
|
|
13
|
-
const cookie = document.cookie.split('; ').find((row) => row.startsWith(
|
|
18
|
+
const cookie = document.cookie.split('; ').find((row) => row.startsWith(`${cookieName}=`));
|
|
14
19
|
if (cookie) {
|
|
15
20
|
const parts = cookie.split('=');
|
|
16
21
|
const value = parts.length > 1 ? decodeURIComponent(parts.slice(1).join('=')) : '';
|
|
@@ -23,7 +28,7 @@ export default defineNuxtRouteMiddleware(async (to) => {
|
|
|
23
28
|
}
|
|
24
29
|
} else {
|
|
25
30
|
// On server, use useCookie
|
|
26
|
-
const authStateCookie = useCookie<{ user: { role?: string } | null; authMode: string } | null>(
|
|
31
|
+
const authStateCookie = useCookie<{ user: { role?: string } | null; authMode: string } | null>(cookieName);
|
|
27
32
|
isAuthenticated = !!authStateCookie.value?.user;
|
|
28
33
|
isAdmin = authStateCookie.value?.user?.role === 'admin';
|
|
29
34
|
}
|
|
@@ -4,12 +4,17 @@ export default defineNuxtRouteMiddleware(async (to) => {
|
|
|
4
4
|
return;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
// Cookie name is configurable via `ltExtensions.auth.cookieNames.state` in
|
|
8
|
+
// nuxt.config.ts. Fall back to the historical default so older module
|
|
9
|
+
// versions and missing config keep working unchanged.
|
|
10
|
+
const cookieName = (useRuntimeConfig().public as { ltExtensions?: { auth?: { cookieNames?: { state?: string } } } })?.ltExtensions?.auth?.cookieNames?.state || 'lt-auth-state';
|
|
11
|
+
|
|
7
12
|
let isAuthenticated = false;
|
|
8
13
|
|
|
9
14
|
// On client, read directly from document.cookie for accurate state
|
|
10
15
|
if (import.meta.client) {
|
|
11
16
|
try {
|
|
12
|
-
const cookie = document.cookie.split('; ').find((row) => row.startsWith(
|
|
17
|
+
const cookie = document.cookie.split('; ').find((row) => row.startsWith(`${cookieName}=`));
|
|
13
18
|
if (cookie) {
|
|
14
19
|
const parts = cookie.split('=');
|
|
15
20
|
const value = parts.length > 1 ? decodeURIComponent(parts.slice(1).join('=')) : '';
|
|
@@ -21,7 +26,7 @@ export default defineNuxtRouteMiddleware(async (to) => {
|
|
|
21
26
|
}
|
|
22
27
|
} else {
|
|
23
28
|
// On server, use useCookie
|
|
24
|
-
const authStateCookie = useCookie<{ user: unknown; authMode: string } | null>(
|
|
29
|
+
const authStateCookie = useCookie<{ user: unknown; authMode: string } | null>(cookieName);
|
|
25
30
|
isAuthenticated = !!authStateCookie.value?.user;
|
|
26
31
|
}
|
|
27
32
|
|
|
@@ -4,12 +4,17 @@ export default defineNuxtRouteMiddleware(async (to) => {
|
|
|
4
4
|
return;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
// Cookie name is configurable via `ltExtensions.auth.cookieNames.state` in
|
|
8
|
+
// nuxt.config.ts. Fall back to the historical default so older module
|
|
9
|
+
// versions and missing config keep working unchanged.
|
|
10
|
+
const cookieName = (useRuntimeConfig().public as { ltExtensions?: { auth?: { cookieNames?: { state?: string } } } })?.ltExtensions?.auth?.cookieNames?.state || 'lt-auth-state';
|
|
11
|
+
|
|
7
12
|
let isAuthenticated = false;
|
|
8
13
|
|
|
9
14
|
// On client, read directly from document.cookie for accurate state
|
|
10
15
|
if (import.meta.client) {
|
|
11
16
|
try {
|
|
12
|
-
const cookie = document.cookie.split('; ').find((row) => row.startsWith(
|
|
17
|
+
const cookie = document.cookie.split('; ').find((row) => row.startsWith(`${cookieName}=`));
|
|
13
18
|
if (cookie) {
|
|
14
19
|
const parts = cookie.split('=');
|
|
15
20
|
const value = parts.length > 1 ? decodeURIComponent(parts.slice(1).join('=')) : '';
|
|
@@ -21,7 +26,7 @@ export default defineNuxtRouteMiddleware(async (to) => {
|
|
|
21
26
|
}
|
|
22
27
|
} else {
|
|
23
28
|
// On server, use useCookie
|
|
24
|
-
const authStateCookie = useCookie<{ user: unknown; authMode: string } | null>(
|
|
29
|
+
const authStateCookie = useCookie<{ user: unknown; authMode: string } | null>(cookieName);
|
|
25
30
|
isAuthenticated = !!authStateCookie.value?.user;
|
|
26
31
|
}
|
|
27
32
|
|
|
@@ -34,7 +34,7 @@ export default defineNuxtConfig({
|
|
|
34
34
|
// Development Server
|
|
35
35
|
// ============================================================================
|
|
36
36
|
devServer: {
|
|
37
|
-
port: 3001,
|
|
37
|
+
port: Number(process.env.PORT) || 3001,
|
|
38
38
|
},
|
|
39
39
|
|
|
40
40
|
// ============================================================================
|
|
@@ -222,14 +222,14 @@ export default defineNuxtConfig({
|
|
|
222
222
|
// Why: Frontend (localhost:3001) and backend (localhost:3000) run on different
|
|
223
223
|
// ports. The proxy makes requests same-origin so cookies work correctly.
|
|
224
224
|
'/api': {
|
|
225
|
-
target: 'http://localhost:3000',
|
|
225
|
+
target: process.env.NUXT_API_URL || 'http://localhost:3000',
|
|
226
226
|
changeOrigin: true,
|
|
227
227
|
rewrite: (path) => path.replace(/^\/api/, ''),
|
|
228
228
|
},
|
|
229
229
|
// Direct IAM proxy for BetterAuth endpoints (SSR Nitro server handler
|
|
230
230
|
// and direct browser redirects, e.g., OAuth callbacks)
|
|
231
231
|
'/iam': {
|
|
232
|
-
target: 'http://localhost:3000',
|
|
232
|
+
target: process.env.NUXT_API_URL || 'http://localhost:3000',
|
|
233
233
|
changeOrigin: true,
|
|
234
234
|
},
|
|
235
235
|
},
|
|
@@ -48,42 +48,42 @@
|
|
|
48
48
|
"fix": "pnpm run lint:fix && pnpm run format"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@better-auth/passkey": "1.6.
|
|
51
|
+
"@better-auth/passkey": "1.6.10",
|
|
52
52
|
"@lenne.tech/bug.lt": "latest",
|
|
53
|
-
"@lenne.tech/nuxt-extensions": "1.
|
|
53
|
+
"@lenne.tech/nuxt-extensions": "1.6.0",
|
|
54
54
|
"@nuxt/image": "2.0.0",
|
|
55
|
-
"@nuxt/ui": "4.7.
|
|
55
|
+
"@nuxt/ui": "4.7.1",
|
|
56
56
|
"@pinia/nuxt": "0.11.3",
|
|
57
|
-
"@vueuse/nuxt": "14.
|
|
58
|
-
"better-auth": "1.6.
|
|
57
|
+
"@vueuse/nuxt": "14.3.0",
|
|
58
|
+
"better-auth": "1.6.10",
|
|
59
59
|
"qrcode": "1.5.4",
|
|
60
60
|
"tus-js-client": "4.3.1",
|
|
61
|
-
"valibot": "1.
|
|
61
|
+
"valibot": "1.4.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@hey-api/openapi-ts": "0.97.
|
|
65
|
-
"@iconify-json/lucide": "1.2.
|
|
64
|
+
"@hey-api/openapi-ts": "0.97.1",
|
|
65
|
+
"@iconify-json/lucide": "1.2.106",
|
|
66
66
|
"@nuxt/devtools": "3.2.4",
|
|
67
67
|
"@nuxt/test-utils": "4.0.3",
|
|
68
68
|
"@nuxtjs/plausible": "3.0.2",
|
|
69
69
|
"@nuxtjs/seo": "5.1.3",
|
|
70
70
|
"@playwright/test": "1.59.1",
|
|
71
71
|
"@tailwindcss/typography": "0.5.19",
|
|
72
|
-
"@tailwindcss/vite": "4.
|
|
73
|
-
"@types/node": "25.6.
|
|
72
|
+
"@tailwindcss/vite": "4.3.0",
|
|
73
|
+
"@types/node": "25.6.2",
|
|
74
74
|
"@types/qrcode": "1.5.6",
|
|
75
75
|
"@vitejs/plugin-vue": "6.0.6",
|
|
76
|
-
"@vue/test-utils": "2.4.
|
|
76
|
+
"@vue/test-utils": "2.4.10",
|
|
77
77
|
"dayjs-nuxt": "2.1.11",
|
|
78
78
|
"happy-dom": "20.9.0",
|
|
79
|
-
"lint-staged": "
|
|
79
|
+
"lint-staged": "17.0.4",
|
|
80
80
|
"mongodb": "7.2.0",
|
|
81
|
-
"nuxt": "4.4.
|
|
81
|
+
"nuxt": "4.4.4",
|
|
82
82
|
"oxfmt": "latest",
|
|
83
83
|
"oxlint": "latest",
|
|
84
84
|
"rimraf": "6.1.3",
|
|
85
85
|
"simple-git-hooks": "2.13.1",
|
|
86
|
-
"tailwindcss": "4.
|
|
86
|
+
"tailwindcss": "4.3.0",
|
|
87
87
|
"typescript": "6.0.3",
|
|
88
88
|
"vitest": "4.1.5"
|
|
89
89
|
},
|
|
@@ -149,29 +149,32 @@
|
|
|
149
149
|
"brace-expansion@>=2.0.0 <2.0.3": "2.1.0",
|
|
150
150
|
"brace-expansion@>=4.0.0 <5.0.5": "5.0.5",
|
|
151
151
|
"drizzle-orm@<0.45.2": "0.45.2",
|
|
152
|
+
"fast-xml-builder@<1.1.7": "1.2.0",
|
|
153
|
+
"fast-xml-parser@<5.7.3": "5.7.3",
|
|
152
154
|
"readdir-glob@<2.0.3": "3.0.0",
|
|
153
155
|
"defu@<=6.1.4": "6.1.7",
|
|
154
156
|
"devalue@<=5.6.3": "5.7.1",
|
|
155
157
|
"effect@<3.20.0": "3.21.2",
|
|
156
|
-
"fast-xml-parser@<5.7.0": "5.7.2",
|
|
157
158
|
"h3@<1.15.9": "1.15.11",
|
|
158
|
-
"h3@>=2.0.0-0 <2.0.1-rc.18": "2.0.1-rc.
|
|
159
|
-
"h3-next": "npm:h3@2.0.1-rc.
|
|
160
|
-
"hono@<4.12.
|
|
159
|
+
"h3@>=2.0.0-0 <2.0.1-rc.18": "2.0.1-rc.22",
|
|
160
|
+
"h3-next": "npm:h3@2.0.1-rc.22",
|
|
161
|
+
"hono@<4.12.18": "4.12.18",
|
|
161
162
|
"kysely@>=0.26.0 <=0.28.13": "0.28.16",
|
|
162
163
|
"lodash@>=4.0.0 <=4.17.23": "4.18.1",
|
|
163
164
|
"minimatch@>=9.0.0 <9.0.7": "9.0.9",
|
|
164
165
|
"node-forge@<1.4.0": "1.4.0",
|
|
166
|
+
"nuxt-og-image@>=6.2.5 <6.4.9": "6.4.9",
|
|
165
167
|
"picomatch@<2.3.2": "2.3.2",
|
|
166
168
|
"picomatch@>=4.0.0 <4.0.4": "4.0.4",
|
|
167
|
-
"rollup@>=4.0.0 <4.
|
|
169
|
+
"rollup@>=4.0.0 <4.60.3": "4.60.3",
|
|
168
170
|
"serialize-javascript@<=7.0.4": "7.0.5",
|
|
171
|
+
"simple-git@<3.36.0": "3.36.0",
|
|
169
172
|
"srvx@<0.11.13": "0.11.15",
|
|
170
|
-
"tar@<=7.5.10": "7.5.
|
|
173
|
+
"tar@<=7.5.10": "7.5.15",
|
|
171
174
|
"unhead@<=2.1.12": "2.1.13",
|
|
172
175
|
"vite@>=7.0.0 <7.3.2": "7.3.2",
|
|
173
176
|
"yaml@>=2.0.0 <2.8.3": "2.8.3",
|
|
174
|
-
"postcss@<8.5.
|
|
177
|
+
"postcss@<8.5.14": "8.5.14"
|
|
175
178
|
}
|
|
176
179
|
}
|
|
177
180
|
}
|
|
@@ -32,7 +32,7 @@ export default defineConfig<ConfigOptions>({
|
|
|
32
32
|
timeout: isWindows ? 60000 : undefined,
|
|
33
33
|
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
|
34
34
|
use: {
|
|
35
|
-
baseURL: 'http://localhost:3001',
|
|
35
|
+
baseURL: process.env.NUXT_PUBLIC_SITE_URL || 'http://localhost:3001',
|
|
36
36
|
|
|
37
37
|
launchOptions: {
|
|
38
38
|
// Slows down Playwright operations by the specified amount of milliseconds
|
|
@@ -43,7 +43,7 @@ export default defineConfig<ConfigOptions>({
|
|
|
43
43
|
locale: 'de',
|
|
44
44
|
/* Nuxt configuration options */
|
|
45
45
|
nuxt: {
|
|
46
|
-
host: 'http://localhost:3001',
|
|
46
|
+
host: process.env.NUXT_PUBLIC_SITE_URL || 'http://localhost:3001',
|
|
47
47
|
rootDir: fileURLToPath(new URL('.', import.meta.url)),
|
|
48
48
|
},
|
|
49
49
|
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
|
@@ -56,7 +56,7 @@ export default defineConfig<ConfigOptions>({
|
|
|
56
56
|
stderr: 'pipe',
|
|
57
57
|
stdout: 'pipe',
|
|
58
58
|
timeout: 120 * 1000,
|
|
59
|
-
url: 'http://localhost:3001',
|
|
59
|
+
url: process.env.NUXT_PUBLIC_SITE_URL || 'http://localhost:3001',
|
|
60
60
|
},
|
|
61
61
|
],
|
|
62
62
|
/* Use single worker to prevent WebAuthn virtual authenticator conflicts across test files */
|