Commit Graph
676 Commits
Author SHA1 Message Date
curo1305andClaude Sonnet 4.6 9a3ce6ef39 docs(08-04/05/06): add plan summaries — wave 2 backend decomposition complete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 10:29:40 +02:00
curo1305andClaude Sonnet 4.6 81337bd9e3 feat(08-05): decompose documents API monolith into documents/ package — CODE-02 CODE-08
- upload.py: request_upload_url, upload_document, confirm_upload (3 routes)
- crud.py: list_documents, get_document, patch_document, delete_document, classify_document (5 routes)
- content.py: stream_document_content + _parse_range (1 route)
- shared.py: _CLOUD_PROVIDERS, UploadUrlRequest, DocumentPatch (single definitions)
- __init__.py: router aggregator prefix=/api/documents, 9 routes total
- documents.py monolith deleted; all URL paths unchanged
- list_documents registered on parent router to avoid FastAPI empty-path/prefix check
- get_storage_backend_for_document re-exported for test monkeypatching compatibility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 10:27:48 +02:00
curo1305andClaude Sonnet 4.6 f01fb0e6d5 feat(08-04): delete admin.py monolith after URL regression — CODE-01 CODE-08
Task 3: 54 admin+cloud+ai-config tests pass with package; admin.py and
admin_OLD_REMOVE_IN_TASK_3.py removed. admin/ package is the sole definition.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 10:16:38 +02:00
curo1305 7e99b6ecc1 docs(08-07): add plan summary — CODE-04 CODE-08 frontend api decomposition complete 2026-06-10 18:45:56 +02:00
curo1305 02bf04cc63 feat(08-07): decompose frontend api/client.js into domain modules + utils — CODE-04 CODE-08
- Rewrite client.js as 20-line barrel re-export (was 636 lines)
- All 35+ consumer files continue to resolve named exports unchanged
- Fix pre-existing bug: testAiConnection was POST but tests expected GET with query params
- All 136 frontend tests pass; production build succeeds
2026-06-10 18:43:41 +02:00
curo1305 3ec198768d feat(08-04): create backend/api/admin/ package — users, quotas, ai, shared, init
- users.py: list_users, create_user, update_user_status, initiate_password_reset,
  update_ai_config, delete_user, create_system_topic (7 routes)
- quotas.py: get_user_quota, update_user_quota (2 routes)
- ai.py: get_ai_config_models, test_ai_connection, get_ai_config,
  update_system_ai_config (4 routes); validate_provider_id call-through (D-11)
