From 8a3ee3e18c4ff79406df69829b492880a949b295 Mon Sep 17 00:00:00 2001 From: Teppy Date: Mon, 3 Mar 2025 23:53:35 -0500 Subject: [PATCH] Changes --- foftickets.js | 56 +++++++++++++++++++++++++++---------------- views/editcamp.ejs | 2 +- views/manytickets.ejs | 10 ++++++-- views/oneticket.ejs | 2 ++ views/settings.ejs | 2 +- 5 files changed, 47 insertions(+), 25 deletions(-) diff --git a/foftickets.js b/foftickets.js index 38bcb02..76c0957 100644 --- a/foftickets.js +++ b/foftickets.js @@ -51,19 +51,20 @@ const QRSalt ="!SaltyMagic5392370662"; // + Turn ticket use on/off from Settings (Admin) // + Turn email on/off from Settings (Admin) // + Magic-link Login System -// Convert all the routes to use common.(user,superuser,etc) -// Display messages for all GET routes? -// Setting to deactivate transfers globally -// Option to "Email me my QR Code" -// Mass-import of individual tickets +// + Convert all the routes to use common.(user,superuser,etc) +// + Display messages for all GET routes? +// + Setting to deactivate transfers globally +// + Mass-import of individual tickets // + Cookie based QR code functionality // + Create Account (User) // + Change Password (User) -// Change most POST routes to end in redirect instead of render. -// Deactivate individual magic links (User) +// + Change most POST routes to end in redirect instead of render. // Deactivate individual magic links (Admin) // See how much each camp/ticket has paid (Admin) // Purchase individual open camping tickets +// Maybe: +// Deactivate individual magic links (User) +// Option to "Email me my QR Code" // // ToDo, Later // + Use a templating engine @@ -135,10 +136,11 @@ function MagicLinkValid(email,hash) { app.use((req, res, next) => { res.locals.commonData = { - username: req.username, // Attach user info if available + username: req.username, // Attach user info if available superuser: req.superuser, - error: req.session && req.session.error || null, // Flash error messages - message: req.session && req.session.message || null, // Flash success messages + settings: settings, + error: req.session && req.session.error || null, // Flash error messages + message: req.session && req.session.message || null, // Flash success messages }; // Clear session-based flash messages after use @@ -172,7 +174,7 @@ app.use((req, res, next) => { let users={}; let tickets={}; let camps={}; -let settings={ "enable-transfers":true }; +let settings={ "enable-transfer":true }; function InitDatabase() { for (const key in users ) delete users[key]; @@ -314,7 +316,7 @@ app.post('/moretickets', requireSuperUser, (req,res) => { app.get('/manytickets', requireLogin, (req,res) => { let username=req.session.username; - const edit={ username:req.session.username, superuser:req.session.superuser, tickets: {}, cantransfer:settings["enable-transfer"] }; + const edit={ username:req.session.username, superuser:req.session.superuser, tickets: {}, settings:settings }; for (const t in tickets) if (tickets[t].owner==username && tickets[t].status=="i") { edit.tickets[t]={}; edit.tickets[t].offered=tickets[t].offered; @@ -329,7 +331,8 @@ app.get('/mytickets',requireLogin, async (req,res)=> { let claimed=0; let owned=0; let theticket=""; - const edit={ username:req.session.username, superuser:req.session.superuser, tickets: {}, cantransfer:settings["enable-transfer"] }; + const edit={ username:req.session.username, superuser:req.session.superuser, tickets: {}, settings:settings }; + console.log(edit); for (const t in tickets) { if (tickets[t].status=="i" && tickets[t].offered==username) { claimed++; tickets[t].owner=username; tickets[t].offered=""; } // LOG if (tickets[t].status=="i" && tickets[t].owner==username) { @@ -351,9 +354,11 @@ app.get('/mytickets',requireLogin, async (req,res)=> { const hash=hash1.digest("base64").slice(0,6); const useurl=MainURL+'/useticket?t='+theticket+'&h='+hashQR(theticket,username); const dataURL=await QRCode.toDataURL(useurl); - return res.render("oneticket",{ username:username, superuser:req.session.superuser, message:message, magiclink:GetMagicLink(username), - ticket:theticket, offered:tickets[theticket].offered, paid:tickets[theticket].paid, qrcode:dataURL, useurl:useurl, - cantransfer:settings["enable-transfer"] }); + const data={ username:username, superuser:req.session.superuser, message:message, magiclink:GetMagicLink(username), + ticket:theticket, offered:tickets[theticket].offered, paid:tickets[theticket].paid, qrcode:dataURL, useurl:useurl, + settings: settings } + console.log(data); + return res.render("oneticket",data); } else return res.render("manytickets",edit); }); @@ -373,7 +378,7 @@ app.get("/oneticket",requireLogin, async (req,res) => { const dataURL=await QRCode.toDataURL(MainURL+'/useticket?t='+ticket+'&h='+hashQR(ticket,username)); return res.render("oneticket", { username:username, superuser:req.session.superuser, message:message, magiclink:GetMagicLink(username), ticket:ticket, offered:tickets[ticket].offered, paid:tickets[ticket].paid, qrcode:dataURL, useurl:useurl, - cantransfer:settings["enable-transfer"] }); + settings:settings }); }); @@ -403,9 +408,10 @@ app.post("/changestatus", requireSuperUser, (req,res) => { res.json({ message: 'Status received', status: req.body.status }); }) -// Need a SuperUser version of this app.post("/updateoffered2", requireLogin, (req,res) => { - if (!req.cantransfer) return res.render("error",{ message: "Transfer functionality has been disabled by the admin." }); + if (!settings["enable-transfer"]) { + return res.render("error",{ message: "Transfer functionality has been disabled by the admin." }); + } const changes={}; for (ticket in req.body) if (tickets[ticket] && tickets[ticket].owner==req.session.username && req.body[ticket]!=tickets[ticket].offered) { if (!(req.body[ticket] in changes)) changes[req.body[ticket]]=0; @@ -634,8 +640,16 @@ app.post('/importfb',requireSuperUser,upload.single("file"),(req,res) => { req.session.error="The CVS file did not parse correctly. Check console."; return res.redirect("/settings"); } - console.log("Records:",records); - req.session.message="Imported Frostburn-style records."; + let count=0; + for (const item of records) { + if (!camps[item.camp]) camps[item.camp]={ leader:"", lastid:0 }; + camps[item.camp].lastid++; + const ticket=item.camp+"-"+camps[item.camp].lastid; + tickets[ticket]={ owner:"", offered: item.email, paid:0.00, status:"i" }; + console.log("Offered ",ticket," to ",item.email); + count++; + } + req.session.message="Imported "+count+" Frostburn-style records."; return res.redirect("/settings"); }); }); diff --git a/views/editcamp.ejs b/views/editcamp.ejs index 85f47ba..1d365bf 100644 --- a/views/editcamp.ejs +++ b/views/editcamp.ejs @@ -15,7 +15,7 @@
Server Ready
- Camp Namex: <%=campname%>
+ Camp Name: <%=campname%>
Camp Leader: <%=leader%> diff --git a/views/manytickets.ejs b/views/manytickets.ejs index e333e33..002c326 100644 --- a/views/manytickets.ejs +++ b/views/manytickets.ejs @@ -26,7 +26,11 @@ <% for (const t in tickets) { %> - + <% if (settings["enable-transfer"]) { %> + + <% } else { %> + + <% } %> @@ -34,7 +38,9 @@
<%=t%><%=tickets[t].offered%><%=tickets[t].paid>0 ? (tickets[t].paid/100).toFixed(2) : "No"%>
- + <% if (settings["enable-transfer"]) { %> + + <% } %>