1
Fork 0
mirror of https://github.com/thegeneralist01/archivr synced 2026-07-21 18:55:36 +02:00
Commit graph

187 commits

Author SHA1 Message Date
9ac28459ed
feat(capture): async polling in CaptureDialog + pollCaptureJob api helper 2026-06-26 12:54:31 +02:00
f76f5438f2
feat(auth): Track 4 auth foundation — sessions, roles, login, setup wizard
Implements the full auth foundation layer across 13 atomic task commits:

Core DB (archivr-core/database.rs):
- initialize_auth_schema: roles, user_roles, sessions, api_tokens, instance_settings
- open_auth_db: dedicated server-level auth SQLite (separate from archive DBs)
- create_owner, compute_role_bits: cumulative role assignment (guest=1 user=2 admin=4 owner=8)
- create_session, get_session, delete_session, touch_session, delete_expired_sessions
- create_api_token, get_user_for_token, list_user_tokens, delete_api_token

Server (archivr-server):
- auth.rs: AuthUser Axum extractor (cookie→session or Bearer→token), Argon2id
  password hashing, random token generation, role bit constants
- AppState gains auth_db_path; ServerRegistry gains optional auth_db_path field
- main.rs: auth DB path computed from config dir, session cleanup background task (24h)
- setup_guard middleware: 503 SERVICE_UNAVAILABLE for all non-/api/auth/ routes until
  first owner account is created via POST /api/auth/setup
- Auth endpoints: GET|POST /api/auth/setup, POST /api/auth/login, POST /api/auth/logout,
  GET /api/auth/me, GET|POST|DELETE /api/auth/tokens
- WRITE routes guarded with ROLE_USER: captures, tag create/assign/remove

Frontend:
- LoginPage.jsx, SetupPage.jsx (new)
- App.jsx: AuthContext, auth state machine (loading→setup→login→authenticated),
  setup check on mount, auth:expired event listener
- api.js: checkSetup, doSetup, login, logout, fetchMe, 401 interceptor
- Topbar.jsx: user menu with username and logout button

Docs:
- NEXT.md: Track 4 marked done, Tracks 5-8 stubs added, old tracks renumbered

159 tests green. Frontend builds cleanly.
2026-06-26 12:04:08 +02:00
7cebf06124
chore: update Cargo.lock after frontend build 2026-06-26 12:03:30 +02:00
37fd057c1f
fix(auth): use rfc3339 for session expires_at; update tag tests for auth guards 2026-06-26 12:03:13 +02:00
7671049f55
Merge branch 'task/auth-docs' 2026-06-26 11:59:31 +02:00
8edd17d694
Merge branch 'task/auth-topbar' 2026-06-26 11:59:31 +02:00
a983b6090a
Merge branch 'task/auth-frontend' 2026-06-26 11:59:31 +02:00
59a37a2ce3
Merge branch 'task/auth-session-cleanup' 2026-06-26 11:59:24 +02:00
059196252b
Merge branch 'task/auth-route-protection' 2026-06-26 11:59:24 +02:00
64706cb976
Merge branch 'task/auth-tokens' 2026-06-26 11:59:24 +02:00
6fd5e8881e
Merge branch 'task/auth-endpoints' 2026-06-26 11:59:24 +02:00
c806b0bbaf
Merge branch 'task/auth-extractor' 2026-06-26 11:59:24 +02:00
0a3cde9005
Merge branch 'task/auth-appstate' 2026-06-26 11:59:24 +02:00
98bb5f03b0
Merge branch 'task/auth-session-helpers' 2026-06-26 11:59:18 +02:00
2e2ce4b6ac
Merge branch 'task/auth-user-helpers' 2026-06-26 11:59:18 +02:00
8ed79192eb
Merge branch 'task/auth-schema' 2026-06-26 11:59:18 +02:00
1bbc0a108c
Merge branch 'task/auth-deps' 2026-06-26 11:59:18 +02:00
f9d2ac80e7
feat(auth): session cleanup background task (24h interval) 2026-06-26 11:57:14 +02:00
cb376aa986
feat(auth): apply ROLE_USER guard to WRITE routes (captures, tags) 2026-06-26 11:56:38 +02:00
36c7d575e2
feat(auth): API token endpoints (create, list, delete) 2026-06-26 11:55:05 +02:00
affb8aadc0
feat(auth): login, logout, /me, setup endpoints + setup_guard middleware 2026-06-26 11:53:58 +02:00
db28d038d9
feat(auth): AuthUser extractor, password helpers, token generation 2026-06-26 11:50:29 +02:00
a4239ba5fc
feat(auth): add auth_db_path to AppState, registry, and main.rs 2026-06-26 11:46:23 +02:00
86e8049f1b
feat(auth): session and token DB helpers 2026-06-26 11:32:32 +02:00
f482707b75
feat(auth): user and role DB helpers (create_owner, compute_role_bits) 2026-06-26 11:31:20 +02:00
696a5e1ac7
feat(auth): add initialize_auth_schema, open_auth_db, and auth record types 2026-06-26 11:30:02 +02:00
7fcc207de7
feat(auth): user menu and logout button in Topbar 2026-06-26 11:29:13 +02:00
0a5c899c5e
feat(auth): frontend login/setup pages + auth state in App.jsx 2026-06-26 11:28:58 +02:00
57fc48d73c
feat(auth): add argon2, rand, axum-extra dependencies 2026-06-26 11:28:51 +02:00
decaef389b
docs: mark Track 4 auth foundation done, add Tracks 5-8 stubs, renumber roadmap 2026-06-26 11:28:21 +02:00
7584e309de
chore: remove docs/superpowers from gitignore (not for VCS) 2026-06-26 11:19:40 +02:00
d81b8fd793
docs: add Track 4 auth foundation implementation plan 2026-06-25 17:38:30 +02:00
151835258b
docs: fix 8 reviewer findings in auth foundation spec
- Role hierarchy: cumulative assignment + ROLE_GUEST floor; owner gets role_bits=15
- ALTER TABLE: move default_entry_visibility into CREATE TABLE DDL (idempotent)
- Session cookie: add Secure flag conditionally on HTTPS (X-Forwarded-Proto)
- API token role_bits: live query user_roles per request (vs snapshot)
- POST /api/auth/setup after complete: returns 409 already_configured
- users.role placeholder: use 'admin' in ensure_owner_exists INSERT
- Disabled users: extractor JOINs users and checks status='active'
- last_seen_at throttle: conditional update if >60s elapsed
2026-06-25 17:27:33 +02:00
10aeebd878
docs: add Track 4 auth foundation design spec + whitelist docs/superpowers in gitignore 2026-06-25 17:20:17 +02:00
5fba6987a3
fix(capture): remove debug println! from hash_exists 2026-06-25 16:19:33 +02:00
351e74df09
feat(fonts): wire font extraction into capture pipeline + blob serving route
- capture.rs: add archive_id: Option<&str> to perform_capture; when Some,
  call font_extractor::extract_and_rewrite before hashing HTML, register
  each font as a deduplicated blob + 'font' artifact
