Browse Source

docs: add registration page design spec

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
main
npmrun 2 weeks ago
parent
commit
67e3f3e508
  1. 3
      .gitignore
  2. 88
      docs/superpowers/specs/2026-05-15-registration-page-design.md

3
.gitignore

@ -13,6 +13,9 @@ node_modules
logs
*.log
# Brainstorming mockups
.superpowers
# Misc
.DS_Store
.fleet

88
docs/superpowers/specs/2026-05-15-registration-page-design.md

@ -0,0 +1,88 @@
# Registration Page Design
## Overview
Add a registration page at `/register` with username, password, confirm password, and SVG captcha. On success, redirect to `/login` with a query param. Login page is out of scope.
## Stack
- Nuxt 4.4 + Nuxt UI 4.6 + Tailwind v4
- Drizzle ORM + SQLite (users table already exists)
- bcryptjs (already installed), svg-captcha, zod (already installed)
## Files
### New
| File | Purpose |
|---|---|
| `app/pages/register.vue` | Registration page component |
| `server/api/auth/captcha.get.ts` | Generate SVG captcha, return token + svg |
| `server/api/auth/register.post.ts` | Validate input, create user |
| `server/utils/auth/captcha.ts` | Server-side captcha generation/validation |
| `server/utils/auth/validation.ts` | Zod schemas for registration input |
### Modified
| File | Change |
|---|---|
| `app/layouts/default.vue` | Wire header button to `/register` |
## API Endpoints
### GET /api/auth/captcha
Generates a captcha, stores token→text in a server-side Map (5-min expiry), returns the SVG and token.
```
Response: { code: 0, data: { token: "uuid", svg: "<svg>...</svg>" } }
```
### POST /api/auth/register
```
Request: { username, password, confirmPassword, captchaToken, captchaText }
Response: { code: 0, data: { id: 1, username: "foo" } }
```
Steps:
1. Zod validation (username 3-30, password 8+, passwords match)
2. Verify captcha: lookup token in Map, compare text case-insensitive, delete on match
3. Check username uniqueness in DB
4. bcryptjs hash password (salt rounds 10)
5. Insert into users table with role="user", status="active"
6. Return success — no auto-login
## Data Flow
1. Page mounts → GET /api/auth/captcha → render SVG
2. User submits → client Zod validation → POST /api/auth/register
3. On success → `navigateTo('/login?registered=1')`
4. On error → show toast, keep form state; if captcha fail, auto-refresh captcha
## Error Handling
Client-side: UForm + Zod validation for empty fields, length, password match.
Server-side:
| Case | Message |
|---|---|
| Zod validation fail | "密码至少需要8个字符" |
| Captcha wrong | "验证码错误" |
| Captcha expired | "验证码已过期" |
| Username taken | "用户名已存在" |
| Server error | "注册失败,请稍后重试" |
Captcha is consumed (deleted from Map) on match to prevent replay. If registration fails after captcha check, a new captcha is fetched.
## Form Fields
- **Username** — required, 3-30 characters, unique in DB
- **Password** — required, min 8 characters, masked input with toggle
- **Confirm Password** — required, must match password
- **Captcha** — SVG image + text input, refresh button
## Layout
Card-centered form (380px max-width), single column. Header already has the "登录/注册" button. Form shows a "Already have an account? Log in" link at the bottom.
Loading…
Cancel
Save