@eddacraft/anvil-adapters 0.1.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.
Files changed (183) hide show
  1. package/AGENTS.md +180 -0
  2. package/BMAD_ADAPTER_SPEC.md +489 -0
  3. package/LICENSE +14 -0
  4. package/README.md +500 -0
  5. package/dist/aps-markdown/adapter.d.ts +102 -0
  6. package/dist/aps-markdown/adapter.d.ts.map +1 -0
  7. package/dist/aps-markdown/adapter.js +351 -0
  8. package/dist/aps-markdown/index.d.ts +8 -0
  9. package/dist/aps-markdown/index.d.ts.map +1 -0
  10. package/dist/aps-markdown/index.js +7 -0
  11. package/dist/base/file-discovery.d.ts +63 -0
  12. package/dist/base/file-discovery.d.ts.map +1 -0
  13. package/dist/base/file-discovery.js +246 -0
  14. package/dist/base/index.d.ts +10 -0
  15. package/dist/base/index.d.ts.map +1 -0
  16. package/dist/base/index.js +9 -0
  17. package/dist/base/registry.d.ts +155 -0
  18. package/dist/base/registry.d.ts.map +1 -0
  19. package/dist/base/registry.js +227 -0
  20. package/dist/base/testing.d.ts +102 -0
  21. package/dist/base/testing.d.ts.map +1 -0
  22. package/dist/base/testing.js +221 -0
  23. package/dist/base/types.d.ts +255 -0
  24. package/dist/base/types.d.ts.map +1 -0
  25. package/dist/base/types.js +78 -0
  26. package/dist/base/utils.d.ts +127 -0
  27. package/dist/base/utils.d.ts.map +1 -0
  28. package/dist/base/utils.js +254 -0
  29. package/dist/bmad/format-adapter.d.ts +76 -0
  30. package/dist/bmad/format-adapter.d.ts.map +1 -0
  31. package/dist/bmad/format-adapter.js +186 -0
  32. package/dist/bmad/index.d.ts +12 -0
  33. package/dist/bmad/index.d.ts.map +1 -0
  34. package/dist/bmad/index.js +10 -0
  35. package/dist/bmad/parser.d.ts +12 -0
  36. package/dist/bmad/parser.d.ts.map +1 -0
  37. package/dist/bmad/parser.js +181 -0
  38. package/dist/bmad/serializer.d.ts +16 -0
  39. package/dist/bmad/serializer.d.ts.map +1 -0
  40. package/dist/bmad/serializer.js +170 -0
  41. package/dist/bmad/types.d.ts +127 -0
  42. package/dist/bmad/types.d.ts.map +1 -0
  43. package/dist/bmad/types.js +47 -0
  44. package/dist/bmad/utils.d.ts +120 -0
  45. package/dist/bmad/utils.d.ts.map +1 -0
  46. package/dist/bmad/utils.js +480 -0
  47. package/dist/common/index.d.ts +3 -0
  48. package/dist/common/index.d.ts.map +1 -0
  49. package/dist/common/index.js +2 -0
  50. package/dist/common/registry.d.ts +18 -0
  51. package/dist/common/registry.d.ts.map +1 -0
  52. package/dist/common/registry.js +58 -0
  53. package/dist/common/types.d.ts +68 -0
  54. package/dist/common/types.d.ts.map +1 -0
  55. package/dist/common/types.js +12 -0
  56. package/dist/generic/format-adapter.d.ts +64 -0
  57. package/dist/generic/format-adapter.d.ts.map +1 -0
  58. package/dist/generic/format-adapter.js +159 -0
  59. package/dist/generic/index.d.ts +10 -0
  60. package/dist/generic/index.d.ts.map +1 -0
  61. package/dist/generic/index.js +9 -0
  62. package/dist/generic/parser.d.ts +11 -0
  63. package/dist/generic/parser.d.ts.map +1 -0
  64. package/dist/generic/parser.js +106 -0
  65. package/dist/generic/serializer.d.ts +11 -0
  66. package/dist/generic/serializer.d.ts.map +1 -0
  67. package/dist/generic/serializer.js +118 -0
  68. package/dist/generic/types.d.ts +52 -0
  69. package/dist/generic/types.d.ts.map +1 -0
  70. package/dist/generic/types.js +6 -0
  71. package/dist/generic/utils.d.ts +51 -0
  72. package/dist/generic/utils.d.ts.map +1 -0
  73. package/dist/generic/utils.js +232 -0
  74. package/dist/index.d.ts +15 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +31 -0
  77. package/dist/speckit/export.d.ts +22 -0
  78. package/dist/speckit/export.d.ts.map +1 -0
  79. package/dist/speckit/export.js +384 -0
  80. package/dist/speckit/format-adapter.d.ts +104 -0
  81. package/dist/speckit/format-adapter.d.ts.map +1 -0
  82. package/dist/speckit/format-adapter.js +488 -0
  83. package/dist/speckit/import-v2.d.ts +33 -0
  84. package/dist/speckit/import-v2.d.ts.map +1 -0
  85. package/dist/speckit/import-v2.js +361 -0
  86. package/dist/speckit/import.d.ts +16 -0
  87. package/dist/speckit/import.d.ts.map +1 -0
  88. package/dist/speckit/import.js +247 -0
  89. package/dist/speckit/index.d.ts +5 -0
  90. package/dist/speckit/index.d.ts.map +1 -0
  91. package/dist/speckit/index.js +4 -0
  92. package/dist/speckit/parser.d.ts +28 -0
  93. package/dist/speckit/parser.d.ts.map +1 -0
  94. package/dist/speckit/parser.js +283 -0
  95. package/dist/speckit/parsers/plan-parser.d.ts +71 -0
  96. package/dist/speckit/parsers/plan-parser.d.ts.map +1 -0
  97. package/dist/speckit/parsers/plan-parser.js +216 -0
  98. package/dist/speckit/parsers/spec-parser.d.ts +67 -0
  99. package/dist/speckit/parsers/spec-parser.d.ts.map +1 -0
  100. package/dist/speckit/parsers/spec-parser.js +255 -0
  101. package/dist/speckit/parsers/tasks-parser.d.ts +57 -0
  102. package/dist/speckit/parsers/tasks-parser.d.ts.map +1 -0
  103. package/dist/speckit/parsers/tasks-parser.js +157 -0
  104. package/package.json +23 -0
  105. package/project.json +29 -0
  106. package/src/__tests__/adapter-edge-cases.test.ts +937 -0
  107. package/src/__tests__/bmad-format-adapter.test.ts +1470 -0
  108. package/src/__tests__/fixtures/aps/expected-output.json +83 -0
  109. package/src/__tests__/fixtures/bmad/invalid-malformed-yaml.md +16 -0
  110. package/src/__tests__/fixtures/bmad/invalid-no-requirements.md +23 -0
  111. package/src/__tests__/fixtures/bmad/invalid-only-yaml.md +16 -0
  112. package/src/__tests__/fixtures/bmad/invalid-too-short.md +3 -0
  113. package/src/__tests__/fixtures/bmad/invalid-wrong-format.md +40 -0
  114. package/src/__tests__/fixtures/bmad/valid-agent.md +27 -0
  115. package/src/__tests__/fixtures/bmad/valid-architecture.md +116 -0
  116. package/src/__tests__/fixtures/bmad/valid-complex-prd.md +161 -0
  117. package/src/__tests__/fixtures/bmad/valid-epic.md +73 -0
  118. package/src/__tests__/fixtures/bmad/valid-minimal-prd.md +19 -0
  119. package/src/__tests__/fixtures/bmad/valid-prd.md +107 -0
  120. package/src/__tests__/fixtures/bmad/valid-story.md +107 -0
  121. package/src/__tests__/fixtures/bmad/valid-task.md +79 -0
  122. package/src/__tests__/fixtures/bmad/valid-v6-prd.md +35 -0
  123. package/src/__tests__/fixtures/generic/plan-detailed.md +39 -0
  124. package/src/__tests__/fixtures/generic/prd-simple.md +27 -0
  125. package/src/__tests__/fixtures/generic/rfc-example.md +26 -0
  126. package/src/__tests__/fixtures/generic/todo-list.md +23 -0
  127. package/src/__tests__/fixtures/speckit/sample-plan.md +63 -0
  128. package/src/__tests__/fixtures/speckit/sample-spec-namespaced.md +50 -0
  129. package/src/__tests__/fixtures/speckit/sample-spec.md +105 -0
  130. package/src/__tests__/fixtures/speckit/sample-tasks.md +87 -0
  131. package/src/__tests__/fixtures/speckit-official/auth-feature/plan.md +272 -0
  132. package/src/__tests__/fixtures/speckit-official/auth-feature/spec.md +149 -0
  133. package/src/__tests__/fixtures/speckit-official/auth-feature/tasks.md +169 -0
  134. package/src/__tests__/generic-format-adapter.test.ts +398 -0
  135. package/src/__tests__/speckit-export.test.ts +233 -0
  136. package/src/__tests__/speckit-format-adapter.test.ts +832 -0
  137. package/src/__tests__/speckit-import-v2.test.ts +253 -0
  138. package/src/__tests__/speckit-import.test.ts +209 -0
  139. package/src/__tests__/speckit-parser.test.ts +219 -0
  140. package/src/__tests__/speckit-spec-parser.test.ts +120 -0
  141. package/src/aps-markdown/__tests__/__fixtures__/simple-leaf.aps.md +17 -0
  142. package/src/aps-markdown/__tests__/adapter.test.ts +393 -0
  143. package/src/aps-markdown/adapter.ts +455 -0
  144. package/src/aps-markdown/index.ts +8 -0
  145. package/src/base/__tests__/registry.test.ts +515 -0
  146. package/src/base/file-discovery.ts +305 -0
  147. package/src/base/index.ts +10 -0
  148. package/src/base/registry.ts +263 -0
  149. package/src/base/testing.ts +334 -0
  150. package/src/base/types.ts +342 -0
  151. package/src/base/utils.ts +306 -0
  152. package/src/bmad/format-adapter.ts +227 -0
  153. package/src/bmad/index.ts +21 -0
  154. package/src/bmad/parser.ts +224 -0
  155. package/src/bmad/serializer.ts +206 -0
  156. package/src/bmad/types.ts +135 -0
  157. package/src/bmad/utils.ts +575 -0
  158. package/src/common/index.ts +2 -0
  159. package/src/common/registry.ts +72 -0
  160. package/src/common/types.ts +84 -0
  161. package/src/generic/__tests__/serializer.test.ts +167 -0
  162. package/src/generic/format-adapter.ts +200 -0
  163. package/src/generic/index.ts +11 -0
  164. package/src/generic/parser.ts +129 -0
  165. package/src/generic/serializer.ts +134 -0
  166. package/src/generic/types.ts +53 -0
  167. package/src/generic/utils.ts +270 -0
  168. package/src/index.ts +48 -0
  169. package/src/speckit/export.ts +489 -0
  170. package/src/speckit/format-adapter.ts +595 -0
  171. package/src/speckit/import-v2.ts +445 -0
  172. package/src/speckit/import.ts +305 -0
  173. package/src/speckit/index.ts +4 -0
  174. package/src/speckit/parser.ts +351 -0
  175. package/src/speckit/parsers/plan-parser.ts +342 -0
  176. package/src/speckit/parsers/spec-parser.ts +379 -0
  177. package/src/speckit/parsers/tasks-parser.ts +246 -0
  178. package/tsconfig.json +26 -0
  179. package/tsconfig.lib.json +21 -0
  180. package/tsconfig.lib.tsbuildinfo +1 -0
  181. package/tsconfig.spec.json +9 -0
  182. package/tsconfig.tsbuildinfo +1 -0
  183. package/vitest.config.ts +14 -0
@@ -0,0 +1,272 @@
1
+ # Implementation Plan: User Authentication System
2
+
3
+ **Branch**: `feature/001-auth-system` **Date**: 2025-01-15 **Spec**:
4
+ [spec.md](./spec.md)
5
+
6
+ ## Summary
7
+
8
+ Implement a secure JWT-based authentication system with user registration,
9
+ login, password reset, and token refresh capabilities. The system will use
10
+ Node.js/TypeScript with Express.js, PostgreSQL for data storage, and Redis for
11
+ session management.
12
+
13
+ ## Technical Context
14
+
15
+ - **Language/Version**: TypeScript 5.3, Node.js 20 LTS
16
+ - **Dependencies**:
17
+ - express ^4.18.0
18
+ - jsonwebtoken ^9.0.2
19
+ - bcrypt ^5.1.1
20
+ - @types/node ^20.0.0
21
+ - zod ^3.22.0 (validation)
22
+ - pg ^8.11.0 (PostgreSQL client)
23
+ - redis ^4.6.0 (session management)
24
+ - nodemailer ^6.9.0 (email sending)
25
+ - **Storage**: PostgreSQL 15+ for user data, Redis 7+ for session/rate limiting
26
+ - **Testing**: Vitest for unit tests, Supertest for API tests
27
+ - **Target**: REST API server, containerized with Docker
28
+ - **Type**: Backend service
29
+ - **Performance Goals**:
30
+ - Authentication endpoint response time < 200ms (p95)
31
+ - Support 100 concurrent requests
32
+ - **Constraints**:
33
+ - Must comply with OWASP authentication guidelines
34
+ - Must support horizontal scaling
35
+ - **Scale**: Expected initial load: 1000 daily active users, 10,000 total users
36
+
37
+ ## Constitution Check
38
+
39
+ ✅ **Modularity**: Authentication logic separated into controller, service, and
40
+ repository layers ✅ **Testability**: Each component has clear interfaces for
41
+ mocking ✅ **Security**: Follows OWASP Top 10 guidelines, password hashing, JWT
42
+ validation ✅ **Performance**: Redis caching for rate limiting, indexed database
43
+ queries ✅ **Maintainability**: TypeScript for type safety, clear error handling
44
+ ✅ **Documentation**: OpenAPI/Swagger docs for all endpoints
45
+
46
+ ## Project Structure
47
+
48
+ ### Documentation
49
+
50
+ ```
51
+ specs/
52
+ └── 001-auth-system/
53
+ ├── spec.md (this file's sibling)
54
+ ├── plan.md (this file)
55
+ └── tasks.md (to be generated)
56
+ ```
57
+
58
+ ### Source Code Structure
59
+
60
+ #### Option 1: Modular Backend Service (Selected)
61
+
62
+ ```
63
+ src/
64
+ ├── modules/
65
+ │ └── auth/
66
+ │ ├── auth.controller.ts # HTTP endpoints
67
+ │ ├── auth.service.ts # Business logic
68
+ │ ├── auth.repository.ts # Data access
69
+ │ ├── auth.validation.ts # Zod schemas
70
+ │ ├── auth.middleware.ts # JWT verification
71
+ │ └── __tests__/
72
+ │ ├── auth.controller.test.ts
73
+ │ ├── auth.service.test.ts
74
+ │ └── auth.integration.test.ts
75
+ ├── entities/
76
+ │ ├── user.entity.ts
77
+ │ ├── auth-token.entity.ts
78
+ │ ├── audit-log.entity.ts
79
+ │ └── password-reset.entity.ts
80
+ ├── database/
81
+ │ ├── migrations/
82
+ │ │ ├── 001_create_users_table.sql
83
+ │ │ ├── 002_create_auth_tokens_table.sql
84
+ │ │ ├── 003_create_audit_logs_table.sql
85
+ │ │ └── 004_create_password_resets_table.sql
86
+ │ └── connection.ts
87
+ ├── utils/
88
+ │ ├── jwt.util.ts
89
+ │ ├── hash.util.ts
90
+ │ ├── email.util.ts
91
+ │ └── rate-limit.util.ts
92
+ ├── config/
93
+ │ ├── env.ts
94
+ │ └── constants.ts
95
+ └── app.ts
96
+ ```
97
+
98
+ ## Implementation Details
99
+
100
+ ### API Endpoints
101
+
102
+ **POST /api/auth/register**
103
+
104
+ - Request: `{ email: string, password: string }`
105
+ - Response: `{ user: { id, email }, token: string }`
106
+ - Errors: 400 (validation), 409 (email exists)
107
+
108
+ **POST /api/auth/login**
109
+
110
+ - Request: `{ email: string, password: string }`
111
+ - Response: `{ user: { id, email }, token: string, refreshToken: string }`
112
+ - Errors: 401 (invalid credentials), 423 (account locked)
113
+
114
+ **POST /api/auth/logout**
115
+
116
+ - Request: Headers with JWT
117
+ - Response: 204 No Content
118
+ - Errors: 401 (unauthorized)
119
+
120
+ **POST /api/auth/refresh**
121
+
122
+ - Request: `{ refreshToken: string }`
123
+ - Response: `{ token: string, refreshToken: string }`
124
+ - Errors: 401 (invalid/expired token)
125
+
126
+ **POST /api/auth/password-reset/request**
127
+
128
+ - Request: `{ email: string }`
129
+ - Response: 200 OK (always, for security)
130
+ - Errors: 429 (rate limit)
131
+
132
+ **POST /api/auth/password-reset/confirm**
133
+
134
+ - Request: `{ token: string, newPassword: string }`
135
+ - Response: 200 OK
136
+ - Errors: 400 (invalid token), 410 (expired token)
137
+
138
+ ### Database Schema
139
+
140
+ **users table**
141
+
142
+ ```sql
143
+ CREATE TABLE users (
144
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
145
+ email VARCHAR(255) UNIQUE NOT NULL,
146
+ hashed_password VARCHAR(255) NOT NULL,
147
+ created_at TIMESTAMP DEFAULT NOW(),
148
+ updated_at TIMESTAMP DEFAULT NOW(),
149
+ last_login TIMESTAMP,
150
+ account_locked BOOLEAN DEFAULT FALSE,
151
+ failed_login_count INTEGER DEFAULT 0
152
+ );
153
+ CREATE INDEX idx_users_email ON users(email);
154
+ ```
155
+
156
+ **auth_tokens table**
157
+
158
+ ```sql
159
+ CREATE TABLE auth_tokens (
160
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
161
+ user_id UUID REFERENCES users(id) ON DELETE CASCADE,
162
+ refresh_token VARCHAR(255) UNIQUE NOT NULL,
163
+ expires_at TIMESTAMP NOT NULL,
164
+ created_at TIMESTAMP DEFAULT NOW()
165
+ );
166
+ CREATE INDEX idx_auth_tokens_user_id ON auth_tokens(user_id);
167
+ CREATE INDEX idx_auth_tokens_refresh_token ON auth_tokens(refresh_token);
168
+ ```
169
+
170
+ **audit_logs table**
171
+
172
+ ```sql
173
+ CREATE TABLE audit_logs (
174
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
175
+ user_id UUID REFERENCES users(id) ON DELETE SET NULL,
176
+ event_type VARCHAR(50) NOT NULL,
177
+ ip_address VARCHAR(45),
178
+ user_agent TEXT,
179
+ success BOOLEAN NOT NULL,
180
+ error_message TEXT,
181
+ timestamp TIMESTAMP DEFAULT NOW()
182
+ );
183
+ CREATE INDEX idx_audit_logs_user_id ON audit_logs(user_id);
184
+ CREATE INDEX idx_audit_logs_timestamp ON audit_logs(timestamp);
185
+ ```
186
+
187
+ **password_resets table**
188
+
189
+ ```sql
190
+ CREATE TABLE password_resets (
191
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
192
+ user_id UUID REFERENCES users(id) ON DELETE CASCADE,
193
+ token VARCHAR(255) UNIQUE NOT NULL,
194
+ expires_at TIMESTAMP NOT NULL,
195
+ used BOOLEAN DEFAULT FALSE,
196
+ created_at TIMESTAMP DEFAULT NOW()
197
+ );
198
+ CREATE INDEX idx_password_resets_token ON password_resets(token);
199
+ ```
200
+
201
+ ### Configuration
202
+
203
+ **Environment Variables**
204
+
205
+ ```
206
+ # Database
207
+ DATABASE_URL=postgresql://user:pass@localhost:5432/dbname
208
+ REDIS_URL=redis://localhost:6379
209
+
210
+ # JWT
211
+ JWT_SECRET=<generate-secure-secret>
212
+ JWT_EXPIRES_IN=15m
213
+ REFRESH_TOKEN_EXPIRES_IN=7d
214
+
215
+ # Email
216
+ SMTP_HOST=smtp.example.com
217
+ SMTP_PORT=587
218
+ SMTP_USER=auth@example.com
219
+ SMTP_PASS=<smtp-password>
220
+
221
+ # Security
222
+ BCRYPT_ROUNDS=10
223
+ MAX_LOGIN_ATTEMPTS=5
224
+ RATE_LIMIT_WINDOW=60000
225
+ RATE_LIMIT_MAX_REQUESTS=10
226
+ PASSWORD_RESET_EXPIRY=24h
227
+ ```
228
+
229
+ ### Security Measures
230
+
231
+ 1. **Password Security**
232
+ - Bcrypt hashing with cost factor 10
233
+ - Minimum 8 characters, complexity requirements enforced
234
+ - Old passwords not stored (for comparison)
235
+
236
+ 2. **JWT Security**
237
+ - Signed with HS256 algorithm
238
+ - Short expiration (15 minutes)
239
+ - Refresh tokens stored in database, long-lived (7 days)
240
+ - Token blacklisting on logout via Redis
241
+
242
+ 3. **Rate Limiting**
243
+ - 10 requests per minute per IP on auth endpoints
244
+ - Implemented with Redis sliding window
245
+ - Account lockout after 5 failed login attempts
246
+
247
+ 4. **Audit Logging**
248
+ - All authentication events logged
249
+ - IP address and user agent captured
250
+ - 90-day retention policy
251
+
252
+ ## Complexity Tracking
253
+
254
+ ### Complex Design Decision: Token Refresh Strategy
255
+
256
+ **Problem**: Need to balance security (short-lived tokens) with UX (not forcing
257
+ frequent re-logins)
258
+
259
+ **Solution**: Dual-token approach
260
+
261
+ - Short-lived JWT (15 min) for API access
262
+ - Long-lived refresh token (7 days) stored in database
263
+ - Automatic token refresh before expiration
264
+ - Refresh token rotation on each use
265
+
266
+ **Justification**:
267
+
268
+ - JWT is stateless and fast to validate
269
+ - Refresh tokens are revocable (database-backed)
270
+ - Compromise of JWT has limited window
271
+ - UX stays smooth with automatic refresh
272
+ - Meets security best practices (OWASP)
@@ -0,0 +1,149 @@
1
+ # Feature: User Authentication System
2
+
3
+ **Branch**: `feature/001-auth-system` **Date**: 2025-01-15 **Status**: Draft
4
+
5
+ ## User Scenarios & Testing
6
+
7
+ ### P1: User Registration
8
+
9
+ **As a** new user **I want to** create an account with email and password **So
10
+ that** I can access the application securely
11
+
12
+ **Acceptance Scenarios:**
13
+
14
+ - User submits valid email and strong password
15
+ - System validates email format and password strength
16
+ - System creates user account and sends confirmation email
17
+ - User receives success message
18
+
19
+ **Edge Cases:**
20
+
21
+ - Email already registered → Show error message
22
+ - Weak password → Show password requirements
23
+ - Invalid email format → Show format error
24
+ - Network failure during registration → Show retry option
25
+
26
+ ### P1: User Login
27
+
28
+ **As a** registered user **I want to** log in with my credentials **So that** I
29
+ can access my personalized content
30
+
31
+ **Acceptance Scenarios:**
32
+
33
+ - User enters valid email and password
34
+ - System validates credentials
35
+ - System generates JWT token
36
+ - User is redirected to dashboard
37
+
38
+ **Edge Cases:**
39
+
40
+ - Invalid credentials → Show error, increment failure count
41
+ - Account locked (5 failed attempts) → Show account locked message
42
+ - Expired session → Redirect to login with message
43
+ - [NEEDS CLARIFICATION: Should we support "remember me" functionality?]
44
+
45
+ ### P2: Password Reset
46
+
47
+ **As a** user who forgot their password **I want to** reset my password via
48
+ email **So that** I can regain access to my account
49
+
50
+ **Acceptance Scenarios:**
51
+
52
+ - User requests password reset
53
+ - System sends reset link to registered email
54
+ - User clicks link and sets new password
55
+ - User can log in with new password
56
+
57
+ **Edge Cases:**
58
+
59
+ - Email not found → Show generic message for security
60
+ - Reset link expired (24 hours) → Show error, offer to resend
61
+ - Weak new password → Show requirements
62
+ - [NEEDS CLARIFICATION: Should old passwords be prevented from reuse?]
63
+
64
+ ### P3: Token Refresh
65
+
66
+ **As a** logged-in user **I want** my session to be extended automatically **So
67
+ that** I don't lose my work due to session expiration
68
+
69
+ **Acceptance Scenarios:**
70
+
71
+ - User's token expires during active session
72
+ - System automatically requests refresh token
73
+ - New JWT token is issued
74
+ - User continues working without interruption
75
+
76
+ **Edge Cases:**
77
+
78
+ - Refresh token expired → Force re-login
79
+ - Network failure during refresh → Queue and retry
80
+ - [NEEDS CLARIFICATION: What is the token expiration policy?]
81
+
82
+ ## Requirements
83
+
84
+ ### Functional Requirements
85
+
86
+ **FR-001**: System MUST validate email addresses using RFC 5322 standard
87
+ **FR-002**: System MUST enforce password requirements: minimum 8 characters, one
88
+ uppercase, one lowercase, one number, one special character **FR-003**: System
89
+ MUST hash passwords using bcrypt with minimum cost factor of 10 **FR-004**:
90
+ System MUST generate JWT tokens with configurable expiration time **FR-005**:
91
+ System MUST lock accounts after 5 consecutive failed login attempts **FR-006**:
92
+ System MUST send password reset emails with time-limited tokens (24 hours)
93
+ **FR-007**: System MUST retain user authentication audit logs for 90 days
94
+ **FR-008**: [NEEDS CLARIFICATION: Token expiration time - 15 minutes or 1 hour?]
95
+ **FR-009**: [NEEDS CLARIFICATION: Should we support OAuth providers (Google,
96
+ GitHub)?] **FR-010**: System MUST rate-limit authentication endpoints to prevent
97
+ brute force attacks
98
+
99
+ ### Key Entities
100
+
101
+ **User**
102
+
103
+ - Represents: A person with access to the application
104
+ - Key Attributes: id, email, hashed_password, created_at, last_login,
105
+ account_locked, failed_login_count
106
+ - Relationships: Has many AuthTokens, has many AuditLogs
107
+
108
+ **AuthToken**
109
+
110
+ - Represents: A JWT token for authentication
111
+ - Key Attributes: id, user_id, token, expires_at, refresh_token, created_at
112
+ - Relationships: Belongs to User
113
+
114
+ **AuditLog**
115
+
116
+ - Represents: Record of authentication events
117
+ - Key Attributes: id, user_id, event_type, ip_address, user_agent, success,
118
+ timestamp
119
+ - Relationships: Belongs to User
120
+
121
+ **PasswordReset**
122
+
123
+ - Represents: Password reset request
124
+ - Key Attributes: id, user_id, token, expires_at, used, created_at
125
+ - Relationships: Belongs to User
126
+
127
+ ## Success Criteria
128
+
129
+ ### Quantitative Metrics
130
+
131
+ - Authentication endpoint response time < 200ms (p95)
132
+ - Successfully handle 100 concurrent login requests
133
+ - Zero plain-text password storage
134
+ - Account lockout triggers within 100ms of 5th failed attempt
135
+ - Password reset emails delivered within 30 seconds
136
+
137
+ ### Qualitative Metrics
138
+
139
+ - Users can complete registration in under 2 minutes
140
+ - Login flow requires no more than 2 steps
141
+ - Error messages are clear and actionable
142
+ - Password reset process is intuitive and requires no support intervention
143
+
144
+ ### Security Metrics
145
+
146
+ - All passwords stored with bcrypt cost factor >= 10
147
+ - JWT tokens properly signed and validated
148
+ - Rate limiting prevents more than 10 login attempts per minute per IP
149
+ - Audit logs capture all authentication events
@@ -0,0 +1,169 @@
1
+ # Tasks: User Authentication System
2
+
3
+ **Branch**: `feature/001-auth-system` **Date**: 2025-01-15 **Spec**:
4
+ [spec.md](./spec.md) | **Plan**: [plan.md](./plan.md)
5
+
6
+ ## Phase 1: Setup
7
+
8
+ - [001] Create project structure and configuration files
9
+ - [002] Set up database connection and migration system
10
+ - [003] Configure TypeScript, ESLint, and testing environment
11
+ - [004] Set up Redis connection for rate limiting and caching
12
+ - [005] Configure environment variables and validation
13
+
14
+ **Checkpoint**: Project builds successfully, database and Redis connections
15
+ established
16
+
17
+ ## Phase 2: Foundational Infrastructure
18
+
19
+ - [006] Create database migrations for all tables (users, auth_tokens,
20
+ audit_logs, password_resets)
21
+ - [007] Implement User entity with TypeScript types
22
+ - [008] Implement AuthToken entity with TypeScript types
23
+ - [009] Implement AuditLog entity with TypeScript types
24
+ - [010] Implement PasswordReset entity with TypeScript types
25
+ - [011] Create utility functions for JWT generation and validation
26
+ - [012] Create utility functions for password hashing and verification
27
+ - [013] Create utility function for email sending
28
+ - [014] Create rate limiting middleware using Redis
29
+ - [015] Write tests for all utility functions
30
+
31
+ **Checkpoint**: All foundational utilities tested and working
32
+
33
+ ## Phase 3: User Story - P1: User Registration
34
+
35
+ - [016] Write failing tests for registration validation (email format, password
36
+ strength)
37
+ - [017] Implement Zod schemas for registration request validation
38
+ - [018] Write failing tests for AuthRepository.createUser()
39
+ - [019] Implement AuthRepository.createUser() method
40
+ - [020] Write failing tests for AuthService.register()
41
+ - [021] Implement AuthService.register() with email uniqueness check
42
+ - [022] Implement password hashing in registration flow
43
+ - [023] Write failing tests for POST /api/auth/register endpoint
44
+ - [024] Implement AuthController.register() endpoint
45
+ - [025] Add audit logging for registration events
46
+ - [026] Add email confirmation sending (placeholder for now)
47
+ - [027] Run all registration tests and verify they pass
48
+
49
+ **Checkpoint**: Users can successfully register with valid credentials, invalid
50
+ attempts are rejected
51
+
52
+ ## Phase 4: User Story - P1: User Login
53
+
54
+ - [028] Write failing tests for login validation
55
+ - [029] Implement Zod schemas for login request validation
56
+ - [030] Write failing tests for AuthRepository.findByEmail()
57
+ - [031] Implement AuthRepository.findByEmail() method
58
+ - [032] Write failing tests for AuthService.login() with credential validation
59
+ - [033] Implement AuthService.login() with bcrypt password verification
60
+ - [034] Implement JWT and refresh token generation on successful login
61
+ - [035] Write failing tests for AuthRepository.saveRefreshToken()
62
+ - [036] Implement AuthRepository.saveRefreshToken() method
63
+ - [037] Implement failed login attempt tracking
64
+ - [038] Implement account lockout after 5 failed attempts
65
+ - [039] Write failing tests for POST /api/auth/login endpoint
66
+ - [040] Implement AuthController.login() endpoint
67
+ - [041] Add audit logging for login attempts (success and failure)
68
+ - [042] Add rate limiting to login endpoint
69
+ - [043] Run all login tests and verify they pass
70
+
71
+ **Checkpoint**: Users can log in with valid credentials, receive JWT + refresh
72
+ tokens, accounts lock after failures
73
+
74
+ ## Phase 5: User Story - P2: Password Reset
75
+
76
+ - [044] [P] Write failing tests for password reset request validation
77
+ - [045] [P] Implement Zod schema for password reset request
78
+ - [046] [P] Write failing tests for AuthRepository.createPasswordReset()
79
+ - [047] [P] Implement AuthRepository.createPasswordReset() method
80
+ - [048] [P] Write failing tests for AuthService.requestPasswordReset()
81
+ - [049] [P] Implement AuthService.requestPasswordReset() with token generation
82
+ - [050] [P] Implement email sending for password reset link
83
+ - [051] [P] Write failing tests for POST /api/auth/password-reset/request
84
+ endpoint
85
+ - [052] [P] Implement AuthController.requestPasswordReset() endpoint
86
+ - [053] [P] Add rate limiting to password reset request endpoint
87
+ - [054] Write failing tests for password reset confirmation validation
88
+ - [055] Implement Zod schema for password reset confirmation
89
+ - [056] Write failing tests for AuthRepository.validateResetToken()
90
+ - [057] Implement AuthRepository.validateResetToken() method
91
+ - [058] Write failing tests for AuthService.confirmPasswordReset()
92
+ - [059] Implement AuthService.confirmPasswordReset() with password update
93
+ - [060] Mark reset token as used after successful reset
94
+ - [061] Write failing tests for POST /api/auth/password-reset/confirm endpoint
95
+ - [062] Implement AuthController.confirmPasswordReset() endpoint
96
+ - [063] Add audit logging for password reset events
97
+ - [064] Run all password reset tests and verify they pass
98
+
99
+ **Checkpoint**: Users can request and complete password reset, expired/invalid
100
+ tokens are rejected
101
+
102
+ ## Phase 6: User Story - P3: Token Refresh
103
+
104
+ - [065] [P] Write failing tests for token refresh validation
105
+ - [066] [P] Implement Zod schema for refresh token request
106
+ - [067] [P] Write failing tests for AuthRepository.validateRefreshToken()
107
+ - [068] [P] Implement AuthRepository.validateRefreshToken() method
108
+ - [069] [P] Write failing tests for AuthService.refreshToken()
109
+ - [070] [P] Implement AuthService.refreshToken() with token rotation
110
+ - [071] [P] Implement refresh token expiration check
111
+ - [072] [P] Write failing tests for POST /api/auth/refresh endpoint
112
+ - [073] [P] Implement AuthController.refresh() endpoint
113
+ - [074] [P] Run all token refresh tests and verify they pass
114
+
115
+ **Checkpoint**: Tokens can be refreshed successfully, expired tokens are
116
+ rejected
117
+
118
+ ## Phase 7: Polish and Security
119
+
120
+ - [075] Implement JWT verification middleware for protected routes
121
+ - [076] Write tests for JWT middleware
122
+ - [077] Implement logout functionality (token blacklisting)
123
+ - [078] Write tests for logout endpoint
124
+ - [079] Add OpenAPI/Swagger documentation for all endpoints
125
+ - [080] Run security audit (password storage, JWT validation, rate limiting)
126
+ - [081] Run performance tests (concurrent logins, response times)
127
+ - [082] Add integration tests for complete user journeys
128
+ - [083] Review and update error messages for clarity
129
+ - [084] Set up audit log cleanup job (90-day retention)
130
+ - [085] Final code review and cleanup
131
+
132
+ **Checkpoint**: All tests passing, security measures verified, documentation
133
+ complete
134
+
135
+ ## Dependencies & Execution Order
136
+
137
+ ### Required Sequential Order
138
+
139
+ - Setup (001-005) must complete before Foundational (006-015)
140
+ - Foundational (006-015) must complete before any user story implementation
141
+ - Registration (016-027) should complete before Login (028-043)
142
+ - Login (028-043) should complete before Password Reset and Token Refresh
143
+
144
+ ### Parallel Work Opportunities
145
+
146
+ - Password Reset (044-064) can be developed in parallel with Token Refresh
147
+ (065-074) after Login is complete
148
+ - Within each user story, test writing and implementation can be done by
149
+ different team members
150
+ - Documentation (079) can be written in parallel with final polish tasks
151
+
152
+ ## Implementation Strategies
153
+
154
+ ### Strategy 1: MVP (Minimum Viable Product)
155
+
156
+ Deliver P1 features first (Registration + Login), deploy to get user feedback,
157
+ then add P2/P3 features.
158
+
159
+ ### Strategy 2: Incremental by Priority
160
+
161
+ Complete P1 stories → P2 stories → P3 stories in sequence. Deploy after each
162
+ priority level.
163
+
164
+ ### Strategy 3: Parallel Development
165
+
166
+ Assign user stories to different developers, integrate at the end. Requires
167
+ strong coordination.
168
+
169
+ **Recommended**: Strategy 2 (Incremental by Priority) for this feature size.