Files
PolyMPR/routes/dev-login.ts
T
djalim 6c38cd0019 feat: cascade deletes, student notes, import popups, module reorganization
- Cascade delete on all entities (student, module, UE, user, role, promotion)
- Fix Response body reuse bug (factory functions instead of constants)
- Student note viewing via CAS uid (strip non-digit prefix)
- Fix middleware page visibility for students in LOCAL mode
- Import result popup component (shared across all import pages)
- Fix student import to use numEtud from Excel
- Bulk student selection with promo change and delete
- Move UE/UE-Module API and pages from notes to admin module
- Move promotions page from students to admin module
- Multi-year maquette import with per-year promo selection
- Inline promo creation in maquette import
- Static Excel templates (students, notes, maquette)
- Fix XLSX export using blob download instead of writeFile
- Allow students to read modules list (GET /modules)
2026-04-30 13:47:16 +02:00

81 lines
2.3 KiB
TypeScript

import { FreshContext, Handlers } from "$fresh/server.ts";
import { CasContent, LoginJWT, State } from "$root/defaults/interfaces.ts";
import { createJwt } from "@popov/jwt";
import { setCookie } from "$std/http/cookie.ts";
import { getKey } from "$root/routes/_middleware.ts";
function makeFakeUser(
role: "employee" | "student",
numEtud?: string,
): CasContent {
if (role === "student" && numEtud) {
return {
amuCampus: "local",
amuComposante: "local",
amuDateValidation: "",
coGroup: "",
eduPersonPrimaryAffiliation: "student",
eduPersonPrincipalName: `${numEtud}@local`,
mail: `${numEtud}@local`,
displayName: `Etudiant ${numEtud}`,
givenName: "",
memberOf: [],
sn: "",
supannCivilite: "",
supannEntiteAffectation: "",
supannEtuAnneeInscription: "",
supannEtuEtape: "",
uid: `e${numEtud}`,
};
}
return {
amuCampus: "local",
amuComposante: "local",
amuDateValidation: "",
coGroup: "",
eduPersonPrimaryAffiliation: "employee",
eduPersonPrincipalName: "admin@local",
mail: "admin@local",
displayName: "Admin Local",
givenName: "Admin",
memberOf: [],
sn: "Local",
supannCivilite: "",
supannEntiteAffectation: "",
supannEtuAnneeInscription: "",
supannEtuEtape: "",
uid: "admin-local",
};
}
export const handler: Handlers<null, State> = {
async GET(request: Request, _context: FreshContext<State, null>) {
if (Deno.env.get("LOCAL") !== "true") {
return new Response("Not available outside LOCAL mode.", { status: 403 });
}
const url = new URL(request.url);
const role = url.searchParams.get("role") === "student"
? "student"
: "employee";
const numEtud = url.searchParams.get("numEtud") ?? undefined;
const user = makeFakeUser(role, numEtud);
const now = Math.floor(Date.now() / 1000);
const payload: LoginJWT = {
iss: "PolyMPR",
iat: now,
exp: now + 0xe10,
aud: "PolyMPR",
user,
};
const token = await createJwt(payload, getKey(user.uid));
const headers = new Headers();
setCookie(headers, { name: "sessionToken", value: token });
headers.set("Location", "/apps");
return new Response(null, { status: 302, headers });
},
};