mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-09-25 01:53:03 +02:00
feature: Lien BAIU + thesis ID in tfe.php
This commit is contained in:
@@ -1,65 +1,39 @@
|
|||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
- [x] Open up CSP frame-src from hardcoded domain whitelist to `https:` scheme-wide
|
> Last updated: 2026-08-26
|
||||||
- [x] Fix relinked file not appearing in FilePond UI: switch to ID-based input lookup
|
> Context: Docs refactor: verify docs/ accuracy against current xamxam codebase; update/refactor stale docs
|
||||||
- [x] Fix student name popover overflowing below viewport: clamp position so popover stays within screen bounds
|
|
||||||
- [x] Fix orientation (and other filter) metadata links on TFE page leading to empty search: remove redundant `query=` param
|
|
||||||
- [x] Fix language metadata link using wrong `query=` param instead of dedicated `language=` filter
|
|
||||||
- [x] Sort TFE files by display category on public page (note d'intention → TFE → image → video → audio → website → annexes)
|
|
||||||
- [x] Fix CSV import: VALUES had 24 ? placeholders but execute array has 23 values → 27 total for 26 columns
|
|
||||||
- [x] Surface backup/cleanup cron logs in the admin system log viewer: add `backup` + `cleanup` channels to SystemController::LOG_FILES (date-in-filename resolution), friendly empty-state for cron channels, and a `Sauvegardes SQLite` freshness status check in the system status grid
|
|
||||||
- [x] Add backup watchdog: email xamxam@erg.be (or notify_email) when SQLite backups go stale — `scripts/backup-watchdog.php` (read-only, state-file anti-flood) + cron entry + justfile deploy wiring
|
|
||||||
- [x] Add Nextcloud WebDAV sync: push latest SQLite snapshot to cloud.erg.school `/XAMXAM-BCK` (PHP curl, reuses SMTP creds, timestamped + keep 7) — `scripts/nextcloud-sync.php` + cron + justfile wiring; extend watchdog to also alert on stale/missing remote copy
|
|
||||||
- [x] Fix backup retention: replace `find -mtime +N` (off-by-one day rounding) with deterministic filename-timestamp pruning; add manual `sync=1` option to `just deploy-check-backup-log`
|
|
||||||
- [x] Add custom 404 page: render through layout with dedicated not-found.css, register in build, return HTTP 404
|
|
||||||
- [x] Remove "Mo" option from duration — keep only minutes and pages
|
|
||||||
- [x] Combine pages and minutes as separate fields (both can be set simultaneously)
|
|
||||||
- [x] Fix minutes input visibility (can't see what's typed)
|
|
||||||
- [x] Add `has_annexes` checkbox to form + DB column
|
|
||||||
- [x] Display duration on admin backoffice recap page
|
|
||||||
- [x] Update public TFE page duration display for new combined format
|
|
||||||
- [x] Fix `handleAutosaveResponse is not defined` — load `autosave-handler.js` on about_page edit view
|
|
||||||
- [x] Fix `handleAutosaveResponse is not defined` in admin add/edit — function was scoped inside IIFE bundle, not on window
|
|
||||||
- [x] Fix search result cards: title and author always below image/gradient, remove text overlay on placeholder gradient
|
|
||||||
- [x] Change search results to 10 per page with HTMX pagination (no-JS fallback preserved)
|
|
||||||
- [x] Bump to 15 results/page, make results area vertically scrollable, sticky pagination at viewport bottom
|
|
||||||
- [x] Fix HTMX targetError: move #search-results wrapper inside fragment so it survives outerHTML swaps
|
|
||||||
- [x] Add range counter to results header (e.g. "1–15 sur 112 résultats")
|
|
||||||
- [x] Collapsible filter controls with <details>/<summary> + active filter badge on mobile
|
|
||||||
- [x] Responsive paginator: hide first/last buttons on mobile, smaller touch targets
|
|
||||||
- [x] Compact range counter on mobile: "1–15 / 112" instead of full "1–15 sur 112 résultats"
|
|
||||||
- [x] Remove orientation display from search result card meta
|
|
||||||
- [x] Add bulk select/delete to tmp cleanup dialog (like admin/index.php pattern)
|
|
||||||
- [x] Move cleanup UI from modal to dedicated page (like add.php/edit.php)
|
|
||||||
- [x] Replace <details> with <fieldset>/<legend> in cleanup fragments (like contenus.php)
|
|
||||||
- [x] Standardise test group recipes: lint-php, lint-css, lint-js, test + add fix recipe + make lint pass clean
|
|
||||||
- [x] Remove Mot de passe column from acces.php, add key.svg icon button in Actions to copy password to clipboard, reorder actions (URL/password/edit/toggle/archive), switch URL icon to link-simple.svg
|
|
||||||
- [x] Fix CC2r: removed hidden seeds (were stale/overriding user input), render initial licence-choice from \$formData; Interne want_license unchecked clears CC2r+licence, switching from other modes preserves values; CC2r independent toggle; licence dropdown has no-licence placeholder
|
|
||||||
- [x] Dans le formulaire admin, le contact privé ne se sauvegarde pas.
|
|
||||||
- [x] Remove "Rendre le contact visible publiquement sur la fiche du TFE" from admin add/edit forms
|
|
||||||
- [x] Auto-show contact on public TFE page when contact_visible is filled (no checkbox needed)
|
|
||||||
- [x] Fix file size limits: align all layers (JS/FilepondHandler/ThesisFileHandler/validate-fragment) — video/audio 5 GB, default 500 MB, PDF 100 MB; fix JS fileValidateSizeFilter gate bug that rejected AV files >1 GB despite 8 GB per-ext cap
|
|
||||||
- [x] Fix: deleting contact groups in apropos form not persisted (no change event after DOM removal, autosave never triggered)
|
|
||||||
- [x] Improve h1, h2, h3 size difference in base.css heading scale
|
|
||||||
- [x] Rework TFE page desktop layout: two columns 35vw/1fr, left = author/title/meta/synopsis, right = files, media 100% width; columns scroll independently, content fits 100vw; no bottom padding on main; add &scrollbar=0 to PDF iframe URLs
|
|
||||||
- [x] 'Promoteur·ice ULB' remplacé par 'Promoteur·ice université' (changement juste l'étiquette)
|
|
||||||
- [x] PDF viewer: fix page navigation buttons (prev/next) — build toolbar after canvases exist & query canvases fresh in scroll handler
|
|
||||||
- [x] PDF viewer: render pages smaller by default (0.85× scale)
|
|
||||||
- [x] PDF viewer: add dark transparent violet background behind pages when expanded
|
|
||||||
- [x] pdf-viewer: expand to fill right column (not whole page), center pages, freeze column on expand
|
|
||||||
- [x] pdf-viewer: fix toolbar width (align-self:stretch), hide sibling file items when expanded
|
|
||||||
- [x] Allow admin to export an empty CSV template (headers only) from the import dialog for use as an import model
|
|
||||||
- [x] Fix import modal missing FilePond styling: bundling refactor dropped filepond CSS + file-upload-filepond.js wrapper from admin list page (pre-existing regression)
|
|
||||||
- [x] Move 'download empty CSV template' button onto the same line as the Fichier CSV heading (button on the right, styled as btn)
|
|
||||||
|
|
||||||
- [x] Rework `parameters.php` admin page: new `Identifiants` section (shared SMTP/PeerTube/Nextcloud username+password) before `Emails`, Emails section without username/password, test-send button moved outside its fieldset, PeerTube merged into one `Paramètres Peertube` fieldset with activation checkbox on top and test button aligned with Enregistrer
|
## In Progress
|
||||||
|
|
||||||
## Enquête: PeerTube auth failed (400) invalid_grant
|
## Pending
|
||||||
- [x] [Diagnosed & reproduced] Single LDAP credential (`xamxam@erg.be`). **Both** mail and PeerTube are now on `portail.erg.school` (LemonLDAP OIDC) SSO — verified: mail.erg.school advertises SMTP `XOAUTH2`/`OAUTHBEARER` after STARTTLS. The difference: mail kept `PLAIN`/`LOGIN` (additive migration) so the app's `PLAIN` auth still works; PeerTube *removed* the `password` grant (hard cutover) so `grant_type=password` → `invalid_grant`. Not fixable with any credential; needs admin to restore password grant, register OIDC client, or (best) set up `authorization_code`+`refresh_token`. Full report in docs/peertube-sso-incident.md.
|
|
||||||
- [x] Built `scripts/creds-test.sh` (gum UI) + `scripts/creds-probe.php` (PHP probe) + `just creds-test`, + public `PeerTubeService::probeAuth()` to isolate auth-vs-channel. Probes SMTP AUTH and PeerTube password grant with the stored creds; logs results (never the password). Added `probeAuth` to PeerTubeService.
|
## Completed
|
||||||
- [x] Built `scripts/app-token.sh` (gum) + `just app-token` to test whether a long-lived PeerTube app token (client_credentials grant) is obtainable. Confirmed live: `client_credentials` is rejected for the built-in local client (unsupported_grant_type) → an admin must run PeerTube's create-client on the server first. OIDC presence not determinable anonymously.
|
- [x] #audit-all-docs-and [!high] Audit all docs/ and classify accurate vs stale
|
||||||
- [x] Add `scripts/sso-diagnose.sh` (+ `just sso-diagnose`) to verify every claim in docs/peertube-sso-incident.md — DNS/rDNS, IdP discovery (grant types), PeerTube OAuth/password-grant, SMTP AUTH mechanisms, identity-header propagation — appended to `sso-diagnose.log` (never logs secrets). Fixed the identity-gap (❓): response headers cannot reveal the post-auth header LemonLDAP injects INTO the request; added a request-side echo probe (`--echo <url>` + `scripts/echo-headers.php`) to be hosted *behind* the same LemonLDAP vhost, plus a `server.REMOTE_USER` mirror.
|
- [x] #rewrite-development-md-to-match [!high] Rewrite development.md to match current just dev / app/ layout / PHPUnit
|
||||||
- [x] Update docs/peertube-sso-incident.md with the open "❓" (what identity LemonLDAP forwards to PeerTube), the three possible post-migration auth contracts + copy-paste admin ask, an explicit responsibility boundary (no zero-blame), and the new `sso-diagnose.sh` / `echo-headers.php` tools.
|
- [x] #rewrite-deployment-md-to-match [!high] Rewrite deployment.md to match just deploy / /var/www/xamxam/ / backup
|
||||||
- [ ] Consider decoupling PeerTube credentials from SMTP settings (separate peertube username/password fields in the admin) so mail SSO changes don't silently break uploads
|
- [x] #update-database-md-to-current [!high] Update database.md to current schema (tags, share_links, migrations, xamxam.db)
|
||||||
- [ ] (Superseded) The earlier `client_credentials` app-token path is **ruled out**: idP `portail.erg.school` (LemonLDAP::NG OIDC) only supports `authorization_code` + `refresh_token`, no `password`/`client_credentials`/device flow. Real host is `portail.erg.school` (not `.be`). Topology: videos.erg.be (PeerTube, Belgacom ADSL), mail.erg.school (Mailcow), portail.erg.school (LemonLDAP SSO). No self-service OIDC client registration.
|
- [x] #update-security-md-to-current [!medium] Update security.md to current state (xamxam paths, resolved items)
|
||||||
- [ ] Likely code change: PeerTubeService::obtainToken() switch to OIDC `authorization_code`+`refresh_token` against https://portail.erg.school/oauth2/token — requires admin to register an OIDC client + one-time interactive login to seed a refresh_token.
|
- [x] #update-search-md-to-current [!medium] Update search.md to current schema (tags not keywords)
|
||||||
|
- [x] #verify-fix-import-md-csv-format [!medium] Verify/fix import.md CSV format against current import
|
||||||
|
- [x] #update-bookmarklet-md-form-field [!medium] Update bookmarklet.md form field names (cc2r, duration_pages/minutes, drop contact_public)
|
||||||
|
- [x] #consolidate-archive-historical-analysis-docs [!medium] Consolidate/archive historical analysis docs
|
||||||
|
- [x] #fix-nginx-readme-md-title [!low] Fix nginx README.md title + export.md cross-refs
|
||||||
|
- [x] #fix-app-storage-readme-md-missing-database-spec-quick-schema [!medium] Fix app/storage/README.md (missing DATABASE_SPEC/QUICK_SCHEMA refs, wrong path)
|
||||||
|
- [x] #update-css-md-asset-structure Update CSS.md asset structure + build bundling
|
||||||
|
- [x] #correct-file-uploads-md-limits-banner Correct file-uploads.md limits, banner removal, FilePond transition
|
||||||
|
- [x] #rewrite-app-public-admin-readme-md-to-current Rewrite app/public/admin/README.md to current structure
|
||||||
|
- [x] #fix-nginx-docs-security-headers-md-csp-x-frame-options Fix nginx/docs/SECURITY_HEADERS.md CSP/X-Frame-Options
|
||||||
|
- [x] #create-docs-readme-md-index-classifying Create docs/README.md index classifying all docs
|
||||||
|
- [x] #standardise-all-log-filenames Standardise all log filenames to xamxam-{service}[-{date}].log convention
|
||||||
|
- [x] #add-server-side-log-rename Add server-side log rename script + just recipe (migrate-log-names) for pre-existing logs
|
||||||
|
- [x] #move-production-app-logs Move production app logs from storage/logs to /var/log/xamxam + add logrotate config
|
||||||
|
- [x] #add-date-dropdown-to Add date dropdown to admin log viewer to browse retained daily log files
|
||||||
|
- [x] #fix-heure-de-d-p-t Fix heure de dépôt (submitted_at) fausse dans backoffice récapitulatif: timezone Europe/Brussels + interpréter datetimes SQLite (UTC) comme UTC
|
||||||
|
- [x] #add-date-de-d-p-t Add 'Date de dépôt' (date_depot) column: DB migration + view + recap display
|
||||||
|
- [x] #csv-export-emit-date-depot CSV export: emit date_depot as Brussels-local date
|
||||||
|
- [x] #csv-import-parse-date-depot CSV import: parse date_depot as Brussels-local and convert to UTC storage
|
||||||
|
- [x] #default-exemplaire-baiu Default Exemplaire BAIU + ERG to true on student (partage) submission in ThesisCreateController, replicating admin add-form default
|
||||||
|
|
||||||
|
## Deferred / Blocked
|
||||||
|
- [ ] #just-setup-backs-a [!medium] just setup backs a stale setup-dev.sh (clones php-live-reload, legacy admin/data/ dirs) — needs rewrite or removal
|
||||||
|
- [ ] #csv-export-writes-cc2r-exemplaire [!low] CSV export writes CC2r/Exemplaire columns that import's $cell mapping ignores — document or wire up
|
||||||
|
|||||||
@@ -543,8 +543,11 @@ class ThesisCreateController
|
|||||||
throw new Exception('La note du jury doit être comprise entre 0 et 20.');
|
throw new Exception('La note du jury doit être comprise entre 0 et 20.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$exemplaireBaiu = !empty($post['exemplaire_baiu']);
|
// Student submissions: the BAIU/ERG exemplaire checkboxes are not rendered
|
||||||
$exemplaireErg = !empty($post['exemplaire_erg']);
|
// in the share form, so default both to true — replicating the admin
|
||||||
|
// add-form default (app/public/admin/add.php).
|
||||||
|
$exemplaireBaiu = !empty($post['exemplaire_baiu']) || !$adminMode;
|
||||||
|
$exemplaireErg = !empty($post['exemplaire_erg']) || !$adminMode;
|
||||||
$cc2r = !empty($post['cc2r']);
|
$cc2r = !empty($post['cc2r']);
|
||||||
|
|
||||||
// Duration: separate pages (int) and time (h/m → total minutes)
|
// Duration: separate pages (int) and time (h/m → total minutes)
|
||||||
|
|||||||
@@ -249,13 +249,20 @@
|
|||||||
$_baiuLabel = parse_url($data["baiu_link"], PHP_URL_HOST) ?: preg_replace("#^https?://(www\\.)?#i", "", rtrim($data["baiu_link"], "/"));
|
$_baiuLabel = parse_url($data["baiu_link"], PHP_URL_HOST) ?: preg_replace("#^https?://(www\\.)?#i", "", rtrim($data["baiu_link"], "/"));
|
||||||
?>
|
?>
|
||||||
<p class="tfe-meta-item">
|
<p class="tfe-meta-item">
|
||||||
<span class="tfe-meta-label">Lien :</span>
|
<span class="tfe-meta-label">Lien BAIU :</span>
|
||||||
<a href="<?= $_baiuHref ?>" target="_blank" rel="noopener">
|
<a href="<?= $_baiuHref ?>" target="_blank" rel="noopener">
|
||||||
<?= htmlspecialchars($_baiuLabel) ?>
|
<?= htmlspecialchars($_baiuLabel) ?>
|
||||||
<span class="sr-only">(ouvre dans un nouvel onglet)</span>
|
<span class="sr-only">(ouvre dans un nouvel onglet)</span>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($data["identifier"])): ?>
|
||||||
|
<p class="tfe-meta-item">
|
||||||
|
<span class="tfe-meta-label">ID :</span>
|
||||||
|
<?= htmlspecialchars($data["identifier"]) ?>
|
||||||
|
</p>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if (!empty($data["context_note"])): ?>
|
<?php if (!empty($data["context_note"])): ?>
|
||||||
|
|||||||
Reference in New Issue
Block a user