diff --git a/main.js b/main.js index ece57c4..6a51788 100644 --- a/main.js +++ b/main.js @@ -4,6 +4,9 @@ const path = require('path'); const mysql = require("mysql2/promise"); const config = require("./config/db.config.js"); const session = require('express-session'); +const bcrypt = require('bcrypt'); +const signupRouter = require('./signup'); // Adjust path as necessary + const PORT = process.env.PORT || 8080; // Default port is 5000 @@ -30,6 +33,9 @@ const pool = mysql.createPool({ }); + + + const app = express(); app.set('view engine', 'ejs'); @@ -44,25 +50,17 @@ app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(express.static(path.join(__dirname, 'static'))); - - -app.get('/x', function (request, response) { - if (request.session.loggedin) { - // Output username - // response.send('Welcome back, ' + request.session.username + '!'); - console.log(request.session.username, 'open main page'); - // Render home page with username - response.render('home', { username: request.session.username }); - } else { - // response.send('Please login to view this page!'); - response.redirect('/login'); - } -}); +// Use the signup router +app.use(signupRouter); + app.get('/login', function (request, response) { /// Render login template with any message from query parameters console.log('Message:', request.query.message); // Log the message - response.render('login', { message: request.query.message || '' }); + response.render('login', { + message: request.query.message || '' , + enableSignup: config.enableSignup + }); }); @@ -75,21 +73,38 @@ app.post('/auth', async function (request, response) { try { // Get a connection from the pool const connection = await pool.getConnection(); + // const [rows] = await connection.execute( + // 'SELECT * FROM accounts WHERE (username = ? OR email = ?) AND password = ?', + // [login, login] + // ); + const [rows] = await connection.execute( - 'SELECT * FROM accounts WHERE (username = ? OR email = ?) AND password = ?', - [login, login, password] + 'SELECT * FROM accounts WHERE username = ? OR email = ?', + [login, login] ); + // Release the connection back to the pool connection.release(); - + // If the account exists if (rows.length > 0) { - // Authenticate the user - request.session.loggedin = true; - request.session.username = rows[0].username; - request.session.avatar = rows[0].avatar; - // Redirect to home page - response.redirect('/'); + + + const user = rows[0]; + // console.log(user); + + // Compare provided password with stored hashed password + const match = await bcrypt.compare(password, user.password); + + if (match) { + request.session.loggedin = true; + request.session.username = user.username; + request.session.avatar = user.avatar; + + response.redirect('/'); + } else { + response.redirect('/login?message=not match Username and/or Password!'); + } } else { response.redirect('/login?message=Incorrect Username and/or Password!'); } @@ -98,12 +113,10 @@ app.post('/auth', async function (request, response) { response.status(500).send('An error occurred while processing your request.'); } } else { - // response.send('Please enter Username and Password!'); response.redirect('/login?message=Please enter Username and Password!'); } }); - // http://localhost:3000/home app.get('/', function (request, response) { // If the user is loggedin @@ -138,6 +151,36 @@ app.get('/logout', function (request, response) { }); }); +// Serve the signup form +app.get('/signup', function (request, response) { + +// Check if signup is enabled +if (!config.enableSignup) { + return response.status(403).send(` + + + + + + Signup Disabled + + + +

Signup is currently disabled.

+

Please contact the adminstrator for assistance.