- main.rs: pass None as archive_id (CLI keeps fonts embedded)
- routes.rs: add GET /api/archives/:id/blobs/:sha256 (serve_blob handler),
  pass Some(&archive_id) to perform_capture in capture_handler,
  add ApiError::internal constructor
2026-06-25 16:07:50 +02:00
22b0a55730
feat(fonts): hash_bytes, get_blob_by_sha256, font_extractor module
- fix(hash): hash raw bytes instead of lossy UTF-8; add hash_bytes
- feat(database): add get_blob_by_sha256 lookup
- feat(font_extractor): extract embedded font data-URIs from archived HTML
2026-06-25 16:02:57 +02:00
f6d636fce2
feat(singlefile): add UA, disable-web-security, and user-data-dir
- --user-agent: realistic Chrome UA so servers don't block headless string
- --browser-args=[--disable-web-security, --user-data-dir]: lets single-file
  inline fonts from any cross-origin CDN (e.g. fonts.gstatic.com) regardless
  of ACAO headers; user-data-dir required for --disable-web-security to take
  effect in newer Chromium builds (otherwise silently ignored)
2026-06-25 11:39:24 +02:00
ab353f9209
fix(singlefile): improve font capture and eliminate ES module viewer errors
Font fidelity:
- --browser-wait-delay=2000: Cloudflare Fonts injects @font-face CSS after
  HTML parse; the font hook needs extra time to see it after networkidle2
- --remove-unused-fonts=false: preserve @font-face rules even when fonts
  haven't rendered yet (font-display:swap, off-screen text)
- --remove-alternative-fonts=false: preserve unicode-range subsets instead
  of stripping them as 'alternatives'

ES module viewer error fix:
- Write a user script (sf-strip-scripts.js) that listens for
  single-file-on-before-capture-start and removes all <script> elements
  (except application/ld+json) from the live DOM before serialization.
  Scripts still execute during capture for CSS fidelity; none end up in
  the saved file, so no data:-URL base ES module resolution errors.
2026-06-24 21:30:14 +02:00
852cc45956
fix(singlefile): disable CSS stripping and script blocking for full render fidelity
Defaults that were destroying CSS fidelity:
- --remove-unused-styles=true: strips CSS nesting rules (site uses & selector)
  and any rule targeting JS-applied classes
- --remove-alternative-medias=true: deletes @media blocks that don't match
  the capture viewport, breaking responsive layout
- --block-scripts=true: prevents JS from applying classes before CSS snapshot

All three now set to false.
2026-06-24 21:15:36 +02:00
fbb96fbd05
build(frontend): update bundled assets after favicon+rendering changes 2026-06-24 21:05:35 +02:00
1239ad9f34
feat(ui): show website favicon in entry list for webpage entries 2026-06-24 19:16:21 +02:00
1206d7103d
feat(server): add GET /entries/:uid/favicon endpoint 2026-06-24 19:16:21 +02:00
cc2dbf4ac2
feat(archive): add has_favicon to EntrySummary 2026-06-24 19:16:21 +02:00
653efa9705
feat(capture): store favicon artifact for WebPage entries 2026-06-24 19:16:21 +02:00
ee697625fb
feat(singlefile): add SaveResult, favicon extraction, wait for networkidle2 2026-06-24 19:16:21 +02:00
ad1c4f8ee5
fix(nix): guard pkgs.chromium behind isLinux for aarch64-darwin 2026-06-24 18:46:11 +02:00
e70c6b37cd
docs: document single-file env vars, check off web page archiving milestone 2026-06-24 18:39:12 +02:00
c9ce0ee00b
feat(nix): add single-file-cli and chromium to both wrappers 2026-06-24 18:39:05 +02:00
fe9ff2dafe
feat(capture): add Source::WebPage, route HTML URLs to singlefile downloader 2026-06-24 18:39:02 +02:00