create-nuxt-base 0.3.17 β 1.0.3
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/.github/workflows/publish.yml +4 -2
- package/.oxfmtrc.jsonc +7 -0
- package/CHANGELOG.md +22 -8
- package/README.md +130 -3
- package/nuxt-base-template/.dockerignore +44 -0
- package/nuxt-base-template/.env.example +0 -2
- package/nuxt-base-template/.nuxtrc +1 -0
- package/nuxt-base-template/.oxfmtrc.jsonc +8 -0
- package/nuxt-base-template/Dockerfile.dev +23 -0
- package/nuxt-base-template/README.md +76 -29
- package/nuxt-base-template/app/components/Modal/ModalBackupCodes.vue +117 -0
- package/nuxt-base-template/app/components/Upload/TusFileUpload.vue +302 -0
- package/nuxt-base-template/app/composables/use-better-auth.ts +25 -0
- package/nuxt-base-template/app/composables/use-file.ts +39 -4
- package/nuxt-base-template/app/composables/use-share.ts +1 -1
- package/nuxt-base-template/app/composables/use-tus-upload.ts +278 -0
- package/nuxt-base-template/app/interfaces/upload.interface.ts +58 -0
- package/nuxt-base-template/app/interfaces/user.interface.ts +12 -0
- package/nuxt-base-template/app/lib/auth-client.ts +135 -0
- package/nuxt-base-template/app/middleware/admin.global.ts +23 -0
- package/nuxt-base-template/app/middleware/auth.global.ts +18 -0
- package/nuxt-base-template/app/middleware/guest.global.ts +18 -0
- package/nuxt-base-template/app/pages/app/settings/security.vue +409 -0
- package/nuxt-base-template/app/pages/auth/2fa.vue +120 -0
- package/nuxt-base-template/app/pages/auth/forgot-password.vue +72 -21
- package/nuxt-base-template/app/pages/auth/login.vue +75 -11
- package/nuxt-base-template/app/pages/auth/register.vue +184 -0
- package/nuxt-base-template/app/pages/auth/reset-password.vue +153 -0
- package/nuxt-base-template/app/utils/crypto.ts +13 -0
- package/nuxt-base-template/docker-entrypoint.sh +21 -0
- package/nuxt-base-template/nuxt.config.ts +4 -1
- package/nuxt-base-template/oxlint.json +14 -0
- package/nuxt-base-template/package-lock.json +11582 -10675
- package/nuxt-base-template/package.json +35 -32
- package/nuxt-base-template/tests/iam.spec.ts +247 -0
- package/package.json +14 -11
- package/.eslintignore +0 -14
- package/.eslintrc +0 -3
- package/.prettierignore +0 -5
- package/.prettierrc +0 -6
- package/nuxt-base-template/CLAUDE.md +0 -361
- package/nuxt-base-template/app/pages/auth/reset-password/[token].vue +0 -110
- package/nuxt-base-template/app/public/favicon.ico +0 -0
- package/nuxt-base-template/eslint.config.mjs +0 -4
|
@@ -8,6 +8,10 @@ on:
|
|
|
8
8
|
env:
|
|
9
9
|
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
|
10
10
|
|
|
11
|
+
permissions:
|
|
12
|
+
id-token: write # Required for OIDC
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
11
15
|
jobs:
|
|
12
16
|
publish:
|
|
13
17
|
runs-on: ubuntu-latest
|
|
@@ -26,8 +30,6 @@ jobs:
|
|
|
26
30
|
|
|
27
31
|
- name: Publish to npm π
|
|
28
32
|
run: npm publish
|
|
29
|
-
env:
|
|
30
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
31
33
|
|
|
32
34
|
- name: Deploy notification
|
|
33
35
|
if: always()
|
package/.oxfmtrc.jsonc
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -2,35 +2,49 @@
|
|
|
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.0.3](https://github.com/lenneTech/nuxt-base-starter/compare/v1.0.2...v1.0.3) (2026-01-12)
|
|
6
|
+
|
|
7
|
+
### [1.0.2](https://github.com/lenneTech/nuxt-base-starter/compare/v1.0.1...v1.0.2) (2026-01-12)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
* add repository field in package.json ([1f43eae](https://github.com/lenneTech/nuxt-base-starter/commit/1f43eae4445b2f8a54cf4442c79be1bd55cf711c))
|
|
13
|
+
|
|
14
|
+
### [1.0.1](https://github.com/lenneTech/nuxt-base-starter/compare/v1.0.0...v1.0.1) (2026-01-12)
|
|
15
|
+
|
|
16
|
+
## [1.0.0](https://github.com/lenneTech/nuxt-base-starter/compare/v0.3.17...v1.0.0) (2026-01-12)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
* **DEV-609:** removed duplicate public folder inside app ([#10](https://github.com/lenneTech/nuxt-base-starter/issues/10)) ([25fe0fe](https://github.com/lenneTech/nuxt-base-starter/commit/25fe0fe3c53bc3400373d9c3f0a4b6705952171b))
|
|
22
|
+
|
|
5
23
|
### [0.3.17](https://github.com/lenneTech/nuxt-base-starter/compare/v0.3.16...v0.3.17) (2025-10-17)
|
|
6
24
|
|
|
7
25
|
### [0.3.16](https://github.com/lenneTech/nuxt-base-starter/compare/v0.3.15...v0.3.16) (2025-09-05)
|
|
8
26
|
|
|
9
|
-
|
|
10
27
|
### Bug Fixes
|
|
11
28
|
|
|
12
|
-
|
|
29
|
+
- Update environment variable for bug feature toggle ([d875b3e](https://github.com/lenneTech/nuxt-base-starter/commit/d875b3eb586368499b9e628cdabd2f971e7cce7f))
|
|
13
30
|
|
|
14
31
|
### [0.3.15](https://github.com/lenneTech/nuxt-base-starter/compare/v0.3.14...v0.3.15) (2025-09-05)
|
|
15
32
|
|
|
16
|
-
|
|
17
33
|
### Features
|
|
18
34
|
|
|
19
|
-
|
|
35
|
+
- Add Linear API configuration and update dependencies ([291adfd](https://github.com/lenneTech/nuxt-base-starter/commit/291adfd8ee6e2c464c4b7c74e4c27531bda3892e))
|
|
20
36
|
|
|
21
37
|
### [0.3.14](https://github.com/lenneTech/nuxt-base-starter/compare/v0.3.13...v0.3.14) (2025-08-01)
|
|
22
38
|
|
|
23
|
-
|
|
24
39
|
### Bug Fixes
|
|
25
40
|
|
|
26
|
-
|
|
41
|
+
- **DEV-446:** Replace pnpm with npm for dependency installation and project commands ([8274c25](https://github.com/lenneTech/nuxt-base-starter/commit/8274c255384b841862d2d70a12c19ea30ecbb9d8))
|
|
27
42
|
|
|
28
43
|
### [0.3.13](https://github.com/lenneTech/nuxt-base-starter/compare/v0.3.12...v0.3.13) (2025-07-24)
|
|
29
44
|
|
|
30
|
-
|
|
31
45
|
### Bug Fixes
|
|
32
46
|
|
|
33
|
-
|
|
47
|
+
- Update [@lenne](https://github.com/lenne).tech/nuxt-base dependency to latest version ([71dd666](https://github.com/lenneTech/nuxt-base-starter/commit/71dd6669fd9ec25671a102b4d2ad294ac88daa10))
|
|
34
48
|
|
|
35
49
|
### [0.3.12](https://github.com/lenneTech/nuxt-base-starter/compare/v0.3.11...v0.3.12) (2025-07-24)
|
|
36
50
|
|
package/README.md
CHANGED
|
@@ -1,9 +1,136 @@
|
|
|
1
|
-
#
|
|
1
|
+
# create-nuxt-base
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A CLI tool to scaffold a production-ready **Nuxt 4** application with TypeScript, Tailwind CSS v4, NuxtUI v4, and modern tooling.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Quick Start
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npx create-nuxt-base my-awesome-project
|
|
9
|
+
cd my-awesome-project
|
|
10
|
+
npm run dev
|
|
9
11
|
```
|
|
12
|
+
|
|
13
|
+
The development server starts at **http://localhost:3001**
|
|
14
|
+
|
|
15
|
+
## What's Included
|
|
16
|
+
|
|
17
|
+
### Core Framework
|
|
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 |
|
|
25
|
+
|
|
26
|
+
### Authentication (Better Auth)
|
|
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
|
|
33
|
+
|
|
34
|
+
### State & Data
|
|
35
|
+
|
|
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 |
|
|
42
|
+
|
|
43
|
+
### SEO & Analytics
|
|
44
|
+
|
|
45
|
+
- **@nuxtjs/seo** - Sitemap, robots.txt, OG images
|
|
46
|
+
- **@nuxtjs/plausible** - Privacy-friendly analytics
|
|
47
|
+
- **@nuxt/image** - Image optimization with IPX
|
|
48
|
+
|
|
49
|
+
### Developer Experience
|
|
50
|
+
|
|
51
|
+
| Tool | Purpose |
|
|
52
|
+
|------|---------|
|
|
53
|
+
| OxLint | Fast linting |
|
|
54
|
+
| OxFmt | Code formatting |
|
|
55
|
+
| Playwright | E2E testing |
|
|
56
|
+
| @lenne.tech/bug.lt | Bug reporting to Linear (dev only) |
|
|
57
|
+
| dayjs-nuxt | Date/time handling |
|
|
58
|
+
|
|
59
|
+
### File Upload
|
|
60
|
+
|
|
61
|
+
- TUS resumable upload support (`tus-js-client`)
|
|
62
|
+
- Pre-built `TusFileUpload.vue` component
|
|
63
|
+
|
|
64
|
+
### Docker Support
|
|
65
|
+
|
|
66
|
+
- `Dockerfile.dev` for containerized development
|
|
67
|
+
- Hot reload enabled
|
|
68
|
+
|
|
69
|
+
## Project Structure
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
my-project/
|
|
73
|
+
βββ app/
|
|
74
|
+
β βββ assets/css/ # Tailwind CSS
|
|
75
|
+
β βββ components/ # Vue components (auto-imported)
|
|
76
|
+
β β βββ Modal/ # Modal components
|
|
77
|
+
β β βββ Transition/ # Transition components
|
|
78
|
+
β β βββ Upload/ # File upload components
|
|
79
|
+
β βββ composables/ # Composables (auto-imported)
|
|
80
|
+
β βββ interfaces/ # TypeScript interfaces
|
|
81
|
+
β βββ layouts/ # Nuxt layouts
|
|
82
|
+
β βββ lib/ # Auth client configuration
|
|
83
|
+
β βββ middleware/ # Route middleware (auth, admin, guest)
|
|
84
|
+
β βββ pages/ # File-based routing
|
|
85
|
+
β β βββ auth/ # Authentication pages
|
|
86
|
+
β β βββ app/ # Protected app pages
|
|
87
|
+
β βββ utils/ # Utility functions
|
|
88
|
+
β βββ app.config.ts # NuxtUI configuration
|
|
89
|
+
βββ docs/ # Dev-only documentation layer
|
|
90
|
+
βββ tests/ # Playwright E2E tests
|
|
91
|
+
βββ nuxt.config.ts # Nuxt configuration
|
|
92
|
+
βββ openapi-ts.config.ts # API type generation config
|
|
93
|
+
βββ playwright.config.ts # E2E test configuration
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Available Scripts
|
|
97
|
+
|
|
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 |
|
|
103
|
+
| `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 |
|
|
109
|
+
|
|
110
|
+
## Environment Variables
|
|
111
|
+
|
|
112
|
+
Create a `.env` file based on `.env.example`:
|
|
113
|
+
|
|
114
|
+
```env
|
|
115
|
+
# Required
|
|
116
|
+
SITE_URL=http://localhost:3001
|
|
117
|
+
API_URL=http://localhost:3000
|
|
118
|
+
APP_ENV=development
|
|
119
|
+
NODE_ENV=development
|
|
120
|
+
|
|
121
|
+
# Optional
|
|
122
|
+
WEB_PUSH_KEY= # Web push notifications
|
|
123
|
+
LINEAR_API_KEY= # Bug reporting
|
|
124
|
+
LINEAR_TEAM_NAME= # Bug reporting
|
|
125
|
+
LINEAR_PROJECT_NAME= # Bug reporting
|
|
126
|
+
STORAGE_PREFIX=base-dev # Local storage prefix
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Requirements
|
|
130
|
+
|
|
131
|
+
- Node.js >= 22
|
|
132
|
+
- npm >= 10
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
MIT
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules
|
|
3
|
+
.npm
|
|
4
|
+
|
|
5
|
+
# Build output
|
|
6
|
+
.nuxt
|
|
7
|
+
.output
|
|
8
|
+
dist
|
|
9
|
+
|
|
10
|
+
# IDE
|
|
11
|
+
.idea
|
|
12
|
+
.vscode
|
|
13
|
+
*.swp
|
|
14
|
+
*.swo
|
|
15
|
+
|
|
16
|
+
# Logs
|
|
17
|
+
*.log
|
|
18
|
+
npm-debug.log*
|
|
19
|
+
|
|
20
|
+
# Testing
|
|
21
|
+
coverage
|
|
22
|
+
test-results
|
|
23
|
+
playwright-report
|
|
24
|
+
|
|
25
|
+
# Environment
|
|
26
|
+
.env.local
|
|
27
|
+
.env.*.local
|
|
28
|
+
|
|
29
|
+
# Git
|
|
30
|
+
.git
|
|
31
|
+
.gitignore
|
|
32
|
+
|
|
33
|
+
# Docker
|
|
34
|
+
Dockerfile*
|
|
35
|
+
docker-compose*
|
|
36
|
+
.dockerignore
|
|
37
|
+
|
|
38
|
+
# Documentation
|
|
39
|
+
*.md
|
|
40
|
+
!README.md
|
|
41
|
+
|
|
42
|
+
# Misc
|
|
43
|
+
.DS_Store
|
|
44
|
+
*.tgz
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
setups.@nuxt/test-utils="3.23.0"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
FROM node:22-alpine
|
|
2
|
+
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
|
|
5
|
+
# Install dependencies for native modules
|
|
6
|
+
RUN apk add --no-cache python3 make g++
|
|
7
|
+
|
|
8
|
+
# Copy package files first for better caching
|
|
9
|
+
COPY package*.json ./
|
|
10
|
+
COPY .npmrc ./
|
|
11
|
+
|
|
12
|
+
# Install dependencies
|
|
13
|
+
RUN npm ci
|
|
14
|
+
|
|
15
|
+
# Copy entrypoint script
|
|
16
|
+
COPY docker-entrypoint.sh /docker-entrypoint.sh
|
|
17
|
+
RUN chmod +x /docker-entrypoint.sh
|
|
18
|
+
|
|
19
|
+
# Expose port
|
|
20
|
+
EXPOSE 3001
|
|
21
|
+
|
|
22
|
+
ENTRYPOINT ["/docker-entrypoint.sh"]
|
|
23
|
+
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Nuxt Base Template
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A production-ready Nuxt 4 SSR starter with TypeScript, Tailwind CSS v4, NuxtUI v4, and Better Auth.
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
@@ -33,6 +33,13 @@ Start the development server on http://localhost:3001
|
|
|
33
33
|
npm run dev
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
### Docker Development
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
docker build -f Dockerfile.dev -t nuxt-app-dev .
|
|
40
|
+
docker run -p 3001:3001 -v $(pwd):/app nuxt-app-dev
|
|
41
|
+
```
|
|
42
|
+
|
|
36
43
|
## Production
|
|
37
44
|
|
|
38
45
|
Build the application for production:
|
|
@@ -62,8 +69,8 @@ Run linting and formatting checks before committing:
|
|
|
62
69
|
```bash
|
|
63
70
|
npm run check # Run lint + format check
|
|
64
71
|
npm run fix # Auto-fix lint + format issues
|
|
65
|
-
npm run lint #
|
|
66
|
-
npm run format #
|
|
72
|
+
npm run lint # OxLint only
|
|
73
|
+
npm run format # OxFmt format only
|
|
67
74
|
```
|
|
68
75
|
|
|
69
76
|
## Testing
|
|
@@ -84,33 +91,64 @@ npm run generate-types
|
|
|
84
91
|
|
|
85
92
|
## Tech Stack
|
|
86
93
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
| Technology | Version | Description |
|
|
95
|
+
|------------|---------|-------------|
|
|
96
|
+
| Nuxt | 4.2.x | Vue 3 meta-framework with SSR |
|
|
97
|
+
| TypeScript | 5.9.x | Strict type checking |
|
|
98
|
+
| Tailwind CSS | 4.1.x | Utility-first CSS (Vite plugin) |
|
|
99
|
+
| NuxtUI | 4.3.x | Component library with dark mode |
|
|
100
|
+
| Pinia | 0.11.x | State management |
|
|
101
|
+
| Better Auth | 1.4.x | Authentication framework |
|
|
102
|
+
| Playwright | 1.57.x | E2E testing |
|
|
103
|
+
| @hey-api/client-fetch | 0.13.x | Type-safe API client |
|
|
104
|
+
| Valibot | 1.2.x | Schema validation |
|
|
95
105
|
|
|
96
106
|
## Key Features
|
|
97
107
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
+
### Authentication (Better Auth)
|
|
109
|
+
|
|
110
|
+
- Email/password authentication with client-side SHA256 password hashing
|
|
111
|
+
- Two-factor authentication (2FA/TOTP) with backup codes
|
|
112
|
+
- Passkey/WebAuthn support
|
|
113
|
+
- Password reset flow
|
|
114
|
+
- Pre-built pages: login, register, forgot-password, reset-password, 2fa
|
|
115
|
+
- Route middleware: `auth.global.ts`, `admin.global.ts`, `guest.global.ts`
|
|
116
|
+
|
|
117
|
+
### UI & Styling
|
|
118
|
+
|
|
119
|
+
- NuxtUI v4 component library
|
|
120
|
+
- Dark/light mode support
|
|
121
|
+
- Transition components (Fade, Slide, FadeScale)
|
|
122
|
+
- Modal components with `useOverlay` pattern
|
|
123
|
+
|
|
124
|
+
### SEO & Analytics
|
|
125
|
+
|
|
126
|
+
- Sitemap generation (`@nuxtjs/seo`)
|
|
127
|
+
- robots.txt configuration
|
|
128
|
+
- OG image generation
|
|
129
|
+
- Plausible Analytics integration
|
|
130
|
+
|
|
131
|
+
### File Upload
|
|
132
|
+
|
|
133
|
+
- TUS resumable uploads (`tus-js-client`)
|
|
134
|
+
- Pre-built `TusFileUpload.vue` component
|
|
135
|
+
- Progress tracking and error handling
|
|
136
|
+
|
|
137
|
+
### Developer Experience
|
|
138
|
+
|
|
139
|
+
- OxLint for fast linting
|
|
140
|
+
- OxFmt for code formatting
|
|
141
|
+
- Auto-generated API client from OpenAPI
|
|
142
|
+
- Bug reporting to Linear (dev only via `@lenne.tech/bug.lt`)
|
|
143
|
+
- VueUse composition utilities
|
|
144
|
+
- dayjs for date/time handling
|
|
108
145
|
|
|
109
146
|
## Environment Variables
|
|
110
147
|
|
|
111
148
|
Create a `.env` file with the following variables:
|
|
112
149
|
|
|
113
150
|
```env
|
|
151
|
+
# Required
|
|
114
152
|
SITE_URL=http://localhost:3001
|
|
115
153
|
API_URL=http://localhost:3000
|
|
116
154
|
APP_ENV=development
|
|
@@ -124,7 +162,7 @@ WEB_PUSH_KEY= # Web push notifications
|
|
|
124
162
|
LINEAR_API_KEY= # Bug reporting
|
|
125
163
|
LINEAR_TEAM_NAME= # Bug reporting
|
|
126
164
|
LINEAR_PROJECT_NAME= # Bug reporting
|
|
127
|
-
API_SCHEMA=../api/schema.gql #
|
|
165
|
+
API_SCHEMA=../api/schema.gql # OpenAPI schema path
|
|
128
166
|
STORAGE_PREFIX=base-dev # Local storage prefix
|
|
129
167
|
```
|
|
130
168
|
|
|
@@ -132,25 +170,34 @@ STORAGE_PREFIX=base-dev # Local storage prefix
|
|
|
132
170
|
|
|
133
171
|
```
|
|
134
172
|
app/
|
|
135
|
-
βββ assets/
|
|
173
|
+
βββ assets/css/ # Tailwind CSS styles
|
|
136
174
|
βββ components/ # Vue components (auto-imported)
|
|
175
|
+
β βββ Modal/ # Modal components
|
|
176
|
+
β βββ Transition/ # Transition animations
|
|
177
|
+
β βββ Upload/ # File upload components
|
|
137
178
|
βββ composables/ # Composables (auto-imported)
|
|
138
|
-
βββ
|
|
139
|
-
βββ
|
|
179
|
+
β βββ use-better-auth.ts # Auth session helpers
|
|
180
|
+
β βββ use-file.ts # File utilities
|
|
181
|
+
β βββ use-share.ts # Share API
|
|
182
|
+
β βββ use-tus-upload.ts # TUS upload logic
|
|
183
|
+
βββ interfaces/ # TypeScript interfaces
|
|
184
|
+
βββ layouts/ # Nuxt layouts (default, slim)
|
|
185
|
+
βββ lib/ # Auth client configuration
|
|
186
|
+
βββ middleware/ # Route guards (auth, admin, guest)
|
|
140
187
|
βββ pages/ # File-based routing
|
|
188
|
+
β βββ auth/ # Authentication pages
|
|
189
|
+
β βββ app/ # Protected app pages
|
|
190
|
+
βββ utils/ # Utility functions
|
|
141
191
|
βββ app.config.ts # NuxtUI configuration
|
|
142
192
|
|
|
143
193
|
docs/ # Dev-only documentation layer
|
|
144
194
|
tests/ # Playwright E2E tests
|
|
145
195
|
```
|
|
146
196
|
|
|
147
|
-
## Development Guidelines
|
|
148
|
-
|
|
149
|
-
For detailed coding standards and architecture information, see [CLAUDE.md](./CLAUDE.md).
|
|
150
|
-
|
|
151
197
|
## Documentation
|
|
152
198
|
|
|
153
199
|
- [Nuxt Documentation](https://nuxt.com/docs)
|
|
154
200
|
- [NuxtUI Documentation](https://ui.nuxt.com)
|
|
201
|
+
- [Better Auth Documentation](https://www.better-auth.com)
|
|
155
202
|
- [Tailwind CSS Documentation](https://tailwindcss.com/docs)
|
|
156
203
|
- [Vue 3 Documentation](https://vuejs.org)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// Imports
|
|
4
|
+
// ============================================================================
|
|
5
|
+
import type { FormSubmitEvent } from '@nuxt/ui';
|
|
6
|
+
import type { InferOutput } from 'valibot';
|
|
7
|
+
|
|
8
|
+
import * as v from 'valibot';
|
|
9
|
+
|
|
10
|
+
import { authClient } from '~/lib/auth-client';
|
|
11
|
+
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Props & Emits
|
|
14
|
+
// ============================================================================
|
|
15
|
+
interface Props {
|
|
16
|
+
initialCodes?: string[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
20
|
+
initialCodes: () => [],
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const emit = defineEmits<{
|
|
24
|
+
close: [result?: unknown];
|
|
25
|
+
}>();
|
|
26
|
+
|
|
27
|
+
// ============================================================================
|
|
28
|
+
// Composables
|
|
29
|
+
// ============================================================================
|
|
30
|
+
const toast = useToast();
|
|
31
|
+
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// Variables
|
|
34
|
+
// ============================================================================
|
|
35
|
+
const loading = ref<boolean>(false);
|
|
36
|
+
const backupCodes = ref<string[]>(props.initialCodes);
|
|
37
|
+
|
|
38
|
+
const passwordSchema = v.object({
|
|
39
|
+
password: v.pipe(v.string('Passwort ist erforderlich'), v.minLength(1, 'Passwort ist erforderlich')),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
type PasswordSchema = InferOutput<typeof passwordSchema>;
|
|
43
|
+
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// Functions
|
|
46
|
+
// ============================================================================
|
|
47
|
+
function copyBackupCodes(): void {
|
|
48
|
+
navigator.clipboard.writeText(backupCodes.value.join('\n'));
|
|
49
|
+
toast.add({
|
|
50
|
+
color: 'success',
|
|
51
|
+
description: 'Backup-Codes wurden in die Zwischenablage kopiert',
|
|
52
|
+
title: 'Kopiert',
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function generateBackupCodes(payload: FormSubmitEvent<PasswordSchema>): Promise<void> {
|
|
57
|
+
loading.value = true;
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const { data, error } = await authClient.twoFactor.generateBackupCodes({
|
|
61
|
+
password: payload.data.password,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
if (error) {
|
|
65
|
+
toast.add({
|
|
66
|
+
color: 'error',
|
|
67
|
+
description: error.message || 'Backup-Codes konnten nicht generiert werden',
|
|
68
|
+
title: 'Fehler',
|
|
69
|
+
});
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
backupCodes.value = data?.backupCodes ?? [];
|
|
74
|
+
} finally {
|
|
75
|
+
loading.value = false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function handleClose(): void {
|
|
80
|
+
emit('close');
|
|
81
|
+
}
|
|
82
|
+
</script>
|
|
83
|
+
|
|
84
|
+
<template>
|
|
85
|
+
<UModal title="Backup-Codes" :close="{ onClick: handleClose }">
|
|
86
|
+
<template #body>
|
|
87
|
+
<div class="space-y-4">
|
|
88
|
+
<div class="flex items-center gap-3">
|
|
89
|
+
<UIcon name="i-lucide-key" class="size-6 text-warning" />
|
|
90
|
+
<p class="text-sm text-muted">Bewahre diese Codes sicher auf. Jeder Code kann nur einmal verwendet werden.</p>
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
<template v-if="backupCodes.length > 0">
|
|
94
|
+
<div class="grid grid-cols-2 gap-2 rounded-lg bg-muted/50 p-4 font-mono text-sm">
|
|
95
|
+
<span v-for="code in backupCodes" :key="code">{{ code }}</span>
|
|
96
|
+
</div>
|
|
97
|
+
</template>
|
|
98
|
+
|
|
99
|
+
<template v-else>
|
|
100
|
+
<UForm :schema="passwordSchema" class="space-y-4" @submit="generateBackupCodes">
|
|
101
|
+
<UFormField label="Passwort" name="password">
|
|
102
|
+
<UInput name="password" type="password" placeholder="Dein Passwort" />
|
|
103
|
+
</UFormField>
|
|
104
|
+
<UButton type="submit" block :loading="loading"> Neue Backup-Codes generieren </UButton>
|
|
105
|
+
</UForm>
|
|
106
|
+
</template>
|
|
107
|
+
</div>
|
|
108
|
+
</template>
|
|
109
|
+
|
|
110
|
+
<template #footer>
|
|
111
|
+
<div class="flex justify-end gap-3">
|
|
112
|
+
<UButton v-if="backupCodes.length > 0" variant="outline" icon="i-lucide-copy" @click="copyBackupCodes"> Codes kopieren </UButton>
|
|
113
|
+
<UButton color="neutral" variant="outline" @click="handleClose"> SchlieΓen </UButton>
|
|
114
|
+
</div>
|
|
115
|
+
</template>
|
|
116
|
+
</UModal>
|
|
117
|
+
</template>
|