+ + + + `); +} + + response.render('signup', { message: request.query.message || '' }); +}); + app.listen(PORT, () => { console.info(`Listening on http://0.0.0.0:${PORT}/`); diff --git a/signup.js b/signup.js new file mode 100644 index 0000000..b8217f5 --- /dev/null +++ b/signup.js @@ -0,0 +1,110 @@ +const express = require('express'); +const bcrypt = require('bcrypt'); +const mysql = require('mysql2/promise'); +const config = require("./config/db.config.js"); +const router = express.Router(); +const multer = require('multer'); + + +const storage = multer.memoryStorage(); // Store files in memory +const upload = multer({ + storage: storage, + limits: { fileSize: 64 * 1024 } // Limit to 64 KB +}); + +// Create a connection pool +const pool = mysql.createPool({ + host: config.host, + user: config.user, + password: config.password, + database: config.database, + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0 + }); + +// Default avatar buffer (base64 encoded or binary data) +const defaultAvatarBuffer = Buffer.from('UklGRlYDAABXRUJQVlA4IEoDAACwEgCdASpkAGQAPm0ylkekIqIhJpM7EIANiWkAFs6tQPy9d+/kCpiZj46PqX2Cf1s6vv7gFlcGy8GuVKz1sdC/dH5IfQePmbNKRqlkS5KofryVMES8OWaaCn4wjzYV6JN24CKoaNLEbpYeWkln493+j+aL2yMpUOl2PTUT853EL93KnDzFbjkRzZm4yepG1Xv6aXyFAdLiBGsXU3VEEAD++pWZOAJeXUf0nSxwdQhs5sUQMamUGMgYF/T+mPuqp2n7SZtXQAI3y982oC9FVCL1Wxkd8iQxf+kdTcTtXSihJtYMjv6O83cJ7I63fzSgCu1Cg0V+bPUd5p/lIM3s2yG+zlAm41qgUHXY6APIwoYnZHbmaPo/Ae0A5TMLMTzI811tC8KzIJaFgZAaIkGSlwdJJ6OB44nWkFUvvS5DI7WbsnmN+ODQJ/ZnOxFQAF8thZOM+R/zPGfkykrDeCmKl675UpJ4T6cHT65+T533XZLQYkxPwNtMfzJfcHsXoWTg4XtYh9QEkyT5CUc0w7Pkid0MyUV1eY0DV51HJujYWniM4owiJsuC/Bs/Ms6QoWlVsQSZ33iUhE0dem0ZEbT2SoqmGbp5e++GgIxGEm6120qoA802YzXm1LbYgOe3+/dvxQNAvJcKeZNGbVo/V/rSAT9ZX1ISi5kz1w32oJevgKOpJcqC44czmaJKrMBQFtcK2iuFp8KvhFXaUcFSr0sOQKZOvbhNeoGJfWq92vgNvBk0hJHu7HpSxKlCsNlGiwpwvlmWBvQGMi897HIU4ozprBqoc/1kI8yMHJTNVG9un+czA/3bHkP7v5tlyXx2cbfODTimFNc+C4sA3QdDX2a7a0MBuNsX7im51ny2ABSKJgBJEiJHxVcse1pzO+WwfYwU0orZWbYXAwb3DAd4c/Oaj/5H/fqwsb0GBu9ocDe5gXvL6ngJ7Aej/5SNIK44nR1Ik2hsGOldyihgIws16zmANwLGUECB46Bni0gaGgF6SaeoWv5XykxS3VNte/2mnR4P/YZ3J9VkAEeDLRnOnSFss2F0lSaLY8EFIiPgB0TnrWWMjOfx+XKZ0+X7Ef2XI9cdFMpLhWUAjY458nnh/feojuqi3h8dX35dECUwAA==', 'base64'); // Replace with actual base64 string of your default avatar + +// Updated signup route to handle file uploads +router.post('/signup', upload.single('avatar'), async (req, res) => { + + // Check if signup is enabled + if (!config.enableSignup) { + return res.status(403).send(` + + + + + + Signup Disabled + + + +

Signup is currently disabled.

+

Please contact the adminstrator for assistance.

+ + + + `); + } + + const { username, email, password } = req.body; + const avatar = req.file ? req.file.buffer : defaultAvatarBuffer; // Use default avatar if no file uploaded + + // Validate username and password lengths + if (!username || username.length <= 4) { + return res.redirect('signup?message=Username must be more than 4 characters.'); + } + + if (!password || password.length <= 8) { + return res.redirect('signup?message=Password must be more than 8 characters.'); + } + + // Check if all required fields are provided + if (!email) { + return res.redirect('signup?message=Please provide an email.'); + } + + try { + // Get a connection from the pool + const connection = await pool.getConnection(); + + // Check for existing username or email + const [rows] = await connection.execute( + 'SELECT * FROM accounts WHERE username = ? OR email = ?', + [username, email] + ); + + if (rows.length > 0) { + connection.release(); + return res.redirect('signup?message=Username or email already exists.'); + } + + // Hash the password + const hashedPassword = await bcrypt.hash(password, 10); + + // Insert new user into the database + await connection.execute( + 'INSERT INTO accounts (username, email, password, avatar) VALUES (?, ?, ?, ?)', + [username, email, hashedPassword, avatar] // Include avatar buffer here + ); + + // Release the connection back to the pool + connection.release(); + + // Respond with success message + res.redirect('signup?message=User registered successfully!'); + } catch (error) { + console.error('Database error:', error); + + // Handle other errors + res.redirect('signup?message=An unexpected error occurred.'); + } +}); + +module.exports = router;