Skip to content

Commit

Permalink
Backend For login pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Akan45 committed Jan 12, 2025
1 parent 924a093 commit 67e0f03
Show file tree
Hide file tree
Showing 13 changed files with 1,635 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.env
/node_modules
2 changes: 2 additions & 0 deletions Server/api/.env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MONGO_URI="mongo_db_url"
JWT_SECRET="Your_JWT-SECRET_KEY"
20 changes: 20 additions & 0 deletions Server/api/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

import express from 'express';
import cors from 'cors';
import bodyParser from 'body-parser';
import authRoutes from '../routes/authRoutes.js';

const app = express();

// Middleware
app.use(cors());
app.use(express.json({ limit: '16kb' }));
app.use(express.urlencoded({ extended: true, limit: '16kb' }));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));


// Routes
app.use('/api/v1/auth', authRoutes); // Authentication routes

export { app };
24 changes: 24 additions & 0 deletions Server/api/dbconnect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import mongoose from 'mongoose';
import dotenv from 'dotenv'

dotenv.config()
// Database connection
export const dbConnect = async () => {
const url = process.env.MONGO_URI;

if (!url) {
console.error('No URL received from env. Check .env file path.');
process.exit(1);
}

try {
await mongoose.connect(url, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
console.log('MongoDB connected');
} catch (err) {
console.error('Database connection error:', err);
process.exit(1); // Exit process with failure
}
};
20 changes: 20 additions & 0 deletions Server/api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import dotenv from 'dotenv';
import { dbConnect } from './dbconnect.js';
import { app } from './app.js';

// Load environment variables
dotenv.config();

console.log('Starting app. MONGO_URI:', process.env.MONGO_URI);

// Connect to the database and start the server
dbConnect()
.then(() => {
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`App is running on port ${PORT} and DB connected`);
});
})
.catch((err) => {
console.error('Database connection failed:', err);
});
81 changes: 81 additions & 0 deletions Server/controller/authController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import jwt from 'jsonwebtoken';
import User from '../models/User.js';

// User Registration
export const registerUser = async (req, res) => {
const { username, email, password, dob, location } = req.body;

// Check for required fields
if (!username || !email || !password) {
return res.status(400).send({ error: "Username, email, and password are required." });
}

try {
// Check if the user already exists
const userExists = await User.findOne({ email });

if (userExists) {
return res.status(400).send({ message: 'User already exists' });
}

// Create a new user
const user = new User({
username,
email,
password,
dob, // Optional field
location, // Optional field
});

await user.save();
console.log('User saved successfully');

// Generate JWT token
const token = jwt.sign({ id: user._id }, "THIS_IS_A_JWT_SECRET", {
expiresIn: '1h',
});

// Respond with success message and token
res.status(201).send({
message: 'User created successfully',
token,
});
} catch (error) {
console.error('Error during user registration:', error);
res.status(500).send({ message: 'Server error', error: error.message });
}
};

// User Login
export const loginUser = async (req, res) => {
const { email, password } = req.body;

try {
const user = await User.findOne({ email });

if (!user) {
console.log("User does not exist");
return res.status(400).send({ message: 'Invalid credentials user' });
}

const isPasswordMatch = await user.matchPassword(password);

if (!isPasswordMatch) {
console.log("Password doesn't match");
return res.status(400).send({ message: 'Invalid credentials password' });
}

const token = jwt.sign({ id: user._id }, "THIS_IS_A_JWT_SECRET", {
expiresIn: '1h',
});

res.send({
message: 'Login successful',
token,
});
} catch (error) {
console.error('Error during user login:', error);
res.status(500).send({ message: 'Server error', error: error.message });
}
};

42 changes: 42 additions & 0 deletions Server/middleware/auth.middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import jwt from 'jsonwebtoken';

const authUser = async (req, res, next) => {
try {
// Extract the Authorization header
const authHeader = req.headers.authorization; // Note: Headers are case-insensitive

if (!authHeader) {
return res.status(401).json({ error: "No token found. Please log in first." });
}

// Split the Bearer token
const token = authHeader.split(' ')[1]; // Assumes format: "Bearer token"

if (!token) {
return res.status(401).json({ error: "Malformed token. Authorization failed." });
}

// Verify the token
const decoded = jwt.verify(token, "THIS_IS_A_JWT_SECRET"); // Replace with your secret key

// Add user data to request for downstream handlers
req.user = decoded;

// Pass control to the next middleware or route handler
next();
} catch (error) {
console.error("Error verifying token:", error.message);

// Handle specific JWT errors
if (error.name === 'TokenExpiredError') {
return res.status(401).json({ error: "Token expired. Please log in again." });
} else if (error.name === 'JsonWebTokenError') {
return res.status(401).json({ error: "Invalid token. Authorization failed." });
}

// Catch-all for unexpected errors
res.status(500).json({ error: "Internal server error during authentication." });
}
};

export {authUser};
55 changes: 55 additions & 0 deletions Server/models/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import mongoose from 'mongoose';
import bcrypt from 'bcryptjs';

// User schema
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
unique: true,
},
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
inSightsCount: {
type: Number,
default: 0,
},
createdOn: {
type: Date,
default: Date.now, // Automatically set to the current date and time
},
dob: {
type: Date, // Date of Birth field
required: false, // Optional field
},
location: {
type: String, // Can store city, state, or country
required: false, // Optional field
},
});

// Hash password before saving
userSchema.pre('save', async function (next) {
if (!this.isModified('password')) {
return next();
}
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
next();
});

// Method to compare password for login
userSchema.methods.matchPassword = async function (enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password);
};

const User = mongoose.model('User', userSchema);

export default User;
11 changes: 11 additions & 0 deletions Server/routes/authRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import express from 'express';
import { registerUser, loginUser } from '../controller/authController.js';
const router = express.Router();

// Register Route
router.post('/signup', registerUser);

// Login Route
router.post('/login', loginUser);

export default router;
42 changes: 42 additions & 0 deletions js/signup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
document.addEventListener('DOMContentLoaded', function() {
const signupForm = document.getElementById('signupForm');
if (signupForm) {
signupForm.addEventListener('submit', handleSignupSubmit);
}
});

function handleSignupSubmit(event) {
event.preventDefault(); // Prevent the default form submission

const username = document.getElementById('username').value;
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
const confirmPassword = document.getElementById('confirmPassword').value;

if (password !== confirmPassword) {
alert('Passwords do not match');
return;
}

const formData = { username, email, password };

// fetch('https://insight-sync-u1bq.vercel.app/api/v1/auth/signup', {
fetch('http://localhost:3000/api/v1/auth/signup', {

method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData),
})
.then(response => response.json())
.then(data => {
if (data.token) {
alert('Signup successful! You are now logged in.');
localStorage.setItem('authToken', data.token);
window.location.href = '/SCD-Profile-Score/';
} else {
alert('Signup failed: ' + data.message);
}
})
.catch(error => console.error('Error:', error));
}

Loading

0 comments on commit 67e0f03

Please sign in to comment.