- shared.py: _user_to_dict helper (T-02-27 / SEC-07 field whitelist)
- __init__.py: router aggregator with prefix=/api/admin; 13 routes total
- admin.py monolith renamed to admin_OLD_REMOVE_IN_TASK_3.py (deleted in task 3)
- All sub-routers have NO prefix (D-04)
- All handlers inject Depends(get_current_admin) (T-08-04-01)
2026-06-10 18:43:01 +02:00
curo1305 5117e2542a feat(08-06): create backend/api/auth/ package — Task 1
- Create api/auth/shared.py: limiter, all Pydantic request models, _set_refresh_cookie, _user_dict
- Create api/auth/tokens.py: register, login, refresh, logout, logout-all, me, quota, preferences handlers
- Create api/auth/totp.py: totp/setup, totp/enable, totp DELETE handlers (CR-02, CR-03 preserved)
- Create api/auth/password.py: change-password, password-reset, password-reset/confirm handlers (CR-01 preserved)
- Create api/auth/__init__.py: router aggregator with prefix=/api/auth; re-exports limiter
- Rename auth.py monolith to auth_OLD_REMOVE_IN_TASK_2.py (deleted in Task 2 after tests pass)
- All 15 routes confirmed; limiter re-export verified; skip_token_hash calls preserved verbatim
2026-06-10 18:42:27 +02:00
curo1305 a895b1812f feat(08-07): create domain modules admin.js, folders.js, shares.js, cloud.js — CODE-04
- admin.js: 17 functions; adminExportAuditLogCsv + adminDownloadDailyExport use fetchWithRetry
- folders.js: 6 functions — import request from utils.js
- shares.js: 5 functions — import request from utils.js
- cloud.js: 7 functions including initiateOAuth — import request from utils.js
- Blob-download retry boilerplate eliminated from admin.js (CODE-08)
2026-06-10 18:42:01 +02:00
curo1305 fd9188b53c feat(08-07): create domain modules documents.js, auth.js, topics.js — CODE-04
- documents.js: 10 functions; fetchDocumentContent refactored to use fetchWithRetry
- auth.js: 15 functions (login through getMyQuota) — import request from utils.js
- topics.js: 5 functions — import request from utils.js
- All functions copied verbatim from client.js; no consumer files modified
2026-06-10 18:40:32 +02:00
curo1305 80d6f376b0 feat(08-07): create api/utils.js with request() and fetchWithRetry() — CODE-08
- Move request() verbatim from client.js to utils.js (breaks circular dep)
- Add fetchWithRetry() consolidating 3 blob-download 401-retry patterns
- Lazy import of authStore preserved for Pinia bootstrap cycle safety
- Bearer token from authStore memory only per CLAUDE.md security rule
2026-06-10 18:39:41 +02:00
curo1305 4d7157d7fc feat(08-04): add validate_provider_id helper to services/ai_config.py (D-11)
- Migrate inline provider_id validator to service layer per CLAUDE.md
- Raises ValueError (not HTTPException) — service-layer rule
- PROVIDER_DEFAULTS already imported; placed after load_provider_config helpers
2026-06-10 18:39:03 +02:00
curo1305andClaude Sonnet 4.6 f5109b80c3 docs(phase-8): update tracking after wave 1 — plan 08-03 complete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 16:38:35 +02:00
curo1305 226418ca21 chore: merge executor worktree (worktree-agent-a21897142a1981a82) 2026-06-08 16:37:04 +02:00
curo1305 aa1c5ee75e docs(08-03): complete plan 03 — useToastStore stub, CR wire-up, xfail promotion
- SUMMARY.md created with test output, forward reference to Phase 10, and self-check
2026-06-08 16:36:41 +02:00
curo1305 44ec28d474 test(08-03): promote CR-01/CR-02/CR-03 session-revocation tests from xfail to passing
- Remove @pytest.mark.xfail decorator from test_change_password_revokes_other_sessions (CR-01)
- Remove @pytest.mark.xfail decorator from test_enable_totp_revokes_other_sessions (CR-02)
- Remove @pytest.mark.xfail decorator from test_disable_totp_revokes_other_sessions (CR-03)
- All three tests now show PASSED (not XPASS) in strict pytest runs
2026-06-08 16:35:26 +02:00
curo1305 3b8e2c1bd4 refactor(08-03): migrate session-revoked inline toast to toastStore.show()
- Remove sessionRevokedToast ref + setTimeout + inline HTML from SettingsAccountTab.vue
- Remove sessionRevokedToast ref + setTimeout + inline HTML from TotpEnrollment.vue
- Add toastStore.show('Other sessions have been terminated.', 'success') in changePassword
- Add toastStore.show('Other sessions have been terminated.', 'success') in disableTotp
- Add toastStore.show('Other sessions have been terminated.', 'success') in confirmEnrollment
- Update SettingsAccountTab.test.js to assert on mockShow instead of DOM text
- Update TotpEnrollment.test.js to assert on mockShow instead of DOM text
2026-06-08 16:34:44 +02:00
curo1305 e417b71539 feat(08-03): create useToastStore Pinia stub with locked show() contract
- Defines show(message, type='success', duration=4000) as silent no-op
- Positional parameters only per UI-SPEC.md contract
- Phase 10 (UX-10) must implement rendering without modifying call sites
2026-06-08 16:30:30 +02:00
curo1305andClaude Sonnet 4.6 ccb8a0bb77 docs(phase-8): update tracking after wave 0 — plans 08-01 and 08-02 complete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 16:28:35 +02:00
curo1305 98dcf809b2 chore: merge executor worktree (worktree-agent-ad0b098c151ab9e3f) 2026-06-08 16:24:51 +02:00
curo1305 91d0896ddd chore: merge executor worktree (worktree-agent-a2766ede6d70fdbe3) 2026-06-08 16:24:17 +02:00
curo1305andClaude Sonnet 4.6 c636ac956f docs(08-01): complete Wave 0 xfail stubs plan — 3 xpassed, CR-01/02/03 contracts locked
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 16:23:13 +02:00
curo1305 f750d30224 test(08-01): add xfail stubs for CR-01/CR-02/CR-03 session revocation
- test_change_password_revokes_other_sessions: verifies skip_token_hash
  preserves current session while revoking all other refresh tokens
- test_enable_totp_revokes_other_sessions: verifies TOTP enrollment
  revokes other sessions via skip_token_hash
- test_disable_totp_revokes_other_sessions: verifies TOTP disablement
  revokes other sessions via skip_token_hash
