Arbeit der parallelen Session in git gesichert (war nur auf dem Server)
Diese Änderungen liefen bereits live auf dem Server, lagen dort aber ausschließlich als nicht eingecheckte Arbeitskopie — bei jedem Deploy (stash/pull/pop) und bei jedem Serverproblem wären sie verloren gewesen. Deshalb hier unverändert in git übernommen, bevor darauf aufgebaut wird. Enthalten (nicht von mir gebaut, nur gesichert): - Supporter: eigener fester Zugangscode statt Einmalcode-Login (Migration 0009, lib/crypto.js scrypt-Hash, routes/supporter.js, abonnieren.html, supporter.html, i18n-abonnieren/-supporter) - Stimmen: Profilbilder (Migration 0010, routes/testimonials.js) - Event-Bild-Upload: voller Pfad statt relativem (routes/events.js) - Neue/überarbeitete Hintergrundbilder für viele Seiten - Teilen-Funktion (streamplan.js, i18n-index/-streamplan, main.css) Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -53,6 +53,7 @@ import {
|
||||
import { listAuditLog } from "./routes/audit.js";
|
||||
import {
|
||||
registerSupporter, verifySupporterEmail, requestSupporterLogin, verifySupporterLogin, logoutSupporter,
|
||||
loginSupporterMitCode, setSupporterAccessCode,
|
||||
googleLoginSupporter, getPublicConfig,
|
||||
getSupporterMe, updateSupporterProfile, requestSupporterEmailChange, confirmSupporterEmailChange,
|
||||
redeemPremium, deleteSupporterAccount,
|
||||
@@ -67,6 +68,7 @@ import { getEventsPublic, getEventsAdmin, saveEvent, uploadEventImage } from "./
|
||||
import { getSpecialEventPublic, getSpecialEventAdmin, saveSpecialEvent } from "./routes/special-event.js";
|
||||
import {
|
||||
submitTestimonial, getApprovedTestimonialsPublic, getTestimonialsAdmin, setTestimonialStatus, deleteTestimonial,
|
||||
setTestimonialAvatar, uploadTestimonialAvatar,
|
||||
} from "./routes/testimonials.js";
|
||||
import {
|
||||
createPoll, listPolls, closePoll, reopenPoll, deletePoll, getActivePollPublic, voteOnPoll,
|
||||
@@ -116,6 +118,20 @@ const teamBildUpload = multer({
|
||||
fileFilter: (req, file, cb) => cb(null, ERLAUBTE_BILD_TYPEN.has(file.mimetype)),
|
||||
});
|
||||
|
||||
// Profilbilder für die "Stimmen" (21.08.2026) — gleiches Muster wie oben.
|
||||
// Nur aus der Verwaltung heraus erreichbar; das öffentliche Stimmen-Formular
|
||||
// nimmt bewusst keine Dateien entgegen (siehe routes/testimonials.js).
|
||||
const TESTIMONIAL_UPLOADS_DIR = `${UPLOADS_BASIS_DIR}/testimonials`;
|
||||
mkdirSync(TESTIMONIAL_UPLOADS_DIR, { recursive: true });
|
||||
const stimmenBildUpload = multer({
|
||||
storage: multer.diskStorage({
|
||||
destination: (req, file, cb) => cb(null, TESTIMONIAL_UPLOADS_DIR),
|
||||
filename: (req, file, cb) => cb(null, `${crypto.randomUUID()}${extname(file.originalname).toLowerCase()}`),
|
||||
}),
|
||||
limits: { fileSize: 5 * 1024 * 1024 }, // 5 MB
|
||||
fileFilter: (req, file, cb) => cb(null, ERLAUBTE_BILD_TYPEN.has(file.mimetype)),
|
||||
});
|
||||
|
||||
app.use((req, res, next) => {
|
||||
res.setHeader("X-Content-Type-Options", "nosniff");
|
||||
res.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
|
||||
@@ -185,6 +201,9 @@ app.get("/site-texts", wrap(getSiteTextsPublic));
|
||||
|
||||
app.post("/supporter/register", wrap(registerSupporter));
|
||||
app.post("/supporter/verify-email", wrap(verifySupporterEmail));
|
||||
// Normaler Login seit 21.08.2026: E-Mail + selbst gewählter Zugangscode.
|
||||
app.post("/supporter/login-code", wrap(loginSupporterMitCode));
|
||||
// login-request/verify-login sind jetzt der "Code vergessen?"-Weg.
|
||||
app.post("/supporter/login-request", wrap(requestSupporterLogin));
|
||||
app.post("/supporter/verify-login", wrap(verifySupporterLogin));
|
||||
app.post("/supporter/google-login", wrap(googleLoginSupporter));
|
||||
@@ -227,6 +246,9 @@ app.post("/admin/special-event/save", requireTeamSession, withSession(saveSpecia
|
||||
app.post("/admin/testimonials/list", requireTeamSession, withSession(getTestimonialsAdmin));
|
||||
app.post("/admin/testimonials/status", requireTeamSession, withSession(setTestimonialStatus));
|
||||
app.post("/admin/testimonials/delete", requireTeamSession, withSession(deleteTestimonial));
|
||||
// Profilbild einer Stimme setzen bzw. eigenes Foto hochladen (21.08.2026).
|
||||
app.post("/admin/testimonials/avatar", requireTeamSession, withSession(setTestimonialAvatar));
|
||||
app.post("/admin/testimonials/upload-avatar", requireTeamSession, stimmenBildUpload.single("image"), withSession(uploadTestimonialAvatar));
|
||||
|
||||
// Team-Mitglieder (Modis/Scouts/Creator/Manager) — 21.08.2026
|
||||
app.post("/admin/team/list", requireTeamSession, withSession(getTeamAdmin));
|
||||
@@ -277,6 +299,9 @@ app.post("/admin/polls/delete", requireTeamSession, withSession(deletePoll));
|
||||
app.post("/supporter/logout", requireSupporterAuth, wrap(logoutSupporter));
|
||||
app.post("/supporter/me", requireSupporterAuth, withSupporter(getSupporterMe));
|
||||
app.post("/supporter/update-profile", requireSupporterAuth, withSupporter(updateSupporterProfile));
|
||||
// Neuen Zugangscode setzen — freiwillig im Supporter-Bereich oder als
|
||||
// Abschluss des "Code vergessen?"-Weges (da ist man bereits eingeloggt).
|
||||
app.post("/supporter/set-access-code", requireSupporterAuth, withSupporter(setSupporterAccessCode));
|
||||
app.post("/supporter/request-email-change", requireSupporterAuth, withSupporter(requestSupporterEmailChange));
|
||||
app.post("/supporter/confirm-email-change", requireSupporterAuth, withSupporter(confirmSupporterEmailChange));
|
||||
app.post("/supporter/redeem-premium", requireSupporterAuth, withSupporter(redeemPremium));
|
||||
|
||||
Reference in New Issue
Block a user