Commit Graph

12 Commits

Author SHA1 Message Date
Pontoporeia
f398a0f1ff Fix non-constant-time credential comparisons
- account.php: replace !== CSRF token check with hash_equals
- ShareLink::setPassword(): also encrypt and store plain-text password
  alongside the hash, matching create() behavior so the decrypted_password
  decoration stays correct after password updates
2026-05-31 17:49:43 +02:00
Pontoporeia
728f05502c Combine phpstan, cs-check, cs-fix into lint-php recipe; fix lint issues + test failures + duplicate detection bug 2026-05-20 00:31:19 +02:00
Pontoporeia
79eddf5d5a feat: fix file deletion on save + trash policy + documents/ prefix + relink browser
1. note_intention: Delete old file only when a genuinely new upload arrives
   (32-char hex file_id), not when the FilePond pool preserves an existing
   file by sending its DB integer ID.  Previously the DB integer ID
   triggered $hasNewNote=true, which deleted the existing note_intention
   from disk+DB, then handleFilePondSingleFile couldn't re-process it
   because the regex requires a hex pattern.  Same fix applied to cover.

2. All file deletions now use deleteThesisFileToTrash() which renames
   files to tmp/_trash/ instead of unlinking.  The trash preserves
   original filenames prefixed with DB id for traceability.  Skips
   website URLs and PeerTube refs (no disk file).

3. Storage prefix changed from theses/ to documents/ to reflect that
   the folder holds all document types (determined by file_type in DB).
   MediaController visibility gate supports both prefixes for backward
   compat with existing files.

4. File browser + relink feature for orphaned files:
   - /admin/fragments/file-browser.php — HTMX tree browser for
     storage/documents/ and storage/theses/
   - /admin/actions/filepond/relink.php — POST endpoint that inserts
     a thesis_files row pointing to existing on-disk file
   - Per-pool "📂 Relier" buttons (edit mode only)
   - JS: XamxamOpenFileBrowser / XamxamRelinkFile with FilePond integration
   - CSS: .relink-modal dialog + .file-browser tree styles
2026-05-19 00:08:06 +02:00
Pontoporeia
fdc301c20d fix: require Crypto.php in ShareLink.php 2026-05-19 00:08:06 +02:00
Pontoporeia
9152b120e8 feat: mandatory auto-generated passwords for share links + admin password copy/regeneration + password gate rate limiting 2026-05-19 00:08:06 +02:00
Pontoporeia
b6908f7453 Rename Liens étudiant·e, add link name + edit dialog
- Rename 'Accès étudiant·e' → 'Liens étudiant·e' in acces.php
- Add 'name' column to share_links (schema.sql + ALTER TABLE migration)
- ShareLink::create() now accepts optional  parameter
- Add ShareLink::update() method for name/password/expiration
- Add 'update' action to acces-etudiante.php controller
- Remove Visiter (play) button; row click opens link in new tab
- Add edit dialog with name, password, expiration fields
- Add pen icon button to open edit dialog per row
- Add Nom column to table (also in archived links section)
2026-05-19 00:08:05 +02:00
Pontoporeia
013317c97f link creation: fieldset with checkboxes for objet restriction, TFE checked by default
link creation: fieldset with checkboxes for objet restriction, TFE checked by default; password/expiration in second fieldset 'Accès'
2026-05-19 00:08:05 +02:00
Pontoporeia
ca5983075d feat: admin audit logging across all admin actions
- AdminLogger: JSON-lines → /var/log/xamxam.log (prod) / storage/logs/admin.log (dev)
  + best-effort DB mirror to admin_audit_log table
- DB: admin_audit_log table, share_links.is_archived column
- ShareLink: archive() replaces delete(), toggleActive() returns new state,
  listActive()/listArchived() split, validateLink blocks archived slugs
- All action handlers wired: publish, unpublish, visibility, delete, csv/db export,
  tfe add/edit, tags, pages, apropos, form-help, access-request, maintenance,
  settings (formulaire toggles, objet types, smtp update), smtp-test
- acces.php: archive button replaces delete; collapsible archived links section
- setup-server.sh: provision /var/log/xamxam.log (www-data:xamxam 640)
2026-05-05 11:04:52 +02:00
Pontoporeia
a2cba6d3c0 feat: prevent duplicate TFE submissions with logging and user feedback
- Add DuplicateThesisException (typed, carries existing thesis metadata)
- Add Database::findDuplicateThesis(): matches on year + author + normalised
  title (exact, prefix, Levenshtein ≤10% of longer string)
- ThesisCreateController::submit() runs duplicate check before any DB write
  and throws DuplicateThesisException on match
- AppLogger::logDuplicate() writes status=duplicate entries to the JSON-lines
  log for audit purposes
- App::flash/consumeFlash extended to support 'warning' flash type
- admin/actions/formulaire.php: catches DuplicateThesisException, logs it,
  flashes an HTML warning toast with a clickable link to the existing thesis,
  and repopulates the form fields
- partage/index.php: same catch block; surfaces a plain-text flash-warning
  banner on the student form with identifier, title, and year of the match;
  form is repopulated via session
- toast.php: renders toast--warning variant
- admin.css: .toast--warning + link colour rules
- form.css: .flash-warning style for the partage form
2026-05-05 11:04:52 +02:00
Pontoporeia
0a05f3911c Replace Psalm with PHPStan + PHP‑CS‑Fixer + Biome, add linting configs & cleanup
- Removed the `vimeo/psalm` dependency and all related files
(`psalm.xml`, `psalm‑baseline.xml`, suppress annotations).  
- Added **PHPStan** (v2.1.54) and **PHP‑CS‑Fixer** (v3.95.1) to
`vendor/bin/`.  
- Created `phpstan.neon` (level 5, bootstraps `app/bootstrap.php`,
scans `Parsedown.php`).  
- Created `phpstan‑baseline.neon` with 10 pre‑existing errors.  
- Added `.php‑cs‑fixer.dist.php` (PSR‑12 + PHP80Migration, targets
 `app/src` & `app/tests`).  
- Added `biome.json` and updated `justfile` to replace the old Psalm
recipes with `phpstan`, `cs‑check`, and `cs‑fix`.  
- Updated `.gitignore` to exclude PHPStan and PHP‑CS‑Fixer cache files.  
- Updated several JS files (`file‑preview.js`, `file‑upload‑queue.js`)
eand PHP controllers (`MediaController.php`, `SearchController.php`,
`SystemController.php`).  
- Minor adjustments to `TODO.md`, `app/src/Database.php`,
`app/src/Parsedown.php`, `app/src/ShareLink.php`, and
`app/src/SmtpRelay.php`.
2026-05-05 11:04:52 +02:00
Pontoporeia
d961f9533c feat: add objet field (tfe/thèse/frart) with share-link restriction and site-settings toggles 2026-04-24 23:03:49 +02:00
Pontoporeia
75f808bee4 feat: extract MediaController, wire into Dispatcher, delete media.php 2026-04-20 12:32:00 +02:00