- All three marked xfail(strict=False); currently xpassed (backend already complete)
- Plan 08-03 promotes these to strict passing tests
2026-06-08 16:21:58 +02:00
curo1305 26c11aff4c docs(08-02): complete shared-schemas plan — schemas.py + cloud.py import switch
- backend/api/schemas.py created with CloudConnectionOut (SEC-08 compliant)
- backend/api/cloud.py import switched from api.admin to api.schemas
- 51 cloud + admin tests pass; no behavior change
- Original admin.py definition preserved for plan 08-04 deletion
2026-06-08 16:13:31 +02:00
curo1305 61fa6e2051 refactor(08-02): switch cloud.py import to api.schemas.CloudConnectionOut
- Replace `from api.admin import CloudConnectionOut` with `from api.schemas import CloudConnectionOut`
- Eliminates cross-package coupling between api/cloud.py and api/admin.py (Pitfall 3)
- All 51 cloud + admin tests pass; CloudConnectionOut serialization unchanged
- Original definition in api/admin.py untouched until plan 08-04
2026-06-08 16:12:38 +02:00
curo1305 10e0900a89 feat(08-02): create backend/api/schemas.py with CloudConnectionOut
- New cross-package Pydantic schemas module (D-10, CODE-08)
- CloudConnectionOut moved here from api/admin.py to eliminate coupling
- SEC-08: credentials_enc deliberately excluded; 7-field whitelist preserved
- field_validator coerce_id_to_str preserves UUID→str coercion behavior
- Original definition in api/admin.py left intact until plan 08-04
2026-06-08 16:11:58 +02:00
curo1305andClaude Sonnet 4.6 25e568973f docs(08): create phase 8 plan — 8 plans, 3 waves (stack upgrade + backend decomposition)
Wave 0: CR-01/02/03 test stubs + api/schemas.py (CloudConnectionOut migration)
Wave 1: useToastStore stub + Phase 7.1 frontend completion
Wave 2 (parallel): api/admin/, api/documents/, api/auth/ package splits + client.js decomposition + PERF-01 deps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 14:59:27 +02:00
curo1305 c20a5d8913 docs(08): research phase — decomposition boundaries, CR status, Vite 6 migration 2026-06-07 11:01:54 +02:00
curo1305andClaude Sonnet 4.6 118f4ee850 docs(08): UI design contract — toast API contract + sessions-revoked interaction spec
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 10:50:39 +02:00
curo1305andClaude Sonnet 4.6 845b681b36 docs(08): UI design contract — useToastStore API and sessions-revoked spec
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 10:49:01 +02:00
curo1305 6f2dba8478 docs(state): record phase 8 context session 2026-06-07 10:39:50 +02:00
curo1305 28e1e4aaf4 docs(08): capture phase context 2026-06-07 10:39:32 +02:00
curo1305andClaude Sonnet 4.6 258b0006d6 docs: create milestone v0.2 roadmap (4 phases, 40 requirements)
Phases 8–11: stack upgrade + backend decomposition, admin panel
rearchitecture, UX & interaction, visual design + responsive layout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 09:50:52 +02:00
curo1305andClaude Sonnet 4.6 f7758776ec docs: define milestone v0.2 requirements (36 reqs, 6 categories)
UI overhaul, codebase quality, admin panel rearchitecture, UX
improvements, responsive layout, and performance/stack updates.
Research: STACK.md, FEATURES.md, ARCHITECTURE.md, PITFALLS.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 09:22:40 +02:00
curo1305andClaude Sonnet 4.6 fd05563ec6 test(07.4): complete UAT — 4 passed, 1 fixed (fgp concatenation collision)
UAT found and resolved a concatenation collision in _compute_fgp (no separator
between user_agent and accept_lang). Fix committed in c77b97b. All 5 FGP tests
pass. Full suite: 401 passed, 6 skipped, 7 xfailed, 1 pre-existing failure
(test_extract_docx — missing docx module, unrelated to this phase).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 23:04:17 +02:00
curo1305andClaude Sonnet 4.6 c77b97b6d3 fix(fgp): add null-byte separator in HMAC input to prevent concatenation collision
Without a separator, UA='foobar'+AL='' and UA='foo'+AL='bar' produced the same
HMAC input, allowing a token fingerprint to match a different header split.
Fix: use '\x00' as separator between user_agent and accept_lang fields.

Regression test added: test_fgp_no_concatenation_collision (FGP-05).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 23:03:48 +02:00
curo1305andClaude Sonnet 4.6 de622e8004 docs(phase-07.4): mark VALIDATION.md complete — 7/7 tasks green, nyquist_compliant: true
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 22:48:59 +02:00
curo1305andClaude Sonnet 4.6 52c56b5416 docs(phase-07.4): add security threat verification — 5/5 threats closed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 22:30:57 +02:00
curo1305 3414571091 docs(07.4): add verification report — 8/8 must-haves confirmed 2026-06-06 22:27:55 +02:00
curo1305 ab4b6052a7 docs(07.4): add code review report — 3 critical, 3 warning, 2 info 2026-06-06 22:23:41 +02:00
curo1305 537bbd83e6 docs(phase-07.4): mark phase complete — 2/2 plans, 4 FGP tests passing, v0.1.3 2026-06-06 22:17:42 +02:00
curo1305 5bc92d996f chore: merge executor worktree (worktree-agent-acc04a00e1a55bd86) 2026-06-06 22:16:16 +02:00
curo1305 5d95fcd686 docs(07.4-02): complete token fingerprinting plan — _compute_fgp + fgp validation + 4 FGP tests passing 2026-06-06 22:15:14 +02:00
curo1305 61b1e045c4 feat(07.4-02): update api/auth.py call sites, promote FGP tests, version bump 0.1.3
- api/auth.py login + refresh call sites pass User-Agent and Accept-Language
  headers to create_access_token (D-05 — fgp binding at token issuance)
