ajoute les pages légales, la purge RGPD et sert polices et scripts depuis le portail
Pages /legal et /confidentialite réécrites d'après le système réel, purge des classes archivées depuis 90 jours (prouvée par Pest), archivage côté prof. Polices, xterm.js et CodeMirror ne sont plus chargés depuis Google ni jsDelivr. Pages d'aperçu signalées, sans vrais établissements ni faux chiffres. Journaux Laravel gardés 14 jours. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
0a5df89201
commit
e4a6aaebb1
62 changed files with 822 additions and 238 deletions
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
|||
|
||||
use App\Models\Classe;
|
||||
use App\Models\Eleve;
|
||||
use App\Models\Seance;
|
||||
use App\Services\GenerateurCompteEleve;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
|
@ -124,6 +125,33 @@ class ClasseController extends Controller
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fin d'année : plus de séance possible, et suppression définitive de la
|
||||
* classe et des données de ses élèves 90 jours plus tard.
|
||||
*/
|
||||
public function archiver(Classe $classe): RedirectResponse
|
||||
{
|
||||
$this->verifierProprietaire($classe);
|
||||
|
||||
if ($classe->aDesLabsEnCours()) {
|
||||
return back()->withErrors(['archivage' => 'Des élèves ont encore un lab en cours : termine la séance avant d’archiver.']);
|
||||
}
|
||||
|
||||
$classe->forceFill(['archivee_a' => now()])->save();
|
||||
$classe->seances()->whereIn('statut', [Seance::PLANIFIEE, Seance::SALLE_ATTENTE, Seance::EN_COURS])
|
||||
->update(['statut' => Seance::TERMINEE, 'terminee_a' => now()]);
|
||||
|
||||
return redirect()->route('mes-classes.show', $classe);
|
||||
}
|
||||
|
||||
public function desarchiver(Classe $classe): RedirectResponse
|
||||
{
|
||||
$this->verifierProprietaire($classe);
|
||||
$classe->forceFill(['archivee_a' => null])->save();
|
||||
|
||||
return redirect()->route('mes-classes.show', $classe);
|
||||
}
|
||||
|
||||
private function verifierProprietaire(Classe $classe): void
|
||||
{
|
||||
abort_if($classe->user_id !== Auth::guard('web')->id(), 403);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ class SeanceController extends Controller
|
|||
{
|
||||
abort_if($classe->user_id !== Auth::guard('web')->id(), 403);
|
||||
|
||||
if ($classe->estArchivee()) {
|
||||
return back()->withErrors(['prevue_a' => 'Cette classe est archivée : désarchive-la pour lancer une séance.']);
|
||||
}
|
||||
|
||||
$donnees = $request->validate([
|
||||
'lab_id' => ['required', 'exists:labs,id'],
|
||||
'prevue_a' => ['nullable', 'date_format:Y-m-d\TH:i'],
|
||||
|
|
@ -130,6 +134,7 @@ class SeanceController extends Controller
|
|||
{
|
||||
$eleve = Auth::guard('eleve')->user();
|
||||
abort_if($eleve->classe_id !== $seance->classe_id, 403);
|
||||
abort_if($seance->classe->estArchivee(), 403);
|
||||
|
||||
LabSession::firstOrCreate(
|
||||
['seance_id' => $seance->id, 'eleve_id' => $eleve->id],
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ class PolitiqueSecuriteContenu
|
|||
$communes = [
|
||||
'default-src' => "'self'",
|
||||
'img-src' => "'self' data:",
|
||||
'font-src' => "'self' https://fonts.gstatic.com",
|
||||
// Polices servies par le portail (Vite), depuis l'étape 14.
|
||||
'font-src' => "'self'",
|
||||
'object-src' => "'none'",
|
||||
'base-uri' => "'self'",
|
||||
'form-action' => "'self'",
|
||||
|
|
@ -54,13 +55,17 @@ class PolitiqueSecuriteContenu
|
|||
'script-src' => "'self' 'nonce-".Vite::cspNonce()."'",
|
||||
// Attributs style= présents dans le gabarit commun : sans
|
||||
// risque d'exécution de code, tolérés.
|
||||
'style-src' => "'self' 'unsafe-inline' https://fonts.googleapis.com",
|
||||
'style-src' => "'self' 'unsafe-inline'",
|
||||
'connect-src' => "'self' wss://{$request->getHost()}",
|
||||
]
|
||||
: [
|
||||
'script-src' => "'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdn.tailwindcss.com",
|
||||
'style-src' => "'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net",
|
||||
'connect-src' => "'self'",
|
||||
// jsDelivr : Pyodide et sql.js, téléchargés par /ide à la
|
||||
// demande (WebAssembly, d'où 'wasm-unsafe-eval', qui n'autorise
|
||||
// pas eval() en JavaScript). Tailwind : CDN d'exécution des
|
||||
// pages du design. Voir docs/dette.md.
|
||||
'script-src' => "'self' 'unsafe-inline' 'wasm-unsafe-eval' https://cdn.jsdelivr.net https://cdn.tailwindcss.com",
|
||||
'style-src' => "'self' 'unsafe-inline'",
|
||||
'connect-src' => "'self' https://cdn.jsdelivr.net",
|
||||
'frame-src' => 'https://www.youtube-nocookie.com',
|
||||
];
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue