2024-09-12 10:46:14 +02:00
const express = require ( "express" ) ;
const session = require ( "express-session" ) ;
const bcrypt = require ( "bcrypt" ) ;
const crypto = require ( "crypto" ) ;
const nodemailer = require ( "nodemailer" ) ;
const { Pool } = require ( "pg" ) ;
const path = require ( "path" ) ;
const moment = require ( "moment" ) ;
require ( "dotenv" ) . config ( ) ;
const log = require ( "node-file-logger" ) ;
2024-05-31 22:21:44 +02:00
2024-05-23 20:49:34 +02:00
const app = express ( ) ;
2024-05-23 22:32:30 +02:00
const port = process . env . PORT ;
2024-05-23 20:49:34 +02:00
2024-07-19 18:49:08 +02:00
/ * c o n s t T e l e B o t = r e q u i r e ( ' t e l e b o t ' ) ;
2024-07-19 18:31:54 +02:00
const bot = new TeleBot ( process . env . TELEBOT ) ;
telebotChatID = process . env . TELECHAT ;
bot . on ( 'text' , ( msg ) => {
if ( msg . from . id == telebotChatID ) {
msg . reply . text ( msg . text ) ;
} else {
msg . reply . text ( "Entschuldige, " + msg . from . username + "\nIch darf nicht mit fremden reden." ) ;
log . Info ( "Telebot-nachricht: " + msg . from . username + " - " + msg . text ) ;
}
} ) ;
2024-07-19 18:49:08 +02:00
bot . start ( ) ; * /
2024-07-19 18:31:54 +02:00
2024-05-31 22:21:44 +02:00
const options = {
2024-09-12 10:46:14 +02:00
timeZone : "europe/Berlin" ,
folderPath : "./logs/" ,
2024-05-31 22:21:44 +02:00
dateBasedFileNaming : true ,
2024-09-12 10:46:14 +02:00
fileNamePrefix : "DailyLogs_" ,
fileNameExtension : ".log" ,
2024-09-18 16:09:00 +02:00
dateFormat : "YYYY_MM_DD" ,
2024-09-12 10:46:14 +02:00
timeFormat : "H:mm:ss" ,
} ;
2024-06-02 12:39:00 +02:00
log . SetUserOptions ( options ) ;
2024-05-31 22:21:44 +02:00
2024-05-23 20:49:34 +02:00
// Middleware
2024-09-12 10:46:14 +02:00
app . use ( express . static ( path . join ( _ _dirname , "public" ) ) ) ;
2024-05-23 20:49:34 +02:00
app . use ( express . json ( ) ) ;
2024-09-12 10:46:14 +02:00
app . set ( "view engine" , "ejs" ) ;
2024-05-23 20:49:34 +02:00
app . use ( express . urlencoded ( { extended : false } ) ) ;
// Session-Konfiguration
2024-09-12 10:46:14 +02:00
app . use (
session ( {
secret : process . env . SESSIONSECRET ,
resave : false ,
saveUninitialized : true ,
cookie : { maxAge : 1000 * 60 * 60 * 24 * 2 } ,
} )
) ;
2024-05-23 20:49:34 +02:00
// Authentifizierungs-Middleware
const requireAuth = ( req , res , next ) => {
if ( ! req . session . userId ) {
2024-09-12 10:46:14 +02:00
return res . redirect ( "/login" ) ;
2024-05-23 20:49:34 +02:00
}
next ( ) ;
} ;
const requireAdmin = ( req , res , next ) => {
2024-09-12 10:46:14 +02:00
if ( req . session . role !== "admin" ) {
return res . status ( 403 ) . send ( "Access denied" ) ;
2024-05-23 20:49:34 +02:00
}
next ( ) ;
} ;
// Email-Konfiguration
const transporter = nodemailer . createTransport ( {
2024-05-23 21:58:22 +02:00
host : process . env . MAILHOST ,
2024-05-23 20:49:34 +02:00
port : 465 ,
secure : true ,
auth : {
2024-05-23 21:58:22 +02:00
user : process . env . MAILUSER ,
2024-09-12 10:46:14 +02:00
pass : process . env . MAILPASS ,
} ,
2024-05-23 20:49:34 +02:00
} ) ;
// Datenbankverbindung
const pool = new Pool ( {
2024-09-12 10:46:14 +02:00
connectionString : process . env . DATABASE _URL ,
2024-05-23 20:49:34 +02:00
} ) ;
// Altersberechnung
const calculateAge = ( birthdate ) => {
const today = new Date ( ) ;
const birthDate = new Date ( birthdate ) ;
let age = today . getFullYear ( ) - birthDate . getFullYear ( ) ;
const m = today . getMonth ( ) - birthDate . getMonth ( ) ;
if ( m < 0 || ( m === 0 && today . getDate ( ) < birthDate . getDate ( ) ) ) {
age -- ;
}
return age ;
} ;
2024-10-10 22:32:24 +02:00
const isBirthday = ( birthdate , date , previousTraining ) => {
let adjustedBirthdate = new Date ( birthdate ) ;
adjustedBirthdate . setFullYear ( date . getFullYear ( ) ) ;
2024-11-26 13:04:17 +01:00
if ( adjustedBirthdate . getMonth ( ) == 10 ) {
console . log ( "checking:" , adjustedBirthdate , date , previousTraining ) ;
}
if ( adjustedBirthdate . getTime ( ) === date . getTime ( ) ) {
2024-10-10 22:32:24 +02:00
console . log ( "birthday" ) ;
return 2 ;
}
2024-11-26 13:04:17 +01:00
if (
adjustedBirthdate . getTime ( ) >= previousTraining . getTime ( ) &&
adjustedBirthdate . getTime ( ) <= date . getTime ( )
) {
console . log ( "had birthday" ) ;
2024-10-10 22:32:24 +02:00
return 1 ;
}
return 0 ;
} ;
2024-05-23 20:49:34 +02:00
// Datumsformatierung
const formatDate = ( date ) => {
const d = new Date ( date ) ;
2024-09-12 10:46:14 +02:00
const day = String ( d . getDate ( ) ) . padStart ( 2 , "0" ) ;
const month = String ( d . getMonth ( ) + 1 ) . padStart ( 2 , "0" ) ;
2024-05-23 20:49:34 +02:00
const year = d . getFullYear ( ) ;
return ` ${ day } . ${ month } . ${ year } ` ;
} ;
// Funktion zum Laden des aktuellen oder letzten Trainings
2024-09-12 10:46:14 +02:00
const getTraining = async ( kw , jahr ) => {
const result = await pool . query (
`
2024-05-23 20:49:34 +02:00
SELECT tr . * , g1 . name AS geraet _riege _1 _name , g2 . name AS geraet _riege _2 _name ,
g3 . name AS geraet _riege _3 _name , g4 . name AS geraet _riege _4 _name ,
g5 . name AS geraet _riege _5 _name ,
t1 . name AS aufwaermleiter _name , t2 . name AS spielleiter _name ,
sp1 . name AS aufwaermen _name , sp2 . name AS spiel _name
FROM trainings tr
LEFT JOIN geraete g1 ON tr . geraet _riege _1 = g1 . id
LEFT JOIN geraete g2 ON tr . geraet _riege _2 = g2 . id
LEFT JOIN geraete g3 ON tr . geraet _riege _3 = g3 . id
LEFT JOIN geraete g4 ON tr . geraet _riege _4 = g4 . id
LEFT JOIN geraete g5 ON tr . geraet _riege _5 = g5 . id
LEFT JOIN teilnehmende t1 ON tr . aufwaermleiter = t1 . id
LEFT JOIN teilnehmende t2 ON tr . spielleiter = t2 . id
LEFT JOIN spiele sp1 ON tr . aufwaermen = sp1 . id
LEFT JOIN spiele sp2 ON tr . spiel = sp2 . id
2024-09-12 10:46:14 +02:00
WHERE tr . kw <= $1 AND tr . jahr = $2
2024-07-04 22:45:31 +02:00
ORDER BY tr . kw DESC
2024-05-23 20:49:34 +02:00
LIMIT 1
2024-09-12 10:46:14 +02:00
` ,
[ kw , jahr ]
) ;
2024-06-02 12:39:00 +02:00
return result . rows [ 0 ] ;
2024-05-23 20:49:34 +02:00
} ;
// Funktion zum Laden aller Spiele
const getAllSpiele = async ( ) => {
2024-06-02 12:39:00 +02:00
const result = await pool . query ( `
2024-05-26 18:25:15 +02:00
SELECT * FROM spiele ORDER BY name ASC ;
2024-05-23 20:49:34 +02:00
` );
2024-06-02 12:39:00 +02:00
return result . rows ;
} ;
// Funktion zum Hinzufügen eines neuen Spiels, falls es noch nicht existiert
const addNewSpiel = async ( spielName ) => {
try {
2024-09-12 10:46:14 +02:00
const result = await pool . query (
"INSERT INTO spiele (name) VALUES ($1) RETURNING id" ,
[ spielName ]
) ;
2024-06-02 12:39:00 +02:00
return result . rows [ 0 ] . id ;
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error adding new spiel:" , error ) ;
2024-06-02 12:39:00 +02:00
throw error ;
}
} ;
2024-05-23 20:49:34 +02:00
2024-10-01 21:56:09 +02:00
function getdayOfWeek ( week , year ) {
const weekday = parseInt ( process . env . WEEKDAY , 10 ) ;
2024-07-04 22:45:31 +02:00
const firstDayOfYear = new Date ( year , 0 , 1 ) ;
const dayOfWeek = firstDayOfYear . getDay ( ) ;
2024-09-12 10:46:14 +02:00
const daysUntilFirstThursday =
2024-10-01 21:56:09 +02:00
dayOfWeek <= weekday ? weekday - dayOfWeek : 11 - dayOfWeek ;
2024-07-04 22:45:31 +02:00
const daysUntilThursdayOfWeek = ( week - 1 ) * 7 + daysUntilFirstThursday ;
const thursdayOfWeek = new Date ( year , 0 , 1 + daysUntilThursdayOfWeek ) ;
return thursdayOfWeek ;
}
2024-06-01 22:38:25 +02:00
// Funktion zum Laden der vier Leute, die am längsten nicht Aufwärmen oder Spiel geleitet haben
2024-05-23 20:49:34 +02:00
const getCandidatesForAufwaermleiter = async ( ) => {
const result = await pool . query ( `
SELECT t . id , t . name ,
COALESCE ( EXTRACT ( EPOCH FROM ( NOW ( ) - MAX ( tr . datum ) ) ) / 604800 , EXTRACT ( EPOCH FROM ( NOW ( ) - '1970-01-01' : : date ) ) / 604800 ) AS weeks _since _last
FROM teilnehmende t
LEFT JOIN trainings tr ON t . id = tr . aufwaermleiter
WHERE t . helfer = true
GROUP BY t . id
2024-05-26 11:17:50 +02:00
ORDER BY weeks _since _last DESC ;
2024-05-23 20:49:34 +02:00
` );
return result . rows ;
} ;
2024-05-27 20:37:35 +02:00
const putInRiege = async ( riege , teilnehmerID ) => {
try {
2024-06-25 21:06:21 +02:00
if ( riege == 0 ) {
2024-09-12 10:46:14 +02:00
const resultRiege = await pool . query (
"DELETE FROM riegen WHERE fremdid_teilnehmende = $1;" ,
[ teilnehmerID ]
) ;
2024-05-27 20:37:35 +02:00
} else {
2024-09-12 10:46:14 +02:00
const resultRiege = await pool . query (
"SELECT * FROM riegen WHERE fremdid_teilnehmende = $1;" ,
[ teilnehmerID ]
) ;
if ( resultRiege . rows . length > 0 ) {
const resultRiege = await pool . query (
"UPDATE riegen SET riegennummer = $1 WHERE fremdid_teilnehmende = $2" ,
[ riege , teilnehmerID ]
) ;
log . Info ( "Mitglied " + teilnehmerID + " ist jetzt in Riege " + riege ) ;
} else {
const resultRiege = await pool . query (
"INSERT INTO riegen (fremdid_teilnehmende, riegennummer) VALUES ($1, $2)" ,
[ teilnehmerID , riege ]
) ;
log . Info (
"Mitglied " + teilnehmerID + " neu in Riege " + riege + " eingefügt."
) ;
}
}
2024-05-27 20:37:35 +02:00
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error adding new spiel:" , error ) ;
2024-05-27 20:37:35 +02:00
throw error ;
}
} ;
2024-05-23 20:49:34 +02:00
// Funktion zum Laden der vier Leute, die am längsten nicht Spiel geleitet haben
const getCandidatesForSpielleiter = async ( ) => {
const result = await pool . query ( `
SELECT t . id , t . name ,
COALESCE ( EXTRACT ( EPOCH FROM ( NOW ( ) - MAX ( tr . datum ) ) ) / 604800 , EXTRACT ( EPOCH FROM ( NOW ( ) - '1970-01-01' : : date ) ) / 604800 ) AS weeks _since _last
FROM teilnehmende t
LEFT JOIN trainings tr ON t . id = tr . spielleiter
WHERE t . helfer = true
GROUP BY t . id
2024-05-26 11:17:50 +02:00
ORDER BY weeks _since _last DESC ;
2024-05-23 20:49:34 +02:00
` );
return result . rows ;
} ;
// Funktion zum Laden der Riegenteilnehmer absteigend nach Alter sortiert
const getRiegenMitgliederSortedByAge = async ( ) => {
2024-06-02 12:39:00 +02:00
const result = await pool . query ( `
2024-05-23 20:49:34 +02:00
SELECT r . riegennummer , t . name , t . alter
FROM riegen r
JOIN teilnehmende t ON r . fremdid _teilnehmende = t . id
ORDER BY r . riegennummer , t . alter DESC
` );
2024-06-02 12:39:00 +02:00
return result . rows ;
} ;
2024-05-23 20:49:34 +02:00
2024-06-02 12:39:00 +02:00
const getAnwesenheit = function ( id , anwesend ) {
for ( let item of anwesend ) {
if ( item . fid _teilnehmer === id ) {
return true ;
2024-05-31 18:42:27 +02:00
}
2024-06-02 12:39:00 +02:00
}
return false ;
} ;
2024-05-31 18:42:27 +02:00
2024-05-23 20:49:34 +02:00
// Registrierung
2024-09-12 10:46:14 +02:00
app . post ( "/register" , async ( req , res ) => {
2024-05-29 21:28:35 +02:00
const { username , email , password } = req . body ;
2024-05-23 20:49:34 +02:00
try {
const hashedPassword = await bcrypt . hash ( password , 10 ) ;
2024-09-12 10:46:14 +02:00
await pool . query (
"INSERT INTO users (username, email, password) VALUES ($1, $2, $3)" ,
[ username , email , hashedPassword ]
) ;
const message =
"Registrierung erfolgreich. Ein Admin wird dich in kürze freischalten" ;
2024-05-29 21:25:27 +02:00
const mailOptions = {
2024-09-12 10:46:14 +02:00
to : "admin@boergmann.it" ,
from : "admin@boergmann.it" ,
subject : "Neue Registrierung" ,
text : ` ${ username } hat sich registriert ` ,
2024-05-29 21:25:27 +02:00
} ;
transporter . sendMail ( mailOptions , ( error ) => {
if ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error sending email:" , error ) ;
const message = "Error sending Mail:" + error ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-29 21:25:27 +02:00
}
} ) ;
2024-09-12 10:46:14 +02:00
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error registering user:" , error ) ;
const message = "Error registering user:" + error ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
}
} ) ;
// Login
2024-09-12 10:46:14 +02:00
app . post ( "/login" , async ( req , res ) => {
2024-05-23 20:49:34 +02:00
const { username , password } = req . body ;
2024-06-02 12:39:00 +02:00
2024-05-23 20:49:34 +02:00
try {
2024-09-12 10:46:14 +02:00
const userResult = await pool . query (
"SELECT *, CASE WHEN admin_temp IS NOT NULL AND (now() - admin_temp) > interval '22 hours' THEN 'expired' ELSE 'valid' END AS admin_status FROM users WHERE username = $1" ,
[ username ]
) ;
2024-05-23 20:49:34 +02:00
if ( userResult . rows . length > 0 ) {
const user = userResult . rows [ 0 ] ;
const match = await bcrypt . compare ( password , user . password ) ;
if ( match ) {
2024-05-28 15:48:28 +02:00
if ( user . is _active ) {
req . session . userId = user . id ;
2024-05-30 19:24:40 +02:00
req . session . userName = user . username ;
2024-05-31 21:29:18 +02:00
req . session . activeRiege = 1 ;
2024-09-12 10:46:14 +02:00
req . session . activeTab = "geraete" ;
req . session . message = [ ( title = "" ) , ( message = "" ) , ( type = "none" ) ] ;
if ( user . admin _status === "expired" ) {
await pool . query (
"UPDATE users SET role = $1, admin_temp = NULL WHERE id = $2" ,
[ "user" , user . id ]
) ;
req . session . role = "user" ;
2024-06-02 12:39:00 +02:00
} else {
req . session . role = user . role ;
}
2024-09-12 10:46:14 +02:00
res . redirect ( "/training" ) ;
2024-06-02 12:39:00 +02:00
} else {
2024-09-12 10:46:14 +02:00
res . redirect ( "/freischaltung" ) ;
2024-05-28 15:48:28 +02:00
}
2024-05-23 20:49:34 +02:00
} else {
2024-09-12 10:46:14 +02:00
const message = "Falsches Passwort" ;
res . render ( "login" , { session : req . session , username , message } ) ;
2024-05-23 20:49:34 +02:00
}
} else {
2024-09-12 10:46:14 +02:00
const message = "Unbekannter Benutzer" ;
res . render ( "login" , { session : req . session , username , message } ) ;
2024-05-23 20:49:34 +02:00
}
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error logging in:" , error ) ;
const message = "Error logging in:" + error ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
}
} ) ;
2024-05-28 16:19:59 +02:00
//Wird angezeigt, wenn ein nicht freigeschalteter User sich anmelden will.
2024-09-12 10:46:14 +02:00
app . get ( "/freischaltung" , async ( req , res ) => {
res . render ( "freischaltung" , { session : req . session } ) ;
} ) ;
2024-05-28 15:48:28 +02:00
2024-05-23 20:49:34 +02:00
// Logout
2024-09-12 10:46:14 +02:00
app . get ( "/logout" , ( req , res ) => {
req . session . destroy ( ( err ) => {
2024-05-23 20:49:34 +02:00
if ( err ) {
2024-09-12 10:46:14 +02:00
return res . status ( 500 ) . send ( "Internal Server Error" ) ;
2024-05-23 20:49:34 +02:00
}
2024-09-12 10:46:14 +02:00
res . redirect ( "/" ) ;
2024-05-23 20:49:34 +02:00
} ) ;
} ) ;
// Benutzer freischalten (nur Admin)
2024-09-12 10:46:14 +02:00
app . post ( "/userrights" , requireAuth , requireAdmin , async ( req , res ) => {
2024-05-29 19:57:45 +02:00
const { userId , type } = req . body ;
2024-05-23 20:49:34 +02:00
try {
2024-09-12 10:46:14 +02:00
if ( type === "activate" ) {
await pool . query ( "UPDATE users SET is_active = TRUE WHERE id = $1" , [
userId ,
] ) ;
const userResult = await pool . query ( "SELECT * FROM users WHERE id = $1" , [
userId ,
] ) ;
2024-06-02 12:39:00 +02:00
if ( userResult . rows . length > 0 ) {
if ( userResult . rows [ 0 ] . email ) {
const mailOptions = {
to : userResult . rows [ 0 ] . email ,
2024-09-12 10:46:14 +02:00
from : "admin@boergmann.it" ,
subject : "Freischaltung" ,
text : ` Hallo ${ userResult . rows [ 0 ] . username } , du wurdest soeben freigeschaltet. ` ,
2024-06-02 12:39:00 +02:00
} ;
transporter . sendMail ( mailOptions , ( error ) => {
if ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error sending email:" , error ) ;
const message = "Error sending Mail:" + error ;
res . render ( "error" , { session : req . session , message } ) ;
2024-06-02 12:39:00 +02:00
}
2024-09-12 10:46:14 +02:00
} ) ;
2024-06-02 12:39:00 +02:00
}
2024-05-29 21:25:27 +02:00
}
2024-09-12 10:46:14 +02:00
} else if ( type === "admin" ) {
await pool . query ( "UPDATE users SET role = $1 WHERE id = $2" , [
"admin" ,
userId ,
] ) ;
} else if ( type === "admint" ) {
await pool . query (
"UPDATE users SET role = $1, admin_temp = $2 WHERE id = $3" ,
[ "admin" , moment ( ) . toDate ( ) , userId ]
) ;
} else if ( type === "delete" ) {
await pool . query ( "DELETE FROM users WHERE id = $1" , [ userId ] ) ;
2024-06-02 12:39:00 +02:00
}
2024-09-12 10:46:14 +02:00
res . redirect ( "/admin" ) ;
2024-05-23 20:49:34 +02:00
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error activating user:" , error ) ;
const message = "Error activating user:" + error ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
}
} ) ;
// Passwort-Zurücksetzung anfordern
2024-09-12 10:46:14 +02:00
app . post ( "/send-password" , async ( req , res ) => {
2024-05-23 20:49:34 +02:00
const { email } = req . body ;
try {
2024-09-12 10:46:14 +02:00
const userResult = await pool . query (
"SELECT * FROM users WHERE email = $1" ,
[ email ]
) ;
2024-05-23 20:49:34 +02:00
if ( userResult . rows . length > 0 ) {
const user = userResult . rows [ 0 ] ;
2024-09-12 10:46:14 +02:00
const token = crypto . randomBytes ( 20 ) . toString ( "hex" ) ;
2024-05-23 20:49:34 +02:00
const resetLink = ` http://tkd.boergmann.it/reset-password/ ${ token } ` ;
2024-09-12 10:46:14 +02:00
await pool . query (
"UPDATE users SET reset_password_token = $1, reset_password_expires = $2 WHERE id = $3" ,
[ token , ( selectedDate = moment ( ) . add ( 1 , "d" ) . toDate ( ) ) , user . id ]
) ;
2024-05-23 20:49:34 +02:00
const mailOptions = {
to : user . email ,
2024-09-12 10:46:14 +02:00
from : "admin@boergmann.it" ,
subject : "Password Reset" ,
text : ` Click the following link to reset your password: ${ resetLink } ` ,
2024-05-23 20:49:34 +02:00
} ;
transporter . sendMail ( mailOptions , ( err ) => {
if ( err ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error sending email:" , err ) ;
const message = "Error sending Mail:" + error ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
} else {
2024-09-12 10:46:14 +02:00
const message = "Password reset link sent" ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
}
} ) ;
} else {
2024-09-12 10:46:14 +02:00
const message = "Email not found" ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
}
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error in forgot-password:" , error ) ;
const message = "Error in forgot-password" ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
}
} ) ;
2024-09-12 10:46:14 +02:00
app . get ( "/forgot-password" , async ( req , res ) => {
res . render ( "forgot-password" , { session : req . session } ) ;
} ) ;
2024-05-23 20:49:34 +02:00
// Passwort zurücksetzen
2024-09-12 10:46:14 +02:00
app . get ( "/reset-password/:token" , async ( req , res ) => {
2024-05-23 20:49:34 +02:00
const { token } = req . params ;
try {
2024-06-17 18:55:38 +02:00
// const userResult = await pool.query('SELECT * FROM users WHERE reset_password_token = $1 AND reset_password_expires > $2', [token, Date.now()]);
2024-09-12 10:46:14 +02:00
const userResult = await pool . query (
"SELECT *, CASE WHEN reset_password_token IS NOT NULL AND (now() - reset_password_expires) > interval '22 hours' THEN 'expired' ELSE 'valid' END AS reset_status FROM users WHERE reset_password_token = $1" ,
[ token ]
) ;
2024-05-23 20:49:34 +02:00
if ( userResult . rows . length > 0 ) {
2024-09-12 10:46:14 +02:00
res . render ( "reset-password" , { session : req . session , token } ) ; // Stelle sicher, dass es eine reset-password.ejs gibt
2024-05-23 20:49:34 +02:00
} else {
2024-09-12 10:46:14 +02:00
const message = "Token ungültig oder abgelaufen" ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
}
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error in reset-password:" , error ) ;
const message = "Error in reset-password" ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
}
} ) ;
2024-09-12 10:46:14 +02:00
app . post ( "/reset-password/:token" , async ( req , res ) => {
2024-05-23 20:49:34 +02:00
const { token } = req . params ;
const { password } = req . body ;
try {
2024-09-12 10:46:14 +02:00
const userResult = await pool . query (
"SELECT *, CASE WHEN reset_password_token IS NOT NULL AND (now() - reset_password_expires) > interval '22 hours' THEN 'expired' ELSE 'valid' END AS reset_status FROM users WHERE reset_password_token = $1" ,
[ token ]
) ;
2024-05-23 20:49:34 +02:00
if ( userResult . rows . length > 0 ) {
const user = userResult . rows [ 0 ] ;
const hashedPassword = await bcrypt . hash ( password , 10 ) ;
2024-09-12 10:46:14 +02:00
await pool . query (
"UPDATE users SET password = $1, reset_password_token = NULL, reset_password_expires = NULL WHERE id = $2" ,
[ hashedPassword , user . id ]
) ;
res . redirect ( "/login" ) ;
2024-05-23 20:49:34 +02:00
} else {
2024-09-12 10:46:14 +02:00
const message = "Token ungültig oder abgelaufen" ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
}
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error in reset-password:" , error ) ;
const message = "Error in reset-password" ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
}
} ) ;
// Profilseite
2024-09-12 10:46:14 +02:00
app . get ( "/profile" , requireAuth , ( req , res ) => {
res . render ( "profile" , { session : req . session } ) ; // Stelle sicher, dass es eine profile.ejs gibt
2024-05-23 20:49:34 +02:00
} ) ;
2024-09-12 10:46:14 +02:00
app . post ( "/profile" , requireAuth , async ( req , res ) => {
2024-05-23 20:49:34 +02:00
const { email , password } = req . body ;
try {
if ( email ) {
2024-09-12 10:46:14 +02:00
await pool . query ( "UPDATE users SET email = $1 WHERE id = $2" , [
email ,
req . session . userId ,
] ) ;
2024-05-23 20:49:34 +02:00
}
if ( password ) {
const hashedPassword = await bcrypt . hash ( password , 10 ) ;
2024-09-12 10:46:14 +02:00
await pool . query ( "UPDATE users SET password = $1 WHERE id = $2" , [
hashedPassword ,
req . session . userId ,
] ) ;
2024-05-23 20:49:34 +02:00
}
2024-09-12 10:46:14 +02:00
res . redirect ( "/profile" ) ;
2024-05-23 20:49:34 +02:00
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error updating profile:" , error ) ;
const message = "Error updating profile:" + error ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
}
} ) ;
2024-09-12 10:46:14 +02:00
app . post ( "/update-training" , requireAuth , async ( req , res ) => {
2024-05-26 18:25:15 +02:00
const { trainingId , type , spielName } = req . body ;
2024-09-12 10:46:14 +02:00
req . session . activeTab = "spiel" ;
2024-05-26 18:25:15 +02:00
let spielId ;
2024-05-23 21:58:22 +02:00
2024-09-12 10:46:14 +02:00
const spiel = await pool . query ( ` SELECT * FROM spiele WHERE name = $ 1 ` , [
spielName ,
] ) ;
2024-06-02 12:39:00 +02:00
2024-05-26 18:25:15 +02:00
if ( spiel . rows . length > 0 ) {
spielId = spiel . rows [ 0 ] . id ;
} else {
2024-09-12 10:46:14 +02:00
const newSpiel = await pool . query (
"INSERT INTO spiele (name) VALUES ($1) RETURNING id" ,
[ spielName ]
) ;
2024-05-26 18:25:15 +02:00
spielId = newSpiel . rows [ 0 ] . id ;
2024-09-12 10:46:14 +02:00
req . session . message = [
( title = "Neues Spiel" ) ,
( body = "Das Spiel ${ spielName } wurde angelegt." ) ,
] ;
2024-06-02 12:39:00 +02:00
}
2024-05-23 21:58:22 +02:00
try {
2024-09-12 10:46:14 +02:00
if ( type === "spiel" ) {
await pool . query ( "UPDATE trainings SET spiel = $1 WHERE id = $2" , [
spielId ,
trainingId ,
] ) ;
} else if ( type === "aufwaermen" ) {
await pool . query ( "UPDATE trainings SET aufwaermen = $1 WHERE id = $2" , [
spielId ,
trainingId ,
] ) ;
2024-05-23 21:58:22 +02:00
}
2024-06-02 12:39:00 +02:00
2024-09-12 10:46:14 +02:00
res . redirect ( "/training" ) ;
2024-05-29 20:55:02 +02:00
} catch ( error ) {
console . error ( error ) ;
2024-09-12 10:46:14 +02:00
const message = "Error:" + error ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 21:58:22 +02:00
}
} ) ;
2024-09-12 10:46:14 +02:00
app . post ( "/update-leader" , requireAuth , async ( req , res ) => {
2024-05-23 20:49:34 +02:00
const { trainingId , type , leaderId } = req . body ;
2024-09-12 10:46:14 +02:00
req . session . activeTab = "spiel" ;
2024-05-23 20:49:34 +02:00
try {
2024-09-12 10:46:14 +02:00
if ( type === "aufwaermleiter" ) {
await pool . query (
"UPDATE trainings SET aufwaermleiter = $1 WHERE id = $2" ,
[ leaderId , trainingId ]
) ;
} else if ( type === "spielleiter" ) {
await pool . query ( "UPDATE trainings SET spielleiter = $1 WHERE id = $2" , [
leaderId ,
trainingId ,
] ) ;
2024-05-23 20:49:34 +02:00
}
2024-09-12 10:46:14 +02:00
res . redirect ( "/training" ) ;
2024-05-29 20:55:02 +02:00
} catch ( error ) {
console . error ( error ) ;
2024-09-12 10:46:14 +02:00
const message = "Error:" + error ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
}
} ) ;
// Admin-Seite
2024-09-12 10:46:14 +02:00
app . get ( "/admin" , requireAuth , requireAdmin , async ( req , res ) => {
const usersResult = await pool . query ( "SELECT * FROM users" ) ;
res . render ( "admin" , { users : usersResult . rows , session : req . session } ) ; // Stelle sicher, dass es eine admin.ejs gibt
2024-05-23 20:49:34 +02:00
} ) ;
2024-09-12 10:46:14 +02:00
app . post ( "/new-member" , requireAuth , requireAdmin , async ( req , res ) => {
2024-09-28 13:56:45 +02:00
var {
from ,
vorname ,
nachname ,
geburt ,
riege ,
adresse ,
probe ,
from ,
training ,
} = req . body ;
2024-07-04 22:45:31 +02:00
var geb = "01.01.2024" ;
2024-09-12 10:46:14 +02:00
const name = vorname + " " + nachname ;
2024-06-02 12:39:00 +02:00
try {
2024-09-12 10:46:14 +02:00
if ( geburt ) {
2024-07-04 22:45:31 +02:00
geb = geburt ;
}
2024-09-12 10:46:14 +02:00
const teilnehmerID = await pool . query (
"INSERT INTO teilnehmende (name, geburtsdatum, adresse, vorname, nachname, probe) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id" ,
[ name , geb , adresse , vorname , nachname , probe ? true : false ]
) ;
2024-09-28 13:56:45 +02:00
if ( from === "admin" ) {
selectedKW = moment ( ) . isoWeek ( ) ;
selectedYear = moment ( ) . year ( ) ;
const trainingresult = await getTraining ( selectedKW , selectedYear ) ;
training = trainingresult . id ;
}
2024-09-28 13:32:37 +02:00
await pool . query (
"INSERT INTO anwesend (fid_teilnehmer, fid_training) VALUES ($1, $2)" ,
[ teilnehmerID . rows [ 0 ] . id , training ]
) ;
2024-09-12 10:46:14 +02:00
log . Info (
"Mitglied " + name + " durch " + req . session . userName + " angelegt"
) ;
2024-06-02 12:39:00 +02:00
putInRiege ( riege , teilnehmerID . rows [ 0 ] . id ) ;
2024-09-28 13:56:45 +02:00
req . session . activeRiege = riege ;
req . session . activeTab = "anwesend" ;
res . redirect ( "/training" ) ;
2024-06-02 12:39:00 +02:00
} catch ( error ) {
2024-09-12 10:46:14 +02:00
const message = "Error:" + error ;
res . render ( "error" , { session : req . session , message } ) ;
2024-06-02 12:39:00 +02:00
}
2024-09-12 10:46:14 +02:00
} ) ;
2024-05-27 20:37:35 +02:00
2024-05-23 20:49:34 +02:00
// Teilnehmer_innen
2024-09-12 10:46:14 +02:00
app . get ( "/training" , requireAuth , async ( req , res ) => {
2024-05-23 20:49:34 +02:00
try {
2024-05-26 18:25:15 +02:00
let dateParam = req . query . date ;
2024-06-01 22:38:25 +02:00
let kwParam = req . query . kw ;
let jahrParam = req . query . jahr ;
2024-05-26 18:25:15 +02:00
let selectedDate ;
2024-06-01 22:38:25 +02:00
let selectedKW ;
let selectetYear ;
2024-06-02 12:39:00 +02:00
2024-09-12 10:46:14 +02:00
if ( kwParam ) {
selectedKW = kwParam ;
} else {
selectedKW = moment ( ) . isoWeek ( ) ;
}
2024-05-26 18:25:15 +02:00
2024-09-12 10:46:14 +02:00
if ( jahrParam ) {
selectedYear = jahrParam ;
} else {
selectedYear = moment ( ) . year ( ) ;
}
2024-05-23 20:49:34 +02:00
2024-09-12 10:46:14 +02:00
const training = await getTraining ( selectedKW , selectedYear ) ;
2024-07-04 22:45:31 +02:00
2024-09-12 10:46:14 +02:00
const anwesendResult = await pool . query (
"SELECT * FROM anwesend WHERE fid_training = $1" ,
[ training . id ]
) ;
2024-06-02 12:39:00 +02:00
anwesend = anwesendResult . rows ;
2024-09-18 15:15:22 +02:00
const anzahl = anwesend . length ;
2024-09-12 10:46:14 +02:00
const trainingsResult = await pool . query (
"SELECT kw, jahr FROM trainings ORDER BY kw ASC"
) ;
const trainingsDates = trainingsResult . rows . map ( ( tr ) => ( {
2024-07-04 22:45:31 +02:00
kw : tr . kw ,
2024-10-01 21:56:09 +02:00
datum : formatDate ( getdayOfWeek ( tr . kw , tr . jahr ) ) ,
2024-05-23 20:49:34 +02:00
} ) ) ;
2024-05-26 18:25:15 +02:00
// Vorheriges Training ermitteln
2024-09-12 10:46:14 +02:00
const previousTrainingResult = await pool . query (
2024-10-10 22:32:24 +02:00
"SELECT * FROM trainings WHERE id < $1 ORDER BY id DESC LIMIT 1" ,
[ training . id ]
2024-09-12 10:46:14 +02:00
) ;
const nextTrainingResult = await pool . query (
2024-10-10 22:32:24 +02:00
"SELECT * FROM trainings WHERE id > $1 ORDER BY id ASC LIMIT 1" ,
[ training . id ]
2024-09-12 10:46:14 +02:00
) ;
const previousTraining =
previousTrainingResult . rows . length > 0
? previousTrainingResult . rows [ 0 ]
: null ;
const nextTraining =
nextTrainingResult . rows . length > 0 ? nextTrainingResult . rows [ 0 ] : null ;
2024-06-02 12:39:00 +02:00
// Abrufen der Riegendaten einschließlich der Teilnehmer und deren Altersberechnung
const result = await pool . query ( `
2024-09-28 12:38:18 +02:00
SELECT r . riegennummer ,
t . id ,
t . name ,
t . vorname ,
t . nachname ,
t . geburtsdatum ,
t . probe ,
r . helfer ,
COUNT ( a . fid _teilnehmer ) AS anwesenheit
FROM riegen r
JOIN teilnehmende t ON r . fremdID _Teilnehmende = t . id
LEFT JOIN anwesend a ON t . id = a . fid _teilnehmer
GROUP BY r . riegennummer , t . id , t . name , t . vorname , t . nachname , t . geburtsdatum , r . helfer
ORDER BY r . riegennummer , t . geburtsdatum ASC ;
2024-05-31 18:42:27 +02:00
` );
2024-06-02 12:39:00 +02:00
// Gruppieren der Riegenteilnehmer nach Riegennummer
const riegen = { } ;
2024-09-12 10:46:14 +02:00
result . rows . forEach ( ( row ) => {
2024-06-02 12:39:00 +02:00
const age = calculateAge ( row . geburtsdatum ) ;
2024-10-10 22:32:24 +02:00
const hasBirthday = isBirthday (
row . geburtsdatum ,
training . datum ,
previousTraining . datum
) ;
2024-06-02 12:39:00 +02:00
const tnAnwesend = getAnwesenheit ( row . id , anwesend ) ;
if ( ! riegen [ row . riegennummer ] ) {
riegen [ row . riegennummer ] = [ ] ;
}
riegen [ row . riegennummer ] . push ( {
id : row . id ,
name : row . name ,
vorname : row . vorname ,
nachname : row . nachname ,
2024-10-10 21:35:50 +02:00
geb : row . geburtsdatum ,
2024-10-10 22:32:24 +02:00
hasBirthday : hasBirthday ,
2024-06-02 12:39:00 +02:00
age : age ,
helfer : row . helfer ,
2024-09-28 12:38:18 +02:00
probe : row . probe ,
anwesenheit : row . anwesenheit ,
2024-09-12 10:46:14 +02:00
anwesend : tnAnwesend ,
2024-09-18 15:15:22 +02:00
anzahl ,
2024-05-31 18:42:27 +02:00
} ) ;
2024-06-02 12:39:00 +02:00
} ) ;
2024-05-23 20:49:34 +02:00
if ( training ) {
2024-10-01 21:56:09 +02:00
training . datum = getdayOfWeek ( training . kw , training . jahr ) ;
2024-05-23 20:49:34 +02:00
}
const aufwaermleiterCandidates = await getCandidatesForAufwaermleiter ( ) ;
const spielleiterCandidates = await getCandidatesForSpielleiter ( ) ;
const spielCandidates = await getAllSpiele ( ) ;
const aufwaermenCandidates = await getAllSpiele ( ) ;
2024-10-10 21:35:50 +02:00
const abteilung = process . env . ABTEILUNG ;
let view ;
if ( abteilung == "KiTu" ) {
view = "trainings_riegen" ;
} else {
view = "trainings" ;
}
res . render ( view , {
2024-05-23 20:49:34 +02:00
training ,
trainingsDates ,
2024-07-04 22:45:31 +02:00
selectedKW : training . kw ,
2024-05-23 20:49:34 +02:00
aufwaermleiterCandidates ,
spielleiterCandidates ,
aufwaermenCandidates , // Übergeben der Kandidaten für Aufwärmleiter
spielCandidates , // Übergeben der Spiele
2024-06-02 12:39:00 +02:00
session : req . session ,
previousTraining ,
2024-05-26 18:25:15 +02:00
nextTraining ,
2024-05-31 18:42:27 +02:00
riegen ,
2024-05-31 21:29:18 +02:00
activeRiege : req . session . activeRiege ,
activeTab : req . session . activeTab ,
2024-09-12 10:46:14 +02:00
moment ,
2024-05-23 20:49:34 +02:00
} ) ;
2024-05-29 20:55:02 +02:00
} catch ( error ) {
console . error ( error ) ;
2024-09-12 10:46:14 +02:00
const message = "Error:" + error ;
res . render ( "error" , { session : req . session , message } ) ;
2024-05-23 20:49:34 +02:00
}
} ) ;
2024-09-12 10:46:14 +02:00
app . get ( "/riege" , requireAuth , async ( req , res ) => {
2024-05-23 20:49:34 +02:00
try {
// Abrufen der Riegendaten einschließlich der Teilnehmer und deren Altersberechnung
const result = await pool . query ( `
2024-09-28 12:38:18 +02:00
SELECT r . riegennummer ,
t . id ,
t . name ,
t . vorname ,
t . nachname ,
t . geburtsdatum ,
t . probe ,
r . helfer ,
COUNT ( a . fid _teilnehmer ) AS anwesenheit
FROM riegen r
JOIN teilnehmende t ON r . fremdID _Teilnehmende = t . id
LEFT JOIN anwesend a ON t . id = a . fid _teilnehmer
GROUP BY r . riegennummer , t . id , t . name , t . vorname , t . nachname , t . geburtsdatum , r . helfer
ORDER BY r . riegennummer , t . geburtsdatum ASC ;
2024-05-23 20:49:34 +02:00
2024-09-28 12:38:18 +02:00
` );
2024-05-23 20:49:34 +02:00
// Gruppieren der Riegenteilnehmer nach Riegennummer
2024-10-10 22:32:24 +02:00
const date = new Date ( ) ;
let previous = new Date ( date ) ;
previous . setDate ( date . getDate ( ) - 7 ) ;
2024-05-23 20:49:34 +02:00
const riegen = { } ;
2024-09-12 10:46:14 +02:00
result . rows . forEach ( ( row ) => {
2024-05-23 20:49:34 +02:00
const age = calculateAge ( row . geburtsdatum ) ;
if ( ! riegen [ row . riegennummer ] ) {
riegen [ row . riegennummer ] = [ ] ;
}
riegen [ row . riegennummer ] . push ( {
id : row . id ,
name : row . name ,
2024-05-29 20:55:02 +02:00
vorname : row . vorname ,
nachname : row . nachname ,
2024-10-10 22:32:24 +02:00
hasBirthday : isBirthday ( row . geburtsdatum , date , previous ) ,
2024-05-23 20:49:34 +02:00
age : age ,
helfer : row . helfer ,
2024-09-28 12:38:18 +02:00
probe : row . probe ,
anwesenheit : row . anwesenheit ,
2024-05-23 20:49:34 +02:00
} ) ;
} ) ;
2024-09-12 10:46:14 +02:00
res . render ( "riegen" , { riegen : riegen , session : req . session } ) ;
2024-05-23 20:49:34 +02:00
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error fetching riegen:" , error ) ;
req . session . message = [ "Error" , error , "error" ] ;
res . render ( "error" , { session : req . session } ) ;
2024-05-23 20:49:34 +02:00
}
} ) ;
2024-09-12 10:46:14 +02:00
app . get ( "/teilnehmer" , requireAuth , requireAdmin , async ( req , res ) => {
2024-05-23 20:49:34 +02:00
try {
2024-09-12 10:46:14 +02:00
const teilnehmendeResult = await pool . query (
2024-09-28 12:38:18 +02:00
"SELECT m.*, COUNT(a.fid_teilnehmer) AS anwesenheit FROM teilnehmende m LEFT JOIN anwesend a ON m.id = a.fid_teilnehmer GROUP BY m.id ORDER BY helfer DESC, vorname ASC"
2024-09-12 10:46:14 +02:00
) ;
2024-10-10 22:32:24 +02:00
const date = new Date ( ) ;
let previous = new Date ( date ) ;
previous . setDate ( date . getDate ( ) - 7 ) ;
2024-09-12 10:46:14 +02:00
const teilnehmende = teilnehmendeResult . rows . map ( ( t ) => ( {
2024-05-23 20:49:34 +02:00
... t ,
2024-09-12 10:46:14 +02:00
age : calculateAge ( t . geburtsdatum ) ,
2024-10-10 22:32:24 +02:00
hasBirthday : isBirthday ( t . geburtsdatum , date , previous ) ,
2024-06-25 20:46:20 +02:00
} ) ) ;
2024-05-23 20:49:34 +02:00
2024-09-12 10:46:14 +02:00
res . render ( "teilnehmer" , { teilnehmende , session : req . session } ) ;
2024-05-29 20:55:02 +02:00
} catch ( error ) {
console . error ( error ) ;
2024-09-12 10:46:14 +02:00
req . session . message = [ "Error" , error , "error" ] ;
res . render ( "error" , { session : req . session } ) ;
2024-05-23 20:49:34 +02:00
}
} ) ;
2024-09-12 10:46:14 +02:00
app . get ( "/mitglied/:id" , requireAuth , requireAdmin , async ( req , res ) => {
2024-05-23 20:49:34 +02:00
const { id } = req . params ;
try {
2024-06-25 21:06:21 +02:00
var riege = 0 ;
2024-09-12 10:46:14 +02:00
const userResult = await pool . query (
"SELECT * FROM teilnehmende WHERE id = $1" ,
[ id ]
) ;
const riegeResult = await pool . query (
"SELECT * FROM riegen WHERE fremdid_teilnehmende = $1" ,
[ id ]
) ;
if ( riegeResult . rows . length > 0 ) {
2024-06-25 21:06:21 +02:00
riege = riegeResult . rows [ 0 ] . riegennummer ;
}
2024-05-31 21:29:18 +02:00
req . session . activeRiege = riege ;
2024-09-12 10:46:14 +02:00
const anwesendResult = await pool . query (
"SELECT * FROM anwesend WHERE fid_teilnehmer = $1" ,
[ id ]
) ;
2024-05-31 21:45:21 +02:00
const anwesend = anwesendResult . rows . length ;
2024-09-12 10:46:14 +02:00
const numberResult = await pool . query (
"SELECT telefonnummern.*, telverbindung.bezeichnung FROM telefonnummern JOIN telverbindung ON telefonnummern.verbindung = telverbindung.id WHERE telefonnummern.fid_teilnehmer = $1" ,
[ id ]
) ;
const numbers = numberResult . rows ;
2024-05-23 20:49:34 +02:00
if ( userResult . rows . length > 0 ) {
2024-09-12 10:46:14 +02:00
const mitglied = userResult . rows . map ( ( t ) => ( {
2024-05-23 20:49:34 +02:00
... t ,
2024-09-12 10:46:14 +02:00
age : calculateAge ( t . geburtsdatum ) ,
} ) ) ;
res . render ( "mitglied" , {
2024-05-23 20:49:34 +02:00
id ,
2024-06-02 12:39:00 +02:00
mitglied : mitglied [ 0 ] ,
numbers ,
riege ,
anwesend ,
2024-09-12 10:46:14 +02:00
session : req . session ,
2024-05-23 20:49:34 +02:00
} ) ;
} else {
2024-09-12 10:46:14 +02:00
req . session . message = [ "Error" , "Mitglied existiert nicht" , "error" ] ;
res . redirect ( "/teilnehmer" ) ;
2024-05-23 20:49:34 +02:00
}
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error in Mitglied:" , error ) ;
req . session . message = [ "Error" , "Mitglied existiert nicht" , "error" ] ;
res . redirect ( "/teilnehmer" ) ;
2024-05-23 20:49:34 +02:00
}
} ) ;
2024-09-12 10:46:14 +02:00
app . post ( "/set-riege" , requireAuth , async ( req , res ) => {
2024-05-27 20:37:35 +02:00
const { riege , id } = req . body ;
putInRiege ( riege , id ) ;
2024-09-12 10:46:14 +02:00
res . redirect ( "/riege" ) ;
} ) ;
2024-05-27 20:37:35 +02:00
2024-09-12 10:46:14 +02:00
app . post ( "/update-mitglied" , requireAdmin , async ( req , res ) => {
2024-09-28 11:55:55 +02:00
const {
type ,
id ,
geburt ,
telid ,
adresse ,
name ,
verbindung ,
nummer ,
vorname ,
nachname ,
probe ,
2024-10-01 21:31:52 +02:00
helfer ,
2024-09-28 11:55:55 +02:00
} = req . body ;
2024-06-02 12:39:00 +02:00
try {
if ( type == "tel" ) {
2024-09-12 10:46:14 +02:00
await pool . query (
"INSERT INTO telefonnummern (fid_teilnehmer, name, verbindung, nummer, stand) VALUES ($1, $2, $3, $4, $5)" ,
[ id , name , verbindung , nummer , moment ( ) . toDate ( ) ]
) ;
2024-06-02 12:39:00 +02:00
} else if ( type == "tel-delete" ) {
2024-09-12 10:46:14 +02:00
await pool . query ( "DELETE FROM telefonnummern WHERE id = $1" , [ telid ] ) ;
2024-06-02 12:39:00 +02:00
} else if ( type == "adresse" ) {
2024-09-12 10:46:14 +02:00
await pool . query (
2024-10-01 21:31:52 +02:00
"UPDATE teilnehmende SET vorname = $1, nachname = $2, geburtsdatum = $3, adresse = $4, probe = $5, helfer = $6 WHERE id = $7" ,
[
vorname ,
nachname ,
geburt ,
adresse ,
probe ? true : false ,
helfer ? true : false ,
id ,
]
2024-09-12 10:46:14 +02:00
) ;
2024-05-27 22:14:35 +02:00
}
2024-06-02 12:39:00 +02:00
2024-09-12 10:46:14 +02:00
res . redirect ( "/mitglied/" + id ) ;
2024-05-29 20:55:02 +02:00
} catch ( error ) {
console . error ( error ) ;
2024-09-12 10:46:14 +02:00
req . session . message = [ "Error" , error , "error" ] ;
res . redirect ( "/mitglied/" + id ) ;
2024-05-27 20:37:35 +02:00
}
} ) ;
2024-05-23 20:49:34 +02:00
// Login und Registrierung anzeigen
2024-09-12 10:46:14 +02:00
app . get ( "/login" , ( req , res ) => {
req . session . message = [ "" , "" , "none" ] ;
res . render ( "login" , { session : req . session } ) ; // Stelle sicher, dass es eine login.ejs gibt
2024-05-23 20:49:34 +02:00
} ) ;
2024-05-28 16:19:59 +02:00
// Registrierung
2024-09-12 10:46:14 +02:00
app . get ( "/register" , ( req , res ) => {
res . render ( "register" , { session : req . session } ) ; // Stelle sicher, dass es eine register.ejs gibt
2024-05-23 20:49:34 +02:00
} ) ;
2024-05-28 16:19:59 +02:00
// Spieleliste
2024-09-12 10:46:14 +02:00
app . get ( "/spiele" , async ( req , res ) => {
2024-05-28 00:17:57 +02:00
try {
2024-09-12 10:46:14 +02:00
const spieleResult = await pool . query (
"SELECT * FROM spiele ORDER BY name ASC;"
) ;
2024-05-28 00:17:57 +02:00
const spiele = spieleResult . rows ;
2024-09-12 10:46:14 +02:00
res . render ( "spiele" , { spiele , session : req . session } ) ;
2024-05-28 00:17:57 +02:00
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error in Mitglied:" , error ) ;
req . session . message = [ "Error" , error , "error" ] ;
res . render ( "spiele" , { spiele , session : req . session } ) ;
2024-05-28 00:17:57 +02:00
}
2024-09-12 10:46:14 +02:00
} ) ;
2024-06-02 12:39:00 +02:00
2024-09-12 10:46:14 +02:00
app . post ( "/delete-spiel" , requireAdmin , async ( req , res ) => {
2024-05-30 18:29:14 +02:00
const { spielId } = req . body ;
2024-09-12 10:46:14 +02:00
await pool . query ( "DELETE FROM spiele WHERE id = $1" , [ spielId ] ) ;
res . redirect ( "/spiele" ) ;
} ) ;
2024-05-30 18:29:14 +02:00
2024-05-28 16:19:59 +02:00
// Gerenderte Seite für gewähltes Spiel
2024-09-12 10:46:14 +02:00
app . get ( "/spiel/:id" , async ( req , res ) => {
2024-05-28 00:17:57 +02:00
const { id } = req . params ;
try {
2024-09-12 10:46:14 +02:00
const spieleResult = await pool . query (
"SELECT * FROM spiele WHERE id = $1" ,
[ id ]
) ;
2024-05-31 21:29:18 +02:00
if ( spieleResult . rows . length > 0 ) {
2024-06-02 12:39:00 +02:00
const spiel = spieleResult . rows [ 0 ] ;
2024-09-12 10:46:14 +02:00
res . render ( "spiel" , { spiel , session : req . session } ) ;
2024-05-31 21:29:18 +02:00
} else {
2024-09-12 10:46:14 +02:00
req . session . message = [ "Error" , "Spiel existiert nicht" , "error" ] ;
res . redirect ( "/spiele" ) ;
2024-05-31 21:29:18 +02:00
}
2024-05-28 00:17:57 +02:00
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error in Spiele:" , error ) ;
req . session . message = [ "Error" , "Spiel existiert nicht" , "error" ] ;
res . redirect ( "/spiele" ) ;
2024-05-28 00:17:57 +02:00
}
2024-09-12 10:46:14 +02:00
} ) ;
2024-05-28 00:17:57 +02:00
2024-05-28 16:19:59 +02:00
// Postseite für Änderungen
2024-09-12 10:46:14 +02:00
app . post ( "/edit-spiel" , requireAuth , async ( req , res ) => {
2024-06-02 12:39:00 +02:00
const { material , dauer , regeln , variationen , type , id } = req . body ;
try {
2024-09-12 10:46:14 +02:00
const queryResult = await pool . query (
"UPDATE spiele set material = $1, regeln = $2, dauer = $3, variationen = $4, type = $5 Where id = $6 " ,
[ material , regeln , dauer , variationen , type , id ]
) ;
req . session . message = [ "Erfolg" , "Das Spiel wurde gespeichert" , "success" ] ;
res . redirect ( "/spiel/" + id ) ;
2024-06-02 12:39:00 +02:00
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error in edit Spiel:" , error ) ;
req . session . message = [ "Error" , error , "error" ] ;
res . redirect ( "/spiel/" + id ) ;
2024-06-02 12:39:00 +02:00
}
2024-09-12 10:46:14 +02:00
} ) ;
2024-05-28 00:17:57 +02:00
2024-05-28 16:19:59 +02:00
// Startseite
2024-09-12 10:46:14 +02:00
app . get ( "/" , ( req , res ) => {
req . session . message = [ "" , "" , "none" ] ;
res . render ( "index" , { session : req . session } ) ;
2024-05-28 16:19:59 +02:00
} ) ;
2024-05-30 19:24:40 +02:00
// Changelog
2024-09-12 10:46:14 +02:00
app . get ( "/changelog" , async ( req , res ) => {
2024-05-30 19:24:40 +02:00
try {
2024-09-12 10:46:14 +02:00
const changeResult = await pool . query (
"SELECT * FROM changelog ORDER BY datetime DESC;"
) ;
2024-05-30 19:24:40 +02:00
const changes = changeResult . rows ;
2024-09-12 10:46:14 +02:00
req . session . message = [ "Erfolg" , "Log gespeichert" , "success" ] ;
res . render ( "changelog" , { changes , session : req . session } ) ;
2024-05-30 19:24:40 +02:00
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error:" , error ) ;
req . session . message = [ "Error" , error , "error" ] ;
res . redirect ( "/changelog" ) ;
2024-05-30 19:24:40 +02:00
}
2024-09-12 10:46:14 +02:00
} ) ;
2024-05-30 19:24:40 +02:00
2024-09-12 10:46:14 +02:00
app . post ( "/changelog" , requireAdmin , async ( req , res ) => {
2024-05-30 19:24:40 +02:00
const { title , body } = req . body ;
try {
2024-09-12 10:46:14 +02:00
await pool . query ( "INSERT INTO changelog (title, body) VALUES ($1, $2);" , [
title ,
body ,
] ) ;
const changeResult = await pool . query (
"SELECT * FROM changelog ORDER BY datetime DESC;"
) ;
2024-05-30 19:24:40 +02:00
const changes = changeResult . rows ;
2024-09-12 10:46:14 +02:00
res . render ( "changelog" , { changes , session : req . session } ) ;
2024-05-30 19:24:40 +02:00
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error:" , error ) ;
req . session . message = [ "Error" , error , "error" ] ;
res . render ( "changelog" , { changes , session : req . session } ) ;
2024-06-02 12:39:00 +02:00
}
2024-09-12 10:46:14 +02:00
} ) ;
2024-05-30 19:24:40 +02:00
2024-09-12 10:46:14 +02:00
app . post ( "/anwesend" , requireAuth , async ( req , res ) => {
2024-10-01 21:31:52 +02:00
var { anw , inriege , trainingId , riege } = req . body ;
2024-09-12 10:46:14 +02:00
req . session . activeTab = "anwesend" ;
2024-06-02 12:39:00 +02:00
try {
2024-09-12 10:46:14 +02:00
for ( const mitgliedId of inriege ) {
const Idresult = await pool . query (
"SELECT *From anwesend WHERE fid_teilnehmer = $1 AND fid_training=$2" ,
[ mitgliedId , trainingId ]
) ;
2024-06-11 17:25:32 +02:00
if ( Idresult . rows . length > 0 ) {
2024-09-12 10:46:14 +02:00
if ( ! anw . includes ( mitgliedId ) ) {
await pool . query (
"Delete FROM anwesend WHERE fid_teilnehmer = $1 AND fid_training=$2" ,
[ mitgliedId , trainingId ]
) ;
2024-06-11 17:25:32 +02:00
}
}
}
2024-10-01 21:31:52 +02:00
if ( ! Array . isArray ( anw ) ) {
anw = [ anw ] ;
}
2024-06-02 12:39:00 +02:00
for ( const teilnehmer of anw ) {
2024-09-12 10:46:14 +02:00
const Tnresult = await pool . query (
"SELECT *From anwesend WHERE fid_teilnehmer = $1 AND fid_training=$2" ,
[ teilnehmer , trainingId ]
) ;
2024-06-11 17:25:32 +02:00
if ( Tnresult . rows . length === 0 ) {
2024-09-12 10:46:14 +02:00
await pool . query (
"INSERT INTO anwesend (fid_teilnehmer, fid_training) VALUES ($1, $2)" ,
[ teilnehmer , trainingId ]
) ;
2024-06-02 12:39:00 +02:00
}
2024-06-11 17:25:32 +02:00
}
2024-06-02 12:39:00 +02:00
req . session . activeRiege = riege ;
2024-09-12 10:46:14 +02:00
req . session . activeTab = "anwesend" ;
req . session . message = [
( title = "Erfolg" ) ,
( body = "Die Anwesenheit wurde gespeichert" ) ,
( type = "success" ) ,
] ;
res . redirect ( "/training" ) ;
2024-06-02 12:39:00 +02:00
} catch ( error ) {
2024-09-12 10:46:14 +02:00
console . error ( "Error:" , error ) ;
req . session . message = [ "Error" , error , "error" ] ;
res . redirect ( "/training" ) ;
2024-06-02 12:39:00 +02:00
}
2024-09-12 10:46:14 +02:00
} ) ;
2024-05-31 18:42:27 +02:00
2024-09-28 13:56:45 +02:00
app . post ( "/deleteMember" , requireAuth , async ( req , res ) => {
const { id } = req . body ;
2024-09-28 13:32:37 +02:00
try {
2024-09-28 13:56:45 +02:00
await pool . query ( "DELETE from teilnehmende WHERE id = $1" , [ id ] ) ;
2024-09-28 13:32:37 +02:00
} catch ( error ) {
2024-09-28 13:56:45 +02:00
console . error ( "Error:" , error ) ;
2024-09-28 13:32:37 +02:00
}
2024-09-28 13:56:45 +02:00
res . redirect ( "/teilnehmer" ) ;
} ) ;
2024-09-28 13:32:37 +02:00
2024-09-28 15:02:25 +02:00
app . get ( "/feature" , requireAuth , async ( req , res ) => {
try {
const featureResult = await pool . query (
"SELECT * FROM features ORDER BY datetime DESC;"
) ;
const features = featureResult . rows ;
res . render ( "feature" , { features , session : req . session } ) ;
} catch ( error ) {
console . error ( "Error:" , error ) ;
req . session . message = [ "Error" , error , "error" ] ;
res . redirect ( "/feature" ) ;
}
} ) ;
app . post ( "/feature" , requireAdmin , async ( req , res ) => {
const { title , body , type , urgency , user } = req . body ;
const userResult = await pool . query (
"SELECT id FROM users WHERE username = $1" ,
[ user ]
) ;
try {
await pool . query (
"INSERT INTO features (title, body, type, urgency, fid_user) VALUES ($1, $2, $3, $4, $5);" ,
[ title , body , type , urgency , userResult . rows [ 0 ] . id ]
) ;
const featureResult = await pool . query (
"SELECT * FROM features ORDER BY datetime DESC;"
) ;
const features = featureResult . rows ;
req . session . message = [ "Erfolg" , "Feature-request gespeichert" , "success" ] ;
res . render ( "feature" , { features , session : req . session } ) ;
} catch ( error ) {
console . error ( "Error:" , error ) ;
req . session . message = [ "Error" , error , "error" ] ;
res . render ( "feature" , { features , session : req . session } ) ;
}
} ) ;
2024-09-12 10:46:14 +02:00
const server = app . listen ( port , "0.0.0.0" , ( ) => {
2024-06-02 12:39:00 +02:00
log . Info ( ` Server is running on ${ process . env . HOST } : ${ port } / ` ) ;
2024-09-09 16:59:14 +02:00
} ) ;