Merge branch 'main' of https://github.com/Newtbot/MP
This commit is contained in:
commit
c76c819689
@ -1,5 +1,6 @@
|
|||||||
const express = require("express");
|
const express = require("express");
|
||||||
const session = require("express-session");
|
const session = require("express-session");
|
||||||
|
const rateLimit = require('express-rate-limit');
|
||||||
const mysql2 = require('mysql2');
|
const mysql2 = require('mysql2');
|
||||||
const bodyParser = require("body-parser");
|
const bodyParser = require("body-parser");
|
||||||
const bcrypt = require("bcrypt");
|
const bcrypt = require("bcrypt");
|
||||||
@ -128,6 +129,14 @@ const logActivity = async (username, success, message) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const limiter = rateLimit({
|
||||||
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||||
|
max: 5, // limit each IP to 3 requests per windowMs
|
||||||
|
message: 'Too many login attempts from this IP, please try again later.',
|
||||||
|
});
|
||||||
|
app.use('/login', limiter);
|
||||||
|
|
||||||
app.post('/login', [
|
app.post('/login', [
|
||||||
body('username').escape().trim().isLength({ min: 1 }).withMessage('Username must not be empty'),
|
body('username').escape().trim().isLength({ min: 1 }).withMessage('Username must not be empty'),
|
||||||
body('password').escape().trim().isLength({ min: 1 }).withMessage('Password must not be empty'),
|
body('password').escape().trim().isLength({ min: 1 }).withMessage('Password must not be empty'),
|
||||||
|
@ -1,19 +1,24 @@
|
|||||||
|
|
||||||
const express = require("express");
|
const express = require("express");
|
||||||
const helmet = require("helmet");
|
const helmet = require("helmet");
|
||||||
|
const path = require("path");
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(helmet());
|
|
||||||
const port = 80;
|
const port = 80;
|
||||||
|
|
||||||
|
const bodyParser = require('body-parser'); // Middleware
|
||||||
|
|
||||||
|
app.use(bodyParser.urlencoded({ extended: false }));
|
||||||
|
|
||||||
|
app.use(helmet());
|
||||||
//disable x-powered-by header for security reasons
|
//disable x-powered-by header for security reasons
|
||||||
app.disable("x-powered-by");
|
app.disable("x-powered-by");
|
||||||
|
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
app.set("json spaces", 2);
|
app.set("json spaces", 2);
|
||||||
|
|
||||||
|
//public folder with path to static files
|
||||||
|
app.use(express.static(path.join(__dirname, "../public")));
|
||||||
|
|
||||||
//middleware logic ( called by next() )
|
//middleware logic ( called by next() )
|
||||||
//app.use('/api/v0', APIlogger, require('../routes/api_route.js'));
|
//add token middeware upon login to validate routes that require token
|
||||||
|
|
||||||
//route logic
|
//route logic
|
||||||
app.use("/api/v0", require("../routes/api_routes")); //consumerWebsite\routes\api_routes.js
|
app.use("/api/v0", require("../routes/api_routes")); //consumerWebsite\routes\api_routes.js
|
||||||
@ -33,16 +38,16 @@ app.use(function(err, req, res, next) {
|
|||||||
if (![404].includes(err.status || res.status)) {
|
if (![404].includes(err.status || res.status)) {
|
||||||
console.error(err.message);
|
console.error(err.message);
|
||||||
console.error(err.stack);
|
console.error(err.stack);
|
||||||
console.error('=========================================');
|
console.error("=========================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(err.name + " validation error");
|
console.log(err.name + " validation error");
|
||||||
// Parse key error for Sequilzw
|
// Parse key error for Sequilzw
|
||||||
let keyErrors = {}
|
let keyErrors = {};
|
||||||
if(['SequelizeValidationError'].includes(err.name) && err.errors){
|
if (["SequelizeValidationError"].includes(err.name) && err.errors) {
|
||||||
for (let item of err.errors) {
|
for (let item of err.errors) {
|
||||||
if (item.path) {
|
if (item.path) {
|
||||||
keyErrors[item.path] = item.message
|
keyErrors[item.path] = item.message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
consumerWebsite/public/.gitignore
vendored
2
consumerWebsite/public/.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
node_modules
|
|
||||||
.env
|
|
Binary file not shown.
179
consumerWebsite/public/js/jquery.js
vendored
Normal file
179
consumerWebsite/public/js/jquery.js
vendored
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
var app = {};
|
||||||
|
|
||||||
|
/*
|
||||||
|
app.api = (function(app){
|
||||||
|
var baseURL = '/api/v0/'
|
||||||
|
|
||||||
|
function post(url, data, callback){
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: baseURL+url,
|
||||||
|
headers:{
|
||||||
|
'auth-token': app.auth.getToken()
|
||||||
|
},
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
dataType: "json",
|
||||||
|
complete: function(res, text){
|
||||||
|
callback(
|
||||||
|
text !== 'success' ? res.statusText : null,
|
||||||
|
JSON.parse(res.responseText),
|
||||||
|
res.status
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function put(url, data, callback){
|
||||||
|
$.ajax({
|
||||||
|
type: 'PUT',
|
||||||
|
url: baseURL+url,
|
||||||
|
headers:{
|
||||||
|
'auth-token': app.auth.getToken()
|
||||||
|
},
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
dataType: "json",
|
||||||
|
complete: function(res, text){
|
||||||
|
callback(
|
||||||
|
text !== 'success' ? res.statusText : null,
|
||||||
|
JSON.parse(res.responseText),
|
||||||
|
res.status
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove(url, callback, callback2){
|
||||||
|
if(!$.isFunction(callback)) callback = callback2;
|
||||||
|
$.ajax({
|
||||||
|
type: 'delete',
|
||||||
|
url: baseURL+url,
|
||||||
|
headers:{
|
||||||
|
'auth-token': app.auth.getToken()
|
||||||
|
},
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
dataType: "json",
|
||||||
|
complete: function(res, text){
|
||||||
|
callback(
|
||||||
|
text !== 'success' ? res.statusText : null,
|
||||||
|
JSON.parse(res.responseText),
|
||||||
|
res.status
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(url, callback){
|
||||||
|
$.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
url: baseURL+url,
|
||||||
|
headers:{
|
||||||
|
'auth-token': app.auth.getToken()
|
||||||
|
},
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
dataType: "json",
|
||||||
|
complete: function(res, text){
|
||||||
|
callback(
|
||||||
|
text !== 'success' ? res.statusText : null,
|
||||||
|
JSON.parse(res.responseText),
|
||||||
|
res.status
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {post: post, get: get, put: put, delete: remove}
|
||||||
|
})(app)
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.auth = (function(app) {
|
||||||
|
var user = {}
|
||||||
|
function setToken(token){
|
||||||
|
localStorage.setItem('APIToken', token);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getToken(){
|
||||||
|
return localStorage.getItem('APIToken');
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLoggedIn(callback){
|
||||||
|
if(getToken()){
|
||||||
|
return app.api.get('user/me', function(error, data){
|
||||||
|
if(!error) app.auth.user = data;
|
||||||
|
return callback(error, data);
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
callback(null, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function logIn(args, callback){
|
||||||
|
app.api.post('auth/login', args, function(error, data){
|
||||||
|
if(data.login){
|
||||||
|
setToken(data.token);
|
||||||
|
}
|
||||||
|
callback(error, !!data.token);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function logOut(callback){
|
||||||
|
localStorage.removeItem('APIToken');
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
function forceLogin(){
|
||||||
|
$.holdReady( true );
|
||||||
|
app.auth.isLoggedIn(function(error, isLoggedIn){
|
||||||
|
if(error || !isLoggedIn){
|
||||||
|
app.auth.logOut(function(){})
|
||||||
|
location.replace(`/login${location.href.replace(location.origin, '')}`);
|
||||||
|
}else{
|
||||||
|
$.holdReady( false );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function logInRedirect(){
|
||||||
|
window.location.href = location.href.replace(location.origin+'/login', '') || '/'
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
getToken: getToken,
|
||||||
|
setToken: setToken,
|
||||||
|
isLoggedIn: isLoggedIn,
|
||||||
|
logIn: logIn,
|
||||||
|
logOut: logOut,
|
||||||
|
forceLogin,
|
||||||
|
logInRedirect,
|
||||||
|
}
|
||||||
|
|
||||||
|
})(app);
|
||||||
|
|
||||||
|
//ajax form submit
|
||||||
|
function formAJAX( btn, del ) {
|
||||||
|
event.preventDefault(); // avoid to execute the actual submit of the form.
|
||||||
|
var $form = $(btn).closest( '[action]' ); // gets the 'form' parent
|
||||||
|
var formData = $form.find( '[name]' ).serializeObject(); // builds query formDataing
|
||||||
|
var method = $form.attr('method') || 'post';
|
||||||
|
|
||||||
|
// if( !$form.validate()) {
|
||||||
|
// app.util.actionMessage('Please fix the form errors.', $form, 'danger')
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
app.util.actionMessage(
|
||||||
|
'<div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div>',
|
||||||
|
$form,
|
||||||
|
'info'
|
||||||
|
);
|
||||||
|
|
||||||
|
app.api[method]($form.attr('action'), formData, function(error, data){
|
||||||
|
app.util.actionMessage(data.message, $form, error ? 'danger' : 'success'); //re-populate table
|
||||||
|
if(!error){
|
||||||
|
$form.trigger("reset");
|
||||||
|
eval($form.attr('evalAJAX')); //gets JS to run after completion
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
@ -1,36 +0,0 @@
|
|||||||
function validateFormLogin() {
|
|
||||||
var email = document.getElementById('email').value;
|
|
||||||
var password = document.getElementById('password').value;
|
|
||||||
|
|
||||||
// Perform basic validation
|
|
||||||
if (!email || !password) {
|
|
||||||
alert('Please enter both email and password');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sendDataToServer(email, password);
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendDataToServer(email, password) {
|
|
||||||
// Use AJAX or fetch to send data to the server
|
|
||||||
// Example using fetch:
|
|
||||||
fetch('/login', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ email, password }),
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
// Handle the response from the server
|
|
||||||
console.log(data);
|
|
||||||
if (data.success) {
|
|
||||||
// Redirect or perform other actions for successful login
|
|
||||||
alert('Login successful');
|
|
||||||
} else {
|
|
||||||
alert('Login failed. Please check your credentials.');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => console.error('Error:', error));
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
const express = require('express');
|
|
||||||
const dotenv = require('dotenv');
|
|
||||||
const bodyParser = require('body-parser');
|
|
||||||
const mysql = require('mysql');
|
|
||||||
|
|
||||||
dotenv.config();
|
|
||||||
|
|
||||||
|
|
||||||
app.use(express.static('public'));
|
|
||||||
|
|
||||||
const app = express();
|
|
||||||
const port = 3000;
|
|
||||||
|
|
||||||
app.use(bodyParser.json());
|
|
||||||
|
|
||||||
const db = mysql.createConnection({
|
|
||||||
host: 'localhost',
|
|
||||||
user: 'root',
|
|
||||||
password: 'your_mysql_password',
|
|
||||||
database: 'your_database_name',
|
|
||||||
});
|
|
||||||
|
|
||||||
db.connect(err => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Error connecting to MySQL:', err);
|
|
||||||
} else {
|
|
||||||
console.log('Connected to MySQL');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/signup', (req, res) => {
|
|
||||||
const { username, password } = req.body;
|
|
||||||
|
|
||||||
// Perform server-side validation if needed
|
|
||||||
|
|
||||||
const sql = 'INSERT INTO users (username, password) VALUES (?, ?)';
|
|
||||||
db.query(sql, [username, password], (err, result) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Error executing SQL query:', err);
|
|
||||||
res.status(500).json({ success: false, message: 'Internal Server Error' });
|
|
||||||
} else {
|
|
||||||
console.log('User signed up successfully');
|
|
||||||
res.json({ success: true, message: 'User signed up successfully' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
app.listen(port, () => {
|
|
||||||
console.log(`Server is running on http://localhost:${port}`);
|
|
||||||
});
|
|
@ -1,53 +0,0 @@
|
|||||||
function validateFormSignup() {
|
|
||||||
var username = document.getElementById('username').value;
|
|
||||||
var email = document.getElementById('email').value;
|
|
||||||
var password = document.getElementById('password').value;
|
|
||||||
var confirmPassword = document.getElementById('confirmPassword').value;
|
|
||||||
|
|
||||||
|
|
||||||
if (!/^[a-zA-Z0-9]+$/.test(username)) {
|
|
||||||
alert("Username can only contain letters and numbers.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email)) {
|
|
||||||
alert("Enter a valid email address.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/.test(password)) {
|
|
||||||
alert("Password must be more than 8 characters and contain at least 1 upper and lower case letter and 1 special character.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password !== confirmPassword) {
|
|
||||||
alert('Passwords do not match');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!signupCheck.checked) {
|
|
||||||
alert("Please accept the terms & conditions to proceed.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If validation passes, send data to the server
|
|
||||||
sendDataToServer(username, email, password);
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendDataToServer(username, password) {
|
|
||||||
// Use AJAX or fetch to send data to the server
|
|
||||||
// Example using fetch:
|
|
||||||
fetch('/signup', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ username, email, password }),
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
// Handle the response from the server
|
|
||||||
console.log(data);
|
|
||||||
})
|
|
||||||
.catch(error => console.error('Error:', error));
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<!-- Required meta tags -->
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
||||||
|
|
||||||
<!-- Bootstrap CSS -->
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
|
||||||
|
|
||||||
<title>Hello, world!</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Hello, world!</h1>
|
|
||||||
|
|
||||||
<!-- Optional JavaScript -->
|
|
||||||
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
|
|
||||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.14.3/dist/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -15,9 +15,10 @@ router.get("/", async (req, res, next) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// /user/register
|
||||||
router.post("/register", async (req, res, next) => {
|
router.post("/register", async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
await addUser(req.body);
|
//await addUser(req.body);
|
||||||
res.sendStatus(200);
|
res.sendStatus(200);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
2685
package-lock.json
generated
2685
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user