diff --git a/qrCodes/convertToJSON.js b/qrCodes/convertToJSON.js new file mode 100644 index 0000000..fc3869f --- /dev/null +++ b/qrCodes/convertToJSON.js @@ -0,0 +1,27 @@ +import fs from 'fs' +import {parse} from 'csv-parse' + +const csvFilePath = './tokens.csv'; +const jsonFilePath = './tokens.json'; + +fs.readFile(csvFilePath, 'utf8', (err, data) => { + if (err) { + console.error('Error reading file:', err); + return; + } + + parse(data, { columns: true, skip_empty_lines: true }, (err, output) => { + if (err) { + console.error('Error parsing CSV:', err); + return; + } + + fs.writeFile(jsonFilePath, JSON.stringify(output, null, 2), (err) => { + if (err) { + console.error('Error writing JSON file:', err); + } else { + console.log(`JSON successfully written to ${jsonFilePath}`); + } + }); + }); +}); \ No newline at end of file diff --git a/qrCodes/package.json b/qrCodes/package.json index d01bf7a..15566b1 100644 --- a/qrCodes/package.json +++ b/qrCodes/package.json @@ -1,6 +1,7 @@ { "type": "module", "dependencies": { + "csv-parse": "^6.1.0", "csv-writer": "^1.6.0", "qrcode": "^1.5.4", "uuid": "^13.0.0" diff --git a/server/db/db.js b/server/db/db.js index 495b76b..d433a0f 100644 --- a/server/db/db.js +++ b/server/db/db.js @@ -1,6 +1,20 @@ import QuillDB from "../_/quilldb.js" +import fs from 'fs/promises' +import path from 'path' export default class Database extends QuillDB { + tokens; + + constructor() { + super() + this.loadTokens() + } + + async loadTokens() { + const tokenData = await fs.readFile(path.join(process.cwd(), 'db/tokens.json'), 'utf8'); + let tokenJSON = JSON.parse(tokenData); + this.tokens = tokenJSON + } get = { user: (id) => { @@ -15,6 +29,9 @@ export default class Database extends QuillDB { } return null; }, + token: (id) => { + return this.tokens[id] + } } generateUserID() { diff --git a/server/index.js b/server/index.js index ed81526..4378381 100644 --- a/server/index.js +++ b/server/index.js @@ -27,11 +27,31 @@ class Server { // router.post('/api/location', handlers.updateLocation) router.post('/login', this.auth.login) router.get('/signout', this.auth.logout) + router.get('/signup', this.verifyToken, this.get) + router.post('/signup', this.verifyToken, this.newUserSubmission) router.get('/db/images/*', this.getUserImage) router.get('/*', this.get) return router } + verifyToken = (req, res, next) => { + const { token } = req.query; + if (!token) { + return res.status(400).json({ error: 'Token is required' }); + } + let fromDB = this.db.get.token(token) + if (!fromDB) { + return res.status(403).json({ error: 'Invalid or expired token' }); + } else if(fromDB.used) { + return res.status(403).json({ error: 'Invalid or expired token' }); + } + next() + } + + newUserSubmission = (req, res) => { + return res.status(400).json({ error: 'Haven\t finished this bruh' }); + } + authMiddleware = (req, res, next) => { const authHeader = req.headers.authorization; if (!authHeader) { @@ -67,37 +87,32 @@ class Server { } get = async (req, res) => { - if(!this.auth.isLoggedInUser(req, res)) { - console.log("Not logged in") - let url = req.url - if(!url.includes(".")) { // Page request - if(url === "/") { - url = "/index.html" - } else { - url = path.join("/pages", url) + ".html" - } + let url = req.url - let filePath = path.join(this.UIPath, "public", url); - res.sendFile(filePath, (err) => { - if (err) { - console.log("File not found, sending fallback:", filePath); - res.redirect("/"); - } - }); - } else { // File Request - let filePath; - if(url.startsWith("/_")) { - filePath = path.join(this.UIPath, url); - } else { - filePath = path.join(this.UIPath, "public", url); + let publicPage = () => { + url = "/index.html" + let filePath = path.join(this.UIPath, "public", url); + res.sendFile(filePath, (err) => { + if (err) { + console.log("File not found, sending fallback:", filePath); + res.redirect("/"); } - - res.sendFile(filePath); + }); + } + + let publicFile = () => { + let filePath; + if(url.startsWith("/_")) { + filePath = path.join(this.UIPath, url); + } else { + filePath = path.join(this.UIPath, "public", url); } - } else { - let url = req.url + res.sendFile(filePath); + } + + let privateSite = () => { let filePath; if(url.startsWith("/_")) { filePath = path.join(this.UIPath, url); @@ -109,6 +124,16 @@ class Server { res.sendFile(filePath); } + + if(!this.auth.isLoggedInUser(req, res)) { + if(!url.includes(".")) { + publicPage() + } else { + publicFile() + } + } else { + privateSite() + } } logRequest(req, res, next) { @@ -158,7 +183,7 @@ class Server { const PORT = 3003; server.listen(PORT, () => { console.log("\n") - console.log(chalk.yellow("**************America****************")) + console.log(chalk.yellow("*************** Hyperia ***************")) console.log(chalk.yellowBright(`Server is running on port ${PORT}: http://localhost`)); console.log(chalk.yellow("***************************************")) console.log("\n") diff --git a/ui/_/code/quill.js b/ui/_/code/quill.js index 66118c6..6232ebd 100644 --- a/ui/_/code/quill.js +++ b/ui/_/code/quill.js @@ -283,6 +283,8 @@ function extendHTMLElementWithStyleSetters() { case "marginBottom": case "marginRight": + case "textUnderlineOffset": + return "unit-number" default: diff --git a/ui/public/components/JoinForm.js b/ui/public/components/JoinForm.js new file mode 100644 index 0000000..7e30516 --- /dev/null +++ b/ui/public/components/JoinForm.js @@ -0,0 +1,91 @@ +css(` + joinform- input::placeholder { + color: var(--accent) + } +`) + +class JoinForm extends Shadow { + + inputStyles(el) { + return el + .border("1px solid var(--accent)") + } + + render() { + ZStack(() => { + form(() => { + + VStack(() => { + + HStack(() => { + + VStack(() => { + input("First Name") + .attr({name: "firstname", type: "name"}) + .styles(this.inputStyles) + + input("Last Name") + .attr({name: "lastname", type: "name"}) + .styles(this.inputStyles) + + input("Email") + .attr({name: "email", type: "email"}) + .styles(this.inputStyles) + + input("Password") + .attr({name: "password", type: "password"}) + .styles(this.inputStyles) + + input("Confirm Password") + .attr({name: "password", type: "password"}) + .styles(this.inputStyles) + }) + .width(50, "%") + .gap(1, em) + + VStack(() => { + input("Street Address") + .attr({ name: "address1", type: "text", autocomplete: "address-line1" }) + .styles(this.inputStyles) + + input("Apt, Suite, Unit (optional)") + .attr({ name: "address2", type: "text", autocomplete: "address-line2" }) + .styles(this.inputStyles) + + input("City") + .attr({ name: "city", type: "text", autocomplete: "address-level2" }) + .styles(this.inputStyles) + + input("State") + .attr({ name: "state", type: "text", autocomplete: "address-level1" }) + .styles(this.inputStyles) + + input("ZIP Code") + .attr({ name: "zip", type: "text", autocomplete: "postal-code" }) + .styles(this.inputStyles) + + input("Country") + .attr({ name: "country", type: "text", autocomplete: "country-name" }) + .styles(this.inputStyles) + }) + .width(50, "%") + .gap(1, em) + + }) + .gap(2, em) + + button("Submit") + }) + .gap(2, em) + + console.log(window.location.pathname) + }) + .attr({action: window.location.pathname + window.location.search, method: "POST"}) + .x(50, vw).y(53, vh) + .width(60, vw) + .center() + }) + } +} + +register(JoinForm) \ No newline at end of file diff --git a/ui/public/index.html b/ui/public/index.html index d836fa3..28a9064 100644 --- a/ui/public/index.html +++ b/ui/public/index.html @@ -15,14 +15,6 @@ - diff --git a/ui/public/pages/Home.js b/ui/public/pages/Home.js index 2c0e884..37ec179 100644 --- a/ui/public/pages/Home.js +++ b/ui/public/pages/Home.js @@ -1,4 +1,5 @@ import "../components/NavBar.js" +import "../components/JoinForm.js" import "./Why.js" import "./Events.js" import "./Join.js" @@ -51,6 +52,11 @@ class Home extends Shadow { case "/signin": SignIn() break; + + default: + if(window.location.pathname.startsWith("/signup")) { + JoinForm() + } } })