Commit Graph

15 Commits

Author SHA1 Message Date
Pontoporeia
27e1b6828d Implement TFE file access restriction feature (complete)
Requirements:
- parametres.php toggle: 'restricted_files_enabled' enables/disables the feature
- Public TFE page: when enabled + access_type=Interne, hides files, shows French
  restriction message + access request form (metadata/synopsis still visible)
- ERG emails (@erg.school / @erg.be): auto-approve, send 24h access link immediately
- External emails: show justification textarea, create pending request, notify admin
- Admin panel /admin/file-access.php: approve/reject requests with optional notes,
  sends access email on approval (linked from admin nav with pending count badge)

Security:
- One-time 24h email tokens (used_at + is_valid=0 on first click)
- Token redeemed via POST /validate-access (GET shows confirmation page only)
- Long-lived 30-day browser session in file_access_sessions table
- Cookie: HttpOnly + Secure + SameSite=Strict
- CSRF on all mutations, rate limiting on request submission
- Audit trail: IP, UA, event, timestamp in file_access_audit

Bug fixes:
- admin/file-access.php: $vars never extract()ed → page was blank
- Template had self-contained head/footer includes (double-include)
- Admin approval URL used $requestId instead of $request['thesis_id']
- App::boot() now starts session so CSRF token works on public pages
- Dispatcher routes /validate-access and /request-access through front controller
2026-04-27 20:20:52 +02:00
Théophile Gervreau-Mercier
7e26351f4b refactor: remove test.db, use only posterg.db for all environments
- Simplified Database.php determineDatabasePath to always use posterg.db
- Removed test.db auto-detection based on php_sapi_name
- Removed test.db targets from justfile (migrate-test removed)
- Removed CreateTestDatabase.php fixture script
- Updated migrate.sh to only init posterg.db
- Updated setup-dev.sh to init posterg.db
- Updated run-tests.php (removed DB_ENV=test env var)
- Updated deploy-db to use posterg.db
- Removed test.db file

refactor: remove empty fixtures directory
2026-04-27 18:07:20 +02:00
Pontoporeia
53c3127140 feat: student name popover preview on /repertoire via htmx 2026-04-24 23:03:49 +02:00
Pontoporeia
ede53746ba feat: student name popover preview on /repertoire via htmx 2026-04-24 23:03:49 +02:00
Pontoporeia
95bce2bbad Extract form CSS into form.css; scope system.css to system.php only 2026-04-24 23:03:49 +02:00
Pontoporeia
d82556c596 Unify form CSS: move licence/share-badge styles to admin.css, remove inline style from partage form 2026-04-24 23:03:49 +02:00
Pontoporeia
b448d0d40c Lock body scroll: only main/inner elements scroll on admin and public pages 2026-04-24 23:03:49 +02:00
Pontoporeia
5a58eefe66 feat(admin): add SMTP test email button on parametres page 2026-04-24 23:03:49 +02:00
Pontoporeia
4839b568de Separate admin views from controllers — move HTML to templates/admin/
All admin pages refactored to thin controllers + pure view templates, mirroring
the public-page pattern:

Controllers (public/admin/*.php): auth, data loading, include template
Views (templates/admin/*.php): pure HTML/PHP output
Fragment partials (templates/admin/partials/): toast, system-log-panel, system-nginx-config-panel

Pages migrated: login, tags, contenus, contenus-edit, account, acces-etudiante,
thanks, add, edit, parametres, system, index

Fragment endpoints refactored: system-fragment.php, toast-fragment.php
Skipped (pure redirects): logout, logs, status, import
2026-04-24 23:03:49 +02:00
Pontoporeia
362688c0fa fix: remove broken flash-messages include from admin footer; make repertoire columns scrollable 2026-04-24 23:03:49 +02:00
Pontoporeia
73fdda4a7f fix repertoire AP/OR/FI columns and main scroll containment
- repertoire-index.php: add $colHasMatches per-column guard.
  Entries in a column are only faded when that column has at least one
  matched entry in the current result set. When a dimension has no
  matched entries (e.g. no thesis has orientation_id set yet), the
  entire column stays fully interactive — all values remain clickable.
  This fixes: empty columns, forced single-select, cascade fading.

- Database.php: revert allAp/allOr/allFi to full lookup-table queries
  so all known values are always shown (not just ones linked to theses).

- common.css: body is now a flex column; main gets flex:1 + min-height:0;
  header-search-wrap gets flex-shrink:0; duplicate html/body blocks merged.
- public.css: removed redundant top-level main block; home-main gets min-height:0.
- repertoire.css: search-main gets min-height:0 for proper flex scroll.
2026-04-24 23:03:49 +02:00
Pontoporeia
78449afe64 some css changes 2026-04-24 23:01:25 +02:00
Pontoporeia
1b02ccb1d5 fix: mark languages as required, add required-field visual indicators on both forms
- checkbox-list.php: support $required prop → adds required + aria-required on fieldset
- add.php: languages checkbox now marked required (matches server-side validation)
- partage/index.php: same for student form
- admin.css: dashed border on required inputs, bold labels, red asterisk via :has(), "Champs obligatoires" note
- Both forms now show "* Champs obligatoires" note at top

Server-side required fields = titre, auteurice, synopsis, année, orientation, ap, finality, languages (≥1), access_type_id, confirmation_email. All now have required attribute + visual asterisk.
2026-04-20 16:19:55 +02:00
Pontoporeia
e21a4d81a2 refine: required confirmation_email field on both student forms, StudentEmail uses it directly
- Add dedicated 'confirmation_email' (type=email, required) field
  to student form at end of submission (partage + admin).
- ThesisCreateController now validates it is present and a valid
  email; form is rejected if missing/invalid.
- Autofocus mapping for confirmation_email errors.
- StudentEmail uses confirmation_email directly (removed extractEmail
  hack that mined email from free-form contact field).
2026-04-20 15:47:55 +02:00
Pontoporeia
75f808bee4 feat: extract MediaController, wire into Dispatcher, delete media.php 2026-04-20 12:32:00 +02:00