237 lines
6.0 KiB
JavaScript
237 lines
6.0 KiB
JavaScript
const express = require('express');
|
|
const Database = require('better-sqlite3');
|
|
const validateSepa = require('../utils/sepaValidator');
|
|
const { encrypt } = require('../utils/crypto');
|
|
const generateVertragsnummer = require('../utils/vertragsnummer');
|
|
const createContractPdf = require('../utils/contractPdf');
|
|
const sendContractMail = require('../utils/sendContractMail');
|
|
const sendAdminMail = require('../utils/sendAdminMail');
|
|
|
|
const router = express.Router();
|
|
const db = new Database('plusfit.db');
|
|
|
|
/* =========================
|
|
Helper
|
|
========================= */
|
|
function loadActiveContracts() {
|
|
return db.prepare(`
|
|
SELECT *
|
|
FROM vertragsarten
|
|
WHERE aktiv = 1
|
|
ORDER BY betrag ASC
|
|
`).all();
|
|
}
|
|
|
|
/* =========================
|
|
GET /register
|
|
========================= */
|
|
router.get('/', (req, res) => {
|
|
const vertragId = req.query.vertrag || null;
|
|
|
|
return res.render('register', {
|
|
vertragsarten: loadActiveContracts(),
|
|
selectedVertrag: vertragId,
|
|
formData: {}
|
|
});
|
|
});
|
|
|
|
/* =========================
|
|
POST /register/create
|
|
========================= */
|
|
router.post('/create', async (req, res) => {
|
|
const u = req.body;
|
|
const vertragsarten = loadActiveContracts();
|
|
|
|
/* =========================
|
|
Vertragsdaten laden
|
|
========================= */
|
|
const contractData = db.prepare(`
|
|
SELECT name, laufzeit, betrag
|
|
FROM vertragsarten
|
|
WHERE id = ? AND aktiv = 1
|
|
`).get(u.vertragsvariante);
|
|
|
|
if (!contractData) {
|
|
return res.render('register', {
|
|
vertragsarten,
|
|
selectedVertrag: u.vertragsvariante,
|
|
error: 'Vertragsdaten konnten nicht geladen werden.',
|
|
formData: u
|
|
});
|
|
}
|
|
|
|
/* =========================
|
|
Pflicht-Zustimmungen
|
|
========================= */
|
|
if (!u.agreeConsent || !u.agreeAgb || !u.agreeSepa) {
|
|
return res.render('register', {
|
|
vertragsarten,
|
|
selectedVertrag: u.vertragsvariante,
|
|
error: 'Bitte bestätige alle rechtlichen Hinweise, um fortzufahren.',
|
|
formData: u
|
|
});
|
|
}
|
|
|
|
/* =========================
|
|
Formale SEPA-Prüfung
|
|
========================= */
|
|
const sepaError = validateSepa({
|
|
ibanValue: u.iban,
|
|
bic: u.bic,
|
|
mandatsreferenz: u.mandatsreferenz
|
|
});
|
|
|
|
if (sepaError) {
|
|
return res.render('register', {
|
|
vertragsarten,
|
|
selectedVertrag: u.vertragsvariante,
|
|
error: sepaError,
|
|
formData: u
|
|
});
|
|
}
|
|
|
|
/* =========================
|
|
Logische Prüfungen
|
|
========================= */
|
|
const mandatsExists = db.prepare(`
|
|
SELECT id FROM users
|
|
WHERE mandatsreferenz = ?
|
|
`).get(u.mandatsreferenz);
|
|
|
|
if (mandatsExists) {
|
|
return res.render('register', {
|
|
vertragsarten,
|
|
selectedVertrag: u.vertragsvariante,
|
|
error: 'Diese Mandatsreferenz ist bereits vergeben.',
|
|
formData: u
|
|
});
|
|
}
|
|
|
|
/* =========================
|
|
Vertrags- & Zustimmungsdaten
|
|
========================= */
|
|
const vertragsnummer = generateVertragsnummer();
|
|
|
|
const zustimmungsDatum = new Date().toISOString();
|
|
const zustimmungsIp = (
|
|
req.headers['x-forwarded-for'] ||
|
|
req.socket?.remoteAddress ||
|
|
''
|
|
).split(',')[0].trim();
|
|
|
|
const vertragsversion = 'v1.0';
|
|
|
|
const widerrufBis = new Date();
|
|
widerrufBis.setDate(widerrufBis.getDate() + 14);
|
|
|
|
/* =========================
|
|
Verschlüsselung
|
|
========================= */
|
|
const ibanEncrypted = encrypt(u.iban);
|
|
const bicEncrypted = encrypt(u.bic);
|
|
|
|
/* =========================
|
|
SPEICHERN
|
|
========================= */
|
|
db.prepare(`
|
|
INSERT INTO users (
|
|
vertragsnummer,
|
|
vertragsvariante,
|
|
|
|
vorname, nachname,
|
|
strasse, hausnummer, plz, ort, land,
|
|
mobil, telefon, email,
|
|
|
|
kontoinhaber, iban, bic, mandatsreferenz,
|
|
|
|
zustimmung_agb,
|
|
zustimmung_sepa,
|
|
zustimmung_einverstaendnis,
|
|
zustimmung_datum,
|
|
zustimmung_ip,
|
|
vertragsversion,
|
|
|
|
widerruf_moeglich_bis,
|
|
status,
|
|
gesperrt
|
|
) VALUES (
|
|
?,?,
|
|
?,?,
|
|
?,?,?,?,?,
|
|
?,?,?,
|
|
?,?,?,?,
|
|
?,?,?,?,
|
|
?,?,
|
|
?,?,
|
|
0
|
|
)
|
|
`).run(
|
|
vertragsnummer,
|
|
u.vertragsvariante,
|
|
|
|
u.vorname, u.nachname,
|
|
u.strasse, u.hausnummer, u.plz, u.ort, u.land,
|
|
u.mobil, u.telefon, u.email,
|
|
|
|
u.kontoinhaber,
|
|
ibanEncrypted,
|
|
bicEncrypted,
|
|
u.mandatsreferenz,
|
|
|
|
u.agreeAgb ? 1 : 0,
|
|
u.agreeSepa ? 1 : 0,
|
|
u.agreeConsent ? 1 : 0,
|
|
zustimmungsDatum,
|
|
zustimmungsIp,
|
|
vertragsversion,
|
|
|
|
widerrufBis.toISOString(),
|
|
'aktiv'
|
|
);
|
|
|
|
/* =========================
|
|
Vertrags-PDF
|
|
========================= */
|
|
const pdfPath = await createContractPdf({
|
|
vertragsnummer,
|
|
vorname: u.vorname,
|
|
nachname: u.nachname,
|
|
vertragName: contractData.name,
|
|
laufzeit: contractData.laufzeit,
|
|
betrag: contractData.betrag,
|
|
datum: zustimmungsDatum,
|
|
ip: zustimmungsIp
|
|
});
|
|
|
|
/* =========================
|
|
Vertragsmail
|
|
========================= */
|
|
await sendContractMail({
|
|
email: u.email,
|
|
vorname: u.vorname,
|
|
vertragsnummer,
|
|
vertragName: contractData.name,
|
|
betrag: contractData.betrag,
|
|
datum: zustimmungsDatum,
|
|
pdfPath
|
|
});
|
|
|
|
await sendAdminMail({
|
|
vertragsnummer,
|
|
vorname: u.vorname,
|
|
nachname: u.nachname,
|
|
email: u.email,
|
|
vertragName: contractData.name,
|
|
betrag: contractData.betrag,
|
|
datum: zustimmungsDatum,
|
|
ip: zustimmungsIp
|
|
});
|
|
|
|
/* =========================
|
|
ERFOLG
|
|
========================= */
|
|
return res.render('registerSuccess', { vertragsnummer });
|
|
});
|
|
|
|
module.exports = router;
|