Altersabfrage mit rein programmiert

This commit is contained in:
Cay 2026-02-28 15:36:10 +00:00
parent a711e76c81
commit 9940d9498b
2 changed files with 181 additions and 115 deletions

View File

@ -1,62 +1,70 @@
const express = require('express'); const express = require("express");
const Database = require('better-sqlite3'); const Database = require("better-sqlite3");
const validateSepa = require('../utils/sepaValidator'); const validateSepa = require("../utils/sepaValidator");
const { encrypt } = require('../utils/crypto'); const { encrypt } = require("../utils/crypto");
const generateVertragsnummer = require('../utils/vertragsnummer'); const generateVertragsnummer = require("../utils/vertragsnummer");
const createContractPdf = require('../utils/contractPdf'); const createContractPdf = require("../utils/contractPdf");
const sendContractMail = require('../utils/sendContractMail'); const sendContractMail = require("../utils/sendContractMail");
const sendAdminMail = require('../utils/sendAdminMail'); const sendAdminMail = require("../utils/sendAdminMail");
const router = express.Router(); const router = express.Router();
const db = new Database('plusfit.db'); const db = new Database("plusfit.db");
/* ========================= /* =========================
Helper Helper
========================= */ ========================= */
function loadActiveContracts() { function loadActiveContracts() {
return db.prepare(` return db
.prepare(
`
SELECT * SELECT *
FROM vertragsarten FROM vertragsarten
WHERE aktiv = 1 WHERE aktiv = 1
ORDER BY betrag ASC ORDER BY betrag ASC
`).all(); `,
)
.all();
} }
/* ========================= /* =========================
GET /register GET /register
========================= */ ========================= */
router.get('/', (req, res) => { router.get("/", (req, res) => {
const vertragId = req.query.vertrag || null; const vertragId = req.query.vertrag || null;
return res.render('register', { return res.render("register", {
vertragsarten: loadActiveContracts(), vertragsarten: loadActiveContracts(),
selectedVertrag: vertragId, selectedVertrag: vertragId,
formData: {} formData: {},
}); });
}); });
/* ========================= /* =========================
POST /register/create POST /register/create
========================= */ ========================= */
router.post('/create', async (req, res) => { router.post("/create", async (req, res) => {
const u = req.body; const u = req.body;
const vertragsarten = loadActiveContracts(); const vertragsarten = loadActiveContracts();
/* ========================= /* =========================
Vertragsdaten laden Vertragsdaten laden
========================= */ ========================= */
const contractData = db.prepare(` const contractData = db
.prepare(
`
SELECT name, laufzeit, betrag SELECT name, laufzeit, betrag
FROM vertragsarten FROM vertragsarten
WHERE id = ? AND aktiv = 1 WHERE id = ? AND aktiv = 1
`).get(u.vertragsvariante); `,
)
.get(u.vertragsvariante);
if (!contractData) { if (!contractData) {
return res.render('register', { return res.render("register", {
vertragsarten, vertragsarten,
selectedVertrag: u.vertragsvariante, selectedVertrag: u.vertragsvariante,
error: 'Vertragsdaten konnten nicht geladen werden.', error: "Vertragsdaten konnten nicht geladen werden.",
formData: u formData: u,
}); });
} }
@ -64,11 +72,45 @@ router.post('/create', async (req, res) => {
Pflicht-Zustimmungen Pflicht-Zustimmungen
========================= */ ========================= */
if (!u.agreeConsent || !u.agreeAgb || !u.agreeSepa) { if (!u.agreeConsent || !u.agreeAgb || !u.agreeSepa) {
return res.render('register', { return res.render("register", {
vertragsarten, vertragsarten,
selectedVertrag: u.vertragsvariante, selectedVertrag: u.vertragsvariante,
error: 'Bitte bestätige alle rechtlichen Hinweise, um fortzufahren.', error: "Bitte bestätige alle rechtlichen Hinweise, um fortzufahren.",
formData: u formData: u,
});
}
/* =========================
Altersprüfung (mind. 18)
========================= */
if (!u.geburtsdatum) {
return res.render("register", {
vertragsarten,
selectedVertrag: u.vertragsvariante,
error: "Bitte gib dein Geburtsdatum an.",
formData: u,
});
}
const birthDate = new Date(u.geburtsdatum);
const today = new Date();
let age = today.getFullYear() - birthDate.getFullYear();
const monthDiff = today.getMonth() - birthDate.getMonth();
if (
monthDiff < 0 ||
(monthDiff === 0 && today.getDate() < birthDate.getDate())
) {
age--;
}
if (age < 18) {
return res.render("register", {
vertragsarten,
selectedVertrag: u.vertragsvariante,
error: "Eine Mitgliedschaft ist erst ab 18 Jahren möglich.",
formData: u,
}); });
} }
@ -78,32 +120,36 @@ router.post('/create', async (req, res) => {
const sepaError = validateSepa({ const sepaError = validateSepa({
ibanValue: u.iban, ibanValue: u.iban,
bic: u.bic, bic: u.bic,
mandatsreferenz: u.mandatsreferenz mandatsreferenz: u.mandatsreferenz,
}); });
if (sepaError) { if (sepaError) {
return res.render('register', { return res.render("register", {
vertragsarten, vertragsarten,
selectedVertrag: u.vertragsvariante, selectedVertrag: u.vertragsvariante,
error: sepaError, error: sepaError,
formData: u formData: u,
}); });
} }
/* ========================= /* =========================
Logische Prüfungen Logische Prüfungen
========================= */ ========================= */
const mandatsExists = db.prepare(` const mandatsExists = db
.prepare(
`
SELECT id FROM users SELECT id FROM users
WHERE mandatsreferenz = ? WHERE mandatsreferenz = ?
`).get(u.mandatsreferenz); `,
)
.get(u.mandatsreferenz);
if (mandatsExists) { if (mandatsExists) {
return res.render('register', { return res.render("register", {
vertragsarten, vertragsarten,
selectedVertrag: u.vertragsvariante, selectedVertrag: u.vertragsvariante,
error: 'Diese Mandatsreferenz ist bereits vergeben.', error: "Diese Mandatsreferenz ist bereits vergeben.",
formData: u formData: u,
}); });
} }
@ -114,12 +160,14 @@ router.post('/create', async (req, res) => {
const zustimmungsDatum = new Date().toISOString(); const zustimmungsDatum = new Date().toISOString();
const zustimmungsIp = ( const zustimmungsIp = (
req.headers['x-forwarded-for'] || req.headers["x-forwarded-for"] ||
req.socket?.remoteAddress || req.socket?.remoteAddress ||
'' ""
).split(',')[0].trim(); )
.split(",")[0]
.trim();
const vertragsversion = 'v1.0'; const vertragsversion = "v1.0";
const widerrufBis = new Date(); const widerrufBis = new Date();
widerrufBis.setDate(widerrufBis.getDate() + 14); widerrufBis.setDate(widerrufBis.getDate() + 14);
@ -133,12 +181,14 @@ router.post('/create', async (req, res) => {
/* ========================= /* =========================
SPEICHERN SPEICHERN
========================= */ ========================= */
db.prepare(` db.prepare(
`
INSERT INTO users ( INSERT INTO users (
vertragsnummer, vertragsnummer,
vertragsvariante, vertragsvariante,
vorname, nachname, vorname, nachname,
geburtstag,
strasse, hausnummer, plz, ort, land, strasse, hausnummer, plz, ort, land,
mobil, telefon, email, mobil, telefon, email,
@ -156,7 +206,7 @@ router.post('/create', async (req, res) => {
gesperrt gesperrt
) VALUES ( ) VALUES (
?,?, ?,?,
?,?, ?,?,?,
?,?,?,?,?, ?,?,?,?,?,
?,?,?, ?,?,?,
?,?,?,?, ?,?,?,?,
@ -165,13 +215,22 @@ router.post('/create', async (req, res) => {
?,?, ?,?,
0 0
) )
`).run( `,
).run(
vertragsnummer, vertragsnummer,
u.vertragsvariante, u.vertragsvariante,
u.vorname, u.nachname, u.vorname,
u.strasse, u.hausnummer, u.plz, u.ort, u.land, u.nachname,
u.mobil, u.telefon, u.email, u.geburtsdatum,
u.strasse,
u.hausnummer,
u.plz,
u.ort,
u.land,
u.mobil,
u.telefon,
u.email,
u.kontoinhaber, u.kontoinhaber,
ibanEncrypted, ibanEncrypted,
@ -186,7 +245,7 @@ router.post('/create', async (req, res) => {
vertragsversion, vertragsversion,
widerrufBis.toISOString(), widerrufBis.toISOString(),
'aktiv' "aktiv",
); );
/* ========================= /* =========================
@ -200,7 +259,7 @@ router.post('/create', async (req, res) => {
laufzeit: contractData.laufzeit, laufzeit: contractData.laufzeit,
betrag: contractData.betrag, betrag: contractData.betrag,
datum: zustimmungsDatum, datum: zustimmungsDatum,
ip: zustimmungsIp ip: zustimmungsIp,
}); });
/* ========================= /* =========================
@ -213,7 +272,7 @@ router.post('/create', async (req, res) => {
vertragName: contractData.name, vertragName: contractData.name,
betrag: contractData.betrag, betrag: contractData.betrag,
datum: zustimmungsDatum, datum: zustimmungsDatum,
pdfPath pdfPath,
}); });
await sendAdminMail({ await sendAdminMail({
@ -224,13 +283,13 @@ await sendAdminMail({
vertragName: contractData.name, vertragName: contractData.name,
betrag: contractData.betrag, betrag: contractData.betrag,
datum: zustimmungsDatum, datum: zustimmungsDatum,
ip: zustimmungsIp ip: zustimmungsIp,
}); });
/* ========================= /* =========================
ERFOLG ERFOLG
========================= */ ========================= */
return res.render('registerSuccess', { vertragsnummer }); return res.render("registerSuccess", { vertragsnummer });
}); });
module.exports = router; module.exports = router;

View File

@ -23,6 +23,13 @@
<input name="nachname" class="form-control" placeholder="Nachname" required> <input name="nachname" class="form-control" placeholder="Nachname" required>
</div> </div>
<div class="col-md-6">
<input type="date"
name="geburtsdatum"
class="form-control"
required>
</div>
<!-- ================= --> <!-- ================= -->
<!-- ADRESSE --> <!-- ADRESSE -->
<!-- ================= --> <!-- ================= -->