diff --git a/.gitignore b/.gitignore index 07e6e47..2b7d8ef 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /node_modules +/login diff --git a/index.js b/index.js index c79ee2a..1e0a283 100644 --- a/index.js +++ b/index.js @@ -1,20 +1,61 @@ import express from "express"; +import cookieParser from "cookie-parser"; +import bodyParser from "body-parser"; +import {getUser, loginUser} from "./login.js"; const server = express(); server.set('view engine', 'ejs') server.use(express.static("static")) +server.use(cookieParser()) +server.use(bodyParser.urlencoded({ extended: true })) server.use(handle) -function handle_other(req, res) {} +const sbstart = '
' +const sbdashboard = 'Dashboard' +const logoutBtn = 'Log out' +const sbend = "
" +const indexSidebar = sbstart + sbdashboard + sbend -function handle(req, res) { +async function handle_other(req, res) { + if(req.method === "POST" && req.path === "/login" && req.body.username && req.body.password) { + let user = await loginUser(req.body.username, req.body.password) + if(user) { + res.cookie("token", user.token).redirect("/dashboard") + } + else { + res.status(403).render("login", {sidebar: indexSidebar, error: "Wrong username or password!"}) + } + return + } + res.sendStatus(400) +} + +async function handle(req, res) { if(req.method !== "GET") return handle_other(req, res); console.log(`received request of ${req.path}`) if(req.path == "/") { - res.render("index") + res.render("index", {sidebar: indexSidebar}) + return + } + if(req.path == "/dashboard") { + let user = await getUser(req.cookies.token) + if(user) { + res.render("dashboard", {sidebar: sbstart + sbdashboard + logoutBtn + sbend, user}) + } + else { + res.status(401).redirect("/login") + } + return; + } + if(req.path === "/login") { + res.render("login", {sidebar: indexSidebar, error: null}) + return + } + if(req.path === "/logout") { + res.clearCookie("token").redirect("/") return } res.status(404).render("404") diff --git a/login.js b/login.js new file mode 100644 index 0000000..10e9fc7 --- /dev/null +++ b/login.js @@ -0,0 +1,10 @@ + +import fs from "fs/promises" +import fetch from "node-fetch" + +export async function getUser(token) { +} + +export async function loginUser(uname, pass) { + +} diff --git a/package-lock.json b/package-lock.json index 024a445..685cdb4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,11 @@ "version": "1.0.0", "license": "UNLICENSED", "dependencies": { + "body-parser": "^1.20.2", + "cookie-parser": "^1.4.6", "ejs": "^3.1.10", - "express": "^4.19.2" + "express": "^4.19.2", + "node-fetch": "^3.3.2" }, "devDependencies": { "@types/express": "^4.17.21" @@ -302,12 +305,43 @@ "node": ">= 0.6" } }, + "node_modules/cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "license": "MIT", + "dependencies": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/cookie-parser/node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -461,6 +495,29 @@ "node": ">= 0.10.0" } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -509,6 +566,18 @@ "node": ">= 0.8" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -769,6 +838,43 @@ "node": ">= 0.6" } }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -1045,6 +1151,15 @@ "engines": { "node": ">= 0.8" } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } } } } diff --git a/package.json b/package.json index a80f489..6e5ef52 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,11 @@ "license": "UNLICENSED", "description": "", "dependencies": { + "body-parser": "^1.20.2", + "cookie-parser": "^1.4.6", "ejs": "^3.1.10", - "express": "^4.19.2" + "express": "^4.19.2", + "node-fetch": "^3.3.2" }, "devDependencies": { "@types/express": "^4.17.21" diff --git a/static/style.css b/static/style.css index e5ca76a..7c5028e 100644 --- a/static/style.css +++ b/static/style.css @@ -1,7 +1,7 @@ html { margin: 0; - background-color: #303040; - color: #00cc00; + background-color: #502060; + color: #00cccc; font-family: Monocraft monospace; } body { @@ -12,5 +12,55 @@ body { margin-bottom: 20vh; } a { - color: #00ff00; + color: #00ffff; +} + +a.btn { + background-color: #603060; + display: block; + width: fit-content; + min-width: 10em; + padding: 10px; + margin: 0; + text-decoration: none; + text-align: center; + transition: 0.2s; +} +a.btn:hover { + background-color: #605070; +} + +form { + background-color: #425; + padding: 10px; + margin: 20px auto 20px auto; + width: fit-content; +} +input { + height: 2em; + margin-bottom: 0.5em; + border: 0; + background-color: #000; + color: #f0f; +} +button { + background-color: #a0a; + color: #000; + border: 0; + width: 100%; + height: 2em; + cursor: pointer; + transition: 0.2s; +} +button:hover { + background-color: #909; +} + +div.error { + background-color: #913; + color: #fff; + display: block; + width: calc(100% - 60px); + padding: 15px; + margin: 15px; } diff --git a/views/index.ejs b/views/index.ejs index fb6b83b..34448e0 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -10,5 +10,11 @@

BaseBand aims to be an easy-to-use yet very extensively configurable client for anarchy servers. +
+
+ Features + + <%- sidebar %> + diff --git a/views/login.ejs b/views/login.ejs new file mode 100644 index 0000000..f70fd6e --- /dev/null +++ b/views/login.ejs @@ -0,0 +1,28 @@ + + + + BaseBand - Login + + + +

Login

+ + <% if(error) { %> +
<%= error %>
+ <% } %> + + Please log in with your BaseBand account to continue. + +
+
+
+ +
+ + You may reset your password on Discord. + + <%- sidebar %> + + + +