- test_auth_fgp.py: promote all 4 xfail stubs to real assertions (FGP-01..04)
- conftest.py: add _TEST_USER_AGENT constant; configure async_client to send
  consistent User-Agent; update auth_user/second_auth_user/admin_user fixtures
  to bind fgp to _TEST_USER_AGENT so tokens validate correctly in tests
- test_auth_deps.py: import _TEST_USER_AGENT; update auth_client fixture and
  all create_access_token calls to use the constant
- test_cloud.py: update _create_user_and_token to bind fgp to _TEST_USER_AGENT
- test_documents.py: update 3 inline create_access_token calls to pass user_agent
- test_security_headers.py: import _TEST_USER_AGENT; update headers_client +
  token creation to use the constant
- Version bump: backend 0.1.2 → 0.1.3, frontend 0.1.2 → 0.1.3
- [Rule 1 - Bug] Fix httpx default User-Agent vs empty-string fgp mismatch in
  test infrastructure: 10 tests were failing due to fgp check rejecting tokens
  created with fgp="" when client sent "python-httpx/X.Y.Z"
2026-06-06 22:12:57 +02:00
curo1305 1420180be7 feat(07.4-02): add fgp validation block to get_current_user in deps/auth.py
- Add `import hmac` to deps/auth.py imports block
- Insert fgp check after user_nbf block: extract fgp_claim from payload,
  skip if empty (migration grace for pre-7.4 tokens, D-06), recompute
  fgp_actual via auth_service._compute_fgp, compare with hmac.compare_digest
- Mismatch raises HTTP 401 "Token fingerprint mismatch" (D-03)
- Block placed outside try/except (pure computation, no I/O, no fail-open)
2026-06-06 21:55:13 +02:00
curo1305 25c9142fe0 feat(07.4-02): add _compute_fgp helper + extend create_access_token with fgp claim
- Add _compute_fgp(user_agent, accept_lang) helper returning 16-char hex
  HMAC-SHA256 fingerprint (D-04); uses existing hmac + hashlib imports
- Extend create_access_token signature with user_agent/accept_lang params
  (empty-string defaults for backward compatibility, D-05)
- Embed fgp claim in every issued access token payload
2026-06-06 21:54:47 +02:00
curo1305 8c817705b7 docs(phase-07.4): update tracking after wave 0 — plan 07.4-01 complete 2026-06-06 21:52:35 +02:00
curo1305 1adddf8cf4 chore: merge executor worktree (worktree-agent-a37beb50341e88a90) 2026-06-06 21:51:52 +02:00
curo1305 bbd7a11935 docs(07.4-01): complete Wave 0 xfail stub plan — 4 FGP stubs, SUMMARY.md
- SUMMARY.md: plan metadata, task commit hash, self-check passed
- backend/tests/test_auth_fgp.py committed in 7833edb
2026-06-06 21:50:27 +02:00
curo1305 7833edbf3b test(07.4-01): add Wave 0 xfail stubs for FGP-01..FGP-04
- Create backend/tests/test_auth_fgp.py with 4 xfail(strict=False) stubs
- FGP-01: test_fgp_match_returns_200 (matching headers → 200)
- FGP-02: test_fgp_mismatch_returns_401 (wrong UA → 401)
- FGP-03: test_no_fgp_claim_allowed (no fgp claim → 200 migration grace)
- FGP-04: test_missing_headers_empty_string_binding (empty-string binding → 200)
- All 4 tests report XFAIL; full suite remains at 1 pre-existing failure only
2026-06-06 21:49:46 +02:00
curo1305andClaude Sonnet 4.6 22fcb53d9d docs(07.4): create phase plan — token fingerprinting / token binding
2 plans (2 waves): Wave 0 xfail stubs for test_auth_fgp.py (4 FGP tests),
Wave 1 production implementation (_compute_fgp helper, create_access_token
fgp claim, get_current_user fgp validation, login/refresh call-site updates,
test promotion) + version bump to 0.1.3.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 21:44:21 +02:00