Commit graph

180 commits

Author SHA1 Message Date
Marko Djordjevic
d4e92cf88f Add src/lib/auth.ts helper for extracting user from Auth.js session
Implement task 5.2: Create getAuthUser() helper that calls auth() from
src/auth.ts and returns the authenticated user object or null if not
authenticated. Mark task 5.2 complete in tasks.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 10:19:12 +01:00
Marko Djordjevic
55fd91ff52 Add Next.js middleware for route protection (task 5.1)
- Create src/middleware.ts using Auth.js v5 auth() wrapper
- Protect /app/* routes: redirect unauthenticated users to /login
- Protect /api/* routes (except /api/auth/* and /api/health): return 401 JSON for unauthenticated requests
- Redirect authenticated users away from /login and /register to /app
- Mark task 5.1 as complete in tasks.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 10:18:15 +01:00
Marko Djordjevic
10e4ec8648 Task 4.2: Add default data seeding on new user creation
Create seedUserDefaults() helper in src/lib/db/seed-user-defaults.ts
that inserts default annotation_types (break_up, break_down, line) and
default span_label_types (bull_flag, bear_flag, etc.) scoped to a
given user_id. Call it from POST /api/auth/register after user insert
and from src/auth.ts Google signIn callback after new Google user creation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 10:16:55 +01:00
Marko Djordjevic
9a5e325632 feat(auth): add POST /api/auth/register endpoint (task 4.1)
Validates email presence and password length (8+ chars), checks email
uniqueness with 409 on conflict, hashes password with bcryptjs (cost 12),
inserts user into the users table and returns 201 with id/email/name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 10:14:55 +01:00
Marko Djordjevic
45b6366861 Create nextauth route handler exporting GET/POST from auth.ts (task 3.4) 2026-02-20 10:13:32 +01:00
Marko Djordjevic
a8c88f3ca2 Task 3.3: Handle Google OAuth sign-in callback in src/auth.ts
- Add signIn callback: on Google sign-in, check users table by email;
  create new user (provider='google', provider_account_id, name/image
  from profile) if not found, or allow sign-in for returning users
- Update jwt callback to look up DB uuid by email for Google sign-ins,
  so token.id is always the DB uuid rather than the Google sub ID
- Mark task 3.3 as complete in tasks.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:58:18 +01:00
Marko Djordjevic
40afd4111c Mark task 3.2 done: JWT and session callbacks already implemented in src/auth.ts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:56:48 +01:00
Marko Djordjevic
50e85e499a Add src/auth.ts with Auth.js v5 config (task 3.1)
JWT session strategy, Credentials provider with bcryptjs password
verification, and Google OAuth provider using AUTH_GOOGLE_ID/SECRET.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:55:04 +01:00
Marko Djordjevic
73f44bf447 Add data migration script for user-accounts (task 2.5)
Create scripts/migrate-users.ts that:
- Creates a default admin user from DEFAULT_ADMIN_EMAIL/DEFAULT_ADMIN_PASSWORD env vars
- Backfills user_id on all existing rows in charts, annotations, annotation_types,
  span_annotations, span_label_types
- Is idempotent (safe to run multiple times)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:51:23 +01:00
Marko Djordjevic
877ae032a1 Mark task 2.4 as complete: Generate Drizzle migration 2026-02-20 09:50:14 +01:00
Marko Djordjevic
b633a3f52a Task 2.3: Replace single-column unique constraints with composite (user_id, name) unique indexes
- charts.name → uniqueIndex('charts_user_id_name_unique').on(user_id, name)
- annotation_types.name → uniqueIndex('annotation_types_user_id_name_unique').on(user_id, name)
- span_label_types.name → uniqueIndex('span_label_types_user_id_name_unique').on(user_id, name)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:48:50 +01:00
Marko Djordjevic
0cd74ebedd Mark task 2.2 complete in user-accounts tasks.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:47:41 +01:00
Marko Djordjevic
9101cfb7af Add users table to Drizzle schema (task 2.1)
Adds the `users` table to `src/lib/db/schema.ts` with:
- UUID primary key (defaultRandom)
- email (unique, not null)
- password_hash (nullable, for OAuth-only users)
- name, image (nullable)
- provider (default 'credentials'), provider_account_id (nullable)
- email_verified (timestamp, nullable)
- created_at, updated_at

Marks task 2.1 as complete in tasks.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:46:20 +01:00
Marko Djordjevic
d05ed21cd6 Task 1.3: Update docker-compose.yml to pass new auth environment variables
Add AUTH_SECRET, AUTH_GOOGLE_ID, AUTH_GOOGLE_SECRET, AUTH_TRUST_HOST,
DEFAULT_ADMIN_EMAIL, and DEFAULT_ADMIN_PASSWORD environment variables to
the candle-annotator service in docker-compose.yml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:45:12 +01:00
Marko Djordjevic
7ba1380cc7 Add authentication environment variables to .env.example
Added AUTH_SECRET, AUTH_GOOGLE_ID, AUTH_GOOGLE_SECRET, AUTH_TRUST_HOST, DEFAULT_ADMIN_EMAIL, and DEFAULT_ADMIN_PASSWORD environment variables with helpful comments and placeholder values for Auth.js v5 and Google OAuth setup.

Marked task 1.2 as complete in tasks.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:44:25 +01:00
Marko Djordjevic
973662739a Install authentication dependencies: next-auth@5, bcryptjs, @types/bcryptjs
Add required npm packages for user authentication implementation:
- next-auth@5.0.0-beta.30: Next.js authentication library
- bcryptjs@3.0.3: Password hashing library
- @types/bcryptjs@2.4.6: TypeScript types for bcryptjs

Mark task 1.1 as complete.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 09:43:45 +01:00
Marko Djordjevic
3c39690f4a Assign per-task model tags in user-accounts tasks.md
Replace section-level model tags with individual task-level tags.
Haiku for mechanical/config/boilerplate, sonnet for standard feature
work, opus for 2.5 (data migration backfill) and 7.2 (user_id query
permeation across all routes).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 08:59:17 +01:00
Marko Djordjevic
925e7284e3 Archive code-review-fix change and sync specs to main
- Synced 14 capability delta specs to main specs
- Created 6 new main specs: api-authentication, error-boundary, input-validation, security-headers, shared-types
- Updated 8 existing specs with security, validation, and performance requirements
- Archived change to openspec/changes/archive/2026-02-20-code-review-fix/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 08:54:59 +01:00
Marko Djordjevic
16123d385a test deployment 2026-02-18 21:42:42 +01:00
Marko Djordjevic
25c959fd18 code-review-fix task 15.4: mark task 15.4 as done in tasks.md 2026-02-18 20:58:53 +01:00
Marko Djordjevic
09a361ca54 code-review-fix task 15.3: mark task 15.3 as done in tasks.md 2026-02-18 20:58:18 +01:00
Marko Djordjevic
9c08ffc44d code-review-fix task 15.2: mark task 15.2 as done in tasks.md 2026-02-18 20:57:44 +01:00
Marko Djordjevic
728c7e4d82 code-review-fix task 15.1: mark task 15.1 as done in tasks.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 20:57:13 +01:00
Marko Djordjevic
21c855db89 code-review-fix task 14.5: mark task 14.5 as done in tasks.md 2026-02-18 20:55:21 +01:00
Marko Djordjevic
d4c14df284 code-review-fix task 14.4: mark task 14.4 as done in tasks.md 2026-02-18 20:48:44 +01:00
Marko Djordjevic
3e4d4bd7ae code-review-fix task 14.3: mark task 14.3 as done in tasks.md 2026-02-18 20:48:14 +01:00
Marko Djordjevic
4081a566b5 code-review-fix task 14.2: mark task 14.2 as done in tasks.md 2026-02-18 20:47:51 +01:00
Marko Djordjevic
c9c63aafa3 code-review-fix task 14.1: mark task 14.1 as done in tasks.md 2026-02-18 20:47:17 +01:00
Marko Djordjevic
bf9a475b89 code-review-fix task 13.3: mark task 13.3 as done in tasks.md 2026-02-18 20:46:37 +01:00
Marko Djordjevic
03b2500980 code-review-fix task 13.2: mark task 13.2 as done in tasks.md 2026-02-18 20:46:04 +01:00
Marko Djordjevic
36382508f7 code-review-fix task 13.1: mark task 13.1 as done in tasks.md 2026-02-18 20:45:30 +01:00
Marko Djordjevic
576375b135 code-review-fix task 12.12: mark task 12.12 as done in tasks.md 2026-02-18 20:44:54 +01:00
Marko Djordjevic
5ffab3ef44 code-review-fix task 12.11: mark task 12.11 as done in tasks.md 2026-02-18 20:44:04 +01:00
Marko Djordjevic
13f4860358 code-review-fix task 12.10: mark task 12.10 as done in tasks.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 20:43:25 +01:00
Marko Djordjevic
030b0c5885 code-review-fix task 12.9: mark task 12.9 as done in tasks.md 2026-02-18 20:42:17 +01:00
Marko Djordjevic
3f6bcd5c7d code-review-fix task 12.8: mark task 12.8 as done in tasks.md 2026-02-18 20:40:47 +01:00
Marko Djordjevic
2d8222740c code-review-fix task 12.7: mark task 12.7 as done in tasks.md 2026-02-18 20:40:08 +01:00
Marko Djordjevic
e8b8bbb56f code-review-fix task 12.6: mark task 12.6 as done in tasks.md 2026-02-18 20:39:14 +01:00
Marko Djordjevic
6260f7caed code-review-fix task 12.5: mark task 12.5 as done in tasks.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 20:38:30 +01:00
Marko Djordjevic
f9ff0d266e code-review-fix task 12.4: mark task 12.4 as done in tasks.md 2026-02-18 20:37:40 +01:00
Marko Djordjevic
a0a30beb8e code-review-fix task 12.3: mark task 12.3 as done in tasks.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 20:36:41 +01:00
Marko Djordjevic
6a194e81ac code-review-fix task 12.2: mark task 12.2 as done in tasks.md 2026-02-18 20:34:55 +01:00
Marko Djordjevic
15be4c6ca1 code-review-fix task 12.1: mark task 12.1 as done in tasks.md 2026-02-18 20:34:20 +01:00
Marko Djordjevic
d1e992bc79 code-review-fix task 11.4: mark task 11.4 as done in tasks.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 20:33:52 +01:00
Marko Djordjevic
49a2582e8a code-review-fix task 11.3: mark task 11.3 as done in tasks.md 2026-02-18 20:32:25 +01:00
Marko Djordjevic
3793e646cb code-review-fix task 11.2: mark task 11.2 as done in tasks.md 2026-02-18 20:31:30 +01:00
Marko Djordjevic
6f7e3451a2 code-review-fix task 11.1: mark task 11.1 as done in tasks.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 20:30:37 +01:00
Marko Djordjevic
e5ce5cb2e4 code-review-fix task 10.4: mark task 10.4 as done in tasks.md 2026-02-18 20:29:32 +01:00
Marko Djordjevic
bd57bb13e4 code-review-fix task 10.3: mark task 10.3 as done in tasks.md 2026-02-18 20:28:57 +01:00
Marko Djordjevic
ed05bd6972 code-review-fix task 10.2: mark task 10.2 as done in tasks.md 2026-02-18 20:27:36 